diff --git a/go.sum b/go.sum index 22518a8a..4cad843f 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= -github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= @@ -34,8 +32,6 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= -github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= @@ -59,8 +55,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -88,8 +82,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stripe/stripe-go/v76 v76.21.0 h1:O3GHImHS4oUI3qWMOClHN3zAQF5/oswS/NB7leV1fsU= -github.com/stripe/stripe-go/v76 v76.21.0/go.mod h1:rw1MxjlAKKcZ+3FOXgTHgwiOa2ya6CPq6ykpJ0Q6Po4= github.com/stripe/stripe-go/v76 v76.23.0 h1:LCnTghh1x9d7r9rPbr2BcrQZ6oLpNSkT/rIWGkuMBHc= github.com/stripe/stripe-go/v76 v76.23.0/go.mod h1:rw1MxjlAKKcZ+3FOXgTHgwiOa2ya6CPq6ykpJ0Q6Po4= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -100,10 +92,10 @@ github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21 github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.3 h1:1JXy1XroaGrzZuG6X9dt7HL6s9AwbY+l4UNL8o5B6ho= -github.com/zclconf/go-cty v1.14.3/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -114,8 +106,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -158,12 +148,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/vendor/github.com/hashicorp/go-hclog/intlogger.go b/vendor/github.com/hashicorp/go-hclog/intlogger.go index 104d82ff..272a710c 100644 --- a/vendor/github.com/hashicorp/go-hclog/intlogger.go +++ b/vendor/github.com/hashicorp/go-hclog/intlogger.go @@ -80,12 +80,13 @@ var _ Logger = &intLogger{} // intLogger is an internal logger implementation. Internal in that it is // defined entirely by this package. type intLogger struct { - json bool - callerOffset int - name string - timeFormat string - timeFn TimeFunction - disableTime bool + json bool + jsonEscapeEnabled bool + callerOffset int + name string + timeFormat string + timeFn TimeFunction + disableTime bool // This is an interface so that it's shared by any derived loggers, since // those derived loggers share the bufio.Writer as well. @@ -173,6 +174,7 @@ func newLogger(opts *LoggerOptions) *intLogger { l := &intLogger{ json: opts.JSONFormat, + jsonEscapeEnabled: !opts.JSONEscapeDisabled, name: opts.Name, timeFormat: TimeFormat, timeFn: time.Now, @@ -667,13 +669,17 @@ func (l *intLogger) logJSON(t time.Time, name string, level Level, msg string, a } } - err := json.NewEncoder(l.writer).Encode(vals) + encoder := json.NewEncoder(l.writer) + encoder.SetEscapeHTML(l.jsonEscapeEnabled) + err := encoder.Encode(vals) if err != nil { if _, ok := err.(*json.UnsupportedTypeError); ok { plainVal := l.jsonMapEntry(t, name, level, msg) plainVal["@warn"] = errJsonUnsupportedTypeMsg - json.NewEncoder(l.writer).Encode(plainVal) + errEncoder := json.NewEncoder(l.writer) + errEncoder.SetEscapeHTML(l.jsonEscapeEnabled) + errEncoder.Encode(plainVal) } } } diff --git a/vendor/github.com/hashicorp/go-hclog/logger.go b/vendor/github.com/hashicorp/go-hclog/logger.go index d7806fb5..ad17544f 100644 --- a/vendor/github.com/hashicorp/go-hclog/logger.go +++ b/vendor/github.com/hashicorp/go-hclog/logger.go @@ -264,6 +264,9 @@ type LoggerOptions struct { // Control if the output should be in JSON. JSONFormat bool + // Control the escape switch of json.Encoder + JSONEscapeDisabled bool + // Include file and line information in each log line IncludeLocation bool diff --git a/vendor/github.com/hashicorp/hcl/v2/CHANGELOG.md b/vendor/github.com/hashicorp/hcl/v2/CHANGELOG.md index 1597a28b..2eebedbc 100644 --- a/vendor/github.com/hashicorp/hcl/v2/CHANGELOG.md +++ b/vendor/github.com/hashicorp/hcl/v2/CHANGELOG.md @@ -1,5 +1,15 @@ # HCL Changelog +## v2.20.1 (March 26, 2024) + +### Bugs Fixed + +* Return `ExprSyntaxError` when an invalid namespaced function is encountered during parsing ([#668](https://github.com/hashicorp/hcl/pull/668)) + +### Internal + +* Standardize on only two value dumping/diffing libraries ([#669](https://github.com/hashicorp/hcl/pull/669)) + ## v2.20.0 (February 29, 2024) ### Enhancements diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression.go index c4a353c4..81597399 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression.go @@ -2013,3 +2013,27 @@ func (e *AnonSymbolExpr) Range() hcl.Range { func (e *AnonSymbolExpr) StartRange() hcl.Range { return e.SrcRange } + +// ExprSyntaxError is a placeholder for an invalid expression that could not +// be parsed due to syntax errors. +type ExprSyntaxError struct { + Placeholder cty.Value + ParseDiags hcl.Diagnostics + SrcRange hcl.Range +} + +func (e *ExprSyntaxError) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { + return e.Placeholder, e.ParseDiags +} + +func (e *ExprSyntaxError) walkChildNodes(w internalWalkFunc) { + // ExprSyntaxError is a leaf node in the tree +} + +func (e *ExprSyntaxError) Range() hcl.Range { + return e.SrcRange +} + +func (e *ExprSyntaxError) StartRange() hcl.Range { + return e.SrcRange +} diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_vars.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_vars.go index ce5a5cb7..6c3e472c 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_vars.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/expression_vars.go @@ -3,7 +3,7 @@ package hclsyntax -// Generated by expression_vars_get.go. DO NOT EDIT. +// Generated by expression_vars_gen.go. DO NOT EDIT. // Run 'go generate' on this package to update the set of functions here. import ( @@ -22,6 +22,10 @@ func (e *ConditionalExpr) Variables() []hcl.Traversal { return Variables(e) } +func (e *ExprSyntaxError) Variables() []hcl.Traversal { + return Variables(e) +} + func (e *ForExpr) Variables() []hcl.Traversal { return Variables(e) } diff --git a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser.go b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser.go index cd9d63d2..ce96ae35 100644 --- a/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser.go +++ b/vendor/github.com/hashicorp/hcl/v2/hclsyntax/parser.go @@ -1161,15 +1161,20 @@ func (p *parser) finishParsingFunctionCall(name Token) (Expression, hcl.Diagnost for openTok.Type == TokenDoubleColon { nextName := p.Read() if nextName.Type != TokenIdent { - diags = append(diags, &hcl.Diagnostic{ + diag := hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Missing function name", Detail: "Function scope resolution symbol :: must be followed by a function name in this scope.", Subject: &nextName.Range, Context: hcl.RangeBetween(name.Range, nextName.Range).Ptr(), - }) + } + diags = append(diags, &diag) p.recoverOver(TokenOParen) - return nil, diags + return &ExprSyntaxError{ + ParseDiags: hcl.Diagnostics{&diag}, + Placeholder: cty.DynamicVal, + SrcRange: hcl.RangeBetween(name.Range, nextName.Range), + }, diags } // Initial versions of HCLv2 didn't support function namespaces, and @@ -1192,15 +1197,21 @@ func (p *parser) finishParsingFunctionCall(name Token) (Expression, hcl.Diagnost } if openTok.Type != TokenOParen { - diags = append(diags, &hcl.Diagnostic{ + diag := hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Missing open parenthesis", Detail: "Function selector must be followed by an open parenthesis to begin the function call.", Subject: &openTok.Range, Context: hcl.RangeBetween(name.Range, openTok.Range).Ptr(), - }) + } + + diags = append(diags, &diag) p.recoverOver(TokenOParen) - return nil, diags + return &ExprSyntaxError{ + ParseDiags: hcl.Diagnostics{&diag}, + Placeholder: cty.DynamicVal, + SrcRange: hcl.RangeBetween(name.Range, openTok.Range), + }, diags } var args []Expression diff --git a/vendor/github.com/stripe/stripe-go/v76/CHANGELOG.md b/vendor/github.com/stripe/stripe-go/v76/CHANGELOG.md index 6cf28d40..727278cc 100644 --- a/vendor/github.com/stripe/stripe-go/v76/CHANGELOG.md +++ b/vendor/github.com/stripe/stripe-go/v76/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## 76.23.0 - 2024-03-28 +* [#1830](https://github.com/stripe/stripe-go/pull/1830) Update generated code + * Add support for new resources `Billing.MeterEventAdjustment`, `Billing.MeterEvent`, and `Billing.Meter` + * Add support for `Deactivate`, `Get`, `List`, `New`, `Reactivate`, and `Update` methods on resource `Meter` + * Add support for `New` method on resources `MeterEventAdjustment` and `MeterEvent` + * Add support for `AmazonPayPayments` on `AccountCapabilitiesParams` and `AccountCapabilities` + * Add support for new value `verification_failed_representative_authority` on enums `AccountFutureRequirementsErrorsCode`, `AccountRequirementsErrorsCode`, `BankAccountFutureRequirementsErrorsCode`, and `BankAccountRequirementsErrorsCode` + * Add support for `DestinationOnBehalfOfChargeManagement` on `AccountSessionComponentsPaymentDetailsFeaturesParams`, `AccountSessionComponentsPaymentDetailsFeatures`, `AccountSessionComponentsPaymentsFeaturesParams`, and `AccountSessionComponentsPaymentsFeatures` + * Add support for `Mandate` on `ChargePaymentMethodDetailsUsBankAccount`, `TreasuryInboundTransferOriginPaymentMethodDetailsUsBankAccount`, `TreasuryOutboundPaymentDestinationPaymentMethodDetailsUsBankAccount`, and `TreasuryOutboundTransferDestinationPaymentMethodDetailsUsBankAccount` + * Add support for `SecondLine` on `IssuingCardParams` + * Add support for `Meter` on `PlanParams`, `Plan`, `PriceListRecurringParams`, `PriceRecurringParams`, and `PriceRecurring` + +## 76.22.0 - 2024-03-21 +* [#1828](https://github.com/stripe/stripe-go/pull/1828) Update generated code + * Add support for new resources `ConfirmationToken` and `Forwarding.Request` + * Add support for `Get` method on resource `ConfirmationToken` + * Add support for `Get`, `List`, and `New` methods on resource `Request` + * Add support for `MobilepayPayments` on `AccountCapabilitiesParams` and `AccountCapabilities` + * Add support for new values `forwarding_api_inactive`, `forwarding_api_invalid_parameter`, `forwarding_api_upstream_connection_error`, and `forwarding_api_upstream_connection_timeout` on enums `InvoiceLastFinalizationErrorCode`, `PaymentIntentLastPaymentErrorCode`, `SetupAttemptSetupErrorCode`, `SetupIntentLastSetupErrorCode`, and `StripeErrorCode` + * Add support for `Mobilepay` on `ChargePaymentMethodDetails`, `PaymentIntentConfirmPaymentMethodDataParams`, `PaymentIntentConfirmPaymentMethodOptionsParams`, `PaymentIntentPaymentMethodDataParams`, `PaymentIntentPaymentMethodOptionsParams`, `PaymentIntentPaymentMethodOptions`, `PaymentMethodParams`, `PaymentMethod`, `SetupIntentConfirmPaymentMethodDataParams`, and `SetupIntentPaymentMethodDataParams` + * Add support for `PaymentReference` on `ChargePaymentMethodDetailsUsBankAccount` + * Add support for `ConfirmationToken` on `PaymentIntentConfirmParams`, `PaymentIntentParams`, `SetupIntentConfirmParams`, and `SetupIntentParams` + * Add support for new value `mobilepay` on enum `PaymentMethodType` + * Add support for `Name` on `TerminalConfigurationParams` and `TerminalConfiguration` + * Add support for `Payout` on `TreasuryReceivedDebitLinkedFlows` + ## 76.21.0 - 2024-03-14 * [#1824](https://github.com/stripe/stripe-go/pull/1824) Update generated code * Add support for new resources `Issuing.PersonalizationDesign` and `Issuing.PhysicalBundle` diff --git a/vendor/github.com/stripe/stripe-go/v76/OPENAPI_VERSION b/vendor/github.com/stripe/stripe-go/v76/OPENAPI_VERSION index 0963e32f..7044b5ab 100644 --- a/vendor/github.com/stripe/stripe-go/v76/OPENAPI_VERSION +++ b/vendor/github.com/stripe/stripe-go/v76/OPENAPI_VERSION @@ -1 +1 @@ -v878 \ No newline at end of file +v911 \ No newline at end of file diff --git a/vendor/github.com/stripe/stripe-go/v76/VERSION b/vendor/github.com/stripe/stripe-go/v76/VERSION index bc1e3984..4eade4bf 100644 --- a/vendor/github.com/stripe/stripe-go/v76/VERSION +++ b/vendor/github.com/stripe/stripe-go/v76/VERSION @@ -1 +1 @@ -76.21.0 +76.23.0 diff --git a/vendor/github.com/stripe/stripe-go/v76/account.go b/vendor/github.com/stripe/stripe-go/v76/account.go index 594d58a4..0aed0038 100644 --- a/vendor/github.com/stripe/stripe-go/v76/account.go +++ b/vendor/github.com/stripe/stripe-go/v76/account.go @@ -264,6 +264,12 @@ type AccountCapabilitiesAfterpayClearpayPaymentsParams struct { Requested *bool `form:"requested"` } +// The amazon_pay_payments capability. +type AccountCapabilitiesAmazonPayPaymentsParams struct { + // Passing true requests the capability for the account, if it is not already requested. A requested capability may not immediately become active. Any requirements to activate the capability are returned in the `requirements` arrays. + Requested *bool `form:"requested"` +} + // The au_becs_debit_payments capability. type AccountCapabilitiesAUBECSDebitPaymentsParams struct { // Passing true requests the capability for the account, if it is not already requested. A requested capability may not immediately become active. Any requirements to activate the capability are returned in the `requirements` arrays. @@ -390,6 +396,12 @@ type AccountCapabilitiesLinkPaymentsParams struct { Requested *bool `form:"requested"` } +// The mobilepay_payments capability. +type AccountCapabilitiesMobilepayPaymentsParams struct { + // Passing true requests the capability for the account, if it is not already requested. A requested capability may not immediately become active. Any requirements to activate the capability are returned in the `requirements` arrays. + Requested *bool `form:"requested"` +} + // The oxxo_payments capability. type AccountCapabilitiesOXXOPaymentsParams struct { // Passing true requests the capability for the account, if it is not already requested. A requested capability may not immediately become active. Any requirements to activate the capability are returned in the `requirements` arrays. @@ -482,6 +494,8 @@ type AccountCapabilitiesParams struct { AffirmPayments *AccountCapabilitiesAffirmPaymentsParams `form:"affirm_payments"` // The afterpay_clearpay_payments capability. AfterpayClearpayPayments *AccountCapabilitiesAfterpayClearpayPaymentsParams `form:"afterpay_clearpay_payments"` + // The amazon_pay_payments capability. + AmazonPayPayments *AccountCapabilitiesAmazonPayPaymentsParams `form:"amazon_pay_payments"` // The au_becs_debit_payments capability. AUBECSDebitPayments *AccountCapabilitiesAUBECSDebitPaymentsParams `form:"au_becs_debit_payments"` // The bacs_debit_payments capability. @@ -524,6 +538,8 @@ type AccountCapabilitiesParams struct { LegacyPayments *AccountCapabilitiesLegacyPaymentsParams `form:"legacy_payments"` // The link_payments capability. LinkPayments *AccountCapabilitiesLinkPaymentsParams `form:"link_payments"` + // The mobilepay_payments capability. + MobilepayPayments *AccountCapabilitiesMobilepayPaymentsParams `form:"mobilepay_payments"` // The oxxo_payments capability. OXXOPayments *AccountCapabilitiesOXXOPaymentsParams `form:"oxxo_payments"` // The p24_payments capability. @@ -979,6 +995,8 @@ type AccountCapabilities struct { AffirmPayments AccountCapabilityStatus `json:"affirm_payments"` // The status of the Afterpay Clearpay capability of the account, or whether the account can directly process Afterpay Clearpay charges. AfterpayClearpayPayments AccountCapabilityStatus `json:"afterpay_clearpay_payments"` + // The status of the AmazonPay capability of the account, or whether the account can directly process AmazonPay payments. + AmazonPayPayments AccountCapabilityStatus `json:"amazon_pay_payments"` // The status of the BECS Direct Debit (AU) payments capability of the account, or whether the account can directly process BECS Direct Debit (AU) charges. AUBECSDebitPayments AccountCapabilityStatus `json:"au_becs_debit_payments"` // The status of the Bacs Direct Debits payments capability of the account, or whether the account can directly process Bacs Direct Debits charges. @@ -1021,6 +1039,8 @@ type AccountCapabilities struct { LegacyPayments AccountCapabilityStatus `json:"legacy_payments"` // The status of the link_payments capability of the account, or whether the account can directly process Link charges. LinkPayments AccountCapabilityStatus `json:"link_payments"` + // The status of the MobilepPay capability of the account, or whether the account can directly process MobilePay charges. + MobilepayPayments AccountCapabilityStatus `json:"mobilepay_payments"` // The status of the OXXO payments capability of the account, or whether the account can directly process OXXO charges. OXXOPayments AccountCapabilityStatus `json:"oxxo_payments"` // The status of the P24 payments capability of the account, or whether the account can directly process P24 charges. diff --git a/vendor/github.com/stripe/stripe-go/v76/accountsession.go b/vendor/github.com/stripe/stripe-go/v76/accountsession.go index 251094c1..cf797743 100644 --- a/vendor/github.com/stripe/stripe-go/v76/accountsession.go +++ b/vendor/github.com/stripe/stripe-go/v76/accountsession.go @@ -32,6 +32,8 @@ type AccountSessionComponentsDocumentsParams struct { type AccountSessionComponentsPaymentDetailsFeaturesParams struct { // Whether to allow capturing and cancelling payment intents. This is `true` by default. CapturePayments *bool `form:"capture_payments"` + // Whether to allow connected accounts to manage destination charges that are created on behalf of them. This is `false` by default. + DestinationOnBehalfOfChargeManagement *bool `form:"destination_on_behalf_of_charge_management"` // Whether to allow responding to disputes, including submitting evidence and accepting disputes. This is `true` by default. DisputeManagement *bool `form:"dispute_management"` // Whether to allow sending refunds. This is `true` by default. @@ -50,6 +52,8 @@ type AccountSessionComponentsPaymentDetailsParams struct { type AccountSessionComponentsPaymentsFeaturesParams struct { // Whether to allow capturing and cancelling payment intents. This is `true` by default. CapturePayments *bool `form:"capture_payments"` + // Whether to allow connected accounts to manage destination charges that are created on behalf of them. This is `false` by default. + DestinationOnBehalfOfChargeManagement *bool `form:"destination_on_behalf_of_charge_management"` // Whether to allow responding to disputes, including submitting evidence and accepting disputes. This is `true` by default. DisputeManagement *bool `form:"dispute_management"` // Whether to allow sending refunds. This is `true` by default. @@ -127,6 +131,8 @@ type AccountSessionComponentsDocuments struct { type AccountSessionComponentsPaymentDetailsFeatures struct { // Whether to allow capturing and cancelling payment intents. This is `true` by default. CapturePayments bool `json:"capture_payments"` + // Whether to allow connected accounts to manage destination charges that are created on behalf of them. This is `false` by default. + DestinationOnBehalfOfChargeManagement bool `json:"destination_on_behalf_of_charge_management"` // Whether to allow responding to disputes, including submitting evidence and accepting disputes. This is `true` by default. DisputeManagement bool `json:"dispute_management"` // Whether to allow sending refunds. This is `true` by default. @@ -140,6 +146,8 @@ type AccountSessionComponentsPaymentDetails struct { type AccountSessionComponentsPaymentsFeatures struct { // Whether to allow capturing and cancelling payment intents. This is `true` by default. CapturePayments bool `json:"capture_payments"` + // Whether to allow connected accounts to manage destination charges that are created on behalf of them. This is `false` by default. + DestinationOnBehalfOfChargeManagement bool `json:"destination_on_behalf_of_charge_management"` // Whether to allow responding to disputes, including submitting evidence and accepting disputes. This is `true` by default. DisputeManagement bool `json:"dispute_management"` // Whether to allow sending refunds. This is `true` by default. diff --git a/vendor/github.com/stripe/stripe-go/v76/bankaccount.go b/vendor/github.com/stripe/stripe-go/v76/bankaccount.go index faf6b01b..1d28cebe 100644 --- a/vendor/github.com/stripe/stripe-go/v76/bankaccount.go +++ b/vendor/github.com/stripe/stripe-go/v76/bankaccount.go @@ -115,6 +115,7 @@ const ( BankAccountFutureRequirementsErrorCodeVerificationFailedKeyedMatch BankAccountFutureRequirementsErrorCode = "verification_failed_keyed_match" BankAccountFutureRequirementsErrorCodeVerificationFailedNameMatch BankAccountFutureRequirementsErrorCode = "verification_failed_name_match" BankAccountFutureRequirementsErrorCodeVerificationFailedOther BankAccountFutureRequirementsErrorCode = "verification_failed_other" + BankAccountFutureRequirementsErrorCodeVerificationFailedRepresentativeAuthority BankAccountFutureRequirementsErrorCode = "verification_failed_representative_authority" BankAccountFutureRequirementsErrorCodeVerificationFailedResidentialAddress BankAccountFutureRequirementsErrorCode = "verification_failed_residential_address" BankAccountFutureRequirementsErrorCodeVerificationFailedTaxIDMatch BankAccountFutureRequirementsErrorCode = "verification_failed_tax_id_match" BankAccountFutureRequirementsErrorCodeVerificationFailedTaxIDNotIssued BankAccountFutureRequirementsErrorCode = "verification_failed_tax_id_not_issued" @@ -209,6 +210,7 @@ const ( BankAccountRequirementsErrorCodeVerificationFailedKeyedMatch BankAccountRequirementsErrorCode = "verification_failed_keyed_match" BankAccountRequirementsErrorCodeVerificationFailedNameMatch BankAccountRequirementsErrorCode = "verification_failed_name_match" BankAccountRequirementsErrorCodeVerificationFailedOther BankAccountRequirementsErrorCode = "verification_failed_other" + BankAccountRequirementsErrorCodeVerificationFailedRepresentativeAuthority BankAccountRequirementsErrorCode = "verification_failed_representative_authority" BankAccountRequirementsErrorCodeVerificationFailedResidentialAddress BankAccountRequirementsErrorCode = "verification_failed_residential_address" BankAccountRequirementsErrorCodeVerificationFailedTaxIDMatch BankAccountRequirementsErrorCode = "verification_failed_tax_id_match" BankAccountRequirementsErrorCodeVerificationFailedTaxIDNotIssued BankAccountRequirementsErrorCode = "verification_failed_tax_id_not_issued" diff --git a/vendor/github.com/stripe/stripe-go/v76/billing/meter/client.go b/vendor/github.com/stripe/stripe-go/v76/billing/meter/client.go new file mode 100644 index 00000000..46aca361 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/billing/meter/client.go @@ -0,0 +1,128 @@ +// +// +// File generated from our OpenAPI spec +// +// + +// Package meter provides the /billing/meters APIs +package meter + +import ( + "net/http" + + stripe "github.com/stripe/stripe-go/v76" + "github.com/stripe/stripe-go/v76/form" +) + +// Client is used to invoke /billing/meters APIs. +type Client struct { + B stripe.Backend + Key string +} + +// New creates a new billing meter. +func New(params *stripe.BillingMeterParams) (*stripe.BillingMeter, error) { + return getC().New(params) +} + +// New creates a new billing meter. +func (c Client) New(params *stripe.BillingMeterParams) (*stripe.BillingMeter, error) { + meter := &stripe.BillingMeter{} + err := c.B.Call(http.MethodPost, "/v1/billing/meters", c.Key, params, meter) + return meter, err +} + +// Get returns the details of a billing meter. +func Get(id string, params *stripe.BillingMeterParams) (*stripe.BillingMeter, error) { + return getC().Get(id, params) +} + +// Get returns the details of a billing meter. +func (c Client) Get(id string, params *stripe.BillingMeterParams) (*stripe.BillingMeter, error) { + path := stripe.FormatURLPath("/v1/billing/meters/%s", id) + meter := &stripe.BillingMeter{} + err := c.B.Call(http.MethodGet, path, c.Key, params, meter) + return meter, err +} + +// Update updates a billing meter's properties. +func Update(id string, params *stripe.BillingMeterParams) (*stripe.BillingMeter, error) { + return getC().Update(id, params) +} + +// Update updates a billing meter's properties. +func (c Client) Update(id string, params *stripe.BillingMeterParams) (*stripe.BillingMeter, error) { + path := stripe.FormatURLPath("/v1/billing/meters/%s", id) + meter := &stripe.BillingMeter{} + err := c.B.Call(http.MethodPost, path, c.Key, params, meter) + return meter, err +} + +// Deactivate is the method for the `POST /v1/billing/meters/{id}/deactivate` API. +func Deactivate(id string, params *stripe.BillingMeterDeactivateParams) (*stripe.BillingMeter, error) { + return getC().Deactivate(id, params) +} + +// Deactivate is the method for the `POST /v1/billing/meters/{id}/deactivate` API. +func (c Client) Deactivate(id string, params *stripe.BillingMeterDeactivateParams) (*stripe.BillingMeter, error) { + path := stripe.FormatURLPath("/v1/billing/meters/%s/deactivate", id) + meter := &stripe.BillingMeter{} + err := c.B.Call(http.MethodPost, path, c.Key, params, meter) + return meter, err +} + +// Reactivate is the method for the `POST /v1/billing/meters/{id}/reactivate` API. +func Reactivate(id string, params *stripe.BillingMeterReactivateParams) (*stripe.BillingMeter, error) { + return getC().Reactivate(id, params) +} + +// Reactivate is the method for the `POST /v1/billing/meters/{id}/reactivate` API. +func (c Client) Reactivate(id string, params *stripe.BillingMeterReactivateParams) (*stripe.BillingMeter, error) { + path := stripe.FormatURLPath("/v1/billing/meters/%s/reactivate", id) + meter := &stripe.BillingMeter{} + err := c.B.Call(http.MethodPost, path, c.Key, params, meter) + return meter, err +} + +// List returns a list of billing meters. +func List(params *stripe.BillingMeterListParams) *Iter { + return getC().List(params) +} + +// List returns a list of billing meters. +func (c Client) List(listParams *stripe.BillingMeterListParams) *Iter { + return &Iter{ + Iter: stripe.GetIter(listParams, func(p *stripe.Params, b *form.Values) ([]interface{}, stripe.ListContainer, error) { + list := &stripe.BillingMeterList{} + err := c.B.CallRaw(http.MethodGet, "/v1/billing/meters", c.Key, b, p, list) + + ret := make([]interface{}, len(list.Data)) + for i, v := range list.Data { + ret[i] = v + } + + return ret, list, err + }), + } +} + +// Iter is an iterator for billing meters. +type Iter struct { + *stripe.Iter +} + +// BillingMeter returns the billing meter which the iterator is currently pointing to. +func (i *Iter) BillingMeter() *stripe.BillingMeter { + return i.Current().(*stripe.BillingMeter) +} + +// BillingMeterList returns the current list object which the iterator is +// currently using. List objects will change as new API calls are made to +// continue pagination. +func (i *Iter) BillingMeterList() *stripe.BillingMeterList { + return i.List().(*stripe.BillingMeterList) +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/vendor/github.com/stripe/stripe-go/v76/billing/meterevent/client.go b/vendor/github.com/stripe/stripe-go/v76/billing/meterevent/client.go new file mode 100644 index 00000000..61a06071 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/billing/meterevent/client.go @@ -0,0 +1,42 @@ +// +// +// File generated from our OpenAPI spec +// +// + +// Package meterevent provides the /billing/meter_events APIs +package meterevent + +import ( + "net/http" + + stripe "github.com/stripe/stripe-go/v76" +) + +// Client is used to invoke /billing/meter_events APIs. +type Client struct { + B stripe.Backend + Key string +} + +// New creates a new billing meter event. +func New(params *stripe.BillingMeterEventParams) (*stripe.BillingMeterEvent, error) { + return getC().New(params) +} + +// New creates a new billing meter event. +func (c Client) New(params *stripe.BillingMeterEventParams) (*stripe.BillingMeterEvent, error) { + meterevent := &stripe.BillingMeterEvent{} + err := c.B.Call( + http.MethodPost, + "/v1/billing/meter_events", + c.Key, + params, + meterevent, + ) + return meterevent, err +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/vendor/github.com/stripe/stripe-go/v76/billing/metereventadjustment/client.go b/vendor/github.com/stripe/stripe-go/v76/billing/metereventadjustment/client.go new file mode 100644 index 00000000..885ebab5 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/billing/metereventadjustment/client.go @@ -0,0 +1,42 @@ +// +// +// File generated from our OpenAPI spec +// +// + +// Package metereventadjustment provides the /billing/meter_event_adjustments APIs +package metereventadjustment + +import ( + "net/http" + + stripe "github.com/stripe/stripe-go/v76" +) + +// Client is used to invoke /billing/meter_event_adjustments APIs. +type Client struct { + B stripe.Backend + Key string +} + +// New creates a new billing meter event adjustment. +func New(params *stripe.BillingMeterEventAdjustmentParams) (*stripe.BillingMeterEventAdjustment, error) { + return getC().New(params) +} + +// New creates a new billing meter event adjustment. +func (c Client) New(params *stripe.BillingMeterEventAdjustmentParams) (*stripe.BillingMeterEventAdjustment, error) { + metereventadjustment := &stripe.BillingMeterEventAdjustment{} + err := c.B.Call( + http.MethodPost, + "/v1/billing/meter_event_adjustments", + c.Key, + params, + metereventadjustment, + ) + return metereventadjustment, err +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/vendor/github.com/stripe/stripe-go/v76/billing/metereventsummary/client.go b/vendor/github.com/stripe/stripe-go/v76/billing/metereventsummary/client.go new file mode 100644 index 00000000..c5614071 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/billing/metereventsummary/client.go @@ -0,0 +1,68 @@ +// +// +// File generated from our OpenAPI spec +// +// + +// Package metereventsummary provides the /billing/meters/{id}/event_summaries APIs +package metereventsummary + +import ( + "net/http" + + stripe "github.com/stripe/stripe-go/v76" + "github.com/stripe/stripe-go/v76/form" +) + +// Client is used to invoke /billing/meters/{id}/event_summaries APIs. +type Client struct { + B stripe.Backend + Key string +} + +// List returns a list of billing meter event summaries. +func List(params *stripe.BillingMeterEventSummaryListParams) *Iter { + return getC().List(params) +} + +// List returns a list of billing meter event summaries. +func (c Client) List(listParams *stripe.BillingMeterEventSummaryListParams) *Iter { + path := stripe.FormatURLPath( + "/v1/billing/meters/%s/event_summaries", + stripe.StringValue(listParams.ID), + ) + return &Iter{ + Iter: stripe.GetIter(listParams, func(p *stripe.Params, b *form.Values) ([]interface{}, stripe.ListContainer, error) { + list := &stripe.BillingMeterEventSummaryList{} + err := c.B.CallRaw(http.MethodGet, path, c.Key, b, p, list) + + ret := make([]interface{}, len(list.Data)) + for i, v := range list.Data { + ret[i] = v + } + + return ret, list, err + }), + } +} + +// Iter is an iterator for billing meter event summaries. +type Iter struct { + *stripe.Iter +} + +// BillingMeterEventSummary returns the billing meter event summary which the iterator is currently pointing to. +func (i *Iter) BillingMeterEventSummary() *stripe.BillingMeterEventSummary { + return i.Current().(*stripe.BillingMeterEventSummary) +} + +// BillingMeterEventSummaryList returns the current list object which the iterator is +// currently using. List objects will change as new API calls are made to +// continue pagination. +func (i *Iter) BillingMeterEventSummaryList() *stripe.BillingMeterEventSummaryList { + return i.List().(*stripe.BillingMeterEventSummaryList) +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/vendor/github.com/stripe/stripe-go/v76/billing_meter.go b/vendor/github.com/stripe/stripe-go/v76/billing_meter.go new file mode 100644 index 00000000..d1b898b0 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/billing_meter.go @@ -0,0 +1,177 @@ +// +// +// File generated from our OpenAPI spec +// +// + +package stripe + +// The method for mapping a meter event to a customer. +type BillingMeterCustomerMappingType string + +// List of values that BillingMeterCustomerMappingType can take +const ( + BillingMeterCustomerMappingTypeByID BillingMeterCustomerMappingType = "by_id" +) + +// Specifies how events are aggregated. +type BillingMeterDefaultAggregationFormula string + +// List of values that BillingMeterDefaultAggregationFormula can take +const ( + BillingMeterDefaultAggregationFormulaCount BillingMeterDefaultAggregationFormula = "count" + BillingMeterDefaultAggregationFormulaSum BillingMeterDefaultAggregationFormula = "sum" +) + +// The time window to pre-aggregate usage events for, if any. +type BillingMeterEventTimeWindow string + +// List of values that BillingMeterEventTimeWindow can take +const ( + BillingMeterEventTimeWindowDay BillingMeterEventTimeWindow = "day" + BillingMeterEventTimeWindowHour BillingMeterEventTimeWindow = "hour" +) + +// The meter's status. +type BillingMeterStatus string + +// List of values that BillingMeterStatus can take +const ( + BillingMeterStatusActive BillingMeterStatus = "active" + BillingMeterStatusInactive BillingMeterStatus = "inactive" +) + +// Retrieve a list of billing meters. +type BillingMeterListParams struct { + ListParams `form:"*"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` + // Filter results to only include meters with the given status. + Status *string `form:"status"` +} + +// AddExpand appends a new field to expand. +func (p *BillingMeterListParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// Fields that specify how to map a meter event to a customer. +type BillingMeterCustomerMappingParams struct { + // The key in the usage event payload to use for mapping the event to a customer. + EventPayloadKey *string `form:"event_payload_key"` + // The method for mapping a meter event to a customer. Must be `by_id`. + Type *string `form:"type"` +} + +// The default settings to aggregate a meter's events with. +type BillingMeterDefaultAggregationParams struct { + // Specifies how events are aggregated. Allowed values are `count` to count the number of events, `sum` to sum each event's value, or `last` to use the last event's value. + Formula *string `form:"formula"` +} + +// Fields that specify how to calculate a usage event's value. +type BillingMeterValueSettingsParams struct { + // The key in the usage event payload to use as the value for this meter. For example, if the event payload contains usage on a `bytes_used` field, then set the event_payload_key to "bytes_used". + EventPayloadKey *string `form:"event_payload_key"` +} + +// Creates a billing meter +type BillingMeterParams struct { + Params `form:"*"` + // Fields that specify how to map a meter event to a customer. + CustomerMapping *BillingMeterCustomerMappingParams `form:"customer_mapping"` + // The default settings to aggregate a meter's events with. + DefaultAggregation *BillingMeterDefaultAggregationParams `form:"default_aggregation"` + // The meter's name. + DisplayName *string `form:"display_name"` + // The name of the usage event to record usage for. Corresponds with the `event_name` field on usage events. + EventName *string `form:"event_name"` + // The time window to pre-aggregate usage events for, if any. + EventTimeWindow *string `form:"event_time_window"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` + // Fields that specify how to calculate a usage event's value. + ValueSettings *BillingMeterValueSettingsParams `form:"value_settings"` +} + +// AddExpand appends a new field to expand. +func (p *BillingMeterParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// Deactivates a billing meter +type BillingMeterDeactivateParams struct { + Params `form:"*"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` +} + +// AddExpand appends a new field to expand. +func (p *BillingMeterDeactivateParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// Reactivates a billing meter +type BillingMeterReactivateParams struct { + Params `form:"*"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` +} + +// AddExpand appends a new field to expand. +func (p *BillingMeterReactivateParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +type BillingMeterCustomerMapping struct { + // The key in the usage event payload to use for mapping the event to a customer. + EventPayloadKey string `json:"event_payload_key"` + // The method for mapping a meter event to a customer. + Type BillingMeterCustomerMappingType `json:"type"` +} +type BillingMeterDefaultAggregation struct { + // Specifies how events are aggregated. + Formula BillingMeterDefaultAggregationFormula `json:"formula"` +} +type BillingMeterStatusTransitions struct { + // The time the meter was deactivated, if any. Measured in seconds since Unix epoch. + DeactivatedAt int64 `json:"deactivated_at"` +} +type BillingMeterValueSettings struct { + // The key in the usage event payload to use as the value for this meter. + EventPayloadKey string `json:"event_payload_key"` +} + +// A billing meter is a resource that allows you to track usage of a particular event. For example, you might create a billing meter to track the number of API calls made by a particular user. You can then use the billing meter to charge the user for the number of API calls they make. +type BillingMeter struct { + APIResource + // Time at which the object was created. Measured in seconds since the Unix epoch. + Created int64 `json:"created"` + CustomerMapping *BillingMeterCustomerMapping `json:"customer_mapping"` + DefaultAggregation *BillingMeterDefaultAggregation `json:"default_aggregation"` + // The meter's name. + DisplayName string `json:"display_name"` + // The name of the usage event to record usage for. Corresponds with the `event_name` field on usage events. + EventName string `json:"event_name"` + // The time window to pre-aggregate usage events for, if any. + EventTimeWindow BillingMeterEventTimeWindow `json:"event_time_window"` + // Unique identifier for the object. + ID string `json:"id"` + // Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. + Livemode bool `json:"livemode"` + // String representing the object's type. Objects of the same type share the same value. + Object string `json:"object"` + // The meter's status. + Status BillingMeterStatus `json:"status"` + StatusTransitions *BillingMeterStatusTransitions `json:"status_transitions"` + // Time at which the object was last updated. Measured in seconds since the Unix epoch. + Updated int64 `json:"updated"` + ValueSettings *BillingMeterValueSettings `json:"value_settings"` +} + +// BillingMeterList is a list of Meters as retrieved from a list endpoint. +type BillingMeterList struct { + APIResource + ListMeta + Data []*BillingMeter `json:"data"` +} diff --git a/vendor/github.com/stripe/stripe-go/v76/billing_meterevent.go b/vendor/github.com/stripe/stripe-go/v76/billing_meterevent.go new file mode 100644 index 00000000..587125f2 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/billing_meterevent.go @@ -0,0 +1,47 @@ +// +// +// File generated from our OpenAPI spec +// +// + +package stripe + +// Creates a billing meter event +type BillingMeterEventParams struct { + Params `form:"*"` + // The name of the meter event. Corresponds with the `event_name` field on a meter. + EventName *string `form:"event_name"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` + // A unique identifier for the event. If not provided, one will be generated. + Identifier *string `form:"identifier"` + // The payload of the event. This must contain a field with the event's numerical value and a field to map the event to a customer. + Payload map[string]string `form:"payload"` + // The time of the event. Measured in seconds since the Unix epoch. + Timestamp *int64 `form:"timestamp"` +} + +// AddExpand appends a new field to expand. +func (p *BillingMeterEventParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// A billing meter event represents a customer's usage of a product. Meter events are used to bill a customer based on their usage. +// Meter events are associated with billing meters, which define the shape of the event's payload and how those events are aggregated for billing. +type BillingMeterEvent struct { + APIResource + // Time at which the object was created. Measured in seconds since the Unix epoch. + Created int64 `json:"created"` + // The name of the meter event. Corresponds with the `event_name` field on a meter. + EventName string `json:"event_name"` + // A unique identifier for the event. + Identifier string `json:"identifier"` + // Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. + Livemode bool `json:"livemode"` + // String representing the object's type. Objects of the same type share the same value. + Object string `json:"object"` + // The payload of the event. + Payload map[string]string `json:"payload"` + // The timestamp passed in when creating the event. Measured in seconds since the Unix epoch. + Timestamp int64 `json:"timestamp"` +} diff --git a/vendor/github.com/stripe/stripe-go/v76/billing_metereventadjustment.go b/vendor/github.com/stripe/stripe-go/v76/billing_metereventadjustment.go new file mode 100644 index 00000000..b96118ef --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/billing_metereventadjustment.go @@ -0,0 +1,49 @@ +// +// +// File generated from our OpenAPI spec +// +// + +package stripe + +// The meter event adjustment's status. +type BillingMeterEventAdjustmentStatus string + +// List of values that BillingMeterEventAdjustmentStatus can take +const ( + BillingMeterEventAdjustmentStatusComplete BillingMeterEventAdjustmentStatus = "complete" + BillingMeterEventAdjustmentStatusPending BillingMeterEventAdjustmentStatus = "pending" +) + +// Specifies which event to cancel. +type BillingMeterEventAdjustmentCancelParams struct { + // Unique identifier for the event. + Identifier *string `form:"identifier"` +} + +// Creates a billing meter event adjustment +type BillingMeterEventAdjustmentParams struct { + Params `form:"*"` + // Specifies which event to cancel. + Cancel *BillingMeterEventAdjustmentCancelParams `form:"cancel"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` + // Specifies whether to cancel a single event or a range of events for a time period. + Type *string `form:"type"` +} + +// AddExpand appends a new field to expand. +func (p *BillingMeterEventAdjustmentParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// A billing meter event adjustment represents the status of a meter event adjustment. +type BillingMeterEventAdjustment struct { + APIResource + // Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. + Livemode bool `json:"livemode"` + // String representing the object's type. Objects of the same type share the same value. + Object string `json:"object"` + // The meter event adjustment's status. + Status BillingMeterEventAdjustmentStatus `json:"status"` +} diff --git a/vendor/github.com/stripe/stripe-go/v76/billing_metereventsummary.go b/vendor/github.com/stripe/stripe-go/v76/billing_metereventsummary.go new file mode 100644 index 00000000..a82eacf3 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/billing_metereventsummary.go @@ -0,0 +1,54 @@ +// +// +// File generated from our OpenAPI spec +// +// + +package stripe + +// Retrieve a list of billing meter event summaries. +type BillingMeterEventSummaryListParams struct { + ListParams `form:"*"` + ID *string `form:"-"` // Included in URL + // The customer for which to fetch event summaries. + Customer *string `form:"customer"` + // The timestamp from when to stop aggregating usage events (exclusive). + EndTime *int64 `form:"end_time"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` + // The timestamp from when to start aggregating usage events (inclusive). + StartTime *int64 `form:"start_time"` + // Specifies what granularity to use when generating event summaries. If not specified, a single event summary would be returned for the specified time range. + ValueGroupingWindow *string `form:"value_grouping_window"` +} + +// AddExpand appends a new field to expand. +func (p *BillingMeterEventSummaryListParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// A billing meter event summary represents an aggregated view of a customer's billing meter events within a specified timeframe. It indicates how much +// usage was accrued by a customer for that period. +type BillingMeterEventSummary struct { + // Aggregated value of all the events within start_time (inclusive) and end_time (inclusive). The aggregation strategy is defined on meter via `default_aggregation``. + AggregatedValue float64 `json:"aggregated_value"` + // End timestamp for this usage summary (inclusive). + EndTime int64 `json:"end_time"` + // Unique identifier for the object. + ID string `json:"id"` + // Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. + Livemode bool `json:"livemode"` + // The meter associated with this usage summary. + Meter string `json:"meter"` + // String representing the object's type. Objects of the same type share the same value. + Object string `json:"object"` + // Start timestamp for this usage summary (inclusive). + StartTime int64 `json:"start_time"` +} + +// BillingMeterEventSummaryList is a list of MeterEventSummaries as retrieved from a list endpoint. +type BillingMeterEventSummaryList struct { + APIResource + ListMeta + Data []*BillingMeterEventSummary `json:"data"` +} diff --git a/vendor/github.com/stripe/stripe-go/v76/charge.go b/vendor/github.com/stripe/stripe-go/v76/charge.go index 7441ecce..fec0d167 100644 --- a/vendor/github.com/stripe/stripe-go/v76/charge.go +++ b/vendor/github.com/stripe/stripe-go/v76/charge.go @@ -847,7 +847,7 @@ type ChargePaymentMethodDetailsCardPresentReceipt struct { AuthorizationCode string `json:"authorization_code"` // EMV tag 8A. A code returned by the card issuer. AuthorizationResponseCode string `json:"authorization_response_code"` - // How the cardholder verified ownership of the card. + // Describes the method used by the cardholder to verify ownership of the card. One of the following: `approval`, `failure`, `none`, `offline_pin`, `offline_pin_and_signature`, `online_pin`, or `signature`. CardholderVerificationMethod string `json:"cardholder_verification_method"` // EMV tag 84. Similar to the application identifier stored on the integrated circuit chip. DedicatedFileName string `json:"dedicated_file_name"` @@ -971,7 +971,7 @@ type ChargePaymentMethodDetailsInteracPresentReceipt struct { AuthorizationCode string `json:"authorization_code"` // EMV tag 8A. A code returned by the card issuer. AuthorizationResponseCode string `json:"authorization_response_code"` - // How the cardholder verified ownership of the card. + // Describes the method used by the cardholder to verify ownership of the card. One of the following: `approval`, `failure`, `none`, `offline_pin`, `offline_pin_and_signature`, `online_pin`, or `signature`. CardholderVerificationMethod string `json:"cardholder_verification_method"` // EMV tag 84. Similar to the application identifier stored on the integrated circuit chip. DedicatedFileName string `json:"dedicated_file_name"` @@ -1043,6 +1043,21 @@ type ChargePaymentMethodDetailsLink struct { // You could use this attribute to get a sense of international fees. Country string `json:"country"` } +type ChargePaymentMethodDetailsMobilepayCard struct { + // Brand of the card used in the transaction + Brand string `json:"brand"` + // Two-letter ISO code representing the country of the card + Country string `json:"country"` + // Two digit number representing the card's expiration month + ExpMonth int64 `json:"exp_month"` + // Two digit number representing the card's expiration year + ExpYear int64 `json:"exp_year"` + // The last 4 digits of the card + Last4 string `json:"last4"` +} +type ChargePaymentMethodDetailsMobilepay struct { + Card *ChargePaymentMethodDetailsMobilepayCard `json:"card"` +} type ChargePaymentMethodDetailsMultibanco struct { // Entity number associated with this Multibanco payment. Entity string `json:"entity"` @@ -1162,6 +1177,10 @@ type ChargePaymentMethodDetailsUSBankAccount struct { Fingerprint string `json:"fingerprint"` // Last four digits of the bank account number. Last4 string `json:"last4"` + // ID of the mandate used to make this payment. + Mandate *Mandate `json:"mandate"` + // Reference number to locate ACH payments with customer's bank. + PaymentReference string `json:"payment_reference"` // Routing number of the bank account. RoutingNumber string `json:"routing_number"` } @@ -1200,6 +1219,7 @@ type ChargePaymentMethodDetails struct { Klarna *ChargePaymentMethodDetailsKlarna `json:"klarna"` Konbini *ChargePaymentMethodDetailsKonbini `json:"konbini"` Link *ChargePaymentMethodDetailsLink `json:"link"` + Mobilepay *ChargePaymentMethodDetailsMobilepay `json:"mobilepay"` Multibanco *ChargePaymentMethodDetailsMultibanco `json:"multibanco"` OXXO *ChargePaymentMethodDetailsOXXO `json:"oxxo"` P24 *ChargePaymentMethodDetailsP24 `json:"p24"` diff --git a/vendor/github.com/stripe/stripe-go/v76/client/api.go b/vendor/github.com/stripe/stripe-go/v76/client/api.go index a3469671..063eb6ee 100644 --- a/vendor/github.com/stripe/stripe-go/v76/client/api.go +++ b/vendor/github.com/stripe/stripe-go/v76/client/api.go @@ -18,6 +18,10 @@ import ( "github.com/stripe/stripe-go/v76/balance" "github.com/stripe/stripe-go/v76/balancetransaction" "github.com/stripe/stripe-go/v76/bankaccount" + billingmeter "github.com/stripe/stripe-go/v76/billing/meter" + billingmeterevent "github.com/stripe/stripe-go/v76/billing/meterevent" + billingmetereventadjustment "github.com/stripe/stripe-go/v76/billing/metereventadjustment" + billingmetereventsummary "github.com/stripe/stripe-go/v76/billing/metereventsummary" billingportalconfiguration "github.com/stripe/stripe-go/v76/billingportal/configuration" billingportalsession "github.com/stripe/stripe-go/v76/billingportal/session" "github.com/stripe/stripe-go/v76/capability" @@ -28,6 +32,7 @@ import ( climateorder "github.com/stripe/stripe-go/v76/climate/order" climateproduct "github.com/stripe/stripe-go/v76/climate/product" climatesupplier "github.com/stripe/stripe-go/v76/climate/supplier" + "github.com/stripe/stripe-go/v76/confirmationtoken" "github.com/stripe/stripe-go/v76/countryspec" "github.com/stripe/stripe-go/v76/coupon" "github.com/stripe/stripe-go/v76/creditnote" @@ -44,6 +49,7 @@ import ( financialconnectionsaccount "github.com/stripe/stripe-go/v76/financialconnections/account" financialconnectionssession "github.com/stripe/stripe-go/v76/financialconnections/session" financialconnectionstransaction "github.com/stripe/stripe-go/v76/financialconnections/transaction" + forwardingrequest "github.com/stripe/stripe-go/v76/forwarding/request" identityverificationreport "github.com/stripe/stripe-go/v76/identity/verificationreport" identityverificationsession "github.com/stripe/stripe-go/v76/identity/verificationsession" "github.com/stripe/stripe-go/v76/invoice" @@ -100,6 +106,7 @@ import ( terminalconnectiontoken "github.com/stripe/stripe-go/v76/terminal/connectiontoken" terminallocation "github.com/stripe/stripe-go/v76/terminal/location" terminalreader "github.com/stripe/stripe-go/v76/terminal/reader" + testhelpersconfirmationtoken "github.com/stripe/stripe-go/v76/testhelpers/confirmationtoken" testhelperscustomer "github.com/stripe/stripe-go/v76/testhelpers/customer" testhelpersissuingauthorization "github.com/stripe/stripe-go/v76/testhelpers/issuing/authorization" testhelpersissuingcard "github.com/stripe/stripe-go/v76/testhelpers/issuing/card" @@ -152,6 +159,14 @@ type API struct { BalanceTransactions *balancetransaction.Client // BankAccounts is the client used to invoke bankaccount related APIs. BankAccounts *bankaccount.Client + // BillingMeterEventAdjustments is the client used to invoke /billing/meter_event_adjustments APIs. + BillingMeterEventAdjustments *billingmetereventadjustment.Client + // BillingMeterEvents is the client used to invoke /billing/meter_events APIs. + BillingMeterEvents *billingmeterevent.Client + // BillingMeterEventSummaries is the client used to invoke /billing/meters/{id}/event_summaries APIs. + BillingMeterEventSummaries *billingmetereventsummary.Client + // BillingMeters is the client used to invoke /billing/meters APIs. + BillingMeters *billingmeter.Client // BillingPortalConfigurations is the client used to invoke /billing_portal/configurations APIs. BillingPortalConfigurations *billingportalconfiguration.Client // BillingPortalSessions is the client used to invoke /billing_portal/sessions APIs. @@ -172,6 +187,8 @@ type API struct { ClimateProducts *climateproduct.Client // ClimateSuppliers is the client used to invoke /climate/suppliers APIs. ClimateSuppliers *climatesupplier.Client + // ConfirmationTokens is the client used to invoke /confirmation_tokens APIs. + ConfirmationTokens *confirmationtoken.Client // CountrySpecs is the client used to invoke /country_specs APIs. CountrySpecs *countryspec.Client // Coupons is the client used to invoke /coupons APIs. @@ -204,6 +221,8 @@ type API struct { FinancialConnectionsSessions *financialconnectionssession.Client // FinancialConnectionsTransactions is the client used to invoke /financial_connections/transactions APIs. FinancialConnectionsTransactions *financialconnectionstransaction.Client + // ForwardingRequests is the client used to invoke /forwarding/requests APIs. + ForwardingRequests *forwardingrequest.Client // IdentityVerificationReports is the client used to invoke /identity/verification_reports APIs. IdentityVerificationReports *identityverificationreport.Client // IdentityVerificationSessions is the client used to invoke /identity/verification_sessions APIs. @@ -316,6 +335,8 @@ type API struct { TerminalLocations *terminallocation.Client // TerminalReaders is the client used to invoke /terminal/readers APIs. TerminalReaders *terminalreader.Client + // TestHelpersConfirmationTokens is the client used to invoke /confirmation_tokens APIs. + TestHelpersConfirmationTokens *testhelpersconfirmationtoken.Client // TestHelpersCustomers is the client used to invoke /customers APIs. TestHelpersCustomers *testhelperscustomer.Client // TestHelpersIssuingAuthorizations is the client used to invoke /issuing/authorizations APIs. @@ -397,6 +418,10 @@ func (a *API) Init(key string, backends *stripe.Backends) { a.Balance = &balance.Client{B: backends.API, Key: key} a.BalanceTransactions = &balancetransaction.Client{B: backends.API, Key: key} a.BankAccounts = &bankaccount.Client{B: backends.API, Key: key} + a.BillingMeterEventAdjustments = &billingmetereventadjustment.Client{B: backends.API, Key: key} + a.BillingMeterEvents = &billingmeterevent.Client{B: backends.API, Key: key} + a.BillingMeterEventSummaries = &billingmetereventsummary.Client{B: backends.API, Key: key} + a.BillingMeters = &billingmeter.Client{B: backends.API, Key: key} a.BillingPortalConfigurations = &billingportalconfiguration.Client{B: backends.API, Key: key} a.BillingPortalSessions = &billingportalsession.Client{B: backends.API, Key: key} a.Capabilities = &capability.Client{B: backends.API, Key: key} @@ -407,6 +432,7 @@ func (a *API) Init(key string, backends *stripe.Backends) { a.ClimateOrders = &climateorder.Client{B: backends.API, Key: key} a.ClimateProducts = &climateproduct.Client{B: backends.API, Key: key} a.ClimateSuppliers = &climatesupplier.Client{B: backends.API, Key: key} + a.ConfirmationTokens = &confirmationtoken.Client{B: backends.API, Key: key} a.CountrySpecs = &countryspec.Client{B: backends.API, Key: key} a.Coupons = &coupon.Client{B: backends.API, Key: key} a.CreditNotes = &creditnote.Client{B: backends.API, Key: key} @@ -423,6 +449,7 @@ func (a *API) Init(key string, backends *stripe.Backends) { a.FinancialConnectionsAccounts = &financialconnectionsaccount.Client{B: backends.API, Key: key} a.FinancialConnectionsSessions = &financialconnectionssession.Client{B: backends.API, Key: key} a.FinancialConnectionsTransactions = &financialconnectionstransaction.Client{B: backends.API, Key: key} + a.ForwardingRequests = &forwardingrequest.Client{B: backends.API, Key: key} a.IdentityVerificationReports = &identityverificationreport.Client{B: backends.API, Key: key} a.IdentityVerificationSessions = &identityverificationsession.Client{B: backends.API, Key: key} a.InvoiceItems = &invoiceitem.Client{B: backends.API, Key: key} @@ -479,6 +506,7 @@ func (a *API) Init(key string, backends *stripe.Backends) { a.TerminalConnectionTokens = &terminalconnectiontoken.Client{B: backends.API, Key: key} a.TerminalLocations = &terminallocation.Client{B: backends.API, Key: key} a.TerminalReaders = &terminalreader.Client{B: backends.API, Key: key} + a.TestHelpersConfirmationTokens = &testhelpersconfirmationtoken.Client{B: backends.API, Key: key} a.TestHelpersCustomers = &testhelperscustomer.Client{B: backends.API, Key: key} a.TestHelpersIssuingAuthorizations = &testhelpersissuingauthorization.Client{B: backends.API, Key: key} a.TestHelpersIssuingCards = &testhelpersissuingcard.Client{B: backends.API, Key: key} diff --git a/vendor/github.com/stripe/stripe-go/v76/confirmationtoken.go b/vendor/github.com/stripe/stripe-go/v76/confirmationtoken.go new file mode 100644 index 00000000..915c2538 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/confirmationtoken.go @@ -0,0 +1,790 @@ +// +// +// File generated from our OpenAPI spec +// +// + +package stripe + +// The type of the card wallet, one of `amex_express_checkout`, `apple_pay`, `google_pay`, `masterpass`, `samsung_pay`, `visa_checkout`, or `link`. An additional hash is included on the Wallet subhash with a name matching this value. It contains additional information specific to the card wallet type. +type ConfirmationTokenPaymentMethodPreviewCardWalletType string + +// List of values that ConfirmationTokenPaymentMethodPreviewCardWalletType can take +const ( + ConfirmationTokenPaymentMethodPreviewCardWalletTypeAmexExpressCheckout ConfirmationTokenPaymentMethodPreviewCardWalletType = "amex_express_checkout" + ConfirmationTokenPaymentMethodPreviewCardWalletTypeApplePay ConfirmationTokenPaymentMethodPreviewCardWalletType = "apple_pay" + ConfirmationTokenPaymentMethodPreviewCardWalletTypeGooglePay ConfirmationTokenPaymentMethodPreviewCardWalletType = "google_pay" + ConfirmationTokenPaymentMethodPreviewCardWalletTypeLink ConfirmationTokenPaymentMethodPreviewCardWalletType = "link" + ConfirmationTokenPaymentMethodPreviewCardWalletTypeMasterpass ConfirmationTokenPaymentMethodPreviewCardWalletType = "masterpass" + ConfirmationTokenPaymentMethodPreviewCardWalletTypeSamsungPay ConfirmationTokenPaymentMethodPreviewCardWalletType = "samsung_pay" + ConfirmationTokenPaymentMethodPreviewCardWalletTypeVisaCheckout ConfirmationTokenPaymentMethodPreviewCardWalletType = "visa_checkout" +) + +// How card details were read in this transaction. +type ConfirmationTokenPaymentMethodPreviewCardPresentReadMethod string + +// List of values that ConfirmationTokenPaymentMethodPreviewCardPresentReadMethod can take +const ( + ConfirmationTokenPaymentMethodPreviewCardPresentReadMethodContactEmv ConfirmationTokenPaymentMethodPreviewCardPresentReadMethod = "contact_emv" + ConfirmationTokenPaymentMethodPreviewCardPresentReadMethodContactlessEmv ConfirmationTokenPaymentMethodPreviewCardPresentReadMethod = "contactless_emv" + ConfirmationTokenPaymentMethodPreviewCardPresentReadMethodContactlessMagstripeMode ConfirmationTokenPaymentMethodPreviewCardPresentReadMethod = "contactless_magstripe_mode" + ConfirmationTokenPaymentMethodPreviewCardPresentReadMethodMagneticStripeFallback ConfirmationTokenPaymentMethodPreviewCardPresentReadMethod = "magnetic_stripe_fallback" + ConfirmationTokenPaymentMethodPreviewCardPresentReadMethodMagneticStripeTrack2 ConfirmationTokenPaymentMethodPreviewCardPresentReadMethod = "magnetic_stripe_track2" +) + +// The customer's bank. Should be one of `arzte_und_apotheker_bank`, `austrian_anadi_bank_ag`, `bank_austria`, `bankhaus_carl_spangler`, `bankhaus_schelhammer_und_schattera_ag`, `bawag_psk_ag`, `bks_bank_ag`, `brull_kallmus_bank_ag`, `btv_vier_lander_bank`, `capital_bank_grawe_gruppe_ag`, `deutsche_bank_ag`, `dolomitenbank`, `easybank_ag`, `erste_bank_und_sparkassen`, `hypo_alpeadriabank_international_ag`, `hypo_noe_lb_fur_niederosterreich_u_wien`, `hypo_oberosterreich_salzburg_steiermark`, `hypo_tirol_bank_ag`, `hypo_vorarlberg_bank_ag`, `hypo_bank_burgenland_aktiengesellschaft`, `marchfelder_bank`, `oberbank_ag`, `raiffeisen_bankengruppe_osterreich`, `schoellerbank_ag`, `sparda_bank_wien`, `volksbank_gruppe`, `volkskreditbank_ag`, or `vr_bank_braunau`. +type ConfirmationTokenPaymentMethodPreviewEPSBank string + +// List of values that ConfirmationTokenPaymentMethodPreviewEPSBank can take +const ( + ConfirmationTokenPaymentMethodPreviewEPSBankArzteUndApothekerBank ConfirmationTokenPaymentMethodPreviewEPSBank = "arzte_und_apotheker_bank" + ConfirmationTokenPaymentMethodPreviewEPSBankAustrianAnadiBankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "austrian_anadi_bank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankBankAustria ConfirmationTokenPaymentMethodPreviewEPSBank = "bank_austria" + ConfirmationTokenPaymentMethodPreviewEPSBankBankhausCarlSpangler ConfirmationTokenPaymentMethodPreviewEPSBank = "bankhaus_carl_spangler" + ConfirmationTokenPaymentMethodPreviewEPSBankBankhausSchelhammerUndSchatteraAg ConfirmationTokenPaymentMethodPreviewEPSBank = "bankhaus_schelhammer_und_schattera_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankBawagPskAg ConfirmationTokenPaymentMethodPreviewEPSBank = "bawag_psk_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankBksBankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "bks_bank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankBrullKallmusBankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "brull_kallmus_bank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankBtvVierLanderBank ConfirmationTokenPaymentMethodPreviewEPSBank = "btv_vier_lander_bank" + ConfirmationTokenPaymentMethodPreviewEPSBankCapitalBankGraweGruppeAg ConfirmationTokenPaymentMethodPreviewEPSBank = "capital_bank_grawe_gruppe_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankDeutscheBankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "deutsche_bank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankDolomitenbank ConfirmationTokenPaymentMethodPreviewEPSBank = "dolomitenbank" + ConfirmationTokenPaymentMethodPreviewEPSBankEasybankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "easybank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankErsteBankUndSparkassen ConfirmationTokenPaymentMethodPreviewEPSBank = "erste_bank_und_sparkassen" + ConfirmationTokenPaymentMethodPreviewEPSBankHypoAlpeadriabankInternationalAg ConfirmationTokenPaymentMethodPreviewEPSBank = "hypo_alpeadriabank_international_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankHypoBankBurgenlandAktiengesellschaft ConfirmationTokenPaymentMethodPreviewEPSBank = "hypo_bank_burgenland_aktiengesellschaft" + ConfirmationTokenPaymentMethodPreviewEPSBankHypoNoeLbFurNiederosterreichUWien ConfirmationTokenPaymentMethodPreviewEPSBank = "hypo_noe_lb_fur_niederosterreich_u_wien" + ConfirmationTokenPaymentMethodPreviewEPSBankHypoOberosterreichSalzburgSteiermark ConfirmationTokenPaymentMethodPreviewEPSBank = "hypo_oberosterreich_salzburg_steiermark" + ConfirmationTokenPaymentMethodPreviewEPSBankHypoTirolBankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "hypo_tirol_bank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankHypoVorarlbergBankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "hypo_vorarlberg_bank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankMarchfelderBank ConfirmationTokenPaymentMethodPreviewEPSBank = "marchfelder_bank" + ConfirmationTokenPaymentMethodPreviewEPSBankOberbankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "oberbank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankRaiffeisenBankengruppeOsterreich ConfirmationTokenPaymentMethodPreviewEPSBank = "raiffeisen_bankengruppe_osterreich" + ConfirmationTokenPaymentMethodPreviewEPSBankSchoellerbankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "schoellerbank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankSpardaBankWien ConfirmationTokenPaymentMethodPreviewEPSBank = "sparda_bank_wien" + ConfirmationTokenPaymentMethodPreviewEPSBankVolksbankGruppe ConfirmationTokenPaymentMethodPreviewEPSBank = "volksbank_gruppe" + ConfirmationTokenPaymentMethodPreviewEPSBankVolkskreditbankAg ConfirmationTokenPaymentMethodPreviewEPSBank = "volkskreditbank_ag" + ConfirmationTokenPaymentMethodPreviewEPSBankVrBankBraunau ConfirmationTokenPaymentMethodPreviewEPSBank = "vr_bank_braunau" +) + +// Account holder type, if provided. Can be one of `individual` or `company`. +type ConfirmationTokenPaymentMethodPreviewFPXAccountHolderType string + +// List of values that ConfirmationTokenPaymentMethodPreviewFPXAccountHolderType can take +const ( + ConfirmationTokenPaymentMethodPreviewFPXAccountHolderTypeCompany ConfirmationTokenPaymentMethodPreviewFPXAccountHolderType = "company" + ConfirmationTokenPaymentMethodPreviewFPXAccountHolderTypeIndividual ConfirmationTokenPaymentMethodPreviewFPXAccountHolderType = "individual" +) + +// The customer's bank, if provided. Can be one of `affin_bank`, `agrobank`, `alliance_bank`, `ambank`, `bank_islam`, `bank_muamalat`, `bank_rakyat`, `bsn`, `cimb`, `hong_leong_bank`, `hsbc`, `kfh`, `maybank2u`, `ocbc`, `public_bank`, `rhb`, `standard_chartered`, `uob`, `deutsche_bank`, `maybank2e`, `pb_enterprise`, or `bank_of_china`. +type ConfirmationTokenPaymentMethodPreviewFPXBank string + +// List of values that ConfirmationTokenPaymentMethodPreviewFPXBank can take +const ( + ConfirmationTokenPaymentMethodPreviewFPXBankAffinBank ConfirmationTokenPaymentMethodPreviewFPXBank = "affin_bank" + ConfirmationTokenPaymentMethodPreviewFPXBankAgrobank ConfirmationTokenPaymentMethodPreviewFPXBank = "agrobank" + ConfirmationTokenPaymentMethodPreviewFPXBankAllianceBank ConfirmationTokenPaymentMethodPreviewFPXBank = "alliance_bank" + ConfirmationTokenPaymentMethodPreviewFPXBankAmbank ConfirmationTokenPaymentMethodPreviewFPXBank = "ambank" + ConfirmationTokenPaymentMethodPreviewFPXBankBankIslam ConfirmationTokenPaymentMethodPreviewFPXBank = "bank_islam" + ConfirmationTokenPaymentMethodPreviewFPXBankBankMuamalat ConfirmationTokenPaymentMethodPreviewFPXBank = "bank_muamalat" + ConfirmationTokenPaymentMethodPreviewFPXBankBankOfChina ConfirmationTokenPaymentMethodPreviewFPXBank = "bank_of_china" + ConfirmationTokenPaymentMethodPreviewFPXBankBankRakyat ConfirmationTokenPaymentMethodPreviewFPXBank = "bank_rakyat" + ConfirmationTokenPaymentMethodPreviewFPXBankBsn ConfirmationTokenPaymentMethodPreviewFPXBank = "bsn" + ConfirmationTokenPaymentMethodPreviewFPXBankCimb ConfirmationTokenPaymentMethodPreviewFPXBank = "cimb" + ConfirmationTokenPaymentMethodPreviewFPXBankDeutscheBank ConfirmationTokenPaymentMethodPreviewFPXBank = "deutsche_bank" + ConfirmationTokenPaymentMethodPreviewFPXBankHongLeongBank ConfirmationTokenPaymentMethodPreviewFPXBank = "hong_leong_bank" + ConfirmationTokenPaymentMethodPreviewFPXBankHsbc ConfirmationTokenPaymentMethodPreviewFPXBank = "hsbc" + ConfirmationTokenPaymentMethodPreviewFPXBankKfh ConfirmationTokenPaymentMethodPreviewFPXBank = "kfh" + ConfirmationTokenPaymentMethodPreviewFPXBankMaybank2e ConfirmationTokenPaymentMethodPreviewFPXBank = "maybank2e" + ConfirmationTokenPaymentMethodPreviewFPXBankMaybank2u ConfirmationTokenPaymentMethodPreviewFPXBank = "maybank2u" + ConfirmationTokenPaymentMethodPreviewFPXBankOcbc ConfirmationTokenPaymentMethodPreviewFPXBank = "ocbc" + ConfirmationTokenPaymentMethodPreviewFPXBankPbEnterprise ConfirmationTokenPaymentMethodPreviewFPXBank = "pb_enterprise" + ConfirmationTokenPaymentMethodPreviewFPXBankPublicBank ConfirmationTokenPaymentMethodPreviewFPXBank = "public_bank" + ConfirmationTokenPaymentMethodPreviewFPXBankRhb ConfirmationTokenPaymentMethodPreviewFPXBank = "rhb" + ConfirmationTokenPaymentMethodPreviewFPXBankStandardChartered ConfirmationTokenPaymentMethodPreviewFPXBank = "standard_chartered" + ConfirmationTokenPaymentMethodPreviewFPXBankUob ConfirmationTokenPaymentMethodPreviewFPXBank = "uob" +) + +// The customer's bank, if provided. Can be one of `abn_amro`, `asn_bank`, `bunq`, `handelsbanken`, `ing`, `knab`, `moneyou`, `n26`, `nn`, `rabobank`, `regiobank`, `revolut`, `sns_bank`, `triodos_bank`, `van_lanschot`, or `yoursafe`. +type ConfirmationTokenPaymentMethodPreviewIDEALBank string + +// List of values that ConfirmationTokenPaymentMethodPreviewIDEALBank can take +const ( + ConfirmationTokenPaymentMethodPreviewIDEALBankAbnAmro ConfirmationTokenPaymentMethodPreviewIDEALBank = "abn_amro" + ConfirmationTokenPaymentMethodPreviewIDEALBankAsnBank ConfirmationTokenPaymentMethodPreviewIDEALBank = "asn_bank" + ConfirmationTokenPaymentMethodPreviewIDEALBankBunq ConfirmationTokenPaymentMethodPreviewIDEALBank = "bunq" + ConfirmationTokenPaymentMethodPreviewIDEALBankHandelsbanken ConfirmationTokenPaymentMethodPreviewIDEALBank = "handelsbanken" + ConfirmationTokenPaymentMethodPreviewIDEALBankIng ConfirmationTokenPaymentMethodPreviewIDEALBank = "ing" + ConfirmationTokenPaymentMethodPreviewIDEALBankKnab ConfirmationTokenPaymentMethodPreviewIDEALBank = "knab" + ConfirmationTokenPaymentMethodPreviewIDEALBankMoneyou ConfirmationTokenPaymentMethodPreviewIDEALBank = "moneyou" + ConfirmationTokenPaymentMethodPreviewIDEALBankN26 ConfirmationTokenPaymentMethodPreviewIDEALBank = "n26" + ConfirmationTokenPaymentMethodPreviewIDEALBankNn ConfirmationTokenPaymentMethodPreviewIDEALBank = "nn" + ConfirmationTokenPaymentMethodPreviewIDEALBankRabobank ConfirmationTokenPaymentMethodPreviewIDEALBank = "rabobank" + ConfirmationTokenPaymentMethodPreviewIDEALBankRegiobank ConfirmationTokenPaymentMethodPreviewIDEALBank = "regiobank" + ConfirmationTokenPaymentMethodPreviewIDEALBankRevolut ConfirmationTokenPaymentMethodPreviewIDEALBank = "revolut" + ConfirmationTokenPaymentMethodPreviewIDEALBankSnsBank ConfirmationTokenPaymentMethodPreviewIDEALBank = "sns_bank" + ConfirmationTokenPaymentMethodPreviewIDEALBankTriodosBank ConfirmationTokenPaymentMethodPreviewIDEALBank = "triodos_bank" + ConfirmationTokenPaymentMethodPreviewIDEALBankVanLanschot ConfirmationTokenPaymentMethodPreviewIDEALBank = "van_lanschot" + ConfirmationTokenPaymentMethodPreviewIDEALBankYoursafe ConfirmationTokenPaymentMethodPreviewIDEALBank = "yoursafe" +) + +// The Bank Identifier Code of the customer's bank, if the bank was provided. +type ConfirmationTokenPaymentMethodPreviewIDEALBIC string + +// List of values that ConfirmationTokenPaymentMethodPreviewIDEALBIC can take +const ( + ConfirmationTokenPaymentMethodPreviewIDEALBICABNANL2A ConfirmationTokenPaymentMethodPreviewIDEALBIC = "ABNANL2A" + ConfirmationTokenPaymentMethodPreviewIDEALBICASNBNL21 ConfirmationTokenPaymentMethodPreviewIDEALBIC = "ASNBNL21" + ConfirmationTokenPaymentMethodPreviewIDEALBICBITSNL2A ConfirmationTokenPaymentMethodPreviewIDEALBIC = "BITSNL2A" + ConfirmationTokenPaymentMethodPreviewIDEALBICBUNQNL2A ConfirmationTokenPaymentMethodPreviewIDEALBIC = "BUNQNL2A" + ConfirmationTokenPaymentMethodPreviewIDEALBICFVLBNL22 ConfirmationTokenPaymentMethodPreviewIDEALBIC = "FVLBNL22" + ConfirmationTokenPaymentMethodPreviewIDEALBICHANDNL2A ConfirmationTokenPaymentMethodPreviewIDEALBIC = "HANDNL2A" + ConfirmationTokenPaymentMethodPreviewIDEALBICINGBNL2A ConfirmationTokenPaymentMethodPreviewIDEALBIC = "INGBNL2A" + ConfirmationTokenPaymentMethodPreviewIDEALBICKNABNL2H ConfirmationTokenPaymentMethodPreviewIDEALBIC = "KNABNL2H" + ConfirmationTokenPaymentMethodPreviewIDEALBICMOYONL21 ConfirmationTokenPaymentMethodPreviewIDEALBIC = "MOYONL21" + ConfirmationTokenPaymentMethodPreviewIDEALBICNNBANL2G ConfirmationTokenPaymentMethodPreviewIDEALBIC = "NNBANL2G" + ConfirmationTokenPaymentMethodPreviewIDEALBICNTSBDEB1 ConfirmationTokenPaymentMethodPreviewIDEALBIC = "NTSBDEB1" + ConfirmationTokenPaymentMethodPreviewIDEALBICRABONL2U ConfirmationTokenPaymentMethodPreviewIDEALBIC = "RABONL2U" + ConfirmationTokenPaymentMethodPreviewIDEALBICRBRBNL21 ConfirmationTokenPaymentMethodPreviewIDEALBIC = "RBRBNL21" + ConfirmationTokenPaymentMethodPreviewIDEALBICREVOIE23 ConfirmationTokenPaymentMethodPreviewIDEALBIC = "REVOIE23" + ConfirmationTokenPaymentMethodPreviewIDEALBICREVOLT21 ConfirmationTokenPaymentMethodPreviewIDEALBIC = "REVOLT21" + ConfirmationTokenPaymentMethodPreviewIDEALBICSNSBNL2A ConfirmationTokenPaymentMethodPreviewIDEALBIC = "SNSBNL2A" + ConfirmationTokenPaymentMethodPreviewIDEALBICTRIONL2U ConfirmationTokenPaymentMethodPreviewIDEALBIC = "TRIONL2U" +) + +// How card details were read in this transaction. +type ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethod string + +// List of values that ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethod can take +const ( + ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethodContactEmv ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethod = "contact_emv" + ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethodContactlessEmv ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethod = "contactless_emv" + ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethodContactlessMagstripeMode ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethod = "contactless_magstripe_mode" + ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethodMagneticStripeFallback ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethod = "magnetic_stripe_fallback" + ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethodMagneticStripeTrack2 ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethod = "magnetic_stripe_track2" +) + +// The customer's bank, if provided. +type ConfirmationTokenPaymentMethodPreviewP24Bank string + +// List of values that ConfirmationTokenPaymentMethodPreviewP24Bank can take +const ( + ConfirmationTokenPaymentMethodPreviewP24BankAliorBank ConfirmationTokenPaymentMethodPreviewP24Bank = "alior_bank" + ConfirmationTokenPaymentMethodPreviewP24BankBankMillennium ConfirmationTokenPaymentMethodPreviewP24Bank = "bank_millennium" + ConfirmationTokenPaymentMethodPreviewP24BankBankNowyBfgSa ConfirmationTokenPaymentMethodPreviewP24Bank = "bank_nowy_bfg_sa" + ConfirmationTokenPaymentMethodPreviewP24BankBankPekaoSa ConfirmationTokenPaymentMethodPreviewP24Bank = "bank_pekao_sa" + ConfirmationTokenPaymentMethodPreviewP24BankBankiSpbdzielcze ConfirmationTokenPaymentMethodPreviewP24Bank = "banki_spbdzielcze" + ConfirmationTokenPaymentMethodPreviewP24BankBLIK ConfirmationTokenPaymentMethodPreviewP24Bank = "blik" + ConfirmationTokenPaymentMethodPreviewP24BankBnpParibas ConfirmationTokenPaymentMethodPreviewP24Bank = "bnp_paribas" + ConfirmationTokenPaymentMethodPreviewP24BankBoz ConfirmationTokenPaymentMethodPreviewP24Bank = "boz" + ConfirmationTokenPaymentMethodPreviewP24BankCitiHandlowy ConfirmationTokenPaymentMethodPreviewP24Bank = "citi_handlowy" + ConfirmationTokenPaymentMethodPreviewP24BankCreditAgricole ConfirmationTokenPaymentMethodPreviewP24Bank = "credit_agricole" + ConfirmationTokenPaymentMethodPreviewP24BankEnvelobank ConfirmationTokenPaymentMethodPreviewP24Bank = "envelobank" + ConfirmationTokenPaymentMethodPreviewP24BankEtransferPocztowy24 ConfirmationTokenPaymentMethodPreviewP24Bank = "etransfer_pocztowy24" + ConfirmationTokenPaymentMethodPreviewP24BankGetinBank ConfirmationTokenPaymentMethodPreviewP24Bank = "getin_bank" + ConfirmationTokenPaymentMethodPreviewP24BankIdeabank ConfirmationTokenPaymentMethodPreviewP24Bank = "ideabank" + ConfirmationTokenPaymentMethodPreviewP24BankIng ConfirmationTokenPaymentMethodPreviewP24Bank = "ing" + ConfirmationTokenPaymentMethodPreviewP24BankInteligo ConfirmationTokenPaymentMethodPreviewP24Bank = "inteligo" + ConfirmationTokenPaymentMethodPreviewP24BankMbankMtransfer ConfirmationTokenPaymentMethodPreviewP24Bank = "mbank_mtransfer" + ConfirmationTokenPaymentMethodPreviewP24BankNestPrzelew ConfirmationTokenPaymentMethodPreviewP24Bank = "nest_przelew" + ConfirmationTokenPaymentMethodPreviewP24BankNoblePay ConfirmationTokenPaymentMethodPreviewP24Bank = "noble_pay" + ConfirmationTokenPaymentMethodPreviewP24BankPbacZIpko ConfirmationTokenPaymentMethodPreviewP24Bank = "pbac_z_ipko" + ConfirmationTokenPaymentMethodPreviewP24BankPlusBank ConfirmationTokenPaymentMethodPreviewP24Bank = "plus_bank" + ConfirmationTokenPaymentMethodPreviewP24BankSantanderPrzelew24 ConfirmationTokenPaymentMethodPreviewP24Bank = "santander_przelew24" + ConfirmationTokenPaymentMethodPreviewP24BankTmobileUsbugiBankowe ConfirmationTokenPaymentMethodPreviewP24Bank = "tmobile_usbugi_bankowe" + ConfirmationTokenPaymentMethodPreviewP24BankToyotaBank ConfirmationTokenPaymentMethodPreviewP24Bank = "toyota_bank" + ConfirmationTokenPaymentMethodPreviewP24BankVelobank ConfirmationTokenPaymentMethodPreviewP24Bank = "velobank" + ConfirmationTokenPaymentMethodPreviewP24BankVolkswagenBank ConfirmationTokenPaymentMethodPreviewP24Bank = "volkswagen_bank" +) + +// The type of the PaymentMethod. An additional hash is included on the PaymentMethod with a name matching this value. It contains additional information specific to the PaymentMethod type. +type ConfirmationTokenPaymentMethodPreviewType string + +// List of values that ConfirmationTokenPaymentMethodPreviewType can take +const ( + ConfirmationTokenPaymentMethodPreviewTypeACSSDebit ConfirmationTokenPaymentMethodPreviewType = "acss_debit" + ConfirmationTokenPaymentMethodPreviewTypeAffirm ConfirmationTokenPaymentMethodPreviewType = "affirm" + ConfirmationTokenPaymentMethodPreviewTypeAfterpayClearpay ConfirmationTokenPaymentMethodPreviewType = "afterpay_clearpay" + ConfirmationTokenPaymentMethodPreviewTypeAlipay ConfirmationTokenPaymentMethodPreviewType = "alipay" + ConfirmationTokenPaymentMethodPreviewTypeAUBECSDebit ConfirmationTokenPaymentMethodPreviewType = "au_becs_debit" + ConfirmationTokenPaymentMethodPreviewTypeBACSDebit ConfirmationTokenPaymentMethodPreviewType = "bacs_debit" + ConfirmationTokenPaymentMethodPreviewTypeBancontact ConfirmationTokenPaymentMethodPreviewType = "bancontact" + ConfirmationTokenPaymentMethodPreviewTypeBLIK ConfirmationTokenPaymentMethodPreviewType = "blik" + ConfirmationTokenPaymentMethodPreviewTypeBoleto ConfirmationTokenPaymentMethodPreviewType = "boleto" + ConfirmationTokenPaymentMethodPreviewTypeCard ConfirmationTokenPaymentMethodPreviewType = "card" + ConfirmationTokenPaymentMethodPreviewTypeCardPresent ConfirmationTokenPaymentMethodPreviewType = "card_present" + ConfirmationTokenPaymentMethodPreviewTypeCashApp ConfirmationTokenPaymentMethodPreviewType = "cashapp" + ConfirmationTokenPaymentMethodPreviewTypeCustomerBalance ConfirmationTokenPaymentMethodPreviewType = "customer_balance" + ConfirmationTokenPaymentMethodPreviewTypeEPS ConfirmationTokenPaymentMethodPreviewType = "eps" + ConfirmationTokenPaymentMethodPreviewTypeFPX ConfirmationTokenPaymentMethodPreviewType = "fpx" + ConfirmationTokenPaymentMethodPreviewTypeGiropay ConfirmationTokenPaymentMethodPreviewType = "giropay" + ConfirmationTokenPaymentMethodPreviewTypeGrabpay ConfirmationTokenPaymentMethodPreviewType = "grabpay" + ConfirmationTokenPaymentMethodPreviewTypeIDEAL ConfirmationTokenPaymentMethodPreviewType = "ideal" + ConfirmationTokenPaymentMethodPreviewTypeInteracPresent ConfirmationTokenPaymentMethodPreviewType = "interac_present" + ConfirmationTokenPaymentMethodPreviewTypeKlarna ConfirmationTokenPaymentMethodPreviewType = "klarna" + ConfirmationTokenPaymentMethodPreviewTypeKonbini ConfirmationTokenPaymentMethodPreviewType = "konbini" + ConfirmationTokenPaymentMethodPreviewTypeLink ConfirmationTokenPaymentMethodPreviewType = "link" + ConfirmationTokenPaymentMethodPreviewTypeMobilepay ConfirmationTokenPaymentMethodPreviewType = "mobilepay" + ConfirmationTokenPaymentMethodPreviewTypeOXXO ConfirmationTokenPaymentMethodPreviewType = "oxxo" + ConfirmationTokenPaymentMethodPreviewTypeP24 ConfirmationTokenPaymentMethodPreviewType = "p24" + ConfirmationTokenPaymentMethodPreviewTypePayNow ConfirmationTokenPaymentMethodPreviewType = "paynow" + ConfirmationTokenPaymentMethodPreviewTypePaypal ConfirmationTokenPaymentMethodPreviewType = "paypal" + ConfirmationTokenPaymentMethodPreviewTypePix ConfirmationTokenPaymentMethodPreviewType = "pix" + ConfirmationTokenPaymentMethodPreviewTypePromptPay ConfirmationTokenPaymentMethodPreviewType = "promptpay" + ConfirmationTokenPaymentMethodPreviewTypeRevolutPay ConfirmationTokenPaymentMethodPreviewType = "revolut_pay" + ConfirmationTokenPaymentMethodPreviewTypeSEPADebit ConfirmationTokenPaymentMethodPreviewType = "sepa_debit" + ConfirmationTokenPaymentMethodPreviewTypeSofort ConfirmationTokenPaymentMethodPreviewType = "sofort" + ConfirmationTokenPaymentMethodPreviewTypeSwish ConfirmationTokenPaymentMethodPreviewType = "swish" + ConfirmationTokenPaymentMethodPreviewTypeUSBankAccount ConfirmationTokenPaymentMethodPreviewType = "us_bank_account" + ConfirmationTokenPaymentMethodPreviewTypeWeChatPay ConfirmationTokenPaymentMethodPreviewType = "wechat_pay" + ConfirmationTokenPaymentMethodPreviewTypeZip ConfirmationTokenPaymentMethodPreviewType = "zip" +) + +// Account holder type: individual or company. +type ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountHolderType string + +// List of values that ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountHolderType can take +const ( + ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountHolderTypeCompany ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountHolderType = "company" + ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountHolderTypeIndividual ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountHolderType = "individual" +) + +// Account type: checkings or savings. Defaults to checking if omitted. +type ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountType string + +// List of values that ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountType can take +const ( + ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountTypeChecking ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountType = "checking" + ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountTypeSavings ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountType = "savings" +) + +// All supported networks. +type ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworksSupported string + +// List of values that ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworksSupported can take +const ( + ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworksSupportedACH ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworksSupported = "ach" + ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworksSupportedUSDomesticWire ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworksSupported = "us_domestic_wire" +) + +// The ACH network code that resulted in this block. +type ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode string + +// List of values that ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode can take +const ( + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR02 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R02" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR03 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R03" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR04 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R04" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR05 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R05" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR07 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R07" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR08 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R08" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR10 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R10" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR11 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R11" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR16 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R16" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR20 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R20" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR29 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R29" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCodeR31 ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode = "R31" +) + +// The reason why this PaymentMethod's fingerprint has been blocked +type ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason string + +// List of values that ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason can take +const ( + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReasonBankAccountClosed ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason = "bank_account_closed" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReasonBankAccountFrozen ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason = "bank_account_frozen" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReasonBankAccountInvalidDetails ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason = "bank_account_invalid_details" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReasonBankAccountRestricted ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason = "bank_account_restricted" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReasonBankAccountUnusable ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason = "bank_account_unusable" + ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReasonDebitNotAuthorized ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason = "debit_not_authorized" +) + +// Indicates that you intend to make future payments with this ConfirmationToken's payment method. +// +// The presence of this property will [attach the payment method](https://stripe.com/docs/payments/save-during-payment) to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any required actions from the user are complete. +type ConfirmationTokenSetupFutureUsage string + +// List of values that ConfirmationTokenSetupFutureUsage can take +const ( + ConfirmationTokenSetupFutureUsageOffSession ConfirmationTokenSetupFutureUsage = "off_session" + ConfirmationTokenSetupFutureUsageOnSession ConfirmationTokenSetupFutureUsage = "on_session" +) + +// Retrieves an existing ConfirmationToken object +type ConfirmationTokenParams struct { + Params `form:"*"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` +} + +// AddExpand appends a new field to expand. +func (p *ConfirmationTokenParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// If this is a Mandate accepted online, this hash contains details about the online acceptance. +type ConfirmationTokenMandateDataCustomerAcceptanceOnline struct { + // The IP address from which the Mandate was accepted by the customer. + IPAddress string `json:"ip_address"` + // The user agent of the browser from which the Mandate was accepted by the customer. + UserAgent string `json:"user_agent"` +} + +// This hash contains details about the customer acceptance of the Mandate. +type ConfirmationTokenMandateDataCustomerAcceptance struct { + // If this is a Mandate accepted online, this hash contains details about the online acceptance. + Online *ConfirmationTokenMandateDataCustomerAcceptanceOnline `json:"online"` + // The type of customer acceptance information included with the Mandate. + Type string `json:"type"` +} + +// Data used for generating a Mandate. +type ConfirmationTokenMandateData struct { + // This hash contains details about the customer acceptance of the Mandate. + CustomerAcceptance *ConfirmationTokenMandateDataCustomerAcceptance `json:"customer_acceptance"` +} +type ConfirmationTokenPaymentMethodPreviewACSSDebit struct { + // Name of the bank associated with the bank account. + BankName string `json:"bank_name"` + // Uniquely identifies this particular bank account. You can use this attribute to check whether two bank accounts are the same. + Fingerprint string `json:"fingerprint"` + // Institution number of the bank account. + InstitutionNumber string `json:"institution_number"` + // Last four digits of the bank account number. + Last4 string `json:"last4"` + // Transit number of the bank account. + TransitNumber string `json:"transit_number"` +} +type ConfirmationTokenPaymentMethodPreviewAffirm struct{} +type ConfirmationTokenPaymentMethodPreviewAfterpayClearpay struct{} +type ConfirmationTokenPaymentMethodPreviewAlipay struct{} +type ConfirmationTokenPaymentMethodPreviewAUBECSDebit struct { + // Six-digit number identifying bank and branch associated with this bank account. + BSBNumber string `json:"bsb_number"` + // Uniquely identifies this particular bank account. You can use this attribute to check whether two bank accounts are the same. + Fingerprint string `json:"fingerprint"` + // Last four digits of the bank account number. + Last4 string `json:"last4"` +} +type ConfirmationTokenPaymentMethodPreviewBACSDebit struct { + // Uniquely identifies this particular bank account. You can use this attribute to check whether two bank accounts are the same. + Fingerprint string `json:"fingerprint"` + // Last four digits of the bank account number. + Last4 string `json:"last4"` + // Sort code of the bank account. (e.g., `10-20-30`) + SortCode string `json:"sort_code"` +} +type ConfirmationTokenPaymentMethodPreviewBancontact struct{} +type ConfirmationTokenPaymentMethodPreviewBillingDetails struct { + // Billing address. + Address *Address `json:"address"` + // Email address. + Email string `json:"email"` + // Full name. + Name string `json:"name"` + // Billing phone number (including extension). + Phone string `json:"phone"` +} +type ConfirmationTokenPaymentMethodPreviewBLIK struct{} +type ConfirmationTokenPaymentMethodPreviewBoleto struct { + // Uniquely identifies the customer tax id (CNPJ or CPF) + TaxID string `json:"tax_id"` +} + +// Checks on Card address and CVC if provided. +type ConfirmationTokenPaymentMethodPreviewCardChecks struct { + // If a address line1 was provided, results of the check, one of `pass`, `fail`, `unavailable`, or `unchecked`. + AddressLine1Check string `json:"address_line1_check"` + // If a address postal code was provided, results of the check, one of `pass`, `fail`, `unavailable`, or `unchecked`. + AddressPostalCodeCheck string `json:"address_postal_code_check"` + // If a CVC was provided, results of the check, one of `pass`, `fail`, `unavailable`, or `unchecked`. + CVCCheck string `json:"cvc_check"` +} + +// Contains information about card networks that can be used to process the payment. +type ConfirmationTokenPaymentMethodPreviewCardNetworks struct { + // All available networks for the card. + Available []string `json:"available"` + // The preferred network for co-branded cards. Can be `cartes_bancaires`, `mastercard`, `visa` or `invalid_preference` if requested network is not valid for the card. + Preferred string `json:"preferred"` +} + +// Contains details on how this Card may be used for 3D Secure authentication. +type ConfirmationTokenPaymentMethodPreviewCardThreeDSecureUsage struct { + // Whether 3D Secure is supported on this card. + Supported bool `json:"supported"` +} +type ConfirmationTokenPaymentMethodPreviewCardWalletAmexExpressCheckout struct{} +type ConfirmationTokenPaymentMethodPreviewCardWalletApplePay struct{} +type ConfirmationTokenPaymentMethodPreviewCardWalletGooglePay struct{} +type ConfirmationTokenPaymentMethodPreviewCardWalletLink struct{} +type ConfirmationTokenPaymentMethodPreviewCardWalletMasterpass struct { + // Owner's verified billing address. Values are verified or provided by the wallet directly (if supported) at the time of authorization or settlement. They cannot be set or mutated. + BillingAddress *Address `json:"billing_address"` + // Owner's verified email. Values are verified or provided by the wallet directly (if supported) at the time of authorization or settlement. They cannot be set or mutated. + Email string `json:"email"` + // Owner's verified full name. Values are verified or provided by the wallet directly (if supported) at the time of authorization or settlement. They cannot be set or mutated. + Name string `json:"name"` + // Owner's verified shipping address. Values are verified or provided by the wallet directly (if supported) at the time of authorization or settlement. They cannot be set or mutated. + ShippingAddress *Address `json:"shipping_address"` +} +type ConfirmationTokenPaymentMethodPreviewCardWalletSamsungPay struct{} +type ConfirmationTokenPaymentMethodPreviewCardWalletVisaCheckout struct { + // Owner's verified billing address. Values are verified or provided by the wallet directly (if supported) at the time of authorization or settlement. They cannot be set or mutated. + BillingAddress *Address `json:"billing_address"` + // Owner's verified email. Values are verified or provided by the wallet directly (if supported) at the time of authorization or settlement. They cannot be set or mutated. + Email string `json:"email"` + // Owner's verified full name. Values are verified or provided by the wallet directly (if supported) at the time of authorization or settlement. They cannot be set or mutated. + Name string `json:"name"` + // Owner's verified shipping address. Values are verified or provided by the wallet directly (if supported) at the time of authorization or settlement. They cannot be set or mutated. + ShippingAddress *Address `json:"shipping_address"` +} + +// If this Card is part of a card wallet, this contains the details of the card wallet. +type ConfirmationTokenPaymentMethodPreviewCardWallet struct { + AmexExpressCheckout *ConfirmationTokenPaymentMethodPreviewCardWalletAmexExpressCheckout `json:"amex_express_checkout"` + ApplePay *ConfirmationTokenPaymentMethodPreviewCardWalletApplePay `json:"apple_pay"` + // (For tokenized numbers only.) The last four digits of the device account number. + DynamicLast4 string `json:"dynamic_last4"` + GooglePay *ConfirmationTokenPaymentMethodPreviewCardWalletGooglePay `json:"google_pay"` + Link *ConfirmationTokenPaymentMethodPreviewCardWalletLink `json:"link"` + Masterpass *ConfirmationTokenPaymentMethodPreviewCardWalletMasterpass `json:"masterpass"` + SamsungPay *ConfirmationTokenPaymentMethodPreviewCardWalletSamsungPay `json:"samsung_pay"` + // The type of the card wallet, one of `amex_express_checkout`, `apple_pay`, `google_pay`, `masterpass`, `samsung_pay`, `visa_checkout`, or `link`. An additional hash is included on the Wallet subhash with a name matching this value. It contains additional information specific to the card wallet type. + Type ConfirmationTokenPaymentMethodPreviewCardWalletType `json:"type"` + VisaCheckout *ConfirmationTokenPaymentMethodPreviewCardWalletVisaCheckout `json:"visa_checkout"` +} +type ConfirmationTokenPaymentMethodPreviewCard struct { + // Card brand. Can be `amex`, `diners`, `discover`, `eftpos_au`, `jcb`, `mastercard`, `unionpay`, `visa`, or `unknown`. + Brand string `json:"brand"` + // Checks on Card address and CVC if provided. + Checks *ConfirmationTokenPaymentMethodPreviewCardChecks `json:"checks"` + // Two-letter ISO code representing the country of the card. You could use this attribute to get a sense of the international breakdown of cards you've collected. + Country string `json:"country"` + // A high-level description of the type of cards issued in this range. (For internal use only and not typically available in standard API requests.) + Description string `json:"description"` + // The brand to use when displaying the card, this accounts for customer's brand choice on dual-branded cards. Can be `american_express`, `cartes_bancaires`, `diners_club`, `discover`, `eftpos_australia`, `interac`, `jcb`, `mastercard`, `union_pay`, `visa`, or `other` and may contain more values in the future. + DisplayBrand string `json:"display_brand"` + // Two-digit number representing the card's expiration month. + ExpMonth int64 `json:"exp_month"` + // Four-digit number representing the card's expiration year. + ExpYear int64 `json:"exp_year"` + // Uniquely identifies this particular card number. You can use this attribute to check whether two customers who've signed up with you are using the same card number, for example. For payment methods that tokenize card information (Apple Pay, Google Pay), the tokenized number might be provided instead of the underlying card number. + // + // *As of May 1, 2021, card fingerprint in India for Connect changed to allow two fingerprints for the same card---one for India and one for the rest of the world.* + Fingerprint string `json:"fingerprint"` + // Card funding type. Can be `credit`, `debit`, `prepaid`, or `unknown`. + Funding string `json:"funding"` + // Issuer identification number of the card. (For internal use only and not typically available in standard API requests.) + IIN string `json:"iin"` + // The name of the card's issuing bank. (For internal use only and not typically available in standard API requests.) + Issuer string `json:"issuer"` + // The last four digits of the card. + Last4 string `json:"last4"` + // Contains information about card networks that can be used to process the payment. + Networks *ConfirmationTokenPaymentMethodPreviewCardNetworks `json:"networks"` + // Contains details on how this Card may be used for 3D Secure authentication. + ThreeDSecureUsage *ConfirmationTokenPaymentMethodPreviewCardThreeDSecureUsage `json:"three_d_secure_usage"` + // If this Card is part of a card wallet, this contains the details of the card wallet. + Wallet *ConfirmationTokenPaymentMethodPreviewCardWallet `json:"wallet"` +} + +// Contains information about card networks that can be used to process the payment. +type ConfirmationTokenPaymentMethodPreviewCardPresentNetworks struct { + // All available networks for the card. + Available []string `json:"available"` + // The preferred network for the card. + Preferred string `json:"preferred"` +} +type ConfirmationTokenPaymentMethodPreviewCardPresent struct { + // Card brand. Can be `amex`, `diners`, `discover`, `eftpos_au`, `jcb`, `mastercard`, `unionpay`, `visa`, or `unknown`. + Brand string `json:"brand"` + // The cardholder name as read from the card, in [ISO 7813](https://en.wikipedia.org/wiki/ISO/IEC_7813) format. May include alphanumeric characters, special characters and first/last name separator (`/`). In some cases, the cardholder name may not be available depending on how the issuer has configured the card. Cardholder name is typically not available on swipe or contactless payments, such as those made with Apple Pay and Google Pay. + CardholderName string `json:"cardholder_name"` + // Two-letter ISO code representing the country of the card. You could use this attribute to get a sense of the international breakdown of cards you've collected. + Country string `json:"country"` + // A high-level description of the type of cards issued in this range. (For internal use only and not typically available in standard API requests.) + Description string `json:"description"` + // Two-digit number representing the card's expiration month. + ExpMonth int64 `json:"exp_month"` + // Four-digit number representing the card's expiration year. + ExpYear int64 `json:"exp_year"` + // Uniquely identifies this particular card number. You can use this attribute to check whether two customers who've signed up with you are using the same card number, for example. For payment methods that tokenize card information (Apple Pay, Google Pay), the tokenized number might be provided instead of the underlying card number. + // + // *As of May 1, 2021, card fingerprint in India for Connect changed to allow two fingerprints for the same card---one for India and one for the rest of the world.* + Fingerprint string `json:"fingerprint"` + // Card funding type. Can be `credit`, `debit`, `prepaid`, or `unknown`. + Funding string `json:"funding"` + // Issuer identification number of the card. (For internal use only and not typically available in standard API requests.) + IIN string `json:"iin"` + // The name of the card's issuing bank. (For internal use only and not typically available in standard API requests.) + Issuer string `json:"issuer"` + // The last four digits of the card. + Last4 string `json:"last4"` + // Contains information about card networks that can be used to process the payment. + Networks *ConfirmationTokenPaymentMethodPreviewCardPresentNetworks `json:"networks"` + // How card details were read in this transaction. + ReadMethod ConfirmationTokenPaymentMethodPreviewCardPresentReadMethod `json:"read_method"` +} +type ConfirmationTokenPaymentMethodPreviewCashApp struct { + // A unique and immutable identifier assigned by Cash App to every buyer. + BuyerID string `json:"buyer_id"` + // A public identifier for buyers using Cash App. + Cashtag string `json:"cashtag"` +} +type ConfirmationTokenPaymentMethodPreviewCustomerBalance struct{} +type ConfirmationTokenPaymentMethodPreviewEPS struct { + // The customer's bank. Should be one of `arzte_und_apotheker_bank`, `austrian_anadi_bank_ag`, `bank_austria`, `bankhaus_carl_spangler`, `bankhaus_schelhammer_und_schattera_ag`, `bawag_psk_ag`, `bks_bank_ag`, `brull_kallmus_bank_ag`, `btv_vier_lander_bank`, `capital_bank_grawe_gruppe_ag`, `deutsche_bank_ag`, `dolomitenbank`, `easybank_ag`, `erste_bank_und_sparkassen`, `hypo_alpeadriabank_international_ag`, `hypo_noe_lb_fur_niederosterreich_u_wien`, `hypo_oberosterreich_salzburg_steiermark`, `hypo_tirol_bank_ag`, `hypo_vorarlberg_bank_ag`, `hypo_bank_burgenland_aktiengesellschaft`, `marchfelder_bank`, `oberbank_ag`, `raiffeisen_bankengruppe_osterreich`, `schoellerbank_ag`, `sparda_bank_wien`, `volksbank_gruppe`, `volkskreditbank_ag`, or `vr_bank_braunau`. + Bank ConfirmationTokenPaymentMethodPreviewEPSBank `json:"bank"` +} +type ConfirmationTokenPaymentMethodPreviewFPX struct { + // Account holder type, if provided. Can be one of `individual` or `company`. + AccountHolderType ConfirmationTokenPaymentMethodPreviewFPXAccountHolderType `json:"account_holder_type"` + // The customer's bank, if provided. Can be one of `affin_bank`, `agrobank`, `alliance_bank`, `ambank`, `bank_islam`, `bank_muamalat`, `bank_rakyat`, `bsn`, `cimb`, `hong_leong_bank`, `hsbc`, `kfh`, `maybank2u`, `ocbc`, `public_bank`, `rhb`, `standard_chartered`, `uob`, `deutsche_bank`, `maybank2e`, `pb_enterprise`, or `bank_of_china`. + Bank ConfirmationTokenPaymentMethodPreviewFPXBank `json:"bank"` +} +type ConfirmationTokenPaymentMethodPreviewGiropay struct{} +type ConfirmationTokenPaymentMethodPreviewGrabpay struct{} +type ConfirmationTokenPaymentMethodPreviewIDEAL struct { + // The customer's bank, if provided. Can be one of `abn_amro`, `asn_bank`, `bunq`, `handelsbanken`, `ing`, `knab`, `moneyou`, `n26`, `nn`, `rabobank`, `regiobank`, `revolut`, `sns_bank`, `triodos_bank`, `van_lanschot`, or `yoursafe`. + Bank ConfirmationTokenPaymentMethodPreviewIDEALBank `json:"bank"` + // The Bank Identifier Code of the customer's bank, if the bank was provided. + BIC ConfirmationTokenPaymentMethodPreviewIDEALBIC `json:"bic"` +} + +// Contains information about card networks that can be used to process the payment. +type ConfirmationTokenPaymentMethodPreviewInteracPresentNetworks struct { + // All available networks for the card. + Available []string `json:"available"` + // The preferred network for the card. + Preferred string `json:"preferred"` +} +type ConfirmationTokenPaymentMethodPreviewInteracPresent struct { + // Card brand. Can be `interac`, `mastercard` or `visa`. + Brand string `json:"brand"` + // The cardholder name as read from the card, in [ISO 7813](https://en.wikipedia.org/wiki/ISO/IEC_7813) format. May include alphanumeric characters, special characters and first/last name separator (`/`). In some cases, the cardholder name may not be available depending on how the issuer has configured the card. Cardholder name is typically not available on swipe or contactless payments, such as those made with Apple Pay and Google Pay. + CardholderName string `json:"cardholder_name"` + // Two-letter ISO code representing the country of the card. You could use this attribute to get a sense of the international breakdown of cards you've collected. + Country string `json:"country"` + // A high-level description of the type of cards issued in this range. (For internal use only and not typically available in standard API requests.) + Description string `json:"description"` + // Two-digit number representing the card's expiration month. + ExpMonth int64 `json:"exp_month"` + // Four-digit number representing the card's expiration year. + ExpYear int64 `json:"exp_year"` + // Uniquely identifies this particular card number. You can use this attribute to check whether two customers who've signed up with you are using the same card number, for example. For payment methods that tokenize card information (Apple Pay, Google Pay), the tokenized number might be provided instead of the underlying card number. + // + // *As of May 1, 2021, card fingerprint in India for Connect changed to allow two fingerprints for the same card---one for India and one for the rest of the world.* + Fingerprint string `json:"fingerprint"` + // Card funding type. Can be `credit`, `debit`, `prepaid`, or `unknown`. + Funding string `json:"funding"` + // Issuer identification number of the card. (For internal use only and not typically available in standard API requests.) + IIN string `json:"iin"` + // The name of the card's issuing bank. (For internal use only and not typically available in standard API requests.) + Issuer string `json:"issuer"` + // The last four digits of the card. + Last4 string `json:"last4"` + // Contains information about card networks that can be used to process the payment. + Networks *ConfirmationTokenPaymentMethodPreviewInteracPresentNetworks `json:"networks"` + // EMV tag 5F2D. Preferred languages specified by the integrated circuit chip. + PreferredLocales []string `json:"preferred_locales"` + // How card details were read in this transaction. + ReadMethod ConfirmationTokenPaymentMethodPreviewInteracPresentReadMethod `json:"read_method"` +} + +// The customer's date of birth, if provided. +type ConfirmationTokenPaymentMethodPreviewKlarnaDOB struct { + // The day of birth, between 1 and 31. + Day int64 `json:"day"` + // The month of birth, between 1 and 12. + Month int64 `json:"month"` + // The four-digit year of birth. + Year int64 `json:"year"` +} +type ConfirmationTokenPaymentMethodPreviewKlarna struct { + // The customer's date of birth, if provided. + DOB *ConfirmationTokenPaymentMethodPreviewKlarnaDOB `json:"dob"` +} +type ConfirmationTokenPaymentMethodPreviewKonbini struct{} +type ConfirmationTokenPaymentMethodPreviewLink struct { + // Account owner's email address. + Email string `json:"email"` + // [Deprecated] This is a legacy parameter that no longer has any function. + PersistentToken string `json:"persistent_token"` +} +type ConfirmationTokenPaymentMethodPreviewMobilepay struct{} +type ConfirmationTokenPaymentMethodPreviewOXXO struct{} +type ConfirmationTokenPaymentMethodPreviewP24 struct { + // The customer's bank, if provided. + Bank ConfirmationTokenPaymentMethodPreviewP24Bank `json:"bank"` +} +type ConfirmationTokenPaymentMethodPreviewPayNow struct{} +type ConfirmationTokenPaymentMethodPreviewPaypal struct { + // Owner's email. Values are provided by PayPal directly + // (if supported) at the time of authorization or settlement. They cannot be set or mutated. + PayerEmail string `json:"payer_email"` + // PayPal account PayerID. This identifier uniquely identifies the PayPal customer. + PayerID string `json:"payer_id"` +} +type ConfirmationTokenPaymentMethodPreviewPix struct{} +type ConfirmationTokenPaymentMethodPreviewPromptPay struct{} +type ConfirmationTokenPaymentMethodPreviewRevolutPay struct{} + +// Information about the object that generated this PaymentMethod. +type ConfirmationTokenPaymentMethodPreviewSEPADebitGeneratedFrom struct { + // The ID of the Charge that generated this PaymentMethod, if any. + Charge *Charge `json:"charge"` + // The ID of the SetupAttempt that generated this PaymentMethod, if any. + SetupAttempt *SetupAttempt `json:"setup_attempt"` +} +type ConfirmationTokenPaymentMethodPreviewSEPADebit struct { + // Bank code of bank associated with the bank account. + BankCode string `json:"bank_code"` + // Branch code of bank associated with the bank account. + BranchCode string `json:"branch_code"` + // Two-letter ISO code representing the country the bank account is located in. + Country string `json:"country"` + // Uniquely identifies this particular bank account. You can use this attribute to check whether two bank accounts are the same. + Fingerprint string `json:"fingerprint"` + // Information about the object that generated this PaymentMethod. + GeneratedFrom *ConfirmationTokenPaymentMethodPreviewSEPADebitGeneratedFrom `json:"generated_from"` + // Last four characters of the IBAN. + Last4 string `json:"last4"` +} +type ConfirmationTokenPaymentMethodPreviewSofort struct { + // Two-letter ISO code representing the country the bank account is located in. + Country string `json:"country"` +} +type ConfirmationTokenPaymentMethodPreviewSwish struct{} + +// Contains information about US bank account networks that can be used. +type ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworks struct { + // The preferred network. + Preferred string `json:"preferred"` + // All supported networks. + Supported []ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworksSupported `json:"supported"` +} +type ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlocked struct { + // The ACH network code that resulted in this block. + NetworkCode ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedNetworkCode `json:"network_code"` + // The reason why this PaymentMethod's fingerprint has been blocked + Reason ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlockedReason `json:"reason"` +} + +// Contains information about the future reusability of this PaymentMethod. +type ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetails struct { + Blocked *ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetailsBlocked `json:"blocked"` +} +type ConfirmationTokenPaymentMethodPreviewUSBankAccount struct { + // Account holder type: individual or company. + AccountHolderType ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountHolderType `json:"account_holder_type"` + // Account type: checkings or savings. Defaults to checking if omitted. + AccountType ConfirmationTokenPaymentMethodPreviewUSBankAccountAccountType `json:"account_type"` + // The name of the bank. + BankName string `json:"bank_name"` + // The ID of the Financial Connections Account used to create the payment method. + FinancialConnectionsAccount string `json:"financial_connections_account"` + // Uniquely identifies this particular bank account. You can use this attribute to check whether two bank accounts are the same. + Fingerprint string `json:"fingerprint"` + // Last four digits of the bank account number. + Last4 string `json:"last4"` + // Contains information about US bank account networks that can be used. + Networks *ConfirmationTokenPaymentMethodPreviewUSBankAccountNetworks `json:"networks"` + // Routing number of the bank account. + RoutingNumber string `json:"routing_number"` + // Contains information about the future reusability of this PaymentMethod. + StatusDetails *ConfirmationTokenPaymentMethodPreviewUSBankAccountStatusDetails `json:"status_details"` +} +type ConfirmationTokenPaymentMethodPreviewWeChatPay struct{} +type ConfirmationTokenPaymentMethodPreviewZip struct{} + +// Payment details collected by the Payment Element, used to create a PaymentMethod when a PaymentIntent or SetupIntent is confirmed with this ConfirmationToken. +type ConfirmationTokenPaymentMethodPreview struct { + ACSSDebit *ConfirmationTokenPaymentMethodPreviewACSSDebit `json:"acss_debit"` + Affirm *ConfirmationTokenPaymentMethodPreviewAffirm `json:"affirm"` + AfterpayClearpay *ConfirmationTokenPaymentMethodPreviewAfterpayClearpay `json:"afterpay_clearpay"` + Alipay *ConfirmationTokenPaymentMethodPreviewAlipay `json:"alipay"` + AUBECSDebit *ConfirmationTokenPaymentMethodPreviewAUBECSDebit `json:"au_becs_debit"` + BACSDebit *ConfirmationTokenPaymentMethodPreviewBACSDebit `json:"bacs_debit"` + Bancontact *ConfirmationTokenPaymentMethodPreviewBancontact `json:"bancontact"` + BillingDetails *ConfirmationTokenPaymentMethodPreviewBillingDetails `json:"billing_details"` + BLIK *ConfirmationTokenPaymentMethodPreviewBLIK `json:"blik"` + Boleto *ConfirmationTokenPaymentMethodPreviewBoleto `json:"boleto"` + Card *ConfirmationTokenPaymentMethodPreviewCard `json:"card"` + CardPresent *ConfirmationTokenPaymentMethodPreviewCardPresent `json:"card_present"` + CashApp *ConfirmationTokenPaymentMethodPreviewCashApp `json:"cashapp"` + CustomerBalance *ConfirmationTokenPaymentMethodPreviewCustomerBalance `json:"customer_balance"` + EPS *ConfirmationTokenPaymentMethodPreviewEPS `json:"eps"` + FPX *ConfirmationTokenPaymentMethodPreviewFPX `json:"fpx"` + Giropay *ConfirmationTokenPaymentMethodPreviewGiropay `json:"giropay"` + Grabpay *ConfirmationTokenPaymentMethodPreviewGrabpay `json:"grabpay"` + IDEAL *ConfirmationTokenPaymentMethodPreviewIDEAL `json:"ideal"` + InteracPresent *ConfirmationTokenPaymentMethodPreviewInteracPresent `json:"interac_present"` + Klarna *ConfirmationTokenPaymentMethodPreviewKlarna `json:"klarna"` + Konbini *ConfirmationTokenPaymentMethodPreviewKonbini `json:"konbini"` + Link *ConfirmationTokenPaymentMethodPreviewLink `json:"link"` + Mobilepay *ConfirmationTokenPaymentMethodPreviewMobilepay `json:"mobilepay"` + OXXO *ConfirmationTokenPaymentMethodPreviewOXXO `json:"oxxo"` + P24 *ConfirmationTokenPaymentMethodPreviewP24 `json:"p24"` + PayNow *ConfirmationTokenPaymentMethodPreviewPayNow `json:"paynow"` + Paypal *ConfirmationTokenPaymentMethodPreviewPaypal `json:"paypal"` + Pix *ConfirmationTokenPaymentMethodPreviewPix `json:"pix"` + PromptPay *ConfirmationTokenPaymentMethodPreviewPromptPay `json:"promptpay"` + RevolutPay *ConfirmationTokenPaymentMethodPreviewRevolutPay `json:"revolut_pay"` + SEPADebit *ConfirmationTokenPaymentMethodPreviewSEPADebit `json:"sepa_debit"` + Sofort *ConfirmationTokenPaymentMethodPreviewSofort `json:"sofort"` + Swish *ConfirmationTokenPaymentMethodPreviewSwish `json:"swish"` + // The type of the PaymentMethod. An additional hash is included on the PaymentMethod with a name matching this value. It contains additional information specific to the PaymentMethod type. + Type ConfirmationTokenPaymentMethodPreviewType `json:"type"` + USBankAccount *ConfirmationTokenPaymentMethodPreviewUSBankAccount `json:"us_bank_account"` + WeChatPay *ConfirmationTokenPaymentMethodPreviewWeChatPay `json:"wechat_pay"` + Zip *ConfirmationTokenPaymentMethodPreviewZip `json:"zip"` +} + +// Shipping information collected on this ConfirmationToken. +type ConfirmationTokenShipping struct { + Address *Address `json:"address"` + // Recipient name. + Name string `json:"name"` + // Recipient phone (including extension). + Phone string `json:"phone"` +} + +// ConfirmationTokens help transport client side data collected by Stripe JS over +// to your server for confirming a PaymentIntent or SetupIntent. If the confirmation +// is successful, values present on the ConfirmationToken are written onto the Intent. +// +// To learn more about how to use ConfirmationToken, visit the related guides: +// - [Finalize payments on the server](https://stripe.com/docs/payments/finalize-payments-on-the-server) +// - [Build two-step confirmation](https://stripe.com/docs/payments/build-a-two-step-confirmation). +type ConfirmationToken struct { + APIResource + // Time at which the object was created. Measured in seconds since the Unix epoch. + Created int64 `json:"created"` + // Time at which this ConfirmationToken expires and can no longer be used to confirm a PaymentIntent or SetupIntent. This is set to null once this ConfirmationToken has been used. + ExpiresAt int64 `json:"expires_at"` + // Unique identifier for the object. + ID string `json:"id"` + // Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. + Livemode bool `json:"livemode"` + // Data used for generating a Mandate. + MandateData *ConfirmationTokenMandateData `json:"mandate_data"` + // String representing the object's type. Objects of the same type share the same value. + Object string `json:"object"` + // ID of the PaymentIntent that this ConfirmationToken was used to confirm, or null if this ConfirmationToken has not yet been used. + PaymentIntent string `json:"payment_intent"` + // Payment details collected by the Payment Element, used to create a PaymentMethod when a PaymentIntent or SetupIntent is confirmed with this ConfirmationToken. + PaymentMethodPreview *ConfirmationTokenPaymentMethodPreview `json:"payment_method_preview"` + // Return URL used to confirm the Intent. + ReturnURL string `json:"return_url"` + // Indicates that you intend to make future payments with this ConfirmationToken's payment method. + // + // The presence of this property will [attach the payment method](https://stripe.com/docs/payments/save-during-payment) to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any required actions from the user are complete. + SetupFutureUsage ConfirmationTokenSetupFutureUsage `json:"setup_future_usage"` + // ID of the SetupIntent that this ConfirmationToken was used to confirm, or null if this ConfirmationToken has not yet been used. + SetupIntent string `json:"setup_intent"` + // Shipping information collected on this ConfirmationToken. + Shipping *ConfirmationTokenShipping `json:"shipping"` + // Indicates whether the Stripe SDK is used to handle confirmation flow. Defaults to `true` on ConfirmationToken. + UseStripeSDK bool `json:"use_stripe_sdk"` +} diff --git a/vendor/github.com/stripe/stripe-go/v76/confirmationtoken/client.go b/vendor/github.com/stripe/stripe-go/v76/confirmationtoken/client.go new file mode 100644 index 00000000..9b3937d4 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/confirmationtoken/client.go @@ -0,0 +1,37 @@ +// +// +// File generated from our OpenAPI spec +// +// + +// Package confirmationtoken provides the /confirmation_tokens APIs +package confirmationtoken + +import ( + "net/http" + + stripe "github.com/stripe/stripe-go/v76" +) + +// Client is used to invoke /confirmation_tokens APIs. +type Client struct { + B stripe.Backend + Key string +} + +// Get returns the details of a confirmation token. +func Get(id string, params *stripe.ConfirmationTokenParams) (*stripe.ConfirmationToken, error) { + return getC().Get(id, params) +} + +// Get returns the details of a confirmation token. +func (c Client) Get(id string, params *stripe.ConfirmationTokenParams) (*stripe.ConfirmationToken, error) { + path := stripe.FormatURLPath("/v1/confirmation_tokens/%s", id) + confirmationtoken := &stripe.ConfirmationToken{} + err := c.B.Call(http.MethodGet, path, c.Key, params, confirmationtoken) + return confirmationtoken, err +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/vendor/github.com/stripe/stripe-go/v76/error.go b/vendor/github.com/stripe/stripe-go/v76/error.go index 98454219..25e16241 100644 --- a/vendor/github.com/stripe/stripe-go/v76/error.go +++ b/vendor/github.com/stripe/stripe-go/v76/error.go @@ -71,6 +71,10 @@ const ( ErrorCodeExpiredCard ErrorCode = "expired_card" ErrorCodeFinancialConnectionsAccountInactive ErrorCode = "financial_connections_account_inactive" ErrorCodeFinancialConnectionsNoSuccessfulTransactionRefresh ErrorCode = "financial_connections_no_successful_transaction_refresh" + ErrorCodeForwardingAPIInactive ErrorCode = "forwarding_api_inactive" + ErrorCodeForwardingAPIInvalidParameter ErrorCode = "forwarding_api_invalid_parameter" + ErrorCodeForwardingAPIUpstreamConnectionError ErrorCode = "forwarding_api_upstream_connection_error" + ErrorCodeForwardingAPIUpstreamConnectionTimeout ErrorCode = "forwarding_api_upstream_connection_timeout" ErrorCodeIdempotencyKeyInUse ErrorCode = "idempotency_key_in_use" ErrorCodeIncorrectAddress ErrorCode = "incorrect_address" ErrorCodeIncorrectCVC ErrorCode = "incorrect_cvc" diff --git a/vendor/github.com/stripe/stripe-go/v76/forwarding/request/client.go b/vendor/github.com/stripe/stripe-go/v76/forwarding/request/client.go new file mode 100644 index 00000000..4a31bf2c --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/forwarding/request/client.go @@ -0,0 +1,95 @@ +// +// +// File generated from our OpenAPI spec +// +// + +// Package request provides the /forwarding/requests APIs +package request + +import ( + "net/http" + + stripe "github.com/stripe/stripe-go/v76" + "github.com/stripe/stripe-go/v76/form" +) + +// Client is used to invoke /forwarding/requests APIs. +type Client struct { + B stripe.Backend + Key string +} + +// New creates a new forwarding request. +func New(params *stripe.ForwardingRequestParams) (*stripe.ForwardingRequest, error) { + return getC().New(params) +} + +// New creates a new forwarding request. +func (c Client) New(params *stripe.ForwardingRequestParams) (*stripe.ForwardingRequest, error) { + request := &stripe.ForwardingRequest{} + err := c.B.Call( + http.MethodPost, + "/v1/forwarding/requests", + c.Key, + params, + request, + ) + return request, err +} + +// Get returns the details of a forwarding request. +func Get(id string, params *stripe.ForwardingRequestParams) (*stripe.ForwardingRequest, error) { + return getC().Get(id, params) +} + +// Get returns the details of a forwarding request. +func (c Client) Get(id string, params *stripe.ForwardingRequestParams) (*stripe.ForwardingRequest, error) { + path := stripe.FormatURLPath("/v1/forwarding/requests/%s", id) + request := &stripe.ForwardingRequest{} + err := c.B.Call(http.MethodGet, path, c.Key, params, request) + return request, err +} + +// List returns a list of forwarding requests. +func List(params *stripe.ForwardingRequestListParams) *Iter { + return getC().List(params) +} + +// List returns a list of forwarding requests. +func (c Client) List(listParams *stripe.ForwardingRequestListParams) *Iter { + return &Iter{ + Iter: stripe.GetIter(listParams, func(p *stripe.Params, b *form.Values) ([]interface{}, stripe.ListContainer, error) { + list := &stripe.ForwardingRequestList{} + err := c.B.CallRaw(http.MethodGet, "/v1/forwarding/requests", c.Key, b, p, list) + + ret := make([]interface{}, len(list.Data)) + for i, v := range list.Data { + ret[i] = v + } + + return ret, list, err + }), + } +} + +// Iter is an iterator for forwarding requests. +type Iter struct { + *stripe.Iter +} + +// ForwardingRequest returns the forwarding request which the iterator is currently pointing to. +func (i *Iter) ForwardingRequest() *stripe.ForwardingRequest { + return i.Current().(*stripe.ForwardingRequest) +} + +// ForwardingRequestList returns the current list object which the iterator is +// currently using. List objects will change as new API calls are made to +// continue pagination. +func (i *Iter) ForwardingRequestList() *stripe.ForwardingRequestList { + return i.List().(*stripe.ForwardingRequestList) +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/vendor/github.com/stripe/stripe-go/v76/forwarding_request.go b/vendor/github.com/stripe/stripe-go/v76/forwarding_request.go new file mode 100644 index 00000000..be258de5 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/forwarding_request.go @@ -0,0 +1,171 @@ +// +// +// File generated from our OpenAPI spec +// +// + +package stripe + +// The field kinds to be replaced in the forwarded request. +type ForwardingRequestReplacement string + +// List of values that ForwardingRequestReplacement can take +const ( + ForwardingRequestReplacementCardCVC ForwardingRequestReplacement = "card_cvc" + ForwardingRequestReplacementCardExpiry ForwardingRequestReplacement = "card_expiry" + ForwardingRequestReplacementCardNumber ForwardingRequestReplacement = "card_number" + ForwardingRequestReplacementCardholderName ForwardingRequestReplacement = "cardholder_name" +) + +// The HTTP method used to call the destination endpoint. +type ForwardingRequestRequestDetailsHTTPMethod string + +// List of values that ForwardingRequestRequestDetailsHTTPMethod can take +const ( + ForwardingRequestRequestDetailsHTTPMethodPOST ForwardingRequestRequestDetailsHTTPMethod = "POST" +) + +// Lists all ForwardingRequest objects. +type ForwardingRequestListParams struct { + ListParams `form:"*"` + // Similar to other List endpoints, filters results based on created timestamp. You can pass gt, gte, lt, and lte timestamp values. + Created *RangeQueryParams `form:"created"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` +} + +// AddExpand appends a new field to expand. +func (p *ForwardingRequestListParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// The headers to include in the forwarded request. Can be omitted if no additional headers (excluding Stripe-generated ones such as the Content-Type header) should be included. +type ForwardingRequestRequestHeaderParams struct { + // The header name. + Name *string `form:"name"` + // The header value. + Value *string `form:"value"` +} + +// The request body and headers to be sent to the destination endpoint. +type ForwardingRequestRequestParams struct { + // The body payload to send to the destination endpoint. + Body *string `form:"body"` + // The headers to include in the forwarded request. Can be omitted if no additional headers (excluding Stripe-generated ones such as the Content-Type header) should be included. + Headers []*ForwardingRequestRequestHeaderParams `form:"headers"` +} + +// Creates a ForwardingRequest object. +type ForwardingRequestParams struct { + Params `form:"*"` + // The Forwarding Config used when making the forwarded request. The config specifes the HTTP method, merchant credentials, connection settings, and supported destination URLs. + Config *string `form:"config"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` + // The PaymentMethod to insert into the forwarded request. Forwarding previously consumed PaymentMethods is allowed. + PaymentMethod *string `form:"payment_method"` + // The field kinds to be replaced in the forwarded request. + Replacements []*string `form:"replacements"` + // The request body and headers to be sent to the destination endpoint. + Request *ForwardingRequestRequestParams `form:"request"` + // The destination URL for the forwarded request. Must be supported by the config. + URL *string `form:"url"` +} + +// AddExpand appends a new field to expand. +func (p *ForwardingRequestParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} + +// Context about the request from Stripe's servers to the destination endpoint. +type ForwardingRequestRequestContext struct { + // The time it took in milliseconds for the destination endpoint to respond. + DestinationDuration int64 `json:"destination_duration"` + // The IP address of the destination. + DestinationIPAddress string `json:"destination_ip_address"` +} + +// The headers to include in the forwarded request. Can be omitted if no additional headers (excluding Stripe-generated ones such as the Content-Type header) should be included. +type ForwardingRequestRequestDetailsHeader struct { + // The header name. + Name string `json:"name"` + // The header value. + Value string `json:"value"` +} + +// The request that was sent to the destination endpoint. We redact any sensitive fields. +type ForwardingRequestRequestDetails struct { + // The body payload to send to the destination endpoint. + Body string `json:"body"` + // The headers to include in the forwarded request. Can be omitted if no additional headers (excluding Stripe-generated ones such as the Content-Type header) should be included. + Headers []*ForwardingRequestRequestDetailsHeader `json:"headers"` + // The HTTP method used to call the destination endpoint. + HTTPMethod ForwardingRequestRequestDetailsHTTPMethod `json:"http_method"` +} + +// HTTP headers that the destination endpoint returned. +type ForwardingRequestResponseDetailsHeader struct { + // The header name. + Name string `json:"name"` + // The header value. + Value string `json:"value"` +} + +// The response that the destination endpoint returned to us. We redact any sensitive fields. +type ForwardingRequestResponseDetails struct { + // The response body from the destination endpoint to Stripe. + Body string `json:"body"` + // HTTP headers that the destination endpoint returned. + Headers []*ForwardingRequestResponseDetailsHeader `json:"headers"` + // The HTTP status code that the destination endpoint returned. + Status int64 `json:"status"` +} + +// Instructs Stripe to make a request on your behalf using the destination URL and HTTP method in the config. +// A config is set up for each destination URL by Stripe at the time of onboarding. Stripe verifies requests with +// your credentials in the config, and injects card details from the payment_method into the request. +// +// Stripe redacts all sensitive fields and headers, including authentication credentials and card numbers, +// before storing the request and response data in the forwarding Request object, which are subject to a +// 30-day retention period. +// +// You can provide a Stripe idempotency key to make sure that requests with the same key result in only one +// outbound request. The Stripe idempotency key provided should be unique and different from any idempotency +// keys provided on the underlying third-party request. +// +// Forwarding Requests are synchronous requests that return a response or time out according to +// Stripe's limits. +// +// Related guide: [Forward card details to third-party API endpoints](https://docs.stripe.com/payments/forwarding). +type ForwardingRequest struct { + APIResource + // The Forwarding Config used when making the forwarded request. The config specifes the HTTP method, merchant credentials, connection settings, and supported destination URLs. + Config string `json:"config"` + // Time at which the object was created. Measured in seconds since the Unix epoch. + Created int64 `json:"created"` + // Unique identifier for the object. + ID string `json:"id"` + // Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. + Livemode bool `json:"livemode"` + // String representing the object's type. Objects of the same type share the same value. + Object string `json:"object"` + // The PaymentMethod to insert into the forwarded request. Forwarding previously consumed PaymentMethods is allowed. + PaymentMethod string `json:"payment_method"` + // The field kinds to be replaced in the forwarded request. + Replacements []ForwardingRequestReplacement `json:"replacements"` + // Context about the request from Stripe's servers to the destination endpoint. + RequestContext *ForwardingRequestRequestContext `json:"request_context"` + // The request that was sent to the destination endpoint. We redact any sensitive fields. + RequestDetails *ForwardingRequestRequestDetails `json:"request_details"` + // The response that the destination endpoint returned to us. We redact any sensitive fields. + ResponseDetails *ForwardingRequestResponseDetails `json:"response_details"` + // The destination URL for the forwarded request. Must be supported by the config. + URL string `json:"url"` +} + +// ForwardingRequestList is a list of Requests as retrieved from a list endpoint. +type ForwardingRequestList struct { + APIResource + ListMeta + Data []*ForwardingRequest `json:"data"` +} diff --git a/vendor/github.com/stripe/stripe-go/v76/invoice.go b/vendor/github.com/stripe/stripe-go/v76/invoice.go index 5b04d249..7854f31b 100644 --- a/vendor/github.com/stripe/stripe-go/v76/invoice.go +++ b/vendor/github.com/stripe/stripe-go/v76/invoice.go @@ -1188,6 +1188,8 @@ func (p *InvoiceSendInvoiceParams) AddExpand(f string) { } // Mark a finalized invoice as void. This cannot be undone. Voiding an invoice is similar to [deletion](https://stripe.com/docs/api#delete_invoice), however it only applies to finalized invoices and maintains a papertrail where the invoice can still be found. +// +// Consult with local regulations to determine whether and how an invoice might be amended, canceled, or voided in the jurisdiction you're doing business in. You might need to [issue another invoice or credit note](https://stripe.com/docs/api#create_invoice) instead. Stripe recommends that you consult with your legal counsel for advice specific to your business. type InvoiceVoidInvoiceParams struct { Params `form:"*"` // Specifies which fields in the response should be expanded. diff --git a/vendor/github.com/stripe/stripe-go/v76/issuing_card.go b/vendor/github.com/stripe/stripe-go/v76/issuing_card.go index 3fc10f01..c613b54d 100644 --- a/vendor/github.com/stripe/stripe-go/v76/issuing_card.go +++ b/vendor/github.com/stripe/stripe-go/v76/issuing_card.go @@ -223,6 +223,8 @@ type IssuingCardParams struct { ReplacementFor *string `form:"replacement_for"` // If `replacement_for` is specified, this should indicate why that card is being replaced. ReplacementReason *string `form:"replacement_reason"` + // The second line to print on the card. + SecondLine *string `form:"second_line"` // The address where the card will be shipped. Shipping *IssuingCardShippingParams `form:"shipping"` // Rules that control spending for this card. Refer to our [documentation](https://stripe.com/docs/issuing/controls/spending-controls) for more details. diff --git a/vendor/github.com/stripe/stripe-go/v76/issuing_token.go b/vendor/github.com/stripe/stripe-go/v76/issuing_token.go index 51f46445..5a47bb1b 100644 --- a/vendor/github.com/stripe/stripe-go/v76/issuing_token.go +++ b/vendor/github.com/stripe/stripe-go/v76/issuing_token.go @@ -224,7 +224,7 @@ type IssuingToken struct { Card *IssuingCard `json:"card"` // Time at which the object was created. Measured in seconds since the Unix epoch. Created int64 `json:"created"` - // The hashed ID derived from the device ID from the card network associated with the token + // The hashed ID derived from the device ID from the card network associated with the token. DeviceFingerprint string `json:"device_fingerprint"` // Unique identifier for the object. ID string `json:"id"` diff --git a/vendor/github.com/stripe/stripe-go/v76/paymentintent.go b/vendor/github.com/stripe/stripe-go/v76/paymentintent.go index 44671387..4664e5cc 100644 --- a/vendor/github.com/stripe/stripe-go/v76/paymentintent.go +++ b/vendor/github.com/stripe/stripe-go/v76/paymentintent.go @@ -592,6 +592,26 @@ const ( PaymentIntentPaymentMethodOptionsLinkSetupFutureUsageOffSession PaymentIntentPaymentMethodOptionsLinkSetupFutureUsage = "off_session" ) +// Controls when the funds will be captured from the customer's account. +type PaymentIntentPaymentMethodOptionsMobilepayCaptureMethod string + +// List of values that PaymentIntentPaymentMethodOptionsMobilepayCaptureMethod can take +const ( + PaymentIntentPaymentMethodOptionsMobilepayCaptureMethodManual PaymentIntentPaymentMethodOptionsMobilepayCaptureMethod = "manual" +) + +// Indicates that you intend to make future payments with this PaymentIntent's payment method. +// +// Providing this parameter will [attach the payment method](https://stripe.com/docs/payments/save-during-payment) to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any required actions from the user are complete. If no Customer was provided, the payment method can still be [attached](https://stripe.com/docs/api/payment_methods/attach) to a Customer after the transaction completes. +// +// When processing card payments, Stripe also uses `setup_future_usage` to dynamically optimize your payment flow and comply with regional legislation and network rules, such as [SCA](https://stripe.com/docs/strong-customer-authentication). +type PaymentIntentPaymentMethodOptionsMobilepaySetupFutureUsage string + +// List of values that PaymentIntentPaymentMethodOptionsMobilepaySetupFutureUsage can take +const ( + PaymentIntentPaymentMethodOptionsMobilepaySetupFutureUsageNone PaymentIntentPaymentMethodOptionsMobilepaySetupFutureUsage = "none" +) + // Indicates that you intend to make future payments with this PaymentIntent's payment method. // // Providing this parameter will [attach the payment method](https://stripe.com/docs/payments/save-during-payment) to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any required actions from the user are complete. If no Customer was provided, the payment method can still be [attached](https://stripe.com/docs/api/payment_methods/attach) to a Customer after the transaction completes. @@ -1015,6 +1035,8 @@ type PaymentIntentPaymentMethodDataParams struct { Link *PaymentIntentPaymentMethodDataLinkParams `form:"link"` // Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`. Metadata map[string]string `form:"metadata"` + // If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. + Mobilepay *PaymentMethodMobilepayParams `form:"mobilepay"` // If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. OXXO *PaymentMethodOXXOParams `form:"oxxo"` // If this is a `p24` PaymentMethod, this hash contains details about the P24 payment method. @@ -1090,7 +1112,7 @@ type PaymentIntentPaymentMethodOptionsACSSDebitParams struct { type PaymentIntentPaymentMethodOptionsAffirmParams struct { // Controls when the funds will be captured from the customer's account. // - // If provided, this parameter will override the top-level `capture_method` when finalizing the payment with this payment method type. + // If provided, this parameter will override the top level behavior of `capture_method` when finalizing the payment with this payment method type. // // If `capture_method` is already set on the PaymentIntent, providing an empty value for this parameter will unset the stored value for this payment method type. CaptureMethod *string `form:"capture_method"` @@ -1110,7 +1132,7 @@ type PaymentIntentPaymentMethodOptionsAffirmParams struct { type PaymentIntentPaymentMethodOptionsAfterpayClearpayParams struct { // Controls when the funds will be captured from the customer's account. // - // If provided, this parameter will override the top-level `capture_method` when finalizing the payment with this payment method type. + // If provided, this parameter will override the top level behavior of `capture_method` when finalizing the payment with this payment method type. // // If `capture_method` is already set on the PaymentIntent, providing an empty value for this parameter will unset the stored value for this payment method type. CaptureMethod *string `form:"capture_method"` @@ -1309,7 +1331,7 @@ type PaymentIntentPaymentMethodOptionsCardThreeDSecureParams struct { type PaymentIntentPaymentMethodOptionsCardParams struct { // Controls when the funds will be captured from the customer's account. // - // If provided, this parameter will override the top-level `capture_method` when finalizing the payment with this payment method type. + // If provided, this parameter will override the top level behavior of `capture_method` when finalizing the payment with this payment method type. // // If `capture_method` is already set on the PaymentIntent, providing an empty value for this parameter will unset the stored value for this payment method type. CaptureMethod *string `form:"capture_method"` @@ -1370,7 +1392,7 @@ type PaymentIntentPaymentMethodOptionsCardPresentParams struct { type PaymentIntentPaymentMethodOptionsCashAppParams struct { // Controls when the funds will be captured from the customer's account. // - // If provided, this parameter will override the top-level `capture_method` when finalizing the payment with this payment method type. + // If provided, this parameter will override the top level behavior of `capture_method` when finalizing the payment with this payment method type. // // If `capture_method` is already set on the PaymentIntent, providing an empty value for this parameter will unset the stored value for this payment method type. CaptureMethod *string `form:"capture_method"` @@ -1485,7 +1507,7 @@ type PaymentIntentPaymentMethodOptionsInteracPresentParams struct{} type PaymentIntentPaymentMethodOptionsKlarnaParams struct { // Controls when the funds will be captured from the customer's account. // - // If provided, this parameter will override the top-level `capture_method` when finalizing the payment with this payment method type. + // If provided, this parameter will override the top level behavior of `capture_method` when finalizing the payment with this payment method type. // // If `capture_method` is already set on the PaymentIntent, providing an empty value for this parameter will unset the stored value for this payment method type. CaptureMethod *string `form:"capture_method"` @@ -1525,7 +1547,7 @@ type PaymentIntentPaymentMethodOptionsKonbiniParams struct { type PaymentIntentPaymentMethodOptionsLinkParams struct { // Controls when the funds will be captured from the customer's account. // - // If provided, this parameter will override the top-level `capture_method` when finalizing the payment with this payment method type. + // If provided, this parameter will override the top level behavior of `capture_method` when finalizing the payment with this payment method type. // // If `capture_method` is already set on the PaymentIntent, providing an empty value for this parameter will unset the stored value for this payment method type. CaptureMethod *string `form:"capture_method"` @@ -1541,6 +1563,24 @@ type PaymentIntentPaymentMethodOptionsLinkParams struct { SetupFutureUsage *string `form:"setup_future_usage"` } +// If this is a `MobilePay` PaymentMethod, this sub-hash contains details about the MobilePay payment method options. +type PaymentIntentPaymentMethodOptionsMobilepayParams struct { + // Controls when the funds will be captured from the customer's account. + // + // If provided, this parameter will override the top level behavior of `capture_method` when finalizing the payment with this payment method type. + // + // If `capture_method` is already set on the PaymentIntent, providing an empty value for this parameter will unset the stored value for this payment method type. + CaptureMethod *string `form:"capture_method"` + // Indicates that you intend to make future payments with this PaymentIntent's payment method. + // + // Providing this parameter will [attach the payment method](https://stripe.com/docs/payments/save-during-payment) to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any required actions from the user are complete. If no Customer was provided, the payment method can still be [attached](https://stripe.com/docs/api/payment_methods/attach) to a Customer after the transaction completes. + // + // When processing card payments, Stripe also uses `setup_future_usage` to dynamically optimize your payment flow and comply with regional legislation and network rules, such as [SCA](https://stripe.com/docs/strong-customer-authentication). + // + // If `setup_future_usage` is already set and you are performing a request using a publishable key, you may only update the value from `on_session` to `off_session`. + SetupFutureUsage *string `form:"setup_future_usage"` +} + // If this is a `oxxo` PaymentMethod, this sub-hash contains details about the OXXO payment method options. type PaymentIntentPaymentMethodOptionsOXXOParams struct { // The number of calendar days before an OXXO voucher expires. For example, if you create an OXXO voucher on Monday and you set expires_after_days to 2, the OXXO invoice will expire on Wednesday at 23:59 America/Mexico_City time. @@ -1802,6 +1842,8 @@ type PaymentIntentPaymentMethodOptionsParams struct { Konbini *PaymentIntentPaymentMethodOptionsKonbiniParams `form:"konbini"` // If this is a `link` PaymentMethod, this sub-hash contains details about the Link payment method options. Link *PaymentIntentPaymentMethodOptionsLinkParams `form:"link"` + // If this is a `MobilePay` PaymentMethod, this sub-hash contains details about the MobilePay payment method options. + Mobilepay *PaymentIntentPaymentMethodOptionsMobilepayParams `form:"mobilepay"` // If this is a `oxxo` PaymentMethod, this sub-hash contains details about the OXXO payment method options. OXXO *PaymentIntentPaymentMethodOptionsOXXOParams `form:"oxxo"` // If this is a `p24` PaymentMethod, this sub-hash contains details about the Przelewy24 payment method options. @@ -1880,6 +1922,10 @@ type PaymentIntentParams struct { Confirm *bool `form:"confirm"` // Describes whether we can confirm this PaymentIntent automatically, or if it requires customer action to confirm the payment. ConfirmationMethod *string `form:"confirmation_method"` + // ID of the ConfirmationToken used to confirm this PaymentIntent. + // + // If the provided ConfirmationToken contains properties that are also being provided in this request, such as `payment_method`, then the values in this request will take precedence. + ConfirmationToken *string `form:"confirmation_token"` // Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase. Must be a [supported currency](https://stripe.com/docs/currencies). Currency *string `form:"currency"` // ID of the Customer this PaymentIntent belongs to, if one exists. @@ -2090,6 +2136,10 @@ type PaymentIntentConfirmParams struct { Params `form:"*"` // Controls when the funds will be captured from the customer's account. CaptureMethod *string `form:"capture_method"` + // ID of the ConfirmationToken used to confirm this PaymentIntent. + // + // If the provided ConfirmationToken contains properties that are also being provided in this request, such as `payment_method`, then the values in this request will take precedence. + ConfirmationToken *string `form:"confirmation_token"` // Set to `true` to fail the payment attempt if the PaymentIntent transitions into `requires_action`. This parameter is intended for simpler integrations that do not handle customer actions, like [saving cards without authentication](https://stripe.com/docs/payments/save-card-without-authentication). ErrorOnRequiresAction *bool `form:"error_on_requires_action"` // Specifies which fields in the response should be expanded. @@ -2859,6 +2909,16 @@ type PaymentIntentPaymentMethodOptionsLink struct { // When processing card payments, Stripe also uses `setup_future_usage` to dynamically optimize your payment flow and comply with regional legislation and network rules, such as [SCA](https://stripe.com/docs/strong-customer-authentication). SetupFutureUsage PaymentIntentPaymentMethodOptionsLinkSetupFutureUsage `json:"setup_future_usage"` } +type PaymentIntentPaymentMethodOptionsMobilepay struct { + // Controls when the funds will be captured from the customer's account. + CaptureMethod PaymentIntentPaymentMethodOptionsMobilepayCaptureMethod `json:"capture_method"` + // Indicates that you intend to make future payments with this PaymentIntent's payment method. + // + // Providing this parameter will [attach the payment method](https://stripe.com/docs/payments/save-during-payment) to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any required actions from the user are complete. If no Customer was provided, the payment method can still be [attached](https://stripe.com/docs/api/payment_methods/attach) to a Customer after the transaction completes. + // + // When processing card payments, Stripe also uses `setup_future_usage` to dynamically optimize your payment flow and comply with regional legislation and network rules, such as [SCA](https://stripe.com/docs/strong-customer-authentication). + SetupFutureUsage PaymentIntentPaymentMethodOptionsMobilepaySetupFutureUsage `json:"setup_future_usage"` +} type PaymentIntentPaymentMethodOptionsOXXO struct { // The number of calendar days before an OXXO invoice expires. For example, if you create an OXXO invoice on Monday and you set expires_after_days to 2, the OXXO invoice will expire on Wednesday at 23:59 America/Mexico_City time. ExpiresAfterDays int64 `json:"expires_after_days"` @@ -3021,6 +3081,7 @@ type PaymentIntentPaymentMethodOptions struct { Klarna *PaymentIntentPaymentMethodOptionsKlarna `json:"klarna"` Konbini *PaymentIntentPaymentMethodOptionsKonbini `json:"konbini"` Link *PaymentIntentPaymentMethodOptionsLink `json:"link"` + Mobilepay *PaymentIntentPaymentMethodOptionsMobilepay `json:"mobilepay"` OXXO *PaymentIntentPaymentMethodOptionsOXXO `json:"oxxo"` P24 *PaymentIntentPaymentMethodOptionsP24 `json:"p24"` PayNow *PaymentIntentPaymentMethodOptionsPayNow `json:"paynow"` diff --git a/vendor/github.com/stripe/stripe-go/v76/paymentmethod.go b/vendor/github.com/stripe/stripe-go/v76/paymentmethod.go index 4c9d1824..b3b7116e 100644 --- a/vendor/github.com/stripe/stripe-go/v76/paymentmethod.go +++ b/vendor/github.com/stripe/stripe-go/v76/paymentmethod.go @@ -164,6 +164,7 @@ const ( PaymentMethodTypeKlarna PaymentMethodType = "klarna" PaymentMethodTypeKonbini PaymentMethodType = "konbini" PaymentMethodTypeLink PaymentMethodType = "link" + PaymentMethodTypeMobilepay PaymentMethodType = "mobilepay" PaymentMethodTypeOXXO PaymentMethodType = "oxxo" PaymentMethodTypeP24 PaymentMethodType = "p24" PaymentMethodTypePayNow PaymentMethodType = "paynow" @@ -392,6 +393,9 @@ type PaymentMethodKonbiniParams struct{} // If this is an `Link` PaymentMethod, this hash contains details about the Link payment method. type PaymentMethodLinkParams struct{} +// If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. +type PaymentMethodMobilepayParams struct{} + // If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. type PaymentMethodOXXOParams struct{} @@ -510,6 +514,8 @@ type PaymentMethodParams struct { Link *PaymentMethodLinkParams `form:"link"` // Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`. Metadata map[string]string `form:"metadata"` + // If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. + Mobilepay *PaymentMethodMobilepayParams `form:"mobilepay"` // If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. OXXO *PaymentMethodOXXOParams `form:"oxxo"` // If this is a `p24` PaymentMethod, this hash contains details about the P24 payment method. @@ -870,6 +876,7 @@ type PaymentMethodLink struct { // [Deprecated] This is a legacy parameter that no longer has any function. PersistentToken string `json:"persistent_token"` } +type PaymentMethodMobilepay struct{} type PaymentMethodOXXO struct{} type PaymentMethodP24 struct { // The customer's bank, if provided. @@ -1000,7 +1007,8 @@ type PaymentMethod struct { // Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. Livemode bool `json:"livemode"` // Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. - Metadata map[string]string `json:"metadata"` + Metadata map[string]string `json:"metadata"` + Mobilepay *PaymentMethodMobilepay `json:"mobilepay"` // String representing the object's type. Objects of the same type share the same value. Object string `json:"object"` OXXO *PaymentMethodOXXO `json:"oxxo"` diff --git a/vendor/github.com/stripe/stripe-go/v76/plan.go b/vendor/github.com/stripe/stripe-go/v76/plan.go index a1959fad..b32ff71c 100644 --- a/vendor/github.com/stripe/stripe-go/v76/plan.go +++ b/vendor/github.com/stripe/stripe-go/v76/plan.go @@ -95,6 +95,8 @@ type PlanParams struct { IntervalCount *int64 `form:"interval_count"` // Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`. Metadata map[string]string `form:"metadata"` + // The meter tracking the usage of a metered price + Meter *string `form:"meter"` // A brief description of the plan, hidden from customers. Nickname *string `form:"nickname"` // The product the plan belongs to. This cannot be changed once it has been used in a subscription or subscription schedule. @@ -268,6 +270,8 @@ type Plan struct { Livemode bool `json:"livemode"` // Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Metadata map[string]string `json:"metadata"` + // The meter tracking the usage of a metered price + Meter string `json:"meter"` // A brief description of the plan, hidden from customers. Nickname string `json:"nickname"` // String representing the object's type. Objects of the same type share the same value. diff --git a/vendor/github.com/stripe/stripe-go/v76/price.go b/vendor/github.com/stripe/stripe-go/v76/price.go index f7c392ca..77ee8792 100644 --- a/vendor/github.com/stripe/stripe-go/v76/price.go +++ b/vendor/github.com/stripe/stripe-go/v76/price.go @@ -102,6 +102,8 @@ const ( type PriceListRecurringParams struct { // Filter by billing frequency. Either `day`, `week`, `month` or `year`. Interval *string `form:"interval"` + // Filter by the price's meter. + Meter *string `form:"meter"` // Filter by the usage type for this price. Can be either `metered` or `licensed`. UsageType *string `form:"usage_type"` } @@ -231,6 +233,8 @@ type PriceRecurringParams struct { Interval *string `form:"interval"` // The number of intervals between subscription billings. For example, `interval=month` and `interval_count=3` bills every 3 months. Maximum of three years interval allowed (3 years, 36 months, or 156 weeks). IntervalCount *int64 `form:"interval_count"` + // The meter tracking the usage of a metered price + Meter *string `form:"meter"` // Default number of trial days when subscribing a customer to this price using [`trial_from_plan=true`](https://stripe.com/docs/api#create_subscription-trial_from_plan). TrialPeriodDays *int64 `form:"trial_period_days"` // Configures how the quantity per period should be determined. Can be either `metered` or `licensed`. `licensed` automatically bills the `quantity` set when adding it to a subscription. `metered` aggregates the total usage based on usage records. Defaults to `licensed`. @@ -397,6 +401,8 @@ type PriceRecurring struct { Interval PriceRecurringInterval `json:"interval"` // The number of intervals (specified in the `interval` attribute) between subscription billings. For example, `interval=month` and `interval_count=3` bills every 3 months. IntervalCount int64 `json:"interval_count"` + // The meter tracking the usage of a metered price + Meter string `json:"meter"` // Default number of trial days when subscribing a customer to this price using [`trial_from_plan=true`](https://stripe.com/docs/api#create_subscription-trial_from_plan). TrialPeriodDays int64 `json:"trial_period_days"` // Configures how the quantity per period should be determined. Can be either `metered` or `licensed`. `licensed` automatically bills the `quantity` set when adding it to a subscription. `metered` aggregates the total usage based on usage records. Defaults to `licensed`. diff --git a/vendor/github.com/stripe/stripe-go/v76/product.go b/vendor/github.com/stripe/stripe-go/v76/product.go index cb497ede..e61503c8 100644 --- a/vendor/github.com/stripe/stripe-go/v76/product.go +++ b/vendor/github.com/stripe/stripe-go/v76/product.go @@ -33,7 +33,7 @@ type ProductParams struct { Description *string `form:"description"` // Specifies which fields in the response should be expanded. Expand []*string `form:"expand"` - // A list of up to 15 features for this product. These are displayed in [pricing tables](https://stripe.com/docs/payments/checkout/pricing-table). + // A list of up to 15 marketing features for this product. These are displayed in [pricing tables](https://stripe.com/docs/payments/checkout/pricing-table). Features []*ProductFeatureParams `form:"features"` // An identifier will be randomly generated by Stripe. You can optionally override this ID, but the ID must be unique across all products in your Stripe account. ID *string `form:"id"` @@ -76,9 +76,9 @@ func (p *ProductParams) AddMetadata(key string, value string) { p.Metadata[key] = value } -// A list of up to 15 features for this product. These are displayed in [pricing tables](https://stripe.com/docs/payments/checkout/pricing-table). +// A list of up to 15 marketing features for this product. These are displayed in [pricing tables](https://stripe.com/docs/payments/checkout/pricing-table). type ProductFeatureParams struct { - // The feature's name. Up to 80 characters long. + // The marketing feature name. Up to 80 characters long. Name *string `form:"name"` } @@ -209,9 +209,9 @@ func (p *ProductSearchParams) AddExpand(f string) { p.Expand = append(p.Expand, &f) } -// A list of up to 15 features for this product. These are displayed in [pricing tables](https://stripe.com/docs/payments/checkout/pricing-table). +// A list of up to 15 marketing features for this product. These are displayed in [pricing tables](https://stripe.com/docs/payments/checkout/pricing-table). type ProductFeature struct { - // The feature's name. Up to 80 characters long. + // The marketing feature name. Up to 80 characters long. Name string `json:"name"` } @@ -246,7 +246,7 @@ type Product struct { Deleted bool `json:"deleted"` // The product's description, meant to be displayable to the customer. Use this field to optionally store a long form explanation of the product being sold for your own rendering purposes. Description string `json:"description"` - // A list of up to 15 features for this product. These are displayed in [pricing tables](https://stripe.com/docs/payments/checkout/pricing-table). + // A list of up to 15 marketing features for this product. These are displayed in [pricing tables](https://stripe.com/docs/payments/checkout/pricing-table). Features []*ProductFeature `json:"features"` // Unique identifier for the object. ID string `json:"id"` diff --git a/vendor/github.com/stripe/stripe-go/v76/quote.go b/vendor/github.com/stripe/stripe-go/v76/quote.go index f1f629a1..5881f1f1 100644 --- a/vendor/github.com/stripe/stripe-go/v76/quote.go +++ b/vendor/github.com/stripe/stripe-go/v76/quote.go @@ -402,7 +402,7 @@ func (p *QuoteFinalizeQuoteParams) AddExpand(f string) { p.Expand = append(p.Expand, &f) } -// Download the PDF for a finalized quote +// Download the PDF for a finalized quote. Explanation for special handling can be found [here](https://docs.corp.stripe.com/quotes/overview#quote_pdf) type QuotePDFParams struct { Params `form:"*"` // Specifies which fields in the response should be expanded. diff --git a/vendor/github.com/stripe/stripe-go/v76/setupintent.go b/vendor/github.com/stripe/stripe-go/v76/setupintent.go index b922c1d5..33691775 100644 --- a/vendor/github.com/stripe/stripe-go/v76/setupintent.go +++ b/vendor/github.com/stripe/stripe-go/v76/setupintent.go @@ -407,6 +407,9 @@ type SetupIntentPaymentMethodDataKonbiniParams struct{} // If this is an `Link` PaymentMethod, this hash contains details about the Link payment method. type SetupIntentPaymentMethodDataLinkParams struct{} +// If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. +type SetupIntentPaymentMethodDataMobilepayParams struct{} + // If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. type SetupIntentPaymentMethodDataOXXOParams struct{} @@ -519,6 +522,8 @@ type SetupIntentPaymentMethodDataParams struct { Link *SetupIntentPaymentMethodDataLinkParams `form:"link"` // Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`. Metadata map[string]string `form:"metadata"` + // If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. + Mobilepay *SetupIntentPaymentMethodDataMobilepayParams `form:"mobilepay"` // If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. OXXO *SetupIntentPaymentMethodDataOXXOParams `form:"oxxo"` // If this is a `p24` PaymentMethod, this hash contains details about the P24 payment method. @@ -773,6 +778,10 @@ type SetupIntentParams struct { ClientSecret *string `form:"client_secret"` // Set to `true` to attempt to confirm this SetupIntent immediately. This parameter defaults to `false`. If a card is the attached payment method, you can provide a `return_url` in case further authentication is necessary. Confirm *bool `form:"confirm"` + // ID of the ConfirmationToken used to confirm this SetupIntent. + // + // If the provided ConfirmationToken contains properties that are also being provided in this request, such as `payment_method`, then the values in this request will take precedence. + ConfirmationToken *string `form:"confirmation_token"` // ID of the Customer this SetupIntent belongs to, if one exists. // // If present, the SetupIntent's payment method will be attached to the Customer on successful setup. Payment methods attached to other Customers cannot be used with this SetupIntent. @@ -958,6 +967,9 @@ type SetupIntentConfirmPaymentMethodDataKonbiniParams struct{} // If this is an `Link` PaymentMethod, this hash contains details about the Link payment method. type SetupIntentConfirmPaymentMethodDataLinkParams struct{} +// If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. +type SetupIntentConfirmPaymentMethodDataMobilepayParams struct{} + // If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. type SetupIntentConfirmPaymentMethodDataOXXOParams struct{} @@ -1070,6 +1082,8 @@ type SetupIntentConfirmPaymentMethodDataParams struct { Link *SetupIntentConfirmPaymentMethodDataLinkParams `form:"link"` // Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`. Metadata map[string]string `form:"metadata"` + // If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. + Mobilepay *SetupIntentConfirmPaymentMethodDataMobilepayParams `form:"mobilepay"` // If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. OXXO *SetupIntentConfirmPaymentMethodDataOXXOParams `form:"oxxo"` // If this is a `p24` PaymentMethod, this hash contains details about the P24 payment method. @@ -1127,6 +1141,10 @@ func (p *SetupIntentConfirmPaymentMethodDataParams) AddMetadata(key string, valu // confirmation limit is reached. type SetupIntentConfirmParams struct { Params `form:"*"` + // ID of the ConfirmationToken used to confirm this SetupIntent. + // + // If the provided ConfirmationToken contains properties that are also being provided in this request, such as `payment_method`, then the values in this request will take precedence. + ConfirmationToken *string `form:"confirmation_token"` // Specifies which fields in the response should be expanded. Expand []*string `form:"expand"` MandateData *SetupIntentMandateDataParams `form:"mandate_data"` diff --git a/vendor/github.com/stripe/stripe-go/v76/stripe.go b/vendor/github.com/stripe/stripe-go/v76/stripe.go index 4b5f351c..26f0a098 100644 --- a/vendor/github.com/stripe/stripe-go/v76/stripe.go +++ b/vendor/github.com/stripe/stripe-go/v76/stripe.go @@ -1283,7 +1283,7 @@ func StringSlice(v []string) []*string { // // clientversion is the binding version -const clientversion = "76.21.0" +const clientversion = "76.23.0" // defaultHTTPTimeout is the default timeout on the http.Client used by the library. // This is chosen to be consistent with the other Stripe language libraries and diff --git a/vendor/github.com/stripe/stripe-go/v76/subscription.go b/vendor/github.com/stripe/stripe-go/v76/subscription.go index 58e1592d..e2287e33 100644 --- a/vendor/github.com/stripe/stripe-go/v76/subscription.go +++ b/vendor/github.com/stripe/stripe-go/v76/subscription.go @@ -210,12 +210,14 @@ const ( SubscriptionPendingInvoiceItemIntervalIntervalYear SubscriptionPendingInvoiceItemIntervalInterval = "year" ) -// Possible values are `incomplete`, `incomplete_expired`, `trialing`, `active`, `past_due`, `canceled`, or `unpaid`. +// Possible values are `incomplete`, `incomplete_expired`, `trialing`, `active`, `past_due`, `canceled`, `unpaid`, or `paused`. // -// For `collection_method=charge_automatically` a subscription moves into `incomplete` if the initial payment attempt fails. A subscription in this state can only have metadata and default_source updated. Once the first invoice is paid, the subscription moves into an `active` state. If the first invoice is not paid within 23 hours, the subscription transitions to `incomplete_expired`. This is a terminal state, the open invoice will be voided and no further invoices will be generated. +// For `collection_method=charge_automatically` a subscription moves into `incomplete` if the initial payment attempt fails. A subscription in this status can only have metadata and default_source updated. Once the first invoice is paid, the subscription moves into an `active` status. If the first invoice is not paid within 23 hours, the subscription transitions to `incomplete_expired`. This is a terminal status, the open invoice will be voided and no further invoices will be generated. // // A subscription that is currently in a trial period is `trialing` and moves to `active` when the trial period is over. // +// A subscription can only enter a `paused` status [when a trial ends without a payment method](https://stripe.com/billing/subscriptions/trials#create-free-trials-without-payment). A `paused` subscription doesn't generate invoices and can be resumed after your customer adds their payment method. The `paused` status is different from [pausing collection](https://stripe.com/billing/subscriptions/pause-payment), which still generates invoices and leaves the subscription's status unchanged. +// // If subscription `collection_method=charge_automatically`, it becomes `past_due` when payment is required but cannot be paid (due to failed payment or awaiting additional user actions). Once Stripe has exhausted all payment retry attempts, the subscription will become `canceled` or `unpaid` (depending on your subscriptions settings). // // If subscription `collection_method=send_invoice` it becomes `past_due` when its invoice is not paid by the due date, and `canceled` or `unpaid` if it is still not paid by an additional deadline after that. Note that when a subscription has a status of `unpaid`, no subsequent invoices will be attempted (invoices will be created, but then immediately automatically closed). After receiving updated payment information from a customer, you may choose to reopen and pay their closed invoices. @@ -328,7 +330,7 @@ type SubscriptionParams struct { OffSession *bool `form:"off_session"` // The account on behalf of which to charge, for each of the subscription's invoices. OnBehalfOf *string `form:"on_behalf_of"` - // If specified, payment collection for this subscription will be paused. + // If specified, payment collection for this subscription will be paused. Note that the subscription status will be unchanged and will not be updated to `paused`. Learn more about [pausing collection](https://stripe.com/billing/subscriptions/pause-payment). PauseCollection *SubscriptionPauseCollectionParams `form:"pause_collection"` // Only applies to subscriptions with `collection_method=charge_automatically`. // @@ -486,7 +488,7 @@ func (p *SubscriptionItemsParams) AddMetadata(key string, value string) { p.Metadata[key] = value } -// If specified, payment collection for this subscription will be paused. +// If specified, payment collection for this subscription will be paused. Note that the subscription status will be unchanged and will not be updated to `paused`. Learn more about [pausing collection](https://stripe.com/billing/subscriptions/pause-payment). type SubscriptionPauseCollectionParams struct { // The payment collection behavior for this subscription while paused. One of `keep_as_draft`, `mark_uncollectible`, or `void`. Behavior *string `form:"behavior"` @@ -774,7 +776,7 @@ type SubscriptionCancellationDetails struct { Reason SubscriptionCancellationDetailsReason `json:"reason"` } -// If specified, payment collection for this subscription will be paused. +// If specified, payment collection for this subscription will be paused. Note that the subscription status will be unchanged and will not be updated to `paused`. Learn more about [pausing collection](https://stripe.com/billing/subscriptions/pause-payment). type SubscriptionPauseCollection struct { // The payment collection behavior for this subscription while paused. One of `keep_as_draft`, `mark_uncollectible`, or `void`. Behavior SubscriptionPauseCollectionBehavior `json:"behavior"` @@ -987,7 +989,7 @@ type Subscription struct { Object string `json:"object"` // The account (if any) the charge was made on behalf of for charges associated with this subscription. See the Connect documentation for details. OnBehalfOf *Account `json:"on_behalf_of"` - // If specified, payment collection for this subscription will be paused. + // If specified, payment collection for this subscription will be paused. Note that the subscription status will be unchanged and will not be updated to `paused`. Learn more about [pausing collection](https://stripe.com/billing/subscriptions/pause-payment). PauseCollection *SubscriptionPauseCollection `json:"pause_collection"` // Payment settings passed on to invoices created by the subscription. PaymentSettings *SubscriptionPaymentSettings `json:"payment_settings"` @@ -1001,12 +1003,14 @@ type Subscription struct { Schedule *SubscriptionSchedule `json:"schedule"` // Date when the subscription was first created. The date might differ from the `created` date due to backdating. StartDate int64 `json:"start_date"` - // Possible values are `incomplete`, `incomplete_expired`, `trialing`, `active`, `past_due`, `canceled`, or `unpaid`. + // Possible values are `incomplete`, `incomplete_expired`, `trialing`, `active`, `past_due`, `canceled`, `unpaid`, or `paused`. // - // For `collection_method=charge_automatically` a subscription moves into `incomplete` if the initial payment attempt fails. A subscription in this state can only have metadata and default_source updated. Once the first invoice is paid, the subscription moves into an `active` state. If the first invoice is not paid within 23 hours, the subscription transitions to `incomplete_expired`. This is a terminal state, the open invoice will be voided and no further invoices will be generated. + // For `collection_method=charge_automatically` a subscription moves into `incomplete` if the initial payment attempt fails. A subscription in this status can only have metadata and default_source updated. Once the first invoice is paid, the subscription moves into an `active` status. If the first invoice is not paid within 23 hours, the subscription transitions to `incomplete_expired`. This is a terminal status, the open invoice will be voided and no further invoices will be generated. // // A subscription that is currently in a trial period is `trialing` and moves to `active` when the trial period is over. // + // A subscription can only enter a `paused` status [when a trial ends without a payment method](https://stripe.com/billing/subscriptions/trials#create-free-trials-without-payment). A `paused` subscription doesn't generate invoices and can be resumed after your customer adds their payment method. The `paused` status is different from [pausing collection](https://stripe.com/billing/subscriptions/pause-payment), which still generates invoices and leaves the subscription's status unchanged. + // // If subscription `collection_method=charge_automatically`, it becomes `past_due` when payment is required but cannot be paid (due to failed payment or awaiting additional user actions). Once Stripe has exhausted all payment retry attempts, the subscription will become `canceled` or `unpaid` (depending on your subscriptions settings). // // If subscription `collection_method=send_invoice` it becomes `past_due` when its invoice is not paid by the due date, and `canceled` or `unpaid` if it is still not paid by an additional deadline after that. Note that when a subscription has a status of `unpaid`, no subsequent invoices will be attempted (invoices will be created, but then immediately automatically closed). After receiving updated payment information from a customer, you may choose to reopen and pay their closed invoices. diff --git a/vendor/github.com/stripe/stripe-go/v76/terminal_configuration.go b/vendor/github.com/stripe/stripe-go/v76/terminal_configuration.go index d855872e..4ecbd863 100644 --- a/vendor/github.com/stripe/stripe-go/v76/terminal_configuration.go +++ b/vendor/github.com/stripe/stripe-go/v76/terminal_configuration.go @@ -13,6 +13,8 @@ type TerminalConfigurationParams struct { BBPOSWisePOSE *TerminalConfigurationBBPOSWisePOSEParams `form:"bbpos_wisepos_e"` // Specifies which fields in the response should be expanded. Expand []*string `form:"expand"` + // Name of the configuration + Name *string `form:"name"` // Configurations for collecting transactions offline. Offline *TerminalConfigurationOfflineParams `form:"offline"` // Tipping configurations for readers supporting on-reader tips @@ -382,6 +384,8 @@ type TerminalConfiguration struct { IsAccountDefault bool `json:"is_account_default"` // Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. Livemode bool `json:"livemode"` + // String indicating the name of the Configuration object, set by the user + Name string `json:"name"` // String representing the object's type. Objects of the same type share the same value. Object string `json:"object"` Offline *TerminalConfigurationOffline `json:"offline"` diff --git a/vendor/github.com/stripe/stripe-go/v76/testhelpers/confirmationtoken/client.go b/vendor/github.com/stripe/stripe-go/v76/testhelpers/confirmationtoken/client.go new file mode 100644 index 00000000..31441936 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/testhelpers/confirmationtoken/client.go @@ -0,0 +1,42 @@ +// +// +// File generated from our OpenAPI spec +// +// + +// Package confirmationtoken provides the /confirmation_tokens APIs +package confirmationtoken + +import ( + "net/http" + + stripe "github.com/stripe/stripe-go/v76" +) + +// Client is used to invoke /confirmation_tokens APIs. +type Client struct { + B stripe.Backend + Key string +} + +// New creates a new confirmation token. +func New(params *stripe.TestHelpersConfirmationTokenParams) (*stripe.ConfirmationToken, error) { + return getC().New(params) +} + +// New creates a new confirmation token. +func (c Client) New(params *stripe.TestHelpersConfirmationTokenParams) (*stripe.ConfirmationToken, error) { + confirmationtoken := &stripe.ConfirmationToken{} + err := c.B.Call( + http.MethodPost, + "/v1/test_helpers/confirmation_tokens", + c.Key, + params, + confirmationtoken, + ) + return confirmationtoken, err +} + +func getC() Client { + return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key} +} diff --git a/vendor/github.com/stripe/stripe-go/v76/testhelpers_confirmationtoken.go b/vendor/github.com/stripe/stripe-go/v76/testhelpers_confirmationtoken.go new file mode 100644 index 00000000..8e3b9c20 --- /dev/null +++ b/vendor/github.com/stripe/stripe-go/v76/testhelpers_confirmationtoken.go @@ -0,0 +1,314 @@ +// +// +// File generated from our OpenAPI spec +// +// + +package stripe + +// If this is an `acss_debit` PaymentMethod, this hash contains details about the ACSS Debit payment method. +type TestHelpersConfirmationTokenPaymentMethodDataACSSDebitParams struct { + // Customer's bank account number. + AccountNumber *string `form:"account_number"` + // Institution number of the customer's bank. + InstitutionNumber *string `form:"institution_number"` + // Transit number of the customer's bank. + TransitNumber *string `form:"transit_number"` +} + +// If this is an `affirm` PaymentMethod, this hash contains details about the Affirm payment method. +type TestHelpersConfirmationTokenPaymentMethodDataAffirmParams struct{} + +// If this is an `AfterpayClearpay` PaymentMethod, this hash contains details about the AfterpayClearpay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataAfterpayClearpayParams struct{} + +// If this is an `Alipay` PaymentMethod, this hash contains details about the Alipay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataAlipayParams struct{} + +// If this is an `au_becs_debit` PaymentMethod, this hash contains details about the bank account. +type TestHelpersConfirmationTokenPaymentMethodDataAUBECSDebitParams struct { + // The account number for the bank account. + AccountNumber *string `form:"account_number"` + // Bank-State-Branch number of the bank account. + BSBNumber *string `form:"bsb_number"` +} + +// If this is a `bacs_debit` PaymentMethod, this hash contains details about the Bacs Direct Debit bank account. +type TestHelpersConfirmationTokenPaymentMethodDataBACSDebitParams struct { + // Account number of the bank account that the funds will be debited from. + AccountNumber *string `form:"account_number"` + // Sort code of the bank account. (e.g., `10-20-30`) + SortCode *string `form:"sort_code"` +} + +// If this is a `bancontact` PaymentMethod, this hash contains details about the Bancontact payment method. +type TestHelpersConfirmationTokenPaymentMethodDataBancontactParams struct{} + +// Billing information associated with the PaymentMethod that may be used or required by particular types of payment methods. +type TestHelpersConfirmationTokenPaymentMethodDataBillingDetailsParams struct { + // Billing address. + Address *AddressParams `form:"address"` + // Email address. + Email *string `form:"email"` + // Full name. + Name *string `form:"name"` + // Billing phone number (including extension). + Phone *string `form:"phone"` +} + +// If this is a `blik` PaymentMethod, this hash contains details about the BLIK payment method. +type TestHelpersConfirmationTokenPaymentMethodDataBLIKParams struct{} + +// If this is a `boleto` PaymentMethod, this hash contains details about the Boleto payment method. +type TestHelpersConfirmationTokenPaymentMethodDataBoletoParams struct { + // The tax ID of the customer (CPF for individual consumers or CNPJ for businesses consumers) + TaxID *string `form:"tax_id"` +} + +// If this is a `cashapp` PaymentMethod, this hash contains details about the Cash App Pay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataCashAppParams struct{} + +// If this is a `customer_balance` PaymentMethod, this hash contains details about the CustomerBalance payment method. +type TestHelpersConfirmationTokenPaymentMethodDataCustomerBalanceParams struct{} + +// If this is an `eps` PaymentMethod, this hash contains details about the EPS payment method. +type TestHelpersConfirmationTokenPaymentMethodDataEPSParams struct { + // The customer's bank. + Bank *string `form:"bank"` +} + +// If this is an `fpx` PaymentMethod, this hash contains details about the FPX payment method. +type TestHelpersConfirmationTokenPaymentMethodDataFPXParams struct { + // Account holder type for FPX transaction + AccountHolderType *string `form:"account_holder_type"` + // The customer's bank. + Bank *string `form:"bank"` +} + +// If this is a `giropay` PaymentMethod, this hash contains details about the Giropay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataGiropayParams struct{} + +// If this is a `grabpay` PaymentMethod, this hash contains details about the GrabPay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataGrabpayParams struct{} + +// If this is an `ideal` PaymentMethod, this hash contains details about the iDEAL payment method. +type TestHelpersConfirmationTokenPaymentMethodDataIDEALParams struct { + // The customer's bank. + Bank *string `form:"bank"` +} + +// If this is an `interac_present` PaymentMethod, this hash contains details about the Interac Present payment method. +type TestHelpersConfirmationTokenPaymentMethodDataInteracPresentParams struct{} + +// Customer's date of birth +type TestHelpersConfirmationTokenPaymentMethodDataKlarnaDOBParams struct { + // The day of birth, between 1 and 31. + Day *int64 `form:"day"` + // The month of birth, between 1 and 12. + Month *int64 `form:"month"` + // The four-digit year of birth. + Year *int64 `form:"year"` +} + +// If this is a `klarna` PaymentMethod, this hash contains details about the Klarna payment method. +type TestHelpersConfirmationTokenPaymentMethodDataKlarnaParams struct { + // Customer's date of birth + DOB *TestHelpersConfirmationTokenPaymentMethodDataKlarnaDOBParams `form:"dob"` +} + +// If this is a `konbini` PaymentMethod, this hash contains details about the Konbini payment method. +type TestHelpersConfirmationTokenPaymentMethodDataKonbiniParams struct{} + +// If this is an `Link` PaymentMethod, this hash contains details about the Link payment method. +type TestHelpersConfirmationTokenPaymentMethodDataLinkParams struct{} + +// If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataMobilepayParams struct{} + +// If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. +type TestHelpersConfirmationTokenPaymentMethodDataOXXOParams struct{} + +// If this is a `p24` PaymentMethod, this hash contains details about the P24 payment method. +type TestHelpersConfirmationTokenPaymentMethodDataP24Params struct { + // The customer's bank. + Bank *string `form:"bank"` +} + +// If this is a `paynow` PaymentMethod, this hash contains details about the PayNow payment method. +type TestHelpersConfirmationTokenPaymentMethodDataPayNowParams struct{} + +// If this is a `paypal` PaymentMethod, this hash contains details about the PayPal payment method. +type TestHelpersConfirmationTokenPaymentMethodDataPaypalParams struct{} + +// If this is a `pix` PaymentMethod, this hash contains details about the Pix payment method. +type TestHelpersConfirmationTokenPaymentMethodDataPixParams struct{} + +// If this is a `promptpay` PaymentMethod, this hash contains details about the PromptPay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataPromptPayParams struct{} + +// Options to configure Radar. See [Radar Session](https://stripe.com/docs/radar/radar-session) for more information. +type TestHelpersConfirmationTokenPaymentMethodDataRadarOptionsParams struct { + // A [Radar Session](https://stripe.com/docs/radar/radar-session) is a snapshot of the browser metadata and device details that help Radar make more accurate predictions on your payments. + Session *string `form:"session"` +} + +// If this is a `Revolut Pay` PaymentMethod, this hash contains details about the Revolut Pay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataRevolutPayParams struct{} + +// If this is a `sepa_debit` PaymentMethod, this hash contains details about the SEPA debit bank account. +type TestHelpersConfirmationTokenPaymentMethodDataSEPADebitParams struct { + // IBAN of the bank account. + IBAN *string `form:"iban"` +} + +// If this is a `sofort` PaymentMethod, this hash contains details about the SOFORT payment method. +type TestHelpersConfirmationTokenPaymentMethodDataSofortParams struct { + // Two-letter ISO code representing the country the bank account is located in. + Country *string `form:"country"` +} + +// If this is a `swish` PaymentMethod, this hash contains details about the Swish payment method. +type TestHelpersConfirmationTokenPaymentMethodDataSwishParams struct{} + +// If this is an `us_bank_account` PaymentMethod, this hash contains details about the US bank account payment method. +type TestHelpersConfirmationTokenPaymentMethodDataUSBankAccountParams struct { + // Account holder type: individual or company. + AccountHolderType *string `form:"account_holder_type"` + // Account number of the bank account. + AccountNumber *string `form:"account_number"` + // Account type: checkings or savings. Defaults to checking if omitted. + AccountType *string `form:"account_type"` + // The ID of a Financial Connections Account to use as a payment method. + FinancialConnectionsAccount *string `form:"financial_connections_account"` + // Routing number of the bank account. + RoutingNumber *string `form:"routing_number"` +} + +// If this is an `wechat_pay` PaymentMethod, this hash contains details about the wechat_pay payment method. +type TestHelpersConfirmationTokenPaymentMethodDataWeChatPayParams struct{} + +// If this is a `zip` PaymentMethod, this hash contains details about the Zip payment method. +type TestHelpersConfirmationTokenPaymentMethodDataZipParams struct{} + +// If provided, this hash will be used to create a PaymentMethod. +type TestHelpersConfirmationTokenPaymentMethodDataParams struct { + // If this is an `acss_debit` PaymentMethod, this hash contains details about the ACSS Debit payment method. + ACSSDebit *TestHelpersConfirmationTokenPaymentMethodDataACSSDebitParams `form:"acss_debit"` + // If this is an `affirm` PaymentMethod, this hash contains details about the Affirm payment method. + Affirm *TestHelpersConfirmationTokenPaymentMethodDataAffirmParams `form:"affirm"` + // If this is an `AfterpayClearpay` PaymentMethod, this hash contains details about the AfterpayClearpay payment method. + AfterpayClearpay *TestHelpersConfirmationTokenPaymentMethodDataAfterpayClearpayParams `form:"afterpay_clearpay"` + // If this is an `Alipay` PaymentMethod, this hash contains details about the Alipay payment method. + Alipay *TestHelpersConfirmationTokenPaymentMethodDataAlipayParams `form:"alipay"` + // If this is an `au_becs_debit` PaymentMethod, this hash contains details about the bank account. + AUBECSDebit *TestHelpersConfirmationTokenPaymentMethodDataAUBECSDebitParams `form:"au_becs_debit"` + // If this is a `bacs_debit` PaymentMethod, this hash contains details about the Bacs Direct Debit bank account. + BACSDebit *TestHelpersConfirmationTokenPaymentMethodDataBACSDebitParams `form:"bacs_debit"` + // If this is a `bancontact` PaymentMethod, this hash contains details about the Bancontact payment method. + Bancontact *TestHelpersConfirmationTokenPaymentMethodDataBancontactParams `form:"bancontact"` + // Billing information associated with the PaymentMethod that may be used or required by particular types of payment methods. + BillingDetails *TestHelpersConfirmationTokenPaymentMethodDataBillingDetailsParams `form:"billing_details"` + // If this is a `blik` PaymentMethod, this hash contains details about the BLIK payment method. + BLIK *TestHelpersConfirmationTokenPaymentMethodDataBLIKParams `form:"blik"` + // If this is a `boleto` PaymentMethod, this hash contains details about the Boleto payment method. + Boleto *TestHelpersConfirmationTokenPaymentMethodDataBoletoParams `form:"boleto"` + // If this is a `cashapp` PaymentMethod, this hash contains details about the Cash App Pay payment method. + CashApp *TestHelpersConfirmationTokenPaymentMethodDataCashAppParams `form:"cashapp"` + // If this is a `customer_balance` PaymentMethod, this hash contains details about the CustomerBalance payment method. + CustomerBalance *TestHelpersConfirmationTokenPaymentMethodDataCustomerBalanceParams `form:"customer_balance"` + // If this is an `eps` PaymentMethod, this hash contains details about the EPS payment method. + EPS *TestHelpersConfirmationTokenPaymentMethodDataEPSParams `form:"eps"` + // If this is an `fpx` PaymentMethod, this hash contains details about the FPX payment method. + FPX *TestHelpersConfirmationTokenPaymentMethodDataFPXParams `form:"fpx"` + // If this is a `giropay` PaymentMethod, this hash contains details about the Giropay payment method. + Giropay *TestHelpersConfirmationTokenPaymentMethodDataGiropayParams `form:"giropay"` + // If this is a `grabpay` PaymentMethod, this hash contains details about the GrabPay payment method. + Grabpay *TestHelpersConfirmationTokenPaymentMethodDataGrabpayParams `form:"grabpay"` + // If this is an `ideal` PaymentMethod, this hash contains details about the iDEAL payment method. + IDEAL *TestHelpersConfirmationTokenPaymentMethodDataIDEALParams `form:"ideal"` + // If this is an `interac_present` PaymentMethod, this hash contains details about the Interac Present payment method. + InteracPresent *TestHelpersConfirmationTokenPaymentMethodDataInteracPresentParams `form:"interac_present"` + // If this is a `klarna` PaymentMethod, this hash contains details about the Klarna payment method. + Klarna *TestHelpersConfirmationTokenPaymentMethodDataKlarnaParams `form:"klarna"` + // If this is a `konbini` PaymentMethod, this hash contains details about the Konbini payment method. + Konbini *TestHelpersConfirmationTokenPaymentMethodDataKonbiniParams `form:"konbini"` + // If this is an `Link` PaymentMethod, this hash contains details about the Link payment method. + Link *TestHelpersConfirmationTokenPaymentMethodDataLinkParams `form:"link"` + // Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`. + Metadata map[string]string `form:"metadata"` + // If this is a `mobilepay` PaymentMethod, this hash contains details about the MobilePay payment method. + Mobilepay *TestHelpersConfirmationTokenPaymentMethodDataMobilepayParams `form:"mobilepay"` + // If this is an `oxxo` PaymentMethod, this hash contains details about the OXXO payment method. + OXXO *TestHelpersConfirmationTokenPaymentMethodDataOXXOParams `form:"oxxo"` + // If this is a `p24` PaymentMethod, this hash contains details about the P24 payment method. + P24 *TestHelpersConfirmationTokenPaymentMethodDataP24Params `form:"p24"` + // If this is a `paynow` PaymentMethod, this hash contains details about the PayNow payment method. + PayNow *TestHelpersConfirmationTokenPaymentMethodDataPayNowParams `form:"paynow"` + // If this is a `paypal` PaymentMethod, this hash contains details about the PayPal payment method. + Paypal *TestHelpersConfirmationTokenPaymentMethodDataPaypalParams `form:"paypal"` + // If this is a `pix` PaymentMethod, this hash contains details about the Pix payment method. + Pix *TestHelpersConfirmationTokenPaymentMethodDataPixParams `form:"pix"` + // If this is a `promptpay` PaymentMethod, this hash contains details about the PromptPay payment method. + PromptPay *TestHelpersConfirmationTokenPaymentMethodDataPromptPayParams `form:"promptpay"` + // Options to configure Radar. See [Radar Session](https://stripe.com/docs/radar/radar-session) for more information. + RadarOptions *TestHelpersConfirmationTokenPaymentMethodDataRadarOptionsParams `form:"radar_options"` + // If this is a `Revolut Pay` PaymentMethod, this hash contains details about the Revolut Pay payment method. + RevolutPay *TestHelpersConfirmationTokenPaymentMethodDataRevolutPayParams `form:"revolut_pay"` + // If this is a `sepa_debit` PaymentMethod, this hash contains details about the SEPA debit bank account. + SEPADebit *TestHelpersConfirmationTokenPaymentMethodDataSEPADebitParams `form:"sepa_debit"` + // If this is a `sofort` PaymentMethod, this hash contains details about the SOFORT payment method. + Sofort *TestHelpersConfirmationTokenPaymentMethodDataSofortParams `form:"sofort"` + // If this is a `swish` PaymentMethod, this hash contains details about the Swish payment method. + Swish *TestHelpersConfirmationTokenPaymentMethodDataSwishParams `form:"swish"` + // The type of the PaymentMethod. An additional hash is included on the PaymentMethod with a name matching this value. It contains additional information specific to the PaymentMethod type. + Type *string `form:"type"` + // If this is an `us_bank_account` PaymentMethod, this hash contains details about the US bank account payment method. + USBankAccount *TestHelpersConfirmationTokenPaymentMethodDataUSBankAccountParams `form:"us_bank_account"` + // If this is an `wechat_pay` PaymentMethod, this hash contains details about the wechat_pay payment method. + WeChatPay *TestHelpersConfirmationTokenPaymentMethodDataWeChatPayParams `form:"wechat_pay"` + // If this is a `zip` PaymentMethod, this hash contains details about the Zip payment method. + Zip *TestHelpersConfirmationTokenPaymentMethodDataZipParams `form:"zip"` +} + +// AddMetadata adds a new key-value pair to the Metadata. +func (p *TestHelpersConfirmationTokenPaymentMethodDataParams) AddMetadata(key string, value string) { + if p.Metadata == nil { + p.Metadata = make(map[string]string) + } + + p.Metadata[key] = value +} + +// Shipping information for this ConfirmationToken. +type TestHelpersConfirmationTokenShippingParams struct { + // Shipping address + Address *AddressParams `form:"address"` + // Recipient name. + Name *string `form:"name"` + // Recipient phone (including extension) + Phone *string `form:"phone"` +} + +// Creates a test mode Confirmation Token server side for your integration tests. +type TestHelpersConfirmationTokenParams struct { + Params `form:"*"` + // Specifies which fields in the response should be expanded. + Expand []*string `form:"expand"` + // ID of an existing PaymentMethod. + PaymentMethod *string `form:"payment_method"` + // If provided, this hash will be used to create a PaymentMethod. + PaymentMethodData *TestHelpersConfirmationTokenPaymentMethodDataParams `form:"payment_method_data"` + // Return URL used to confirm the Intent. + ReturnURL *string `form:"return_url"` + // Indicates that you intend to make future payments with this ConfirmationToken's payment method. + // + // The presence of this property will [attach the payment method](https://stripe.com/docs/payments/save-during-payment) to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any required actions from the user are complete. + SetupFutureUsage *string `form:"setup_future_usage"` + // Shipping information for this ConfirmationToken. + Shipping *TestHelpersConfirmationTokenShippingParams `form:"shipping"` +} + +// AddExpand appends a new field to expand. +func (p *TestHelpersConfirmationTokenParams) AddExpand(f string) { + p.Expand = append(p.Expand, &f) +} diff --git a/vendor/github.com/stripe/stripe-go/v76/treasury_inboundtransfer.go b/vendor/github.com/stripe/stripe-go/v76/treasury_inboundtransfer.go index 4cb8d446..4f797ce1 100644 --- a/vendor/github.com/stripe/stripe-go/v76/treasury_inboundtransfer.go +++ b/vendor/github.com/stripe/stripe-go/v76/treasury_inboundtransfer.go @@ -161,6 +161,8 @@ type TreasuryInboundTransferOriginPaymentMethodDetailsUSBankAccount struct { Fingerprint string `json:"fingerprint"` // Last four digits of the bank account number. Last4 string `json:"last4"` + // ID of the mandate used to make this payment. + Mandate *Mandate `json:"mandate"` // The network rails used. See the [docs](https://stripe.com/docs/treasury/money-movement/timelines) to learn more about money movement timelines for each network type. Network TreasuryInboundTransferOriginPaymentMethodDetailsUSBankAccountNetwork `json:"network"` // Routing number of the bank account. diff --git a/vendor/github.com/stripe/stripe-go/v76/treasury_outboundpayment.go b/vendor/github.com/stripe/stripe-go/v76/treasury_outboundpayment.go index 346189f4..85812fe8 100644 --- a/vendor/github.com/stripe/stripe-go/v76/treasury_outboundpayment.go +++ b/vendor/github.com/stripe/stripe-go/v76/treasury_outboundpayment.go @@ -249,6 +249,8 @@ type TreasuryOutboundPaymentDestinationPaymentMethodDetailsUSBankAccount struct Fingerprint string `json:"fingerprint"` // Last four digits of the bank account number. Last4 string `json:"last4"` + // ID of the mandate used to make this payment. + Mandate *Mandate `json:"mandate"` // The network rails used. See the [docs](https://stripe.com/docs/treasury/money-movement/timelines) to learn more about money movement timelines for each network type. Network TreasuryOutboundPaymentDestinationPaymentMethodDetailsUSBankAccountNetwork `json:"network"` // Routing number of the bank account. diff --git a/vendor/github.com/stripe/stripe-go/v76/treasury_outboundtransfer.go b/vendor/github.com/stripe/stripe-go/v76/treasury_outboundtransfer.go index 405933db..e8f015b5 100644 --- a/vendor/github.com/stripe/stripe-go/v76/treasury_outboundtransfer.go +++ b/vendor/github.com/stripe/stripe-go/v76/treasury_outboundtransfer.go @@ -165,6 +165,8 @@ type TreasuryOutboundTransferDestinationPaymentMethodDetailsUSBankAccount struct Fingerprint string `json:"fingerprint"` // Last four digits of the bank account number. Last4 string `json:"last4"` + // ID of the mandate used to make this payment. + Mandate *Mandate `json:"mandate"` // The network rails used. See the [docs](https://stripe.com/docs/treasury/money-movement/timelines) to learn more about money movement timelines for each network type. Network TreasuryOutboundTransferDestinationPaymentMethodDetailsUSBankAccountNetwork `json:"network"` // Routing number of the bank account. diff --git a/vendor/github.com/stripe/stripe-go/v76/treasury_receiveddebit.go b/vendor/github.com/stripe/stripe-go/v76/treasury_receiveddebit.go index f547019b..4f9b6ba2 100644 --- a/vendor/github.com/stripe/stripe-go/v76/treasury_receiveddebit.go +++ b/vendor/github.com/stripe/stripe-go/v76/treasury_receiveddebit.go @@ -145,6 +145,8 @@ type TreasuryReceivedDebitLinkedFlows struct { IssuingAuthorization string `json:"issuing_authorization"` // Set if the ReceivedDebit is also viewable as an [Issuing Dispute](https://stripe.com/docs/api#issuing_disputes) object. IssuingTransaction string `json:"issuing_transaction"` + // Set if the ReceivedDebit was created due to a [Payout](https://stripe.com/docs/api#payouts) object. + Payout string `json:"payout"` } // Details describing when a ReceivedDebit might be reversed. diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go index 1816bb9c..25df19b0 100644 --- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go +++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/collection.go @@ -1506,8 +1506,8 @@ func Keys(inputMap cty.Value) (cty.Value, error) { } // Lookup performs a dynamic lookup into a map. -// There are two required arguments, map and key, plus an optional default, -// which is a value to return if no key is found in map. +// There are three required arguments, inputMap and key, plus a defaultValue, +// which is a value to return if the given key is not found in the inputMap. func Lookup(inputMap, key, defaultValue cty.Value) (cty.Value, error) { return LookupFunc.Call([]cty.Value{inputMap, key, defaultValue}) } diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/conversion.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/conversion.go index 5d06a451..406dea23 100644 --- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/conversion.go +++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/conversion.go @@ -30,8 +30,9 @@ func MakeToFunc(wantTy cty.Type) function.Function { // messages to be more appropriate for an explicit type // conversion, whereas the cty function system produces // messages aimed at _implicit_ type conversions. - Type: cty.DynamicPseudoType, - AllowNull: true, + Type: cty.DynamicPseudoType, + AllowNull: true, + AllowDynamicType: true, }, }, Type: func(args []cty.Value) (cty.Type, error) { diff --git a/vendor/github.com/zclconf/go-cty/cty/json/marshal.go b/vendor/github.com/zclconf/go-cty/cty/json/marshal.go index 7a14ce81..07d9f331 100644 --- a/vendor/github.com/zclconf/go-cty/cty/json/marshal.go +++ b/vendor/github.com/zclconf/go-cty/cty/json/marshal.go @@ -12,6 +12,9 @@ func marshal(val cty.Value, t cty.Type, path cty.Path, b *bytes.Buffer) error { if val.IsMarked() { return path.NewErrorf("value has marks, so it cannot be serialized as JSON") } + if !val.IsKnown() { + return path.NewErrorf("value is not known") + } // If we're going to decode as DynamicPseudoType then we need to save // dynamic type information to recover the real type. @@ -24,10 +27,6 @@ func marshal(val cty.Value, t cty.Type, path cty.Path, b *bytes.Buffer) error { return nil } - if !val.IsKnown() { - return path.NewErrorf("value is not known") - } - // The caller should've guaranteed that the given val is conformant with // the given type t, so we'll proceed under that assumption here. @@ -185,7 +184,10 @@ func marshalDynamic(val cty.Value, path cty.Path, b *bytes.Buffer) error { return path.NewErrorf("failed to serialize type: %s", err) } b.WriteString(`{"value":`) - marshal(val, val.Type(), path, b) + err = marshal(val, val.Type(), path, b) + if err != nil { + return path.NewErrorf("failed to serialize value: %s", err) + } b.WriteString(`,"type":`) b.Write(typeJSON) b.WriteRune('}') diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index e2b298d8..43557ab7 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -1564,6 +1564,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { if size > remainSize { hdec.SetEmitEnabled(false) mh.Truncated = true + remainSize = 0 return } remainSize -= size @@ -1576,6 +1577,36 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { var hc headersOrContinuation = hf for { frag := hc.HeaderBlockFragment() + + // Avoid parsing large amounts of headers that we will then discard. + // If the sender exceeds the max header list size by too much, + // skip parsing the fragment and close the connection. + // + // "Too much" is either any CONTINUATION frame after we've already + // exceeded the max header list size (in which case remainSize is 0), + // or a frame whose encoded size is more than twice the remaining + // header list bytes we're willing to accept. + if int64(len(frag)) > int64(2*remainSize) { + if VerboseLogs { + log.Printf("http2: header list too large") + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return nil, ConnectionError(ErrCodeProtocol) + } + + // Also close the connection after any CONTINUATION frame following an + // invalid header, since we stop tracking the size of the headers after + // an invalid one. + if invalid != nil { + if VerboseLogs { + log.Printf("http2: invalid header: %v", invalid) + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return nil, ConnectionError(ErrCodeProtocol) + } + if _, err := hdec.Write(frag); err != nil { return nil, ConnectionError(ErrCodeCompression) } diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go index 684d984f..3b9f06b9 100644 --- a/vendor/golang.org/x/net/http2/pipe.go +++ b/vendor/golang.org/x/net/http2/pipe.go @@ -77,7 +77,10 @@ func (p *pipe) Read(d []byte) (n int, err error) { } } -var errClosedPipeWrite = errors.New("write on closed buffer") +var ( + errClosedPipeWrite = errors.New("write on closed buffer") + errUninitializedPipeWrite = errors.New("write on uninitialized buffer") +) // Write copies bytes from p into the buffer and wakes a reader. // It is an error to write more data than the buffer can hold. @@ -91,6 +94,12 @@ func (p *pipe) Write(d []byte) (n int, err error) { if p.err != nil || p.breakErr != nil { return 0, errClosedPipeWrite } + // pipe.setBuffer is never invoked, leaving the buffer uninitialized. + // We shouldn't try to write to an uninitialized pipe, + // but returning an error is better than panicking. + if p.b == nil { + return 0, errUninitializedPipeWrite + } return p.b.Write(d) } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index ae94c640..ce2e8b40 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -124,6 +124,7 @@ type Server struct { // IdleTimeout specifies how long until idle clients should be // closed with a GOAWAY frame. PING frames are not considered // activity for the purposes of IdleTimeout. + // If zero or negative, there is no timeout. IdleTimeout time.Duration // MaxUploadBufferPerConnection is the size of the initial flow @@ -434,7 +435,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { // passes the connection off to us with the deadline already set. // Write deadlines are set per stream in serverConn.newStream. // Disarm the net.Conn write deadline here. - if sc.hs.WriteTimeout != 0 { + if sc.hs.WriteTimeout > 0 { sc.conn.SetWriteDeadline(time.Time{}) } @@ -924,7 +925,7 @@ func (sc *serverConn) serve() { sc.setConnState(http.StateActive) sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout != 0 { + if sc.srv.IdleTimeout > 0 { sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() } @@ -1637,7 +1638,7 @@ func (sc *serverConn) closeStream(st *stream, err error) { delete(sc.streams, st.id) if len(sc.streams) == 0 { sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout != 0 { + if sc.srv.IdleTimeout > 0 { sc.idleTimer.Reset(sc.srv.IdleTimeout) } if h1ServerKeepAlivesDisabled(sc.hs) { @@ -2017,7 +2018,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // similar to how the http1 server works. Here it's // technically more like the http1 Server's ReadHeaderTimeout // (in Go 1.8), though. That's a more sane option anyway. - if sc.hs.ReadTimeout != 0 { + if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } @@ -2038,7 +2039,7 @@ func (sc *serverConn) upgradeRequest(req *http.Request) { // Disable any read deadline set by the net/http package // prior to the upgrade. - if sc.hs.ReadTimeout != 0 { + if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) } @@ -2116,7 +2117,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.flow.conn = &sc.flow // link to conn-level counter st.flow.add(sc.initialStreamSendWindowSize) st.inflow.init(sc.srv.initialStreamRecvWindowSize()) - if sc.hs.WriteTimeout != 0 { + if sc.hs.WriteTimeout > 0 { st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } diff --git a/vendor/golang.org/x/net/http2/testsync.go b/vendor/golang.org/x/net/http2/testsync.go new file mode 100644 index 00000000..61075bd1 --- /dev/null +++ b/vendor/golang.org/x/net/http2/testsync.go @@ -0,0 +1,331 @@ +// Copyright 2024 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. +package http2 + +import ( + "context" + "sync" + "time" +) + +// testSyncHooks coordinates goroutines in tests. +// +// For example, a call to ClientConn.RoundTrip involves several goroutines, including: +// - the goroutine running RoundTrip; +// - the clientStream.doRequest goroutine, which writes the request; and +// - the clientStream.readLoop goroutine, which reads the response. +// +// Using testSyncHooks, a test can start a RoundTrip and identify when all these goroutines +// are blocked waiting for some condition such as reading the Request.Body or waiting for +// flow control to become available. +// +// The testSyncHooks also manage timers and synthetic time in tests. +// This permits us to, for example, start a request and cause it to time out waiting for +// response headers without resorting to time.Sleep calls. +type testSyncHooks struct { + // active/inactive act as a mutex and condition variable. + // + // - neither chan contains a value: testSyncHooks is locked. + // - active contains a value: unlocked, and at least one goroutine is not blocked + // - inactive contains a value: unlocked, and all goroutines are blocked + active chan struct{} + inactive chan struct{} + + // goroutine counts + total int // total goroutines + condwait map[*sync.Cond]int // blocked in sync.Cond.Wait + blocked []*testBlockedGoroutine // otherwise blocked + + // fake time + now time.Time + timers []*fakeTimer + + // Transport testing: Report various events. + newclientconn func(*ClientConn) + newstream func(*clientStream) +} + +// testBlockedGoroutine is a blocked goroutine. +type testBlockedGoroutine struct { + f func() bool // blocked until f returns true + ch chan struct{} // closed when unblocked +} + +func newTestSyncHooks() *testSyncHooks { + h := &testSyncHooks{ + active: make(chan struct{}, 1), + inactive: make(chan struct{}, 1), + condwait: map[*sync.Cond]int{}, + } + h.inactive <- struct{}{} + h.now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) + return h +} + +// lock acquires the testSyncHooks mutex. +func (h *testSyncHooks) lock() { + select { + case <-h.active: + case <-h.inactive: + } +} + +// waitInactive waits for all goroutines to become inactive. +func (h *testSyncHooks) waitInactive() { + for { + <-h.inactive + if !h.unlock() { + break + } + } +} + +// unlock releases the testSyncHooks mutex. +// It reports whether any goroutines are active. +func (h *testSyncHooks) unlock() (active bool) { + // Look for a blocked goroutine which can be unblocked. + blocked := h.blocked[:0] + unblocked := false + for _, b := range h.blocked { + if !unblocked && b.f() { + unblocked = true + close(b.ch) + } else { + blocked = append(blocked, b) + } + } + h.blocked = blocked + + // Count goroutines blocked on condition variables. + condwait := 0 + for _, count := range h.condwait { + condwait += count + } + + if h.total > condwait+len(blocked) { + h.active <- struct{}{} + return true + } else { + h.inactive <- struct{}{} + return false + } +} + +// goRun starts a new goroutine. +func (h *testSyncHooks) goRun(f func()) { + h.lock() + h.total++ + h.unlock() + go func() { + defer func() { + h.lock() + h.total-- + h.unlock() + }() + f() + }() +} + +// blockUntil indicates that a goroutine is blocked waiting for some condition to become true. +// It waits until f returns true before proceeding. +// +// Example usage: +// +// h.blockUntil(func() bool { +// // Is the context done yet? +// select { +// case <-ctx.Done(): +// default: +// return false +// } +// return true +// }) +// // Wait for the context to become done. +// <-ctx.Done() +// +// The function f passed to blockUntil must be non-blocking and idempotent. +func (h *testSyncHooks) blockUntil(f func() bool) { + if f() { + return + } + ch := make(chan struct{}) + h.lock() + h.blocked = append(h.blocked, &testBlockedGoroutine{ + f: f, + ch: ch, + }) + h.unlock() + <-ch +} + +// broadcast is sync.Cond.Broadcast. +func (h *testSyncHooks) condBroadcast(cond *sync.Cond) { + h.lock() + delete(h.condwait, cond) + h.unlock() + cond.Broadcast() +} + +// broadcast is sync.Cond.Wait. +func (h *testSyncHooks) condWait(cond *sync.Cond) { + h.lock() + h.condwait[cond]++ + h.unlock() +} + +// newTimer creates a new fake timer. +func (h *testSyncHooks) newTimer(d time.Duration) timer { + h.lock() + defer h.unlock() + t := &fakeTimer{ + hooks: h, + when: h.now.Add(d), + c: make(chan time.Time), + } + h.timers = append(h.timers, t) + return t +} + +// afterFunc creates a new fake AfterFunc timer. +func (h *testSyncHooks) afterFunc(d time.Duration, f func()) timer { + h.lock() + defer h.unlock() + t := &fakeTimer{ + hooks: h, + when: h.now.Add(d), + f: f, + } + h.timers = append(h.timers, t) + return t +} + +func (h *testSyncHooks) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + ctx, cancel := context.WithCancel(ctx) + t := h.afterFunc(d, cancel) + return ctx, func() { + t.Stop() + cancel() + } +} + +func (h *testSyncHooks) timeUntilEvent() time.Duration { + h.lock() + defer h.unlock() + var next time.Time + for _, t := range h.timers { + if next.IsZero() || t.when.Before(next) { + next = t.when + } + } + if d := next.Sub(h.now); d > 0 { + return d + } + return 0 +} + +// advance advances time and causes synthetic timers to fire. +func (h *testSyncHooks) advance(d time.Duration) { + h.lock() + defer h.unlock() + h.now = h.now.Add(d) + timers := h.timers[:0] + for _, t := range h.timers { + t := t // remove after go.mod depends on go1.22 + t.mu.Lock() + switch { + case t.when.After(h.now): + timers = append(timers, t) + case t.when.IsZero(): + // stopped timer + default: + t.when = time.Time{} + if t.c != nil { + close(t.c) + } + if t.f != nil { + h.total++ + go func() { + defer func() { + h.lock() + h.total-- + h.unlock() + }() + t.f() + }() + } + } + t.mu.Unlock() + } + h.timers = timers +} + +// A timer wraps a time.Timer, or a synthetic equivalent in tests. +// Unlike time.Timer, timer is single-use: The timer channel is closed when the timer expires. +type timer interface { + C() <-chan time.Time + Stop() bool + Reset(d time.Duration) bool +} + +// timeTimer implements timer using real time. +type timeTimer struct { + t *time.Timer + c chan time.Time +} + +// newTimeTimer creates a new timer using real time. +func newTimeTimer(d time.Duration) timer { + ch := make(chan time.Time) + t := time.AfterFunc(d, func() { + close(ch) + }) + return &timeTimer{t, ch} +} + +// newTimeAfterFunc creates an AfterFunc timer using real time. +func newTimeAfterFunc(d time.Duration, f func()) timer { + return &timeTimer{ + t: time.AfterFunc(d, f), + } +} + +func (t timeTimer) C() <-chan time.Time { return t.c } +func (t timeTimer) Stop() bool { return t.t.Stop() } +func (t timeTimer) Reset(d time.Duration) bool { return t.t.Reset(d) } + +// fakeTimer implements timer using fake time. +type fakeTimer struct { + hooks *testSyncHooks + + mu sync.Mutex + when time.Time // when the timer will fire + c chan time.Time // closed when the timer fires; mutually exclusive with f + f func() // called when the timer fires; mutually exclusive with c +} + +func (t *fakeTimer) C() <-chan time.Time { return t.c } + +func (t *fakeTimer) Stop() bool { + t.mu.Lock() + defer t.mu.Unlock() + stopped := t.when.IsZero() + t.when = time.Time{} + return stopped +} + +func (t *fakeTimer) Reset(d time.Duration) bool { + if t.c != nil || t.f == nil { + panic("fakeTimer only supports Reset on AfterFunc timers") + } + t.mu.Lock() + defer t.mu.Unlock() + t.hooks.lock() + defer t.hooks.unlock() + active := !t.when.IsZero() + t.when = t.hooks.now.Add(d) + if !active { + t.hooks.timers = append(t.hooks.timers, t) + } + return active +} diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index c2a5b44b..ce375c8c 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -147,6 +147,12 @@ type Transport struct { // waiting for their turn. StrictMaxConcurrentStreams bool + // IdleConnTimeout is the maximum amount of time an idle + // (keep-alive) connection will remain idle before closing + // itself. + // Zero means no limit. + IdleConnTimeout time.Duration + // ReadIdleTimeout is the timeout after which a health check using ping // frame will be carried out if no frame is received on the connection. // Note that a ping response will is considered a received frame, so if @@ -178,6 +184,8 @@ type Transport struct { connPoolOnce sync.Once connPoolOrDef ClientConnPool // non-nil version of ConnPool + + syncHooks *testSyncHooks } func (t *Transport) maxHeaderListSize() uint32 { @@ -302,7 +310,7 @@ type ClientConn struct { readerErr error // set before readerDone is closed idleTimeout time.Duration // or 0 for never - idleTimer *time.Timer + idleTimer timer mu sync.Mutex // guards following cond *sync.Cond // hold mu; broadcast on flow/closed changes @@ -344,6 +352,60 @@ type ClientConn struct { werr error // first write error that has occurred hbuf bytes.Buffer // HPACK encoder writes into this henc *hpack.Encoder + + syncHooks *testSyncHooks // can be nil +} + +// Hook points used for testing. +// Outside of tests, cc.syncHooks is nil and these all have minimal implementations. +// Inside tests, see the testSyncHooks function docs. + +// goRun starts a new goroutine. +func (cc *ClientConn) goRun(f func()) { + if cc.syncHooks != nil { + cc.syncHooks.goRun(f) + return + } + go f() +} + +// condBroadcast is cc.cond.Broadcast. +func (cc *ClientConn) condBroadcast() { + if cc.syncHooks != nil { + cc.syncHooks.condBroadcast(cc.cond) + } + cc.cond.Broadcast() +} + +// condWait is cc.cond.Wait. +func (cc *ClientConn) condWait() { + if cc.syncHooks != nil { + cc.syncHooks.condWait(cc.cond) + } + cc.cond.Wait() +} + +// newTimer creates a new time.Timer, or a synthetic timer in tests. +func (cc *ClientConn) newTimer(d time.Duration) timer { + if cc.syncHooks != nil { + return cc.syncHooks.newTimer(d) + } + return newTimeTimer(d) +} + +// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. +func (cc *ClientConn) afterFunc(d time.Duration, f func()) timer { + if cc.syncHooks != nil { + return cc.syncHooks.afterFunc(d, f) + } + return newTimeAfterFunc(d, f) +} + +func (cc *ClientConn) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + if cc.syncHooks != nil { + return cc.syncHooks.contextWithTimeout(ctx, d) + } + return context.WithTimeout(ctx, d) } // clientStream is the state for a single HTTP/2 stream. One of these @@ -425,7 +487,7 @@ func (cs *clientStream) abortStreamLocked(err error) { // TODO(dneil): Clean up tests where cs.cc.cond is nil. if cs.cc.cond != nil { // Wake up writeRequestBody if it is waiting on flow control. - cs.cc.cond.Broadcast() + cs.cc.condBroadcast() } } @@ -435,7 +497,7 @@ func (cs *clientStream) abortRequestBodyWrite() { defer cc.mu.Unlock() if cs.reqBody != nil && cs.reqBodyClosed == nil { cs.closeReqBodyLocked() - cc.cond.Broadcast() + cc.condBroadcast() } } @@ -445,10 +507,10 @@ func (cs *clientStream) closeReqBodyLocked() { } cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed - go func() { + cs.cc.goRun(func() { cs.reqBody.Close() close(reqBodyClosed) - }() + }) } type stickyErrWriter struct { @@ -537,15 +599,6 @@ func authorityAddr(scheme string, authority string) (addr string) { return net.JoinHostPort(host, port) } -var retryBackoffHook func(time.Duration) *time.Timer - -func backoffNewTimer(d time.Duration) *time.Timer { - if retryBackoffHook != nil { - return retryBackoffHook(d) - } - return time.NewTimer(d) -} - // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) { @@ -573,13 +626,27 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) - timer := backoffNewTimer(d) + var tm timer + if t.syncHooks != nil { + tm = t.syncHooks.newTimer(d) + t.syncHooks.blockUntil(func() bool { + select { + case <-tm.C(): + case <-req.Context().Done(): + default: + return false + } + return true + }) + } else { + tm = newTimeTimer(d) + } select { - case <-timer.C: + case <-tm.C(): t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) continue case <-req.Context().Done(): - timer.Stop() + tm.Stop() err = req.Context().Err() } } @@ -658,6 +725,9 @@ func canRetryError(err error) bool { } func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { + if t.syncHooks != nil { + return t.newClientConn(nil, singleUse, t.syncHooks) + } host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -666,7 +736,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } - return t.newClientConn(tconn, singleUse) + return t.newClientConn(tconn, singleUse, nil) } func (t *Transport) newTLSConfig(host string) *tls.Config { @@ -732,10 +802,10 @@ func (t *Transport) maxEncoderHeaderTableSize() uint32 { } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { - return t.newClientConn(c, t.disableKeepAlives()) + return t.newClientConn(c, t.disableKeepAlives(), nil) } -func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { +func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHooks) (*ClientConn, error) { cc := &ClientConn{ t: t, tconn: c, @@ -750,10 +820,15 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro wantSettingsAck: true, pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), + syncHooks: hooks, + } + if hooks != nil { + hooks.newclientconn(cc) + c = cc.tconn } if d := t.idleConnTimeout(); d != 0 { cc.idleTimeout = d - cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) + cc.idleTimer = cc.afterFunc(d, cc.onIdleTimeout) } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -818,7 +893,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro return nil, cc.werr } - go cc.readLoop() + cc.goRun(cc.readLoop) return cc, nil } @@ -826,7 +901,7 @@ func (cc *ClientConn) healthCheck() { pingTimeout := cc.t.pingTimeout() // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. - ctx, cancel := context.WithTimeout(context.Background(), pingTimeout) + ctx, cancel := cc.contextWithTimeout(context.Background(), pingTimeout) defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) @@ -1056,7 +1131,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { // Wait for all in-flight streams to complete or connection to close done := make(chan struct{}) cancelled := false // guarded by cc.mu - go func() { + cc.goRun(func() { cc.mu.Lock() defer cc.mu.Unlock() for { @@ -1068,9 +1143,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { if cancelled { break } - cc.cond.Wait() + cc.condWait() } - }() + }) shutdownEnterWaitStateHook() select { case <-done: @@ -1080,7 +1155,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { cc.mu.Lock() // Free the goroutine above cancelled = true - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() return ctx.Err() } @@ -1118,7 +1193,7 @@ func (cc *ClientConn) closeForError(err error) { for _, cs := range cc.streams { cs.abortStreamLocked(err) } - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() cc.closeConn() } @@ -1215,6 +1290,10 @@ func (cc *ClientConn) decrStreamReservationsLocked() { } func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { + return cc.roundTrip(req, nil) +} + +func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) { ctx := req.Context() cs := &clientStream{ cc: cc, @@ -1229,9 +1308,23 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { respHeaderRecv: make(chan struct{}), donec: make(chan struct{}), } - go cs.doRequest(req) + cc.goRun(func() { + cs.doRequest(req) + }) waitDone := func() error { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.donec: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.donec: return nil @@ -1292,7 +1385,24 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { return err } + if streamf != nil { + streamf(cs) + } + for { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.respHeaderRecv: + case <-cs.abort: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.respHeaderRecv: return handleResponseHeaders() @@ -1348,6 +1458,21 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { if cc.reqHeaderMu == nil { panic("RoundTrip on uninitialized ClientConn") // for tests } + var newStreamHook func(*clientStream) + if cc.syncHooks != nil { + newStreamHook = cc.syncHooks.newstream + cc.syncHooks.blockUntil(func() bool { + select { + case cc.reqHeaderMu <- struct{}{}: + <-cc.reqHeaderMu + case <-cs.reqCancel: + case <-ctx.Done(): + default: + return false + } + return true + }) + } select { case cc.reqHeaderMu <- struct{}{}: case <-cs.reqCancel: @@ -1372,6 +1497,10 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { } cc.mu.Unlock() + if newStreamHook != nil { + newStreamHook(cs) + } + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? if !cc.t.disableCompression() && req.Header.Get("Accept-Encoding") == "" && @@ -1452,15 +1581,30 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { - timer := time.NewTimer(d) + timer := cc.newTimer(d) defer timer.Stop() - respHeaderTimer = timer.C + respHeaderTimer = timer.C() respHeaderRecv = cs.respHeaderRecv } // Wait until the peer half-closes its end of the stream, // or until the request is aborted (via context, error, or otherwise), // whichever comes first. for { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.peerClosed: + case <-respHeaderTimer: + case <-respHeaderRecv: + case <-cs.abort: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.peerClosed: return nil @@ -1609,7 +1753,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { return nil } cc.pendingRequests++ - cc.cond.Wait() + cc.condWait() cc.pendingRequests-- select { case <-cs.abort: @@ -1871,8 +2015,24 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) cs.flow.take(take) return take, nil } - cc.cond.Wait() + cc.condWait() + } +} + +func validateHeaders(hdrs http.Header) string { + for k, vv := range hdrs { + if !httpguts.ValidHeaderFieldName(k) { + return fmt.Sprintf("name %q", k) + } + for _, v := range vv { + if !httpguts.ValidHeaderFieldValue(v) { + // Don't include the value in the error, + // because it may be sensitive. + return fmt.Sprintf("value for header %q", k) + } + } } + return "" } var errNilRequestURL = errors.New("http2: Request.URI is nil") @@ -1912,19 +2072,14 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail } } - // Check for any invalid headers and return an error before we + // Check for any invalid headers+trailers and return an error before we // potentially pollute our hpack state. (We want to be able to // continue to reuse the hpack encoder for future requests) - for k, vv := range req.Header { - if !httpguts.ValidHeaderFieldName(k) { - return nil, fmt.Errorf("invalid HTTP header name %q", k) - } - for _, v := range vv { - if !httpguts.ValidHeaderFieldValue(v) { - // Don't include the value in the error, because it may be sensitive. - return nil, fmt.Errorf("invalid HTTP header value for header %q", k) - } - } + if err := validateHeaders(req.Header); err != "" { + return nil, fmt.Errorf("invalid HTTP header %s", err) + } + if err := validateHeaders(req.Trailer); err != "" { + return nil, fmt.Errorf("invalid HTTP trailer %s", err) } enumerateHeaders := func(f func(name, value string)) { @@ -2143,7 +2298,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) { } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. - cc.cond.Broadcast() + cc.condBroadcast() closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { @@ -2231,7 +2386,7 @@ func (rl *clientConnReadLoop) cleanup() { cs.abortStreamLocked(err) } } - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() } @@ -2266,10 +2421,9 @@ func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false readIdleTimeout := cc.t.ReadIdleTimeout - var t *time.Timer + var t timer if readIdleTimeout != 0 { - t = time.AfterFunc(readIdleTimeout, cc.healthCheck) - defer t.Stop() + t = cc.afterFunc(readIdleTimeout, cc.healthCheck) } for { f, err := cc.fr.ReadFrame() @@ -2684,7 +2838,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { }) return nil } - if !cs.firstByte { + if !cs.pastHeaders { cc.logf("protocol error: received DATA before a HEADERS frame") rl.endStreamError(cs, StreamError{ StreamID: f.StreamID, @@ -2867,7 +3021,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { for _, cs := range cc.streams { cs.flow.add(delta) } - cc.cond.Broadcast() + cc.condBroadcast() cc.initialWindowSize = s.Val case SettingHeaderTableSize: @@ -2922,7 +3076,7 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { return ConnectionError(ErrCodeFlowControl) } - cc.cond.Broadcast() + cc.condBroadcast() return nil } @@ -2964,24 +3118,38 @@ func (cc *ClientConn) Ping(ctx context.Context) error { } cc.mu.Unlock() } - errc := make(chan error, 1) - go func() { + var pingError error + errc := make(chan struct{}) + cc.goRun(func() { cc.wmu.Lock() defer cc.wmu.Unlock() - if err := cc.fr.WritePing(false, p); err != nil { - errc <- err + if pingError = cc.fr.WritePing(false, p); pingError != nil { + close(errc) return } - if err := cc.bw.Flush(); err != nil { - errc <- err + if pingError = cc.bw.Flush(); pingError != nil { + close(errc) return } - }() + }) + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-c: + case <-errc: + case <-ctx.Done(): + case <-cc.readerDone: + default: + return false + } + return true + }) + } select { case <-c: return nil - case err := <-errc: - return err + case <-errc: + return pingError case <-ctx.Done(): return ctx.Err() case <-cc.readerDone: @@ -3150,9 +3318,17 @@ func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, err } func (t *Transport) idleConnTimeout() time.Duration { + // to keep things backwards compatible, we use non-zero values of + // IdleConnTimeout, followed by using the IdleConnTimeout on the underlying + // http1 transport, followed by 0 + if t.IdleConnTimeout != 0 { + return t.IdleConnTimeout + } + if t.t1 != nil { return t.t1.IdleConnTimeout } + return 0 } diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index d79560a2..f391744f 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -54,13 +54,14 @@ var ( // an init() function), and is not thread-safe. If multiple Balancers are // registered with the same name, the one registered last will take effect. func Register(b Builder) { - if strings.ToLower(b.Name()) != b.Name() { + name := strings.ToLower(b.Name()) + if name != b.Name() { // TODO: Skip the use of strings.ToLower() to index the map after v1.59 // is released to switch to case sensitive balancer registry. Also, // remove this warning and update the docstrings for Register and Get. logger.Warningf("Balancer registered with name %q. grpc-go will be switching to case sensitive balancer registries soon", b.Name()) } - m[strings.ToLower(b.Name())] = b + m[name] = b } // unregisterForTesting deletes the balancer with the given name from the @@ -232,8 +233,8 @@ type BuildOptions struct { // implementations which do not communicate with a remote load balancer // server can ignore this field. Authority string - // ChannelzParentID is the parent ClientConn's channelz ID. - ChannelzParentID *channelz.Identifier + // ChannelzParent is the parent ClientConn's channelz channel. + ChannelzParent channelz.Identifier // CustomUserAgent is the custom user agent set on the parent ClientConn. // The balancer should set the same custom user agent if it creates a // ClientConn. diff --git a/vendor/google.golang.org/grpc/balancer_wrapper.go b/vendor/google.golang.org/grpc/balancer_wrapper.go index b5e30cff..af39b8a4 100644 --- a/vendor/google.golang.org/grpc/balancer_wrapper.go +++ b/vendor/google.golang.org/grpc/balancer_wrapper.go @@ -21,7 +21,6 @@ package grpc import ( "context" "fmt" - "strings" "sync" "google.golang.org/grpc/balancer" @@ -66,19 +65,20 @@ type ccBalancerWrapper struct { } // newCCBalancerWrapper creates a new balancer wrapper in idle state. The -// underlying balancer is not created until the switchTo() method is invoked. +// underlying balancer is not created until the updateClientConnState() method +// is invoked. func newCCBalancerWrapper(cc *ClientConn) *ccBalancerWrapper { ctx, cancel := context.WithCancel(cc.ctx) ccb := &ccBalancerWrapper{ cc: cc, opts: balancer.BuildOptions{ - DialCreds: cc.dopts.copts.TransportCredentials, - CredsBundle: cc.dopts.copts.CredsBundle, - Dialer: cc.dopts.copts.Dialer, - Authority: cc.authority, - CustomUserAgent: cc.dopts.copts.UserAgent, - ChannelzParentID: cc.channelzID, - Target: cc.parsedTarget, + DialCreds: cc.dopts.copts.TransportCredentials, + CredsBundle: cc.dopts.copts.CredsBundle, + Dialer: cc.dopts.copts.Dialer, + Authority: cc.authority, + CustomUserAgent: cc.dopts.copts.UserAgent, + ChannelzParent: cc.channelz, + Target: cc.parsedTarget, }, serializer: grpcsync.NewCallbackSerializer(ctx), serializerCancel: cancel, @@ -97,6 +97,11 @@ func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnStat if ctx.Err() != nil || ccb.balancer == nil { return } + name := gracefulswitch.ChildName(ccs.BalancerConfig) + if ccb.curBalancerName != name { + ccb.curBalancerName = name + channelz.Infof(logger, ccb.cc.channelz, "Channel switches to new LB policy %q", name) + } err := ccb.balancer.UpdateClientConnState(*ccs) if logger.V(2) && err != nil { logger.Infof("error from balancer.UpdateClientConnState: %v", err) @@ -120,54 +125,6 @@ func (ccb *ccBalancerWrapper) resolverError(err error) { }) } -// switchTo is invoked by grpc to instruct the balancer wrapper to switch to the -// LB policy identified by name. -// -// ClientConn calls newCCBalancerWrapper() at creation time. Upon receipt of the -// first good update from the name resolver, it determines the LB policy to use -// and invokes the switchTo() method. Upon receipt of every subsequent update -// from the name resolver, it invokes this method. -// -// the ccBalancerWrapper keeps track of the current LB policy name, and skips -// the graceful balancer switching process if the name does not change. -func (ccb *ccBalancerWrapper) switchTo(name string) { - ccb.serializer.Schedule(func(ctx context.Context) { - if ctx.Err() != nil || ccb.balancer == nil { - return - } - // TODO: Other languages use case-sensitive balancer registries. We should - // switch as well. See: https://github.com/grpc/grpc-go/issues/5288. - if strings.EqualFold(ccb.curBalancerName, name) { - return - } - ccb.buildLoadBalancingPolicy(name) - }) -} - -// buildLoadBalancingPolicy performs the following: -// - retrieve a balancer builder for the given name. Use the default LB -// policy, pick_first, if no LB policy with name is found in the registry. -// - instruct the gracefulswitch balancer to switch to the above builder. This -// will actually build the new balancer. -// - update the `curBalancerName` field -// -// Must be called from a serializer callback. -func (ccb *ccBalancerWrapper) buildLoadBalancingPolicy(name string) { - builder := balancer.Get(name) - if builder == nil { - channelz.Warningf(logger, ccb.cc.channelzID, "Channel switches to new LB policy %q, since the specified LB policy %q was not registered", PickFirstBalancerName, name) - builder = newPickfirstBuilder() - } else { - channelz.Infof(logger, ccb.cc.channelzID, "Channel switches to new LB policy %q", name) - } - - if err := ccb.balancer.SwitchTo(builder); err != nil { - channelz.Errorf(logger, ccb.cc.channelzID, "Channel failed to build new LB policy %q: %v", name, err) - return - } - ccb.curBalancerName = builder.Name() -} - // close initiates async shutdown of the wrapper. cc.mu must be held when // calling this function. To determine the wrapper has finished shutting down, // the channel should block on ccb.serializer.Done() without cc.mu held. @@ -175,7 +132,7 @@ func (ccb *ccBalancerWrapper) close() { ccb.mu.Lock() ccb.closed = true ccb.mu.Unlock() - channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: closing") + channelz.Info(logger, ccb.cc.channelz, "ccBalancerWrapper: closing") ccb.serializer.Schedule(func(context.Context) { if ccb.balancer == nil { return @@ -212,7 +169,7 @@ func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer } ac, err := ccb.cc.newAddrConnLocked(addrs, opts) if err != nil { - channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err) + channelz.Warningf(logger, ccb.cc.channelz, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err) return nil, err } acbw := &acBalancerWrapper{ @@ -304,7 +261,7 @@ func (acbw *acBalancerWrapper) updateState(s connectivity.State, err error) { } func (acbw *acBalancerWrapper) String() string { - return fmt.Sprintf("SubConn(id:%d)", acbw.ac.channelzID.Int()) + return fmt.Sprintf("SubConn(id:%d)", acbw.ac.channelz.ID) } func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index f0b7f320..e3eb44d5 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -67,7 +67,7 @@ var ( errConnDrain = errors.New("grpc: the connection is drained") // errConnClosing indicates that the connection is closing. errConnClosing = errors.New("grpc: the connection is closing") - // errConnIdling indicates the the connection is being closed as the channel + // errConnIdling indicates the connection is being closed as the channel // is moving to an idle mode due to inactivity. errConnIdling = errors.New("grpc: the connection is closing due to channel idleness") // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default @@ -101,11 +101,6 @@ const ( defaultReadBufSize = 32 * 1024 ) -// Dial creates a client connection to the given target. -func Dial(target string, opts ...DialOption) (*ClientConn, error) { - return DialContext(context.Background(), target, opts...) -} - type defaultConfigSelector struct { sc *ServiceConfig } @@ -117,13 +112,22 @@ func (dcs *defaultConfigSelector) SelectConfig(rpcInfo iresolver.RPCInfo) (*ires }, nil } -// newClient returns a new client in idle mode. -func newClient(target string, opts ...DialOption) (conn *ClientConn, err error) { +// NewClient creates a new gRPC "channel" for the target URI provided. No I/O +// is performed. Use of the ClientConn for RPCs will automatically cause it to +// connect. Connect may be used to manually create a connection, but for most +// users this is unnecessary. +// +// The target name syntax is defined in +// https://github.com/grpc/grpc/blob/master/doc/naming.md. e.g. to use dns +// resolver, a "dns:///" prefix should be applied to the target. +// +// The DialOptions returned by WithBlock, WithTimeout, and +// WithReturnConnectionError are ignored by this function. +func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) { cc := &ClientConn{ target: target, conns: make(map[*addrConn]struct{}), dopts: defaultDialOptions(), - czData: new(channelzData), } cc.retryThrottler.Store((*retryThrottler)(nil)) @@ -175,15 +179,15 @@ func newClient(target string, opts ...DialOption) (conn *ClientConn, err error) // Determine the resolver to use. if err := cc.parseTargetAndFindResolver(); err != nil { - channelz.RemoveEntry(cc.channelzID) + channelz.RemoveEntry(cc.channelz.ID) return nil, err } if err = cc.determineAuthority(); err != nil { - channelz.RemoveEntry(cc.channelzID) + channelz.RemoveEntry(cc.channelz.ID) return nil, err } - cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelzID) + cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelz) cc.pickerWrapper = newPickerWrapper(cc.dopts.copts.StatsHandlers) cc.initIdleStateLocked() // Safe to call without the lock, since nothing else has a reference to cc. @@ -191,39 +195,36 @@ func newClient(target string, opts ...DialOption) (conn *ClientConn, err error) return cc, nil } -// DialContext creates a client connection to the given target. By default, it's -// a non-blocking dial (the function won't wait for connections to be -// established, and connecting happens in the background). To make it a blocking -// dial, use WithBlock() dial option. +// Dial calls DialContext(context.Background(), target, opts...). // -// In the non-blocking case, the ctx does not act against the connection. It -// only controls the setup steps. +// Deprecated: use NewClient instead. Will be supported throughout 1.x. +func Dial(target string, opts ...DialOption) (*ClientConn, error) { + return DialContext(context.Background(), target, opts...) +} + +// DialContext calls NewClient and then exits idle mode. If WithBlock(true) is +// used, it calls Connect and WaitForStateChange until either the context +// expires or the state of the ClientConn is Ready. // -// In the blocking case, ctx can be used to cancel or expire the pending -// connection. Once this function returns, the cancellation and expiration of -// ctx will be noop. Users should call ClientConn.Close to terminate all the -// pending operations after this function returns. +// One subtle difference between NewClient and Dial and DialContext is that the +// former uses "dns" as the default name resolver, while the latter use +// "passthrough" for backward compatibility. This distinction should not matter +// to most users, but could matter to legacy users that specify a custom dialer +// and expect it to receive the target string directly. // -// The target name syntax is defined in -// https://github.com/grpc/grpc/blob/master/doc/naming.md. -// e.g. to use dns resolver, a "dns:///" prefix should be applied to the target. +// Deprecated: use NewClient instead. Will be supported throughout 1.x. func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { - cc, err := newClient(target, opts...) + // At the end of this method, we kick the channel out of idle, rather than + // waiting for the first rpc. + opts = append([]DialOption{withDefaultScheme("passthrough")}, opts...) + cc, err := NewClient(target, opts...) if err != nil { return nil, err } // We start the channel off in idle mode, but kick it out of idle now, - // instead of waiting for the first RPC. Other gRPC implementations do wait - // for the first RPC to kick the channel out of idle. But doing so would be - // a major behavior change for our users who are used to seeing the channel - // active after Dial. - // - // Taking this approach of kicking it out of idle at the end of this method - // allows us to share the code between channel creation and exiting idle - // mode. This will also make it easy for us to switch to starting the - // channel off in idle, i.e. by making newClient exported. - + // instead of waiting for the first RPC. This is the legacy behavior of + // Dial. defer func() { if err != nil { cc.Close() @@ -291,17 +292,17 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * // addTraceEvent is a helper method to add a trace event on the channel. If the // channel is a nested one, the same event is also added on the parent channel. func (cc *ClientConn) addTraceEvent(msg string) { - ted := &channelz.TraceEventDesc{ + ted := &channelz.TraceEvent{ Desc: fmt.Sprintf("Channel %s", msg), Severity: channelz.CtInfo, } - if cc.dopts.channelzParentID != nil { - ted.Parent = &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Nested channel(id:%d) %s", cc.channelzID.Int(), msg), + if cc.dopts.channelzParent != nil { + ted.Parent = &channelz.TraceEvent{ + Desc: fmt.Sprintf("Nested channel(id:%d) %s", cc.channelz.ID, msg), Severity: channelz.CtInfo, } } - channelz.AddTraceEvent(logger, cc.channelzID, 0, ted) + channelz.AddTraceEvent(logger, cc.channelz, 0, ted) } type idler ClientConn @@ -418,14 +419,15 @@ func (cc *ClientConn) validateTransportCredentials() error { } // channelzRegistration registers the newly created ClientConn with channelz and -// stores the returned identifier in `cc.channelzID` and `cc.csMgr.channelzID`. -// A channelz trace event is emitted for ClientConn creation. If the newly -// created ClientConn is a nested one, i.e a valid parent ClientConn ID is -// specified via a dial option, the trace event is also added to the parent. +// stores the returned identifier in `cc.channelz`. A channelz trace event is +// emitted for ClientConn creation. If the newly created ClientConn is a nested +// one, i.e a valid parent ClientConn ID is specified via a dial option, the +// trace event is also added to the parent. // // Doesn't grab cc.mu as this method is expected to be called only at Dial time. func (cc *ClientConn) channelzRegistration(target string) { - cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, cc.dopts.channelzParentID, target) + parentChannel, _ := cc.dopts.channelzParent.(*channelz.Channel) + cc.channelz = channelz.RegisterChannel(parentChannel, target) cc.addTraceEvent("created") } @@ -492,11 +494,11 @@ func getChainStreamer(interceptors []StreamClientInterceptor, curr int, finalStr } // newConnectivityStateManager creates an connectivityStateManager with -// the specified id. -func newConnectivityStateManager(ctx context.Context, id *channelz.Identifier) *connectivityStateManager { +// the specified channel. +func newConnectivityStateManager(ctx context.Context, channel *channelz.Channel) *connectivityStateManager { return &connectivityStateManager{ - channelzID: id, - pubSub: grpcsync.NewPubSub(ctx), + channelz: channel, + pubSub: grpcsync.NewPubSub(ctx), } } @@ -510,7 +512,7 @@ type connectivityStateManager struct { mu sync.Mutex state connectivity.State notifyChan chan struct{} - channelzID *channelz.Identifier + channelz *channelz.Channel pubSub *grpcsync.PubSub } @@ -527,9 +529,10 @@ func (csm *connectivityStateManager) updateState(state connectivity.State) { return } csm.state = state + csm.channelz.ChannelMetrics.State.Store(&state) csm.pubSub.Publish(state) - channelz.Infof(logger, csm.channelzID, "Channel Connectivity change to %v", state) + channelz.Infof(logger, csm.channelz, "Channel Connectivity change to %v", state) if csm.notifyChan != nil { // There are other goroutines waiting on this channel. close(csm.notifyChan) @@ -583,12 +586,12 @@ type ClientConn struct { cancel context.CancelFunc // Cancelled on close. // The following are initialized at dial time, and are read-only after that. - target string // User's dial target. - parsedTarget resolver.Target // See parseTargetAndFindResolver(). - authority string // See determineAuthority(). - dopts dialOptions // Default and user specified dial options. - channelzID *channelz.Identifier // Channelz identifier for the channel. - resolverBuilder resolver.Builder // See parseTargetAndFindResolver(). + target string // User's dial target. + parsedTarget resolver.Target // See parseTargetAndFindResolver(). + authority string // See determineAuthority(). + dopts dialOptions // Default and user specified dial options. + channelz *channelz.Channel // Channelz object. + resolverBuilder resolver.Builder // See parseTargetAndFindResolver(). idlenessMgr *idle.Manager // The following provide their own synchronization, and therefore don't @@ -596,7 +599,6 @@ type ClientConn struct { csMgr *connectivityStateManager pickerWrapper *pickerWrapper safeConfigSelector iresolver.SafeConfigSelector - czData *channelzData retryThrottler atomic.Value // Updated from service config. // mu protects the following fields. @@ -690,6 +692,7 @@ func (cc *ClientConn) waitForResolvedAddrs(ctx context.Context) error { var emptyServiceConfig *ServiceConfig func init() { + balancer.Register(pickfirstBuilder{}) cfg := parseServiceConfig("{}") if cfg.Err != nil { panic(fmt.Sprintf("impossible error parsing empty service config: %v", cfg.Err)) @@ -707,15 +710,15 @@ func init() { } } -func (cc *ClientConn) maybeApplyDefaultServiceConfig(addrs []resolver.Address) { +func (cc *ClientConn) maybeApplyDefaultServiceConfig() { if cc.sc != nil { - cc.applyServiceConfigAndBalancer(cc.sc, nil, addrs) + cc.applyServiceConfigAndBalancer(cc.sc, nil) return } if cc.dopts.defaultServiceConfig != nil { - cc.applyServiceConfigAndBalancer(cc.dopts.defaultServiceConfig, &defaultConfigSelector{cc.dopts.defaultServiceConfig}, addrs) + cc.applyServiceConfigAndBalancer(cc.dopts.defaultServiceConfig, &defaultConfigSelector{cc.dopts.defaultServiceConfig}) } else { - cc.applyServiceConfigAndBalancer(emptyServiceConfig, &defaultConfigSelector{emptyServiceConfig}, addrs) + cc.applyServiceConfigAndBalancer(emptyServiceConfig, &defaultConfigSelector{emptyServiceConfig}) } } @@ -733,7 +736,7 @@ func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error) // May need to apply the initial service config in case the resolver // doesn't support service configs, or doesn't provide a service config // with the new addresses. - cc.maybeApplyDefaultServiceConfig(nil) + cc.maybeApplyDefaultServiceConfig() cc.balancerWrapper.resolverError(err) @@ -744,10 +747,10 @@ func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error) var ret error if cc.dopts.disableServiceConfig { - channelz.Infof(logger, cc.channelzID, "ignoring service config from resolver (%v) and applying the default because service config is disabled", s.ServiceConfig) - cc.maybeApplyDefaultServiceConfig(s.Addresses) + channelz.Infof(logger, cc.channelz, "ignoring service config from resolver (%v) and applying the default because service config is disabled", s.ServiceConfig) + cc.maybeApplyDefaultServiceConfig() } else if s.ServiceConfig == nil { - cc.maybeApplyDefaultServiceConfig(s.Addresses) + cc.maybeApplyDefaultServiceConfig() // TODO: do we need to apply a failing LB policy if there is no // default, per the error handling design? } else { @@ -755,12 +758,12 @@ func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error) configSelector := iresolver.GetConfigSelector(s) if configSelector != nil { if len(s.ServiceConfig.Config.(*ServiceConfig).Methods) != 0 { - channelz.Infof(logger, cc.channelzID, "method configs in service config will be ignored due to presence of config selector") + channelz.Infof(logger, cc.channelz, "method configs in service config will be ignored due to presence of config selector") } } else { configSelector = &defaultConfigSelector{sc} } - cc.applyServiceConfigAndBalancer(sc, configSelector, s.Addresses) + cc.applyServiceConfigAndBalancer(sc, configSelector) } else { ret = balancer.ErrBadResolverState if cc.sc == nil { @@ -775,7 +778,7 @@ func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error) var balCfg serviceconfig.LoadBalancingConfig if cc.sc != nil && cc.sc.lbConfig != nil { - balCfg = cc.sc.lbConfig.cfg + balCfg = cc.sc.lbConfig } bw := cc.balancerWrapper cc.mu.Unlock() @@ -834,22 +837,17 @@ func (cc *ClientConn) newAddrConnLocked(addrs []resolver.Address, opts balancer. addrs: copyAddressesWithoutBalancerAttributes(addrs), scopts: opts, dopts: cc.dopts, - czData: new(channelzData), + channelz: channelz.RegisterSubChannel(cc.channelz.ID, ""), resetBackoff: make(chan struct{}), stateChan: make(chan struct{}), } ac.ctx, ac.cancel = context.WithCancel(cc.ctx) - var err error - ac.channelzID, err = channelz.RegisterSubChannel(ac, cc.channelzID, "") - if err != nil { - return nil, err - } - channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{ + channelz.AddTraceEvent(logger, ac.channelz, 0, &channelz.TraceEvent{ Desc: "Subchannel created", Severity: channelz.CtInfo, - Parent: &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Subchannel(id:%d) created", ac.channelzID.Int()), + Parent: &channelz.TraceEvent{ + Desc: fmt.Sprintf("Subchannel(id:%d) created", ac.channelz.ID), Severity: channelz.CtInfo, }, }) @@ -872,38 +870,27 @@ func (cc *ClientConn) removeAddrConn(ac *addrConn, err error) { ac.tearDown(err) } -func (cc *ClientConn) channelzMetric() *channelz.ChannelInternalMetric { - return &channelz.ChannelInternalMetric{ - State: cc.GetState(), - Target: cc.target, - CallsStarted: atomic.LoadInt64(&cc.czData.callsStarted), - CallsSucceeded: atomic.LoadInt64(&cc.czData.callsSucceeded), - CallsFailed: atomic.LoadInt64(&cc.czData.callsFailed), - LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&cc.czData.lastCallStartedTime)), - } -} - // Target returns the target string of the ClientConn. -// -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. func (cc *ClientConn) Target() string { return cc.target } +// CanonicalTarget returns the canonical target string of the ClientConn. +func (cc *ClientConn) CanonicalTarget() string { + return cc.parsedTarget.String() +} + func (cc *ClientConn) incrCallsStarted() { - atomic.AddInt64(&cc.czData.callsStarted, 1) - atomic.StoreInt64(&cc.czData.lastCallStartedTime, time.Now().UnixNano()) + cc.channelz.ChannelMetrics.CallsStarted.Add(1) + cc.channelz.ChannelMetrics.LastCallStartedTimestamp.Store(time.Now().UnixNano()) } func (cc *ClientConn) incrCallsSucceeded() { - atomic.AddInt64(&cc.czData.callsSucceeded, 1) + cc.channelz.ChannelMetrics.CallsSucceeded.Add(1) } func (cc *ClientConn) incrCallsFailed() { - atomic.AddInt64(&cc.czData.callsFailed, 1) + cc.channelz.ChannelMetrics.CallsFailed.Add(1) } // connect starts creating a transport. @@ -947,7 +934,7 @@ func equalAddresses(a, b []resolver.Address) bool { // connections or connection attempts. func (ac *addrConn) updateAddrs(addrs []resolver.Address) { ac.mu.Lock() - channelz.Infof(logger, ac.channelzID, "addrConn: updateAddrs curAddr: %v, addrs: %v", pretty.ToJSON(ac.curAddr), pretty.ToJSON(addrs)) + channelz.Infof(logger, ac.channelz, "addrConn: updateAddrs curAddr: %v, addrs: %v", pretty.ToJSON(ac.curAddr), pretty.ToJSON(addrs)) addrs = copyAddressesWithoutBalancerAttributes(addrs) if equalAddresses(ac.addrs, addrs) { @@ -1067,7 +1054,7 @@ func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method st }) } -func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSelector iresolver.ConfigSelector, addrs []resolver.Address) { +func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSelector iresolver.ConfigSelector) { if sc == nil { // should never reach here. return @@ -1088,17 +1075,6 @@ func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSel } else { cc.retryThrottler.Store((*retryThrottler)(nil)) } - - var newBalancerName string - if cc.sc == nil || (cc.sc.lbConfig == nil && cc.sc.LB == nil) { - // No service config or no LB policy specified in config. - newBalancerName = PickFirstBalancerName - } else if cc.sc.lbConfig != nil { - newBalancerName = cc.sc.lbConfig.name - } else { // cc.sc.LB != nil - newBalancerName = *cc.sc.LB - } - cc.balancerWrapper.switchTo(newBalancerName) } func (cc *ClientConn) resolveNow(o resolver.ResolveNowOptions) { @@ -1174,7 +1150,7 @@ func (cc *ClientConn) Close() error { // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add // trace reference to the entity being deleted, and thus prevent it from being // deleted right away. - channelz.RemoveEntry(cc.channelzID) + channelz.RemoveEntry(cc.channelz.ID) return nil } @@ -1206,8 +1182,7 @@ type addrConn struct { backoffIdx int // Needs to be stateful for resetConnectBackoff. resetBackoff chan struct{} - channelzID *channelz.Identifier - czData *channelzData + channelz *channelz.SubChannel } // Note: this requires a lock on ac.mu. @@ -1219,10 +1194,11 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error) close(ac.stateChan) ac.stateChan = make(chan struct{}) ac.state = s + ac.channelz.ChannelMetrics.State.Store(&s) if lastErr == nil { - channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v", s) + channelz.Infof(logger, ac.channelz, "Subchannel Connectivity change to %v", s) } else { - channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v, last error: %s", s, lastErr) + channelz.Infof(logger, ac.channelz, "Subchannel Connectivity change to %v, last error: %s", s, lastErr) } ac.acbw.updateState(s, lastErr) } @@ -1335,7 +1311,7 @@ func (ac *addrConn) tryAllAddrs(ctx context.Context, addrs []resolver.Address, c } ac.mu.Unlock() - channelz.Infof(logger, ac.channelzID, "Subchannel picks a new address %q to connect", addr.Addr) + channelz.Infof(logger, ac.channelz, "Subchannel picks a new address %q to connect", addr.Addr) err := ac.createTransport(ctx, addr, copts, connectDeadline) if err == nil { @@ -1388,7 +1364,7 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address, connectCtx, cancel := context.WithDeadline(ctx, connectDeadline) defer cancel() - copts.ChannelzParentID = ac.channelzID + copts.ChannelzParent = ac.channelz newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onClose) if err != nil { @@ -1397,7 +1373,7 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address, } // newTr is either nil, or closed. hcancel() - channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %s. Err: %v", addr, err) + channelz.Warningf(logger, ac.channelz, "grpc: addrConn.createTransport failed to connect to %s. Err: %v", addr, err) return err } @@ -1469,7 +1445,7 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) { // The health package is not imported to set health check function. // // TODO: add a link to the health check doc in the error message. - channelz.Error(logger, ac.channelzID, "Health check is requested but health check function is not set.") + channelz.Error(logger, ac.channelz, "Health check is requested but health check function is not set.") return } @@ -1499,9 +1475,9 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) { err := ac.cc.dopts.healthCheckFunc(ctx, newStream, setConnectivityState, healthCheckConfig.ServiceName) if err != nil { if status.Code(err) == codes.Unimplemented { - channelz.Error(logger, ac.channelzID, "Subchannel health check is unimplemented at server side, thus health check is disabled") + channelz.Error(logger, ac.channelz, "Subchannel health check is unimplemented at server side, thus health check is disabled") } else { - channelz.Errorf(logger, ac.channelzID, "Health checking failed: %v", err) + channelz.Errorf(logger, ac.channelz, "Health checking failed: %v", err) } } }() @@ -1566,18 +1542,18 @@ func (ac *addrConn) tearDown(err error) { ac.cancel() ac.curAddr = resolver.Address{} - channelz.AddTraceEvent(logger, ac.channelzID, 0, &channelz.TraceEventDesc{ + channelz.AddTraceEvent(logger, ac.channelz, 0, &channelz.TraceEvent{ Desc: "Subchannel deleted", Severity: channelz.CtInfo, - Parent: &channelz.TraceEventDesc{ - Desc: fmt.Sprintf("Subchannel(id:%d) deleted", ac.channelzID.Int()), + Parent: &channelz.TraceEvent{ + Desc: fmt.Sprintf("Subchannel(id:%d) deleted", ac.channelz.ID), Severity: channelz.CtInfo, }, }) // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add // trace reference to the entity being deleted, and thus prevent it from // being deleted right away. - channelz.RemoveEntry(ac.channelzID) + channelz.RemoveEntry(ac.channelz.ID) ac.mu.Unlock() // We have to release the lock before the call to GracefulClose/Close here @@ -1604,39 +1580,6 @@ func (ac *addrConn) tearDown(err error) { } } -func (ac *addrConn) getState() connectivity.State { - ac.mu.Lock() - defer ac.mu.Unlock() - return ac.state -} - -func (ac *addrConn) ChannelzMetric() *channelz.ChannelInternalMetric { - ac.mu.Lock() - addr := ac.curAddr.Addr - ac.mu.Unlock() - return &channelz.ChannelInternalMetric{ - State: ac.getState(), - Target: addr, - CallsStarted: atomic.LoadInt64(&ac.czData.callsStarted), - CallsSucceeded: atomic.LoadInt64(&ac.czData.callsSucceeded), - CallsFailed: atomic.LoadInt64(&ac.czData.callsFailed), - LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&ac.czData.lastCallStartedTime)), - } -} - -func (ac *addrConn) incrCallsStarted() { - atomic.AddInt64(&ac.czData.callsStarted, 1) - atomic.StoreInt64(&ac.czData.lastCallStartedTime, time.Now().UnixNano()) -} - -func (ac *addrConn) incrCallsSucceeded() { - atomic.AddInt64(&ac.czData.callsSucceeded, 1) -} - -func (ac *addrConn) incrCallsFailed() { - atomic.AddInt64(&ac.czData.callsFailed, 1) -} - type retryThrottler struct { max float64 thresh float64 @@ -1674,12 +1617,17 @@ func (rt *retryThrottler) successfulRPC() { } } -type channelzChannel struct { - cc *ClientConn +func (ac *addrConn) incrCallsStarted() { + ac.channelz.ChannelMetrics.CallsStarted.Add(1) + ac.channelz.ChannelMetrics.LastCallStartedTimestamp.Store(time.Now().UnixNano()) } -func (c *channelzChannel) ChannelzMetric() *channelz.ChannelInternalMetric { - return c.cc.channelzMetric() +func (ac *addrConn) incrCallsSucceeded() { + ac.channelz.ChannelMetrics.CallsSucceeded.Add(1) +} + +func (ac *addrConn) incrCallsFailed() { + ac.channelz.ChannelMetrics.CallsFailed.Add(1) } // ErrClientConnTimeout indicates that the ClientConn cannot establish the @@ -1721,14 +1669,14 @@ func (cc *ClientConn) connectionError() error { // // Doesn't grab cc.mu as this method is expected to be called only at Dial time. func (cc *ClientConn) parseTargetAndFindResolver() error { - channelz.Infof(logger, cc.channelzID, "original dial target is: %q", cc.target) + channelz.Infof(logger, cc.channelz, "original dial target is: %q", cc.target) var rb resolver.Builder parsedTarget, err := parseTarget(cc.target) if err != nil { - channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", cc.target, err) + channelz.Infof(logger, cc.channelz, "dial target %q parse failed: %v", cc.target, err) } else { - channelz.Infof(logger, cc.channelzID, "parsed dial target is: %#v", parsedTarget) + channelz.Infof(logger, cc.channelz, "parsed dial target is: %#v", parsedTarget) rb = cc.getResolver(parsedTarget.URL.Scheme) if rb != nil { cc.parsedTarget = parsedTarget @@ -1740,17 +1688,22 @@ func (cc *ClientConn) parseTargetAndFindResolver() error { // We are here because the user's dial target did not contain a scheme or // specified an unregistered scheme. We should fallback to the default // scheme, except when a custom dialer is specified in which case, we should - // always use passthrough scheme. - defScheme := resolver.GetDefaultScheme() - channelz.Infof(logger, cc.channelzID, "fallback to scheme %q", defScheme) + // always use passthrough scheme. For either case, we need to respect any overridden + // global defaults set by the user. + defScheme := cc.dopts.defaultScheme + if internal.UserSetDefaultScheme { + defScheme = resolver.GetDefaultScheme() + } + + channelz.Infof(logger, cc.channelz, "fallback to scheme %q", defScheme) canonicalTarget := defScheme + ":///" + cc.target parsedTarget, err = parseTarget(canonicalTarget) if err != nil { - channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", canonicalTarget, err) + channelz.Infof(logger, cc.channelz, "dial target %q parse failed: %v", canonicalTarget, err) return err } - channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget) + channelz.Infof(logger, cc.channelz, "parsed dial target is: %+v", parsedTarget) rb = cc.getResolver(parsedTarget.URL.Scheme) if rb == nil { return fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.URL.Scheme) @@ -1873,6 +1826,6 @@ func (cc *ClientConn) determineAuthority() error { } else { cc.authority = encodeAuthority(endpoint) } - channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority) + channelz.Infof(logger, cc.channelz, "Channel authority set to %q", cc.authority) return nil } diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 5feac3aa..f6b55c68 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -28,9 +28,9 @@ import ( "fmt" "net" - "github.com/golang/protobuf/proto" "google.golang.org/grpc/attributes" icredentials "google.golang.org/grpc/internal/credentials" + "google.golang.org/protobuf/protoadapt" ) // PerRPCCredentials defines the common interface for the credentials which need to @@ -287,5 +287,5 @@ type ChannelzSecurityValue interface { type OtherChannelzSecurityValue struct { ChannelzSecurityValue Name string - Value proto.Message + Value protoadapt.MessageV1 } diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index ba242618..40249322 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -68,7 +68,7 @@ type dialOptions struct { binaryLogger binarylog.Logger copts transport.ConnectOptions callOptions []CallOption - channelzParentID *channelz.Identifier + channelzParent channelz.Identifier disableServiceConfig bool disableRetry bool disableHealthCheck bool @@ -79,6 +79,7 @@ type dialOptions struct { resolvers []resolver.Builder idleTimeout time.Duration recvBufferPool SharedBufferPool + defaultScheme string } // DialOption configures how we set up the connection. @@ -154,9 +155,7 @@ func WithSharedWriteBuffer(val bool) DialOption { } // WithWriteBufferSize determines how much data can be batched before doing a -// write on the wire. The corresponding memory allocation for this buffer will -// be twice the size to keep syscalls low. The default value for this buffer is -// 32KB. +// write on the wire. The default value for this buffer is 32KB. // // Zero or negative values will disable the write buffer such that each write // will be on underlying connection. Note: A Send call may not directly @@ -555,9 +554,9 @@ func WithAuthority(a string) DialOption { // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. -func WithChannelzParentID(id *channelz.Identifier) DialOption { +func WithChannelzParentID(c channelz.Identifier) DialOption { return newFuncDialOption(func(o *dialOptions) { - o.channelzParentID = id + o.channelzParent = c }) } @@ -645,6 +644,7 @@ func defaultDialOptions() dialOptions { healthCheckFunc: internal.HealthCheckFunc, idleTimeout: 30 * time.Minute, recvBufferPool: nopBufferPool{}, + defaultScheme: "dns", } } @@ -659,6 +659,14 @@ func withMinConnectDeadline(f func() time.Duration) DialOption { }) } +// withDefaultScheme is used to allow Dial to use "passthrough" as the default +// name resolver, while NewClient uses "dns" otherwise. +func withDefaultScheme(s string) DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.defaultScheme = s + }) +} + // WithResolvers allows a list of resolver implementations to be registered // locally with the ClientConn without needing to be globally registered via // resolver.Register. They will be matched against the scheme used for the diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go new file mode 100644 index 00000000..6bf7f873 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go @@ -0,0 +1,83 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package gracefulswitch + +import ( + "encoding/json" + "fmt" + + "google.golang.org/grpc/balancer" + "google.golang.org/grpc/serviceconfig" +) + +type lbConfig struct { + serviceconfig.LoadBalancingConfig + + childBuilder balancer.Builder + childConfig serviceconfig.LoadBalancingConfig +} + +func ChildName(l serviceconfig.LoadBalancingConfig) string { + return l.(*lbConfig).childBuilder.Name() +} + +// ParseConfig parses a child config list and returns a LB config for the +// gracefulswitch Balancer. +// +// cfg is expected to be a json.RawMessage containing a JSON array of LB policy +// names + configs as the format of the "loadBalancingConfig" field in +// ServiceConfig. It returns a type that should be passed to +// UpdateClientConnState in the BalancerConfig field. +func ParseConfig(cfg json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { + var lbCfg []map[string]json.RawMessage + if err := json.Unmarshal(cfg, &lbCfg); err != nil { + return nil, err + } + for i, e := range lbCfg { + if len(e) != 1 { + return nil, fmt.Errorf("expected a JSON struct with one entry; received entry %v at index %d", e, i) + } + + var name string + var jsonCfg json.RawMessage + for name, jsonCfg = range e { + } + + builder := balancer.Get(name) + if builder == nil { + // Skip unregistered balancer names. + continue + } + + parser, ok := builder.(balancer.ConfigParser) + if !ok { + // This is a valid child with no config. + return &lbConfig{childBuilder: builder}, nil + } + + cfg, err := parser.ParseConfig(jsonCfg) + if err != nil { + return nil, fmt.Errorf("error parsing config for policy %q: %v", name, err) + } + + return &lbConfig{childBuilder: builder, childConfig: cfg}, nil + } + + return nil, fmt.Errorf("no supported policies found in config: %v", string(cfg)) +} diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go index 3c594e6e..45d5e50e 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go @@ -94,14 +94,23 @@ func (gsb *Balancer) balancerCurrentOrPending(bw *balancerWrapper) bool { // process is not complete when this method returns. This method must be called // synchronously alongside the rest of the balancer.Balancer methods this // Graceful Switch Balancer implements. +// +// Deprecated: use ParseConfig and pass a parsed config to UpdateClientConnState +// to cause the Balancer to automatically change to the new child when necessary. func (gsb *Balancer) SwitchTo(builder balancer.Builder) error { + _, err := gsb.switchTo(builder) + return err +} + +func (gsb *Balancer) switchTo(builder balancer.Builder) (*balancerWrapper, error) { gsb.mu.Lock() if gsb.closed { gsb.mu.Unlock() - return errBalancerClosed + return nil, errBalancerClosed } bw := &balancerWrapper{ - gsb: gsb, + builder: builder, + gsb: gsb, lastState: balancer.State{ ConnectivityState: connectivity.Connecting, Picker: base.NewErrPicker(balancer.ErrNoSubConnAvailable), @@ -129,7 +138,7 @@ func (gsb *Balancer) SwitchTo(builder balancer.Builder) error { gsb.balancerCurrent = nil } gsb.mu.Unlock() - return balancer.ErrBadResolverState + return nil, balancer.ErrBadResolverState } // This write doesn't need to take gsb.mu because this field never gets read @@ -138,7 +147,7 @@ func (gsb *Balancer) SwitchTo(builder balancer.Builder) error { // bw.Balancer field will never be forwarded to until this SwitchTo() // function returns. bw.Balancer = newBalancer - return nil + return bw, nil } // Returns nil if the graceful switch balancer is closed. @@ -152,12 +161,33 @@ func (gsb *Balancer) latestBalancer() *balancerWrapper { } // UpdateClientConnState forwards the update to the latest balancer created. +// +// If the state's BalancerConfig is the config returned by a call to +// gracefulswitch.ParseConfig, then this function will automatically SwitchTo +// the balancer indicated by the config before forwarding its config to it, if +// necessary. func (gsb *Balancer) UpdateClientConnState(state balancer.ClientConnState) error { // The resolver data is only relevant to the most recent LB Policy. balToUpdate := gsb.latestBalancer() + + gsbCfg, ok := state.BalancerConfig.(*lbConfig) + if ok { + // Switch to the child in the config unless it is already active. + if balToUpdate == nil || gsbCfg.childBuilder.Name() != balToUpdate.builder.Name() { + var err error + balToUpdate, err = gsb.switchTo(gsbCfg.childBuilder) + if err != nil { + return fmt.Errorf("could not switch to new child balancer: %w", err) + } + } + // Unwrap the child balancer's config. + state.BalancerConfig = gsbCfg.childConfig + } + if balToUpdate == nil { return errBalancerClosed } + // Perform this call without gsb.mu to prevent deadlocks if the child calls // back into the channel. The latest balancer can never be closed during a // call from the channel, even without gsb.mu held. @@ -169,6 +199,10 @@ func (gsb *Balancer) ResolverError(err error) { // The resolver data is only relevant to the most recent LB Policy. balToUpdate := gsb.latestBalancer() if balToUpdate == nil { + gsb.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.TransientFailure, + Picker: base.NewErrPicker(err), + }) return } // Perform this call without gsb.mu to prevent deadlocks if the child calls @@ -261,7 +295,8 @@ func (gsb *Balancer) Close() { // graceful switch logic. type balancerWrapper struct { balancer.Balancer - gsb *Balancer + gsb *Balancer + builder balancer.Builder lastState balancer.State subconns map[balancer.SubConn]bool // subconns created by this balancer diff --git a/vendor/google.golang.org/grpc/internal/channelz/channel.go b/vendor/google.golang.org/grpc/internal/channelz/channel.go new file mode 100644 index 00000000..d7e9e1d5 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/channel.go @@ -0,0 +1,255 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package channelz + +import ( + "fmt" + "sync/atomic" + + "google.golang.org/grpc/connectivity" +) + +// Channel represents a channel within channelz, which includes metrics and +// internal channelz data, such as channelz id, child list, etc. +type Channel struct { + Entity + // ID is the channelz id of this channel. + ID int64 + // RefName is the human readable reference string of this channel. + RefName string + + closeCalled bool + nestedChans map[int64]string + subChans map[int64]string + Parent *Channel + trace *ChannelTrace + // traceRefCount is the number of trace events that reference this channel. + // Non-zero traceRefCount means the trace of this channel cannot be deleted. + traceRefCount int32 + + ChannelMetrics ChannelMetrics +} + +// Implemented to make Channel implement the Identifier interface used for +// nesting. +func (c *Channel) channelzIdentifier() {} + +func (c *Channel) String() string { + if c.Parent == nil { + return fmt.Sprintf("Channel #%d", c.ID) + } + return fmt.Sprintf("%s Channel #%d", c.Parent, c.ID) +} + +func (c *Channel) id() int64 { + return c.ID +} + +func (c *Channel) SubChans() map[int64]string { + db.mu.RLock() + defer db.mu.RUnlock() + return copyMap(c.subChans) +} + +func (c *Channel) NestedChans() map[int64]string { + db.mu.RLock() + defer db.mu.RUnlock() + return copyMap(c.nestedChans) +} + +func (c *Channel) Trace() *ChannelTrace { + db.mu.RLock() + defer db.mu.RUnlock() + return c.trace.copy() +} + +type ChannelMetrics struct { + // The current connectivity state of the channel. + State atomic.Pointer[connectivity.State] + // The target this channel originally tried to connect to. May be absent + Target atomic.Pointer[string] + // The number of calls started on the channel. + CallsStarted atomic.Int64 + // The number of calls that have completed with an OK status. + CallsSucceeded atomic.Int64 + // The number of calls that have a completed with a non-OK status. + CallsFailed atomic.Int64 + // The last time a call was started on the channel. + LastCallStartedTimestamp atomic.Int64 +} + +// CopyFrom copies the metrics in o to c. For testing only. +func (c *ChannelMetrics) CopyFrom(o *ChannelMetrics) { + c.State.Store(o.State.Load()) + c.Target.Store(o.Target.Load()) + c.CallsStarted.Store(o.CallsStarted.Load()) + c.CallsSucceeded.Store(o.CallsSucceeded.Load()) + c.CallsFailed.Store(o.CallsFailed.Load()) + c.LastCallStartedTimestamp.Store(o.LastCallStartedTimestamp.Load()) +} + +// Equal returns true iff the metrics of c are the same as the metrics of o. +// For testing only. +func (c *ChannelMetrics) Equal(o any) bool { + oc, ok := o.(*ChannelMetrics) + if !ok { + return false + } + if (c.State.Load() == nil) != (oc.State.Load() == nil) { + return false + } + if c.State.Load() != nil && *c.State.Load() != *oc.State.Load() { + return false + } + if (c.Target.Load() == nil) != (oc.Target.Load() == nil) { + return false + } + if c.Target.Load() != nil && *c.Target.Load() != *oc.Target.Load() { + return false + } + return c.CallsStarted.Load() == oc.CallsStarted.Load() && + c.CallsFailed.Load() == oc.CallsFailed.Load() && + c.CallsSucceeded.Load() == oc.CallsSucceeded.Load() && + c.LastCallStartedTimestamp.Load() == oc.LastCallStartedTimestamp.Load() +} + +func strFromPointer(s *string) string { + if s == nil { + return "" + } + return *s +} + +func (c *ChannelMetrics) String() string { + return fmt.Sprintf("State: %v, Target: %s, CallsStarted: %v, CallsSucceeded: %v, CallsFailed: %v, LastCallStartedTimestamp: %v", + c.State.Load(), strFromPointer(c.Target.Load()), c.CallsStarted.Load(), c.CallsSucceeded.Load(), c.CallsFailed.Load(), c.LastCallStartedTimestamp.Load(), + ) +} + +func NewChannelMetricForTesting(state connectivity.State, target string, started, succeeded, failed, timestamp int64) *ChannelMetrics { + c := &ChannelMetrics{} + c.State.Store(&state) + c.Target.Store(&target) + c.CallsStarted.Store(started) + c.CallsSucceeded.Store(succeeded) + c.CallsFailed.Store(failed) + c.LastCallStartedTimestamp.Store(timestamp) + return c +} + +func (c *Channel) addChild(id int64, e entry) { + switch v := e.(type) { + case *SubChannel: + c.subChans[id] = v.RefName + case *Channel: + c.nestedChans[id] = v.RefName + default: + logger.Errorf("cannot add a child (id = %d) of type %T to a channel", id, e) + } +} + +func (c *Channel) deleteChild(id int64) { + delete(c.subChans, id) + delete(c.nestedChans, id) + c.deleteSelfIfReady() +} + +func (c *Channel) triggerDelete() { + c.closeCalled = true + c.deleteSelfIfReady() +} + +func (c *Channel) getParentID() int64 { + if c.Parent == nil { + return -1 + } + return c.Parent.ID +} + +// deleteSelfFromTree tries to delete the channel from the channelz entry relation tree, which means +// deleting the channel reference from its parent's child list. +// +// In order for a channel to be deleted from the tree, it must meet the criteria that, removal of the +// corresponding grpc object has been invoked, and the channel does not have any children left. +// +// The returned boolean value indicates whether the channel has been successfully deleted from tree. +func (c *Channel) deleteSelfFromTree() (deleted bool) { + if !c.closeCalled || len(c.subChans)+len(c.nestedChans) != 0 { + return false + } + // not top channel + if c.Parent != nil { + c.Parent.deleteChild(c.ID) + } + return true +} + +// deleteSelfFromMap checks whether it is valid to delete the channel from the map, which means +// deleting the channel from channelz's tracking entirely. Users can no longer use id to query the +// channel, and its memory will be garbage collected. +// +// The trace reference count of the channel must be 0 in order to be deleted from the map. This is +// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, +// the trace of the referenced entity must not be deleted. In order to release the resource allocated +// by grpc, the reference to the grpc object is reset to a dummy object. +// +// deleteSelfFromMap must be called after deleteSelfFromTree returns true. +// +// It returns a bool to indicate whether the channel can be safely deleted from map. +func (c *Channel) deleteSelfFromMap() (delete bool) { + return c.getTraceRefCount() == 0 +} + +// deleteSelfIfReady tries to delete the channel itself from the channelz database. +// The delete process includes two steps: +// 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its +// parent's child list. +// 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id +// will return entry not found error. +func (c *Channel) deleteSelfIfReady() { + if !c.deleteSelfFromTree() { + return + } + if !c.deleteSelfFromMap() { + return + } + db.deleteEntry(c.ID) + c.trace.clear() +} + +func (c *Channel) getChannelTrace() *ChannelTrace { + return c.trace +} + +func (c *Channel) incrTraceRefCount() { + atomic.AddInt32(&c.traceRefCount, 1) +} + +func (c *Channel) decrTraceRefCount() { + atomic.AddInt32(&c.traceRefCount, -1) +} + +func (c *Channel) getTraceRefCount() int { + i := atomic.LoadInt32(&c.traceRefCount) + return int(i) +} + +func (c *Channel) getRefName() string { + return c.RefName +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/channelmap.go b/vendor/google.golang.org/grpc/internal/channelz/channelmap.go new file mode 100644 index 00000000..dfe18b08 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/channelmap.go @@ -0,0 +1,402 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package channelz + +import ( + "fmt" + "sort" + "sync" + "time" +) + +// entry represents a node in the channelz database. +type entry interface { + // addChild adds a child e, whose channelz id is id to child list + addChild(id int64, e entry) + // deleteChild deletes a child with channelz id to be id from child list + deleteChild(id int64) + // triggerDelete tries to delete self from channelz database. However, if + // child list is not empty, then deletion from the database is on hold until + // the last child is deleted from database. + triggerDelete() + // deleteSelfIfReady check whether triggerDelete() has been called before, + // and whether child list is now empty. If both conditions are met, then + // delete self from database. + deleteSelfIfReady() + // getParentID returns parent ID of the entry. 0 value parent ID means no parent. + getParentID() int64 + Entity +} + +// channelMap is the storage data structure for channelz. +// +// Methods of channelMap can be divided in two two categories with respect to +// locking. +// +// 1. Methods acquire the global lock. +// 2. Methods that can only be called when global lock is held. +// +// A second type of method need always to be called inside a first type of method. +type channelMap struct { + mu sync.RWMutex + topLevelChannels map[int64]struct{} + channels map[int64]*Channel + subChannels map[int64]*SubChannel + sockets map[int64]*Socket + servers map[int64]*Server +} + +func newChannelMap() *channelMap { + return &channelMap{ + topLevelChannels: make(map[int64]struct{}), + channels: make(map[int64]*Channel), + subChannels: make(map[int64]*SubChannel), + sockets: make(map[int64]*Socket), + servers: make(map[int64]*Server), + } +} + +func (c *channelMap) addServer(id int64, s *Server) { + c.mu.Lock() + defer c.mu.Unlock() + s.cm = c + c.servers[id] = s +} + +func (c *channelMap) addChannel(id int64, cn *Channel, isTopChannel bool, pid int64) { + c.mu.Lock() + defer c.mu.Unlock() + cn.trace.cm = c + c.channels[id] = cn + if isTopChannel { + c.topLevelChannels[id] = struct{}{} + } else if p := c.channels[pid]; p != nil { + p.addChild(id, cn) + } else { + logger.Infof("channel %d references invalid parent ID %d", id, pid) + } +} + +func (c *channelMap) addSubChannel(id int64, sc *SubChannel, pid int64) { + c.mu.Lock() + defer c.mu.Unlock() + sc.trace.cm = c + c.subChannels[id] = sc + if p := c.channels[pid]; p != nil { + p.addChild(id, sc) + } else { + logger.Infof("subchannel %d references invalid parent ID %d", id, pid) + } +} + +func (c *channelMap) addSocket(s *Socket) { + c.mu.Lock() + defer c.mu.Unlock() + s.cm = c + c.sockets[s.ID] = s + if s.Parent == nil { + logger.Infof("normal socket %d has no parent", s.ID) + } + s.Parent.(entry).addChild(s.ID, s) +} + +// removeEntry triggers the removal of an entry, which may not indeed delete the +// entry, if it has to wait on the deletion of its children and until no other +// entity's channel trace references it. It may lead to a chain of entry +// deletion. For example, deleting the last socket of a gracefully shutting down +// server will lead to the server being also deleted. +func (c *channelMap) removeEntry(id int64) { + c.mu.Lock() + defer c.mu.Unlock() + c.findEntry(id).triggerDelete() +} + +// tracedChannel represents tracing operations which are present on both +// channels and subChannels. +type tracedChannel interface { + getChannelTrace() *ChannelTrace + incrTraceRefCount() + decrTraceRefCount() + getRefName() string +} + +// c.mu must be held by the caller +func (c *channelMap) decrTraceRefCount(id int64) { + e := c.findEntry(id) + if v, ok := e.(tracedChannel); ok { + v.decrTraceRefCount() + e.deleteSelfIfReady() + } +} + +// c.mu must be held by the caller. +func (c *channelMap) findEntry(id int64) entry { + if v, ok := c.channels[id]; ok { + return v + } + if v, ok := c.subChannels[id]; ok { + return v + } + if v, ok := c.servers[id]; ok { + return v + } + if v, ok := c.sockets[id]; ok { + return v + } + return &dummyEntry{idNotFound: id} +} + +// c.mu must be held by the caller +// +// deleteEntry deletes an entry from the channelMap. Before calling this method, +// caller must check this entry is ready to be deleted, i.e removeEntry() has +// been called on it, and no children still exist. +func (c *channelMap) deleteEntry(id int64) entry { + if v, ok := c.sockets[id]; ok { + delete(c.sockets, id) + return v + } + if v, ok := c.subChannels[id]; ok { + delete(c.subChannels, id) + return v + } + if v, ok := c.channels[id]; ok { + delete(c.channels, id) + delete(c.topLevelChannels, id) + return v + } + if v, ok := c.servers[id]; ok { + delete(c.servers, id) + return v + } + return &dummyEntry{idNotFound: id} +} + +func (c *channelMap) traceEvent(id int64, desc *TraceEvent) { + c.mu.Lock() + defer c.mu.Unlock() + child := c.findEntry(id) + childTC, ok := child.(tracedChannel) + if !ok { + return + } + childTC.getChannelTrace().append(&traceEvent{Desc: desc.Desc, Severity: desc.Severity, Timestamp: time.Now()}) + if desc.Parent != nil { + parent := c.findEntry(child.getParentID()) + var chanType RefChannelType + switch child.(type) { + case *Channel: + chanType = RefChannel + case *SubChannel: + chanType = RefSubChannel + } + if parentTC, ok := parent.(tracedChannel); ok { + parentTC.getChannelTrace().append(&traceEvent{ + Desc: desc.Parent.Desc, + Severity: desc.Parent.Severity, + Timestamp: time.Now(), + RefID: id, + RefName: childTC.getRefName(), + RefType: chanType, + }) + childTC.incrTraceRefCount() + } + } +} + +type int64Slice []int64 + +func (s int64Slice) Len() int { return len(s) } +func (s int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s int64Slice) Less(i, j int) bool { return s[i] < s[j] } + +func copyMap(m map[int64]string) map[int64]string { + n := make(map[int64]string) + for k, v := range m { + n[k] = v + } + return n +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func (c *channelMap) getTopChannels(id int64, maxResults int) ([]*Channel, bool) { + if maxResults <= 0 { + maxResults = EntriesPerPage + } + c.mu.RLock() + defer c.mu.RUnlock() + l := int64(len(c.topLevelChannels)) + ids := make([]int64, 0, l) + + for k := range c.topLevelChannels { + ids = append(ids, k) + } + sort.Sort(int64Slice(ids)) + idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) + end := true + var t []*Channel + for _, v := range ids[idx:] { + if len(t) == maxResults { + end = false + break + } + if cn, ok := c.channels[v]; ok { + t = append(t, cn) + } + } + return t, end +} + +func (c *channelMap) getServers(id int64, maxResults int) ([]*Server, bool) { + if maxResults <= 0 { + maxResults = EntriesPerPage + } + c.mu.RLock() + defer c.mu.RUnlock() + ids := make([]int64, 0, len(c.servers)) + for k := range c.servers { + ids = append(ids, k) + } + sort.Sort(int64Slice(ids)) + idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) + end := true + var s []*Server + for _, v := range ids[idx:] { + if len(s) == maxResults { + end = false + break + } + if svr, ok := c.servers[v]; ok { + s = append(s, svr) + } + } + return s, end +} + +func (c *channelMap) getServerSockets(id int64, startID int64, maxResults int) ([]*Socket, bool) { + if maxResults <= 0 { + maxResults = EntriesPerPage + } + c.mu.RLock() + defer c.mu.RUnlock() + svr, ok := c.servers[id] + if !ok { + // server with id doesn't exist. + return nil, true + } + svrskts := svr.sockets + ids := make([]int64, 0, len(svrskts)) + sks := make([]*Socket, 0, min(len(svrskts), maxResults)) + for k := range svrskts { + ids = append(ids, k) + } + sort.Sort(int64Slice(ids)) + idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= startID }) + end := true + for _, v := range ids[idx:] { + if len(sks) == maxResults { + end = false + break + } + if ns, ok := c.sockets[v]; ok { + sks = append(sks, ns) + } + } + return sks, end +} + +func (c *channelMap) getChannel(id int64) *Channel { + c.mu.RLock() + defer c.mu.RUnlock() + return c.channels[id] +} + +func (c *channelMap) getSubChannel(id int64) *SubChannel { + c.mu.RLock() + defer c.mu.RUnlock() + return c.subChannels[id] +} + +func (c *channelMap) getSocket(id int64) *Socket { + c.mu.RLock() + defer c.mu.RUnlock() + return c.sockets[id] +} + +func (c *channelMap) getServer(id int64) *Server { + c.mu.RLock() + defer c.mu.RUnlock() + return c.servers[id] +} + +type dummyEntry struct { + // dummyEntry is a fake entry to handle entry not found case. + idNotFound int64 + Entity +} + +func (d *dummyEntry) String() string { + return fmt.Sprintf("non-existent entity #%d", d.idNotFound) +} + +func (d *dummyEntry) ID() int64 { return d.idNotFound } + +func (d *dummyEntry) addChild(id int64, e entry) { + // Note: It is possible for a normal program to reach here under race + // condition. For example, there could be a race between ClientConn.Close() + // info being propagated to addrConn and http2Client. ClientConn.Close() + // cancel the context and result in http2Client to error. The error info is + // then caught by transport monitor and before addrConn.tearDown() is called + // in side ClientConn.Close(). Therefore, the addrConn will create a new + // transport. And when registering the new transport in channelz, its parent + // addrConn could have already been torn down and deleted from channelz + // tracking, and thus reach the code here. + logger.Infof("attempt to add child of type %T with id %d to a parent (id=%d) that doesn't currently exist", e, id, d.idNotFound) +} + +func (d *dummyEntry) deleteChild(id int64) { + // It is possible for a normal program to reach here under race condition. + // Refer to the example described in addChild(). + logger.Infof("attempt to delete child with id %d from a parent (id=%d) that doesn't currently exist", id, d.idNotFound) +} + +func (d *dummyEntry) triggerDelete() { + logger.Warningf("attempt to delete an entry (id=%d) that doesn't currently exist", d.idNotFound) +} + +func (*dummyEntry) deleteSelfIfReady() { + // code should not reach here. deleteSelfIfReady is always called on an existing entry. +} + +func (*dummyEntry) getParentID() int64 { + return 0 +} + +// Entity is implemented by all channelz types. +type Entity interface { + isEntity() + fmt.Stringer + id() int64 +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/funcs.go b/vendor/google.golang.org/grpc/internal/channelz/funcs.go index fc094f34..f461e9bc 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/funcs.go +++ b/vendor/google.golang.org/grpc/internal/channelz/funcs.go @@ -16,47 +16,32 @@ * */ -// Package channelz defines APIs for enabling channelz service, entry +// Package channelz defines internal APIs for enabling channelz service, entry // registration/deletion, and accessing channelz data. It also defines channelz // metric struct formats. -// -// All APIs in this package are experimental. package channelz import ( - "errors" - "sort" - "sync" "sync/atomic" "time" - "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal" ) -const ( - defaultMaxTraceEntry int32 = 30 -) - var ( // IDGen is the global channelz entity ID generator. It should not be used // outside this package except by tests. IDGen IDGenerator - db dbWrapper - // EntryPerPage defines the number of channelz entries to be shown on a web page. - EntryPerPage = int64(50) - curState int32 - maxTraceEntry = defaultMaxTraceEntry + db *channelMap = newChannelMap() + // EntriesPerPage defines the number of channelz entries to be shown on a web page. + EntriesPerPage = 50 + curState int32 ) // TurnOn turns on channelz data collection. func TurnOn() { - if !IsOn() { - db.set(newChannelMap()) - IDGen.Reset() - atomic.StoreInt32(&curState, 1) - } + atomic.StoreInt32(&curState, 1) } func init() { @@ -70,49 +55,15 @@ func IsOn() bool { return atomic.LoadInt32(&curState) == 1 } -// SetMaxTraceEntry sets maximum number of trace entry per entity (i.e. channel/subchannel). -// Setting it to 0 will disable channel tracing. -func SetMaxTraceEntry(i int32) { - atomic.StoreInt32(&maxTraceEntry, i) -} - -// ResetMaxTraceEntryToDefault resets the maximum number of trace entry per entity to default. -func ResetMaxTraceEntryToDefault() { - atomic.StoreInt32(&maxTraceEntry, defaultMaxTraceEntry) -} - -func getMaxTraceEntry() int { - i := atomic.LoadInt32(&maxTraceEntry) - return int(i) -} - -// dbWarpper wraps around a reference to internal channelz data storage, and -// provide synchronized functionality to set and get the reference. -type dbWrapper struct { - mu sync.RWMutex - DB *channelMap -} - -func (d *dbWrapper) set(db *channelMap) { - d.mu.Lock() - d.DB = db - d.mu.Unlock() -} - -func (d *dbWrapper) get() *channelMap { - d.mu.RLock() - defer d.mu.RUnlock() - return d.DB -} - // GetTopChannels returns a slice of top channel's ChannelMetric, along with a // boolean indicating whether there's more top channels to be queried for. // -// The arg id specifies that only top channel with id at or above it will be included -// in the result. The returned slice is up to a length of the arg maxResults or -// EntryPerPage if maxResults is zero, and is sorted in ascending id order. -func GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { - return db.get().GetTopChannels(id, maxResults) +// The arg id specifies that only top channel with id at or above it will be +// included in the result. The returned slice is up to a length of the arg +// maxResults or EntriesPerPage if maxResults is zero, and is sorted in ascending +// id order. +func GetTopChannels(id int64, maxResults int) ([]*Channel, bool) { + return db.getTopChannels(id, maxResults) } // GetServers returns a slice of server's ServerMetric, along with a @@ -120,73 +71,69 @@ func GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { // // The arg id specifies that only server with id at or above it will be included // in the result. The returned slice is up to a length of the arg maxResults or -// EntryPerPage if maxResults is zero, and is sorted in ascending id order. -func GetServers(id int64, maxResults int64) ([]*ServerMetric, bool) { - return db.get().GetServers(id, maxResults) +// EntriesPerPage if maxResults is zero, and is sorted in ascending id order. +func GetServers(id int64, maxResults int) ([]*Server, bool) { + return db.getServers(id, maxResults) } // GetServerSockets returns a slice of server's (identified by id) normal socket's -// SocketMetric, along with a boolean indicating whether there's more sockets to +// SocketMetrics, along with a boolean indicating whether there's more sockets to // be queried for. // // The arg startID specifies that only sockets with id at or above it will be // included in the result. The returned slice is up to a length of the arg maxResults -// or EntryPerPage if maxResults is zero, and is sorted in ascending id order. -func GetServerSockets(id int64, startID int64, maxResults int64) ([]*SocketMetric, bool) { - return db.get().GetServerSockets(id, startID, maxResults) +// or EntriesPerPage if maxResults is zero, and is sorted in ascending id order. +func GetServerSockets(id int64, startID int64, maxResults int) ([]*Socket, bool) { + return db.getServerSockets(id, startID, maxResults) } -// GetChannel returns the ChannelMetric for the channel (identified by id). -func GetChannel(id int64) *ChannelMetric { - return db.get().GetChannel(id) +// GetChannel returns the Channel for the channel (identified by id). +func GetChannel(id int64) *Channel { + return db.getChannel(id) } -// GetSubChannel returns the SubChannelMetric for the subchannel (identified by id). -func GetSubChannel(id int64) *SubChannelMetric { - return db.get().GetSubChannel(id) +// GetSubChannel returns the SubChannel for the subchannel (identified by id). +func GetSubChannel(id int64) *SubChannel { + return db.getSubChannel(id) } -// GetSocket returns the SocketInternalMetric for the socket (identified by id). -func GetSocket(id int64) *SocketMetric { - return db.get().GetSocket(id) +// GetSocket returns the Socket for the socket (identified by id). +func GetSocket(id int64) *Socket { + return db.getSocket(id) } // GetServer returns the ServerMetric for the server (identified by id). -func GetServer(id int64) *ServerMetric { - return db.get().GetServer(id) +func GetServer(id int64) *Server { + return db.getServer(id) } // RegisterChannel registers the given channel c in the channelz database with -// ref as its reference name, and adds it to the child list of its parent -// (identified by pid). pid == nil means no parent. +// target as its target and reference name, and adds it to the child list of its +// parent. parent == nil means no parent. // // Returns a unique channelz identifier assigned to this channel. // // If channelz is not turned ON, the channelz database is not mutated. -func RegisterChannel(c Channel, pid *Identifier, ref string) *Identifier { +func RegisterChannel(parent *Channel, target string) *Channel { id := IDGen.genID() - var parent int64 - isTopChannel := true - if pid != nil { - isTopChannel = false - parent = pid.Int() - } if !IsOn() { - return newIdentifer(RefChannel, id, pid) + return &Channel{ID: id} } - cn := &channel{ - refName: ref, - c: c, - subChans: make(map[int64]string), + isTopChannel := parent == nil + + cn := &Channel{ + ID: id, + RefName: target, nestedChans: make(map[int64]string), - id: id, - pid: parent, - trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())}, + subChans: make(map[int64]string), + Parent: parent, + trace: &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())}, } - db.get().addChannel(id, cn, isTopChannel, parent) - return newIdentifer(RefChannel, id, pid) + cn.ChannelMetrics.Target.Store(&target) + db.addChannel(id, cn, isTopChannel, cn.getParentID()) + return cn } // RegisterSubChannel registers the given subChannel c in the channelz database @@ -196,555 +143,66 @@ func RegisterChannel(c Channel, pid *Identifier, ref string) *Identifier { // Returns a unique channelz identifier assigned to this subChannel. // // If channelz is not turned ON, the channelz database is not mutated. -func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, error) { - if pid == nil { - return nil, errors.New("a SubChannel's parent id cannot be nil") - } +func RegisterSubChannel(pid int64, ref string) *SubChannel { id := IDGen.genID() if !IsOn() { - return newIdentifer(RefSubChannel, id, pid), nil + return &SubChannel{ID: id} } - sc := &subChannel{ - refName: ref, - c: c, + sc := &SubChannel{ + RefName: ref, + ID: id, sockets: make(map[int64]string), - id: id, - pid: pid.Int(), - trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())}, + parent: db.getChannel(pid), + trace: &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())}, } - db.get().addSubChannel(id, sc, pid.Int()) - return newIdentifer(RefSubChannel, id, pid), nil + db.addSubChannel(id, sc, pid) + return sc } // RegisterServer registers the given server s in channelz database. It returns // the unique channelz tracking id assigned to this server. // // If channelz is not turned ON, the channelz database is not mutated. -func RegisterServer(s Server, ref string) *Identifier { +func RegisterServer(ref string) *Server { id := IDGen.genID() if !IsOn() { - return newIdentifer(RefServer, id, nil) + return &Server{ID: id} } - svr := &server{ - refName: ref, - s: s, + svr := &Server{ + RefName: ref, sockets: make(map[int64]string), listenSockets: make(map[int64]string), - id: id, - } - db.get().addServer(id, svr) - return newIdentifer(RefServer, id, nil) -} - -// RegisterListenSocket registers the given listen socket s in channelz database -// with ref as its reference name, and add it to the child list of its parent -// (identified by pid). It returns the unique channelz tracking id assigned to -// this listen socket. -// -// If channelz is not turned ON, the channelz database is not mutated. -func RegisterListenSocket(s Socket, pid *Identifier, ref string) (*Identifier, error) { - if pid == nil { - return nil, errors.New("a ListenSocket's parent id cannot be 0") + ID: id, } - id := IDGen.genID() - if !IsOn() { - return newIdentifer(RefListenSocket, id, pid), nil - } - - ls := &listenSocket{refName: ref, s: s, id: id, pid: pid.Int()} - db.get().addListenSocket(id, ls, pid.Int()) - return newIdentifer(RefListenSocket, id, pid), nil + db.addServer(id, svr) + return svr } -// RegisterNormalSocket registers the given normal socket s in channelz database +// RegisterSocket registers the given normal socket s in channelz database // with ref as its reference name, and adds it to the child list of its parent -// (identified by pid). It returns the unique channelz tracking id assigned to -// this normal socket. +// (identified by skt.Parent, which must be set). It returns the unique channelz +// tracking id assigned to this normal socket. // // If channelz is not turned ON, the channelz database is not mutated. -func RegisterNormalSocket(s Socket, pid *Identifier, ref string) (*Identifier, error) { - if pid == nil { - return nil, errors.New("a NormalSocket's parent id cannot be 0") - } - id := IDGen.genID() - if !IsOn() { - return newIdentifer(RefNormalSocket, id, pid), nil +func RegisterSocket(skt *Socket) *Socket { + skt.ID = IDGen.genID() + if IsOn() { + db.addSocket(skt) } - - ns := &normalSocket{refName: ref, s: s, id: id, pid: pid.Int()} - db.get().addNormalSocket(id, ns, pid.Int()) - return newIdentifer(RefNormalSocket, id, pid), nil + return skt } // RemoveEntry removes an entry with unique channelz tracking id to be id from // channelz database. // // If channelz is not turned ON, this function is a no-op. -func RemoveEntry(id *Identifier) { +func RemoveEntry(id int64) { if !IsOn() { return } - db.get().removeEntry(id.Int()) -} - -// TraceEventDesc is what the caller of AddTraceEvent should provide to describe -// the event to be added to the channel trace. -// -// The Parent field is optional. It is used for an event that will be recorded -// in the entity's parent trace. -type TraceEventDesc struct { - Desc string - Severity Severity - Parent *TraceEventDesc -} - -// AddTraceEvent adds trace related to the entity with specified id, using the -// provided TraceEventDesc. -// -// If channelz is not turned ON, this will simply log the event descriptions. -func AddTraceEvent(l grpclog.DepthLoggerV2, id *Identifier, depth int, desc *TraceEventDesc) { - // Log only the trace description associated with the bottom most entity. - switch desc.Severity { - case CtUnknown, CtInfo: - l.InfoDepth(depth+1, withParens(id)+desc.Desc) - case CtWarning: - l.WarningDepth(depth+1, withParens(id)+desc.Desc) - case CtError: - l.ErrorDepth(depth+1, withParens(id)+desc.Desc) - } - - if getMaxTraceEntry() == 0 { - return - } - if IsOn() { - db.get().traceEvent(id.Int(), desc) - } -} - -// channelMap is the storage data structure for channelz. -// Methods of channelMap can be divided in two two categories with respect to locking. -// 1. Methods acquire the global lock. -// 2. Methods that can only be called when global lock is held. -// A second type of method need always to be called inside a first type of method. -type channelMap struct { - mu sync.RWMutex - topLevelChannels map[int64]struct{} - servers map[int64]*server - channels map[int64]*channel - subChannels map[int64]*subChannel - listenSockets map[int64]*listenSocket - normalSockets map[int64]*normalSocket -} - -func newChannelMap() *channelMap { - return &channelMap{ - topLevelChannels: make(map[int64]struct{}), - channels: make(map[int64]*channel), - listenSockets: make(map[int64]*listenSocket), - normalSockets: make(map[int64]*normalSocket), - servers: make(map[int64]*server), - subChannels: make(map[int64]*subChannel), - } -} - -func (c *channelMap) addServer(id int64, s *server) { - c.mu.Lock() - s.cm = c - c.servers[id] = s - c.mu.Unlock() -} - -func (c *channelMap) addChannel(id int64, cn *channel, isTopChannel bool, pid int64) { - c.mu.Lock() - cn.cm = c - cn.trace.cm = c - c.channels[id] = cn - if isTopChannel { - c.topLevelChannels[id] = struct{}{} - } else { - c.findEntry(pid).addChild(id, cn) - } - c.mu.Unlock() -} - -func (c *channelMap) addSubChannel(id int64, sc *subChannel, pid int64) { - c.mu.Lock() - sc.cm = c - sc.trace.cm = c - c.subChannels[id] = sc - c.findEntry(pid).addChild(id, sc) - c.mu.Unlock() -} - -func (c *channelMap) addListenSocket(id int64, ls *listenSocket, pid int64) { - c.mu.Lock() - ls.cm = c - c.listenSockets[id] = ls - c.findEntry(pid).addChild(id, ls) - c.mu.Unlock() -} - -func (c *channelMap) addNormalSocket(id int64, ns *normalSocket, pid int64) { - c.mu.Lock() - ns.cm = c - c.normalSockets[id] = ns - c.findEntry(pid).addChild(id, ns) - c.mu.Unlock() -} - -// removeEntry triggers the removal of an entry, which may not indeed delete the entry, if it has to -// wait on the deletion of its children and until no other entity's channel trace references it. -// It may lead to a chain of entry deletion. For example, deleting the last socket of a gracefully -// shutting down server will lead to the server being also deleted. -func (c *channelMap) removeEntry(id int64) { - c.mu.Lock() - c.findEntry(id).triggerDelete() - c.mu.Unlock() -} - -// c.mu must be held by the caller -func (c *channelMap) decrTraceRefCount(id int64) { - e := c.findEntry(id) - if v, ok := e.(tracedChannel); ok { - v.decrTraceRefCount() - e.deleteSelfIfReady() - } -} - -// c.mu must be held by the caller. -func (c *channelMap) findEntry(id int64) entry { - var v entry - var ok bool - if v, ok = c.channels[id]; ok { - return v - } - if v, ok = c.subChannels[id]; ok { - return v - } - if v, ok = c.servers[id]; ok { - return v - } - if v, ok = c.listenSockets[id]; ok { - return v - } - if v, ok = c.normalSockets[id]; ok { - return v - } - return &dummyEntry{idNotFound: id} -} - -// c.mu must be held by the caller -// deleteEntry simply deletes an entry from the channelMap. Before calling this -// method, caller must check this entry is ready to be deleted, i.e removeEntry() -// has been called on it, and no children still exist. -// Conditionals are ordered by the expected frequency of deletion of each entity -// type, in order to optimize performance. -func (c *channelMap) deleteEntry(id int64) { - var ok bool - if _, ok = c.normalSockets[id]; ok { - delete(c.normalSockets, id) - return - } - if _, ok = c.subChannels[id]; ok { - delete(c.subChannels, id) - return - } - if _, ok = c.channels[id]; ok { - delete(c.channels, id) - delete(c.topLevelChannels, id) - return - } - if _, ok = c.listenSockets[id]; ok { - delete(c.listenSockets, id) - return - } - if _, ok = c.servers[id]; ok { - delete(c.servers, id) - return - } -} - -func (c *channelMap) traceEvent(id int64, desc *TraceEventDesc) { - c.mu.Lock() - child := c.findEntry(id) - childTC, ok := child.(tracedChannel) - if !ok { - c.mu.Unlock() - return - } - childTC.getChannelTrace().append(&TraceEvent{Desc: desc.Desc, Severity: desc.Severity, Timestamp: time.Now()}) - if desc.Parent != nil { - parent := c.findEntry(child.getParentID()) - var chanType RefChannelType - switch child.(type) { - case *channel: - chanType = RefChannel - case *subChannel: - chanType = RefSubChannel - } - if parentTC, ok := parent.(tracedChannel); ok { - parentTC.getChannelTrace().append(&TraceEvent{ - Desc: desc.Parent.Desc, - Severity: desc.Parent.Severity, - Timestamp: time.Now(), - RefID: id, - RefName: childTC.getRefName(), - RefType: chanType, - }) - childTC.incrTraceRefCount() - } - } - c.mu.Unlock() -} - -type int64Slice []int64 - -func (s int64Slice) Len() int { return len(s) } -func (s int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s int64Slice) Less(i, j int) bool { return s[i] < s[j] } - -func copyMap(m map[int64]string) map[int64]string { - n := make(map[int64]string) - for k, v := range m { - n[k] = v - } - return n -} - -func min(a, b int64) int64 { - if a < b { - return a - } - return b -} - -func (c *channelMap) GetTopChannels(id int64, maxResults int64) ([]*ChannelMetric, bool) { - if maxResults <= 0 { - maxResults = EntryPerPage - } - c.mu.RLock() - l := int64(len(c.topLevelChannels)) - ids := make([]int64, 0, l) - cns := make([]*channel, 0, min(l, maxResults)) - - for k := range c.topLevelChannels { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := int64(0) - var end bool - var t []*ChannelMetric - for i, v := range ids[idx:] { - if count == maxResults { - break - } - if cn, ok := c.channels[v]; ok { - cns = append(cns, cn) - t = append(t, &ChannelMetric{ - NestedChans: copyMap(cn.nestedChans), - SubChans: copyMap(cn.subChans), - }) - count++ - } - if i == len(ids[idx:])-1 { - end = true - break - } - } - c.mu.RUnlock() - if count == 0 { - end = true - } - - for i, cn := range cns { - t[i].ChannelData = cn.c.ChannelzMetric() - t[i].ID = cn.id - t[i].RefName = cn.refName - t[i].Trace = cn.trace.dumpData() - } - return t, end -} - -func (c *channelMap) GetServers(id, maxResults int64) ([]*ServerMetric, bool) { - if maxResults <= 0 { - maxResults = EntryPerPage - } - c.mu.RLock() - l := int64(len(c.servers)) - ids := make([]int64, 0, l) - ss := make([]*server, 0, min(l, maxResults)) - for k := range c.servers { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= id }) - count := int64(0) - var end bool - var s []*ServerMetric - for i, v := range ids[idx:] { - if count == maxResults { - break - } - if svr, ok := c.servers[v]; ok { - ss = append(ss, svr) - s = append(s, &ServerMetric{ - ListenSockets: copyMap(svr.listenSockets), - }) - count++ - } - if i == len(ids[idx:])-1 { - end = true - break - } - } - c.mu.RUnlock() - if count == 0 { - end = true - } - - for i, svr := range ss { - s[i].ServerData = svr.s.ChannelzMetric() - s[i].ID = svr.id - s[i].RefName = svr.refName - } - return s, end -} - -func (c *channelMap) GetServerSockets(id int64, startID int64, maxResults int64) ([]*SocketMetric, bool) { - if maxResults <= 0 { - maxResults = EntryPerPage - } - var svr *server - var ok bool - c.mu.RLock() - if svr, ok = c.servers[id]; !ok { - // server with id doesn't exist. - c.mu.RUnlock() - return nil, true - } - svrskts := svr.sockets - l := int64(len(svrskts)) - ids := make([]int64, 0, l) - sks := make([]*normalSocket, 0, min(l, maxResults)) - for k := range svrskts { - ids = append(ids, k) - } - sort.Sort(int64Slice(ids)) - idx := sort.Search(len(ids), func(i int) bool { return ids[i] >= startID }) - count := int64(0) - var end bool - for i, v := range ids[idx:] { - if count == maxResults { - break - } - if ns, ok := c.normalSockets[v]; ok { - sks = append(sks, ns) - count++ - } - if i == len(ids[idx:])-1 { - end = true - break - } - } - c.mu.RUnlock() - if count == 0 { - end = true - } - s := make([]*SocketMetric, 0, len(sks)) - for _, ns := range sks { - sm := &SocketMetric{} - sm.SocketData = ns.s.ChannelzMetric() - sm.ID = ns.id - sm.RefName = ns.refName - s = append(s, sm) - } - return s, end -} - -func (c *channelMap) GetChannel(id int64) *ChannelMetric { - cm := &ChannelMetric{} - var cn *channel - var ok bool - c.mu.RLock() - if cn, ok = c.channels[id]; !ok { - // channel with id doesn't exist. - c.mu.RUnlock() - return nil - } - cm.NestedChans = copyMap(cn.nestedChans) - cm.SubChans = copyMap(cn.subChans) - // cn.c can be set to &dummyChannel{} when deleteSelfFromMap is called. Save a copy of cn.c when - // holding the lock to prevent potential data race. - chanCopy := cn.c - c.mu.RUnlock() - cm.ChannelData = chanCopy.ChannelzMetric() - cm.ID = cn.id - cm.RefName = cn.refName - cm.Trace = cn.trace.dumpData() - return cm -} - -func (c *channelMap) GetSubChannel(id int64) *SubChannelMetric { - cm := &SubChannelMetric{} - var sc *subChannel - var ok bool - c.mu.RLock() - if sc, ok = c.subChannels[id]; !ok { - // subchannel with id doesn't exist. - c.mu.RUnlock() - return nil - } - cm.Sockets = copyMap(sc.sockets) - // sc.c can be set to &dummyChannel{} when deleteSelfFromMap is called. Save a copy of sc.c when - // holding the lock to prevent potential data race. - chanCopy := sc.c - c.mu.RUnlock() - cm.ChannelData = chanCopy.ChannelzMetric() - cm.ID = sc.id - cm.RefName = sc.refName - cm.Trace = sc.trace.dumpData() - return cm -} - -func (c *channelMap) GetSocket(id int64) *SocketMetric { - sm := &SocketMetric{} - c.mu.RLock() - if ls, ok := c.listenSockets[id]; ok { - c.mu.RUnlock() - sm.SocketData = ls.s.ChannelzMetric() - sm.ID = ls.id - sm.RefName = ls.refName - return sm - } - if ns, ok := c.normalSockets[id]; ok { - c.mu.RUnlock() - sm.SocketData = ns.s.ChannelzMetric() - sm.ID = ns.id - sm.RefName = ns.refName - return sm - } - c.mu.RUnlock() - return nil -} - -func (c *channelMap) GetServer(id int64) *ServerMetric { - sm := &ServerMetric{} - var svr *server - var ok bool - c.mu.RLock() - if svr, ok = c.servers[id]; !ok { - c.mu.RUnlock() - return nil - } - sm.ListenSockets = copyMap(svr.listenSockets) - c.mu.RUnlock() - sm.ID = svr.id - sm.RefName = svr.refName - sm.ServerData = svr.s.ChannelzMetric() - return sm + db.removeEntry(id) } // IDGenerator is an incrementing atomic that tracks IDs for channelz entities. @@ -761,3 +219,11 @@ func (i *IDGenerator) Reset() { func (i *IDGenerator) genID() int64 { return atomic.AddInt64(&i.id, 1) } + +// Identifier is an opaque channelz identifier used to expose channelz symbols +// outside of grpc. Currently only implemented by Channel since no other +// types require exposure outside grpc. +type Identifier interface { + Entity + channelzIdentifier() +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/id.go b/vendor/google.golang.org/grpc/internal/channelz/id.go deleted file mode 100644 index c9a27acd..00000000 --- a/vendor/google.golang.org/grpc/internal/channelz/id.go +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright 2022 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import "fmt" - -// Identifier is an opaque identifier which uniquely identifies an entity in the -// channelz database. -type Identifier struct { - typ RefChannelType - id int64 - str string - pid *Identifier -} - -// Type returns the entity type corresponding to id. -func (id *Identifier) Type() RefChannelType { - return id.typ -} - -// Int returns the integer identifier corresponding to id. -func (id *Identifier) Int() int64 { - return id.id -} - -// String returns a string representation of the entity corresponding to id. -// -// This includes some information about the parent as well. Examples: -// Top-level channel: [Channel #channel-number] -// Nested channel: [Channel #parent-channel-number Channel #channel-number] -// Sub channel: [Channel #parent-channel SubChannel #subchannel-number] -func (id *Identifier) String() string { - return id.str -} - -// Equal returns true if other is the same as id. -func (id *Identifier) Equal(other *Identifier) bool { - if (id != nil) != (other != nil) { - return false - } - if id == nil && other == nil { - return true - } - return id.typ == other.typ && id.id == other.id && id.pid == other.pid -} - -// NewIdentifierForTesting returns a new opaque identifier to be used only for -// testing purposes. -func NewIdentifierForTesting(typ RefChannelType, id int64, pid *Identifier) *Identifier { - return newIdentifer(typ, id, pid) -} - -func newIdentifer(typ RefChannelType, id int64, pid *Identifier) *Identifier { - str := fmt.Sprintf("%s #%d", typ, id) - if pid != nil { - str = fmt.Sprintf("%s %s", pid, str) - } - return &Identifier{typ: typ, id: id, str: str, pid: pid} -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/logging.go b/vendor/google.golang.org/grpc/internal/channelz/logging.go index f89e6f77..ee4d7212 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/logging.go +++ b/vendor/google.golang.org/grpc/internal/channelz/logging.go @@ -26,53 +26,49 @@ import ( var logger = grpclog.Component("channelz") -func withParens(id *Identifier) string { - return "[" + id.String() + "] " -} - // Info logs and adds a trace event if channelz is on. -func Info(l grpclog.DepthLoggerV2, id *Identifier, args ...any) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Info(l grpclog.DepthLoggerV2, e Entity, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprint(args...), Severity: CtInfo, }) } // Infof logs and adds a trace event if channelz is on. -func Infof(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Infof(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprintf(format, args...), Severity: CtInfo, }) } // Warning logs and adds a trace event if channelz is on. -func Warning(l grpclog.DepthLoggerV2, id *Identifier, args ...any) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Warning(l grpclog.DepthLoggerV2, e Entity, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprint(args...), Severity: CtWarning, }) } // Warningf logs and adds a trace event if channelz is on. -func Warningf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Warningf(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprintf(format, args...), Severity: CtWarning, }) } // Error logs and adds a trace event if channelz is on. -func Error(l grpclog.DepthLoggerV2, id *Identifier, args ...any) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Error(l grpclog.DepthLoggerV2, e Entity, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprint(args...), Severity: CtError, }) } // Errorf logs and adds a trace event if channelz is on. -func Errorf(l grpclog.DepthLoggerV2, id *Identifier, format string, args ...any) { - AddTraceEvent(l, id, 1, &TraceEventDesc{ +func Errorf(l grpclog.DepthLoggerV2, e Entity, format string, args ...any) { + AddTraceEvent(l, e, 1, &TraceEvent{ Desc: fmt.Sprintf(format, args...), Severity: CtError, }) diff --git a/vendor/google.golang.org/grpc/internal/channelz/server.go b/vendor/google.golang.org/grpc/internal/channelz/server.go new file mode 100644 index 00000000..cdfc49d6 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/server.go @@ -0,0 +1,119 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package channelz + +import ( + "fmt" + "sync/atomic" +) + +// Server is the channelz representation of a server. +type Server struct { + Entity + ID int64 + RefName string + + ServerMetrics ServerMetrics + + closeCalled bool + sockets map[int64]string + listenSockets map[int64]string + cm *channelMap +} + +// ServerMetrics defines a struct containing metrics for servers. +type ServerMetrics struct { + // The number of incoming calls started on the server. + CallsStarted atomic.Int64 + // The number of incoming calls that have completed with an OK status. + CallsSucceeded atomic.Int64 + // The number of incoming calls that have a completed with a non-OK status. + CallsFailed atomic.Int64 + // The last time a call was started on the server. + LastCallStartedTimestamp atomic.Int64 +} + +// NewServerMetricsForTesting returns an initialized ServerMetrics. +func NewServerMetricsForTesting(started, succeeded, failed, timestamp int64) *ServerMetrics { + sm := &ServerMetrics{} + sm.CallsStarted.Store(started) + sm.CallsSucceeded.Store(succeeded) + sm.CallsFailed.Store(failed) + sm.LastCallStartedTimestamp.Store(timestamp) + return sm +} + +func (sm *ServerMetrics) CopyFrom(o *ServerMetrics) { + sm.CallsStarted.Store(o.CallsStarted.Load()) + sm.CallsSucceeded.Store(o.CallsSucceeded.Load()) + sm.CallsFailed.Store(o.CallsFailed.Load()) + sm.LastCallStartedTimestamp.Store(o.LastCallStartedTimestamp.Load()) +} + +// ListenSockets returns the listening sockets for s. +func (s *Server) ListenSockets() map[int64]string { + db.mu.RLock() + defer db.mu.RUnlock() + return copyMap(s.listenSockets) +} + +// String returns a printable description of s. +func (s *Server) String() string { + return fmt.Sprintf("Server #%d", s.ID) +} + +func (s *Server) id() int64 { + return s.ID +} + +func (s *Server) addChild(id int64, e entry) { + switch v := e.(type) { + case *Socket: + switch v.SocketType { + case SocketTypeNormal: + s.sockets[id] = v.RefName + case SocketTypeListen: + s.listenSockets[id] = v.RefName + } + default: + logger.Errorf("cannot add a child (id = %d) of type %T to a server", id, e) + } +} + +func (s *Server) deleteChild(id int64) { + delete(s.sockets, id) + delete(s.listenSockets, id) + s.deleteSelfIfReady() +} + +func (s *Server) triggerDelete() { + s.closeCalled = true + s.deleteSelfIfReady() +} + +func (s *Server) deleteSelfIfReady() { + if !s.closeCalled || len(s.sockets)+len(s.listenSockets) != 0 { + return + } + s.cm.deleteEntry(s.ID) +} + +func (s *Server) getParentID() int64 { + return 0 +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/socket.go b/vendor/google.golang.org/grpc/internal/channelz/socket.go new file mode 100644 index 00000000..fa64834b --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/socket.go @@ -0,0 +1,130 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package channelz + +import ( + "fmt" + "net" + "sync/atomic" + + "google.golang.org/grpc/credentials" +) + +// SocketMetrics defines the struct that the implementor of Socket interface +// should return from ChannelzMetric(). +type SocketMetrics struct { + // The number of streams that have been started. + StreamsStarted atomic.Int64 + // The number of streams that have ended successfully: + // On client side, receiving frame with eos bit set. + // On server side, sending frame with eos bit set. + StreamsSucceeded atomic.Int64 + // The number of streams that have ended unsuccessfully: + // On client side, termination without receiving frame with eos bit set. + // On server side, termination without sending frame with eos bit set. + StreamsFailed atomic.Int64 + // The number of messages successfully sent on this socket. + MessagesSent atomic.Int64 + MessagesReceived atomic.Int64 + // The number of keep alives sent. This is typically implemented with HTTP/2 + // ping messages. + KeepAlivesSent atomic.Int64 + // The last time a stream was created by this endpoint. Usually unset for + // servers. + LastLocalStreamCreatedTimestamp atomic.Int64 + // The last time a stream was created by the remote endpoint. Usually unset + // for clients. + LastRemoteStreamCreatedTimestamp atomic.Int64 + // The last time a message was sent by this endpoint. + LastMessageSentTimestamp atomic.Int64 + // The last time a message was received by this endpoint. + LastMessageReceivedTimestamp atomic.Int64 +} + +// EphemeralSocketMetrics are metrics that change rapidly and are tracked +// outside of channelz. +type EphemeralSocketMetrics struct { + // The amount of window, granted to the local endpoint by the remote endpoint. + // This may be slightly out of date due to network latency. This does NOT + // include stream level or TCP level flow control info. + LocalFlowControlWindow int64 + // The amount of window, granted to the remote endpoint by the local endpoint. + // This may be slightly out of date due to network latency. This does NOT + // include stream level or TCP level flow control info. + RemoteFlowControlWindow int64 +} + +type SocketType string + +const ( + SocketTypeNormal = "NormalSocket" + SocketTypeListen = "ListenSocket" +) + +type Socket struct { + Entity + SocketType SocketType + ID int64 + Parent Entity + cm *channelMap + SocketMetrics SocketMetrics + EphemeralMetrics func() *EphemeralSocketMetrics + + RefName string + // The locally bound address. Immutable. + LocalAddr net.Addr + // The remote bound address. May be absent. Immutable. + RemoteAddr net.Addr + // Optional, represents the name of the remote endpoint, if different than + // the original target name. Immutable. + RemoteName string + // Immutable. + SocketOptions *SocketOptionData + // Immutable. + Security credentials.ChannelzSecurityValue +} + +func (ls *Socket) String() string { + return fmt.Sprintf("%s %s #%d", ls.Parent, ls.SocketType, ls.ID) +} + +func (ls *Socket) id() int64 { + return ls.ID +} + +func (ls *Socket) addChild(id int64, e entry) { + logger.Errorf("cannot add a child (id = %d) of type %T to a listen socket", id, e) +} + +func (ls *Socket) deleteChild(id int64) { + logger.Errorf("cannot delete a child (id = %d) from a listen socket", id) +} + +func (ls *Socket) triggerDelete() { + ls.cm.deleteEntry(ls.ID) + ls.Parent.(entry).deleteChild(ls.ID) +} + +func (ls *Socket) deleteSelfIfReady() { + logger.Errorf("cannot call deleteSelfIfReady on a listen socket") +} + +func (ls *Socket) getParentID() int64 { + return ls.Parent.id() +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/subchannel.go b/vendor/google.golang.org/grpc/internal/channelz/subchannel.go new file mode 100644 index 00000000..3b88e4cb --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/subchannel.go @@ -0,0 +1,151 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package channelz + +import ( + "fmt" + "sync/atomic" +) + +// SubChannel is the channelz representation of a subchannel. +type SubChannel struct { + Entity + // ID is the channelz id of this subchannel. + ID int64 + // RefName is the human readable reference string of this subchannel. + RefName string + closeCalled bool + sockets map[int64]string + parent *Channel + trace *ChannelTrace + traceRefCount int32 + + ChannelMetrics ChannelMetrics +} + +func (sc *SubChannel) String() string { + return fmt.Sprintf("%s SubChannel #%d", sc.parent, sc.ID) +} + +func (sc *SubChannel) id() int64 { + return sc.ID +} + +func (sc *SubChannel) Sockets() map[int64]string { + db.mu.RLock() + defer db.mu.RUnlock() + return copyMap(sc.sockets) +} + +func (sc *SubChannel) Trace() *ChannelTrace { + db.mu.RLock() + defer db.mu.RUnlock() + return sc.trace.copy() +} + +func (sc *SubChannel) addChild(id int64, e entry) { + if v, ok := e.(*Socket); ok && v.SocketType == SocketTypeNormal { + sc.sockets[id] = v.RefName + } else { + logger.Errorf("cannot add a child (id = %d) of type %T to a subChannel", id, e) + } +} + +func (sc *SubChannel) deleteChild(id int64) { + delete(sc.sockets, id) + sc.deleteSelfIfReady() +} + +func (sc *SubChannel) triggerDelete() { + sc.closeCalled = true + sc.deleteSelfIfReady() +} + +func (sc *SubChannel) getParentID() int64 { + return sc.parent.ID +} + +// deleteSelfFromTree tries to delete the subchannel from the channelz entry relation tree, which +// means deleting the subchannel reference from its parent's child list. +// +// In order for a subchannel to be deleted from the tree, it must meet the criteria that, removal of +// the corresponding grpc object has been invoked, and the subchannel does not have any children left. +// +// The returned boolean value indicates whether the channel has been successfully deleted from tree. +func (sc *SubChannel) deleteSelfFromTree() (deleted bool) { + if !sc.closeCalled || len(sc.sockets) != 0 { + return false + } + sc.parent.deleteChild(sc.ID) + return true +} + +// deleteSelfFromMap checks whether it is valid to delete the subchannel from the map, which means +// deleting the subchannel from channelz's tracking entirely. Users can no longer use id to query +// the subchannel, and its memory will be garbage collected. +// +// The trace reference count of the subchannel must be 0 in order to be deleted from the map. This is +// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, +// the trace of the referenced entity must not be deleted. In order to release the resource allocated +// by grpc, the reference to the grpc object is reset to a dummy object. +// +// deleteSelfFromMap must be called after deleteSelfFromTree returns true. +// +// It returns a bool to indicate whether the channel can be safely deleted from map. +func (sc *SubChannel) deleteSelfFromMap() (delete bool) { + return sc.getTraceRefCount() == 0 +} + +// deleteSelfIfReady tries to delete the subchannel itself from the channelz database. +// The delete process includes two steps: +// 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from +// its parent's child list. +// 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup +// by id will return entry not found error. +func (sc *SubChannel) deleteSelfIfReady() { + if !sc.deleteSelfFromTree() { + return + } + if !sc.deleteSelfFromMap() { + return + } + db.deleteEntry(sc.ID) + sc.trace.clear() +} + +func (sc *SubChannel) getChannelTrace() *ChannelTrace { + return sc.trace +} + +func (sc *SubChannel) incrTraceRefCount() { + atomic.AddInt32(&sc.traceRefCount, 1) +} + +func (sc *SubChannel) decrTraceRefCount() { + atomic.AddInt32(&sc.traceRefCount, -1) +} + +func (sc *SubChannel) getTraceRefCount() int { + i := atomic.LoadInt32(&sc.traceRefCount) + return int(i) +} + +func (sc *SubChannel) getRefName() string { + return sc.RefName +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go b/vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go similarity index 83% rename from vendor/google.golang.org/grpc/internal/channelz/types_linux.go rename to vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go index 1b1c4cce..5ac73ff8 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/syscall_linux.go @@ -49,3 +49,17 @@ func (s *SocketOptionData) Getsockopt(fd uintptr) { s.TCPInfo = v } } + +// GetSocketOption gets the socket option info of the conn. +func GetSocketOption(socket any) *SocketOptionData { + c, ok := socket.(syscall.Conn) + if !ok { + return nil + } + data := &SocketOptionData{} + if rawConn, err := c.SyscallConn(); err == nil { + rawConn.Control(data.Getsockopt) + return data + } + return nil +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go similarity index 90% rename from vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go rename to vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go index 8b06eed1..d1ed8df6 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux /* * @@ -41,3 +40,8 @@ func (s *SocketOptionData) Getsockopt(fd uintptr) { logger.Warning("Channelz: socket options are not supported on non-linux environments") }) } + +// GetSocketOption gets the socket option info of the conn. +func GetSocketOption(c any) *SocketOptionData { + return nil +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/trace.go b/vendor/google.golang.org/grpc/internal/channelz/trace.go new file mode 100644 index 00000000..36b86740 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/channelz/trace.go @@ -0,0 +1,204 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package channelz + +import ( + "fmt" + "sync" + "sync/atomic" + "time" + + "google.golang.org/grpc/grpclog" +) + +const ( + defaultMaxTraceEntry int32 = 30 +) + +var maxTraceEntry = defaultMaxTraceEntry + +// SetMaxTraceEntry sets maximum number of trace entries per entity (i.e. +// channel/subchannel). Setting it to 0 will disable channel tracing. +func SetMaxTraceEntry(i int32) { + atomic.StoreInt32(&maxTraceEntry, i) +} + +// ResetMaxTraceEntryToDefault resets the maximum number of trace entries per +// entity to default. +func ResetMaxTraceEntryToDefault() { + atomic.StoreInt32(&maxTraceEntry, defaultMaxTraceEntry) +} + +func getMaxTraceEntry() int { + i := atomic.LoadInt32(&maxTraceEntry) + return int(i) +} + +// traceEvent is an internal representation of a single trace event +type traceEvent struct { + // Desc is a simple description of the trace event. + Desc string + // Severity states the severity of this trace event. + Severity Severity + // Timestamp is the event time. + Timestamp time.Time + // RefID is the id of the entity that gets referenced in the event. RefID is 0 if no other entity is + // involved in this event. + // e.g. SubChannel (id: 4[]) Created. --> RefID = 4, RefName = "" (inside []) + RefID int64 + // RefName is the reference name for the entity that gets referenced in the event. + RefName string + // RefType indicates the referenced entity type, i.e Channel or SubChannel. + RefType RefChannelType +} + +// TraceEvent is what the caller of AddTraceEvent should provide to describe the +// event to be added to the channel trace. +// +// The Parent field is optional. It is used for an event that will be recorded +// in the entity's parent trace. +type TraceEvent struct { + Desc string + Severity Severity + Parent *TraceEvent +} + +type ChannelTrace struct { + cm *channelMap + clearCalled bool + CreationTime time.Time + EventNum int64 + mu sync.Mutex + Events []*traceEvent +} + +func (c *ChannelTrace) copy() *ChannelTrace { + return &ChannelTrace{ + CreationTime: c.CreationTime, + EventNum: c.EventNum, + Events: append(([]*traceEvent)(nil), c.Events...), + } +} + +func (c *ChannelTrace) append(e *traceEvent) { + c.mu.Lock() + if len(c.Events) == getMaxTraceEntry() { + del := c.Events[0] + c.Events = c.Events[1:] + if del.RefID != 0 { + // start recursive cleanup in a goroutine to not block the call originated from grpc. + go func() { + // need to acquire c.cm.mu lock to call the unlocked attemptCleanup func. + c.cm.mu.Lock() + c.cm.decrTraceRefCount(del.RefID) + c.cm.mu.Unlock() + }() + } + } + e.Timestamp = time.Now() + c.Events = append(c.Events, e) + c.EventNum++ + c.mu.Unlock() +} + +func (c *ChannelTrace) clear() { + if c.clearCalled { + return + } + c.clearCalled = true + c.mu.Lock() + for _, e := range c.Events { + if e.RefID != 0 { + // caller should have already held the c.cm.mu lock. + c.cm.decrTraceRefCount(e.RefID) + } + } + c.mu.Unlock() +} + +// Severity is the severity level of a trace event. +// The canonical enumeration of all valid values is here: +// https://github.com/grpc/grpc-proto/blob/9b13d199cc0d4703c7ea26c9c330ba695866eb23/grpc/channelz/v1/channelz.proto#L126. +type Severity int + +const ( + // CtUnknown indicates unknown severity of a trace event. + CtUnknown Severity = iota + // CtInfo indicates info level severity of a trace event. + CtInfo + // CtWarning indicates warning level severity of a trace event. + CtWarning + // CtError indicates error level severity of a trace event. + CtError +) + +// RefChannelType is the type of the entity being referenced in a trace event. +type RefChannelType int + +const ( + // RefUnknown indicates an unknown entity type, the zero value for this type. + RefUnknown RefChannelType = iota + // RefChannel indicates the referenced entity is a Channel. + RefChannel + // RefSubChannel indicates the referenced entity is a SubChannel. + RefSubChannel + // RefServer indicates the referenced entity is a Server. + RefServer + // RefListenSocket indicates the referenced entity is a ListenSocket. + RefListenSocket + // RefNormalSocket indicates the referenced entity is a NormalSocket. + RefNormalSocket +) + +var refChannelTypeToString = map[RefChannelType]string{ + RefUnknown: "Unknown", + RefChannel: "Channel", + RefSubChannel: "SubChannel", + RefServer: "Server", + RefListenSocket: "ListenSocket", + RefNormalSocket: "NormalSocket", +} + +func (r RefChannelType) String() string { + return refChannelTypeToString[r] +} + +// AddTraceEvent adds trace related to the entity with specified id, using the +// provided TraceEventDesc. +// +// If channelz is not turned ON, this will simply log the event descriptions. +func AddTraceEvent(l grpclog.DepthLoggerV2, e Entity, depth int, desc *TraceEvent) { + // Log only the trace description associated with the bottom most entity. + d := fmt.Sprintf("[%s]%s", e, desc.Desc) + switch desc.Severity { + case CtUnknown, CtInfo: + l.InfoDepth(depth+1, d) + case CtWarning: + l.WarningDepth(depth+1, d) + case CtError: + l.ErrorDepth(depth+1, d) + } + + if getMaxTraceEntry() == 0 { + return + } + if IsOn() { + db.traceEvent(e.id(), desc) + } +} diff --git a/vendor/google.golang.org/grpc/internal/channelz/types.go b/vendor/google.golang.org/grpc/internal/channelz/types.go deleted file mode 100644 index 1d4020f5..00000000 --- a/vendor/google.golang.org/grpc/internal/channelz/types.go +++ /dev/null @@ -1,727 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "net" - "sync" - "sync/atomic" - "time" - - "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/credentials" -) - -// entry represents a node in the channelz database. -type entry interface { - // addChild adds a child e, whose channelz id is id to child list - addChild(id int64, e entry) - // deleteChild deletes a child with channelz id to be id from child list - deleteChild(id int64) - // triggerDelete tries to delete self from channelz database. However, if child - // list is not empty, then deletion from the database is on hold until the last - // child is deleted from database. - triggerDelete() - // deleteSelfIfReady check whether triggerDelete() has been called before, and whether child - // list is now empty. If both conditions are met, then delete self from database. - deleteSelfIfReady() - // getParentID returns parent ID of the entry. 0 value parent ID means no parent. - getParentID() int64 -} - -// dummyEntry is a fake entry to handle entry not found case. -type dummyEntry struct { - idNotFound int64 -} - -func (d *dummyEntry) addChild(id int64, e entry) { - // Note: It is possible for a normal program to reach here under race condition. - // For example, there could be a race between ClientConn.Close() info being propagated - // to addrConn and http2Client. ClientConn.Close() cancel the context and result - // in http2Client to error. The error info is then caught by transport monitor - // and before addrConn.tearDown() is called in side ClientConn.Close(). Therefore, - // the addrConn will create a new transport. And when registering the new transport in - // channelz, its parent addrConn could have already been torn down and deleted - // from channelz tracking, and thus reach the code here. - logger.Infof("attempt to add child of type %T with id %d to a parent (id=%d) that doesn't currently exist", e, id, d.idNotFound) -} - -func (d *dummyEntry) deleteChild(id int64) { - // It is possible for a normal program to reach here under race condition. - // Refer to the example described in addChild(). - logger.Infof("attempt to delete child with id %d from a parent (id=%d) that doesn't currently exist", id, d.idNotFound) -} - -func (d *dummyEntry) triggerDelete() { - logger.Warningf("attempt to delete an entry (id=%d) that doesn't currently exist", d.idNotFound) -} - -func (*dummyEntry) deleteSelfIfReady() { - // code should not reach here. deleteSelfIfReady is always called on an existing entry. -} - -func (*dummyEntry) getParentID() int64 { - return 0 -} - -// ChannelMetric defines the info channelz provides for a specific Channel, which -// includes ChannelInternalMetric and channelz-specific data, such as channelz id, -// child list, etc. -type ChannelMetric struct { - // ID is the channelz id of this channel. - ID int64 - // RefName is the human readable reference string of this channel. - RefName string - // ChannelData contains channel internal metric reported by the channel through - // ChannelzMetric(). - ChannelData *ChannelInternalMetric - // NestedChans tracks the nested channel type children of this channel in the format of - // a map from nested channel channelz id to corresponding reference string. - NestedChans map[int64]string - // SubChans tracks the subchannel type children of this channel in the format of a - // map from subchannel channelz id to corresponding reference string. - SubChans map[int64]string - // Sockets tracks the socket type children of this channel in the format of a map - // from socket channelz id to corresponding reference string. - // Note current grpc implementation doesn't allow channel having sockets directly, - // therefore, this is field is unused. - Sockets map[int64]string - // Trace contains the most recent traced events. - Trace *ChannelTrace -} - -// SubChannelMetric defines the info channelz provides for a specific SubChannel, -// which includes ChannelInternalMetric and channelz-specific data, such as -// channelz id, child list, etc. -type SubChannelMetric struct { - // ID is the channelz id of this subchannel. - ID int64 - // RefName is the human readable reference string of this subchannel. - RefName string - // ChannelData contains subchannel internal metric reported by the subchannel - // through ChannelzMetric(). - ChannelData *ChannelInternalMetric - // NestedChans tracks the nested channel type children of this subchannel in the format of - // a map from nested channel channelz id to corresponding reference string. - // Note current grpc implementation doesn't allow subchannel to have nested channels - // as children, therefore, this field is unused. - NestedChans map[int64]string - // SubChans tracks the subchannel type children of this subchannel in the format of a - // map from subchannel channelz id to corresponding reference string. - // Note current grpc implementation doesn't allow subchannel to have subchannels - // as children, therefore, this field is unused. - SubChans map[int64]string - // Sockets tracks the socket type children of this subchannel in the format of a map - // from socket channelz id to corresponding reference string. - Sockets map[int64]string - // Trace contains the most recent traced events. - Trace *ChannelTrace -} - -// ChannelInternalMetric defines the struct that the implementor of Channel interface -// should return from ChannelzMetric(). -type ChannelInternalMetric struct { - // current connectivity state of the channel. - State connectivity.State - // The target this channel originally tried to connect to. May be absent - Target string - // The number of calls started on the channel. - CallsStarted int64 - // The number of calls that have completed with an OK status. - CallsSucceeded int64 - // The number of calls that have a completed with a non-OK status. - CallsFailed int64 - // The last time a call was started on the channel. - LastCallStartedTimestamp time.Time -} - -// ChannelTrace stores traced events on a channel/subchannel and related info. -type ChannelTrace struct { - // EventNum is the number of events that ever got traced (i.e. including those that have been deleted) - EventNum int64 - // CreationTime is the creation time of the trace. - CreationTime time.Time - // Events stores the most recent trace events (up to $maxTraceEntry, newer event will overwrite the - // oldest one) - Events []*TraceEvent -} - -// TraceEvent represent a single trace event -type TraceEvent struct { - // Desc is a simple description of the trace event. - Desc string - // Severity states the severity of this trace event. - Severity Severity - // Timestamp is the event time. - Timestamp time.Time - // RefID is the id of the entity that gets referenced in the event. RefID is 0 if no other entity is - // involved in this event. - // e.g. SubChannel (id: 4[]) Created. --> RefID = 4, RefName = "" (inside []) - RefID int64 - // RefName is the reference name for the entity that gets referenced in the event. - RefName string - // RefType indicates the referenced entity type, i.e Channel or SubChannel. - RefType RefChannelType -} - -// Channel is the interface that should be satisfied in order to be tracked by -// channelz as Channel or SubChannel. -type Channel interface { - ChannelzMetric() *ChannelInternalMetric -} - -type dummyChannel struct{} - -func (d *dummyChannel) ChannelzMetric() *ChannelInternalMetric { - return &ChannelInternalMetric{} -} - -type channel struct { - refName string - c Channel - closeCalled bool - nestedChans map[int64]string - subChans map[int64]string - id int64 - pid int64 - cm *channelMap - trace *channelTrace - // traceRefCount is the number of trace events that reference this channel. - // Non-zero traceRefCount means the trace of this channel cannot be deleted. - traceRefCount int32 -} - -func (c *channel) addChild(id int64, e entry) { - switch v := e.(type) { - case *subChannel: - c.subChans[id] = v.refName - case *channel: - c.nestedChans[id] = v.refName - default: - logger.Errorf("cannot add a child (id = %d) of type %T to a channel", id, e) - } -} - -func (c *channel) deleteChild(id int64) { - delete(c.subChans, id) - delete(c.nestedChans, id) - c.deleteSelfIfReady() -} - -func (c *channel) triggerDelete() { - c.closeCalled = true - c.deleteSelfIfReady() -} - -func (c *channel) getParentID() int64 { - return c.pid -} - -// deleteSelfFromTree tries to delete the channel from the channelz entry relation tree, which means -// deleting the channel reference from its parent's child list. -// -// In order for a channel to be deleted from the tree, it must meet the criteria that, removal of the -// corresponding grpc object has been invoked, and the channel does not have any children left. -// -// The returned boolean value indicates whether the channel has been successfully deleted from tree. -func (c *channel) deleteSelfFromTree() (deleted bool) { - if !c.closeCalled || len(c.subChans)+len(c.nestedChans) != 0 { - return false - } - // not top channel - if c.pid != 0 { - c.cm.findEntry(c.pid).deleteChild(c.id) - } - return true -} - -// deleteSelfFromMap checks whether it is valid to delete the channel from the map, which means -// deleting the channel from channelz's tracking entirely. Users can no longer use id to query the -// channel, and its memory will be garbage collected. -// -// The trace reference count of the channel must be 0 in order to be deleted from the map. This is -// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, -// the trace of the referenced entity must not be deleted. In order to release the resource allocated -// by grpc, the reference to the grpc object is reset to a dummy object. -// -// deleteSelfFromMap must be called after deleteSelfFromTree returns true. -// -// It returns a bool to indicate whether the channel can be safely deleted from map. -func (c *channel) deleteSelfFromMap() (delete bool) { - if c.getTraceRefCount() != 0 { - c.c = &dummyChannel{} - return false - } - return true -} - -// deleteSelfIfReady tries to delete the channel itself from the channelz database. -// The delete process includes two steps: -// 1. delete the channel from the entry relation tree, i.e. delete the channel reference from its -// parent's child list. -// 2. delete the channel from the map, i.e. delete the channel entirely from channelz. Lookup by id -// will return entry not found error. -func (c *channel) deleteSelfIfReady() { - if !c.deleteSelfFromTree() { - return - } - if !c.deleteSelfFromMap() { - return - } - c.cm.deleteEntry(c.id) - c.trace.clear() -} - -func (c *channel) getChannelTrace() *channelTrace { - return c.trace -} - -func (c *channel) incrTraceRefCount() { - atomic.AddInt32(&c.traceRefCount, 1) -} - -func (c *channel) decrTraceRefCount() { - atomic.AddInt32(&c.traceRefCount, -1) -} - -func (c *channel) getTraceRefCount() int { - i := atomic.LoadInt32(&c.traceRefCount) - return int(i) -} - -func (c *channel) getRefName() string { - return c.refName -} - -type subChannel struct { - refName string - c Channel - closeCalled bool - sockets map[int64]string - id int64 - pid int64 - cm *channelMap - trace *channelTrace - traceRefCount int32 -} - -func (sc *subChannel) addChild(id int64, e entry) { - if v, ok := e.(*normalSocket); ok { - sc.sockets[id] = v.refName - } else { - logger.Errorf("cannot add a child (id = %d) of type %T to a subChannel", id, e) - } -} - -func (sc *subChannel) deleteChild(id int64) { - delete(sc.sockets, id) - sc.deleteSelfIfReady() -} - -func (sc *subChannel) triggerDelete() { - sc.closeCalled = true - sc.deleteSelfIfReady() -} - -func (sc *subChannel) getParentID() int64 { - return sc.pid -} - -// deleteSelfFromTree tries to delete the subchannel from the channelz entry relation tree, which -// means deleting the subchannel reference from its parent's child list. -// -// In order for a subchannel to be deleted from the tree, it must meet the criteria that, removal of -// the corresponding grpc object has been invoked, and the subchannel does not have any children left. -// -// The returned boolean value indicates whether the channel has been successfully deleted from tree. -func (sc *subChannel) deleteSelfFromTree() (deleted bool) { - if !sc.closeCalled || len(sc.sockets) != 0 { - return false - } - sc.cm.findEntry(sc.pid).deleteChild(sc.id) - return true -} - -// deleteSelfFromMap checks whether it is valid to delete the subchannel from the map, which means -// deleting the subchannel from channelz's tracking entirely. Users can no longer use id to query -// the subchannel, and its memory will be garbage collected. -// -// The trace reference count of the subchannel must be 0 in order to be deleted from the map. This is -// specified in the channel tracing gRFC that as long as some other trace has reference to an entity, -// the trace of the referenced entity must not be deleted. In order to release the resource allocated -// by grpc, the reference to the grpc object is reset to a dummy object. -// -// deleteSelfFromMap must be called after deleteSelfFromTree returns true. -// -// It returns a bool to indicate whether the channel can be safely deleted from map. -func (sc *subChannel) deleteSelfFromMap() (delete bool) { - if sc.getTraceRefCount() != 0 { - // free the grpc struct (i.e. addrConn) - sc.c = &dummyChannel{} - return false - } - return true -} - -// deleteSelfIfReady tries to delete the subchannel itself from the channelz database. -// The delete process includes two steps: -// 1. delete the subchannel from the entry relation tree, i.e. delete the subchannel reference from -// its parent's child list. -// 2. delete the subchannel from the map, i.e. delete the subchannel entirely from channelz. Lookup -// by id will return entry not found error. -func (sc *subChannel) deleteSelfIfReady() { - if !sc.deleteSelfFromTree() { - return - } - if !sc.deleteSelfFromMap() { - return - } - sc.cm.deleteEntry(sc.id) - sc.trace.clear() -} - -func (sc *subChannel) getChannelTrace() *channelTrace { - return sc.trace -} - -func (sc *subChannel) incrTraceRefCount() { - atomic.AddInt32(&sc.traceRefCount, 1) -} - -func (sc *subChannel) decrTraceRefCount() { - atomic.AddInt32(&sc.traceRefCount, -1) -} - -func (sc *subChannel) getTraceRefCount() int { - i := atomic.LoadInt32(&sc.traceRefCount) - return int(i) -} - -func (sc *subChannel) getRefName() string { - return sc.refName -} - -// SocketMetric defines the info channelz provides for a specific Socket, which -// includes SocketInternalMetric and channelz-specific data, such as channelz id, etc. -type SocketMetric struct { - // ID is the channelz id of this socket. - ID int64 - // RefName is the human readable reference string of this socket. - RefName string - // SocketData contains socket internal metric reported by the socket through - // ChannelzMetric(). - SocketData *SocketInternalMetric -} - -// SocketInternalMetric defines the struct that the implementor of Socket interface -// should return from ChannelzMetric(). -type SocketInternalMetric struct { - // The number of streams that have been started. - StreamsStarted int64 - // The number of streams that have ended successfully: - // On client side, receiving frame with eos bit set. - // On server side, sending frame with eos bit set. - StreamsSucceeded int64 - // The number of streams that have ended unsuccessfully: - // On client side, termination without receiving frame with eos bit set. - // On server side, termination without sending frame with eos bit set. - StreamsFailed int64 - // The number of messages successfully sent on this socket. - MessagesSent int64 - MessagesReceived int64 - // The number of keep alives sent. This is typically implemented with HTTP/2 - // ping messages. - KeepAlivesSent int64 - // The last time a stream was created by this endpoint. Usually unset for - // servers. - LastLocalStreamCreatedTimestamp time.Time - // The last time a stream was created by the remote endpoint. Usually unset - // for clients. - LastRemoteStreamCreatedTimestamp time.Time - // The last time a message was sent by this endpoint. - LastMessageSentTimestamp time.Time - // The last time a message was received by this endpoint. - LastMessageReceivedTimestamp time.Time - // The amount of window, granted to the local endpoint by the remote endpoint. - // This may be slightly out of date due to network latency. This does NOT - // include stream level or TCP level flow control info. - LocalFlowControlWindow int64 - // The amount of window, granted to the remote endpoint by the local endpoint. - // This may be slightly out of date due to network latency. This does NOT - // include stream level or TCP level flow control info. - RemoteFlowControlWindow int64 - // The locally bound address. - LocalAddr net.Addr - // The remote bound address. May be absent. - RemoteAddr net.Addr - // Optional, represents the name of the remote endpoint, if different than - // the original target name. - RemoteName string - SocketOptions *SocketOptionData - Security credentials.ChannelzSecurityValue -} - -// Socket is the interface that should be satisfied in order to be tracked by -// channelz as Socket. -type Socket interface { - ChannelzMetric() *SocketInternalMetric -} - -type listenSocket struct { - refName string - s Socket - id int64 - pid int64 - cm *channelMap -} - -func (ls *listenSocket) addChild(id int64, e entry) { - logger.Errorf("cannot add a child (id = %d) of type %T to a listen socket", id, e) -} - -func (ls *listenSocket) deleteChild(id int64) { - logger.Errorf("cannot delete a child (id = %d) from a listen socket", id) -} - -func (ls *listenSocket) triggerDelete() { - ls.cm.deleteEntry(ls.id) - ls.cm.findEntry(ls.pid).deleteChild(ls.id) -} - -func (ls *listenSocket) deleteSelfIfReady() { - logger.Errorf("cannot call deleteSelfIfReady on a listen socket") -} - -func (ls *listenSocket) getParentID() int64 { - return ls.pid -} - -type normalSocket struct { - refName string - s Socket - id int64 - pid int64 - cm *channelMap -} - -func (ns *normalSocket) addChild(id int64, e entry) { - logger.Errorf("cannot add a child (id = %d) of type %T to a normal socket", id, e) -} - -func (ns *normalSocket) deleteChild(id int64) { - logger.Errorf("cannot delete a child (id = %d) from a normal socket", id) -} - -func (ns *normalSocket) triggerDelete() { - ns.cm.deleteEntry(ns.id) - ns.cm.findEntry(ns.pid).deleteChild(ns.id) -} - -func (ns *normalSocket) deleteSelfIfReady() { - logger.Errorf("cannot call deleteSelfIfReady on a normal socket") -} - -func (ns *normalSocket) getParentID() int64 { - return ns.pid -} - -// ServerMetric defines the info channelz provides for a specific Server, which -// includes ServerInternalMetric and channelz-specific data, such as channelz id, -// child list, etc. -type ServerMetric struct { - // ID is the channelz id of this server. - ID int64 - // RefName is the human readable reference string of this server. - RefName string - // ServerData contains server internal metric reported by the server through - // ChannelzMetric(). - ServerData *ServerInternalMetric - // ListenSockets tracks the listener socket type children of this server in the - // format of a map from socket channelz id to corresponding reference string. - ListenSockets map[int64]string -} - -// ServerInternalMetric defines the struct that the implementor of Server interface -// should return from ChannelzMetric(). -type ServerInternalMetric struct { - // The number of incoming calls started on the server. - CallsStarted int64 - // The number of incoming calls that have completed with an OK status. - CallsSucceeded int64 - // The number of incoming calls that have a completed with a non-OK status. - CallsFailed int64 - // The last time a call was started on the server. - LastCallStartedTimestamp time.Time -} - -// Server is the interface to be satisfied in order to be tracked by channelz as -// Server. -type Server interface { - ChannelzMetric() *ServerInternalMetric -} - -type server struct { - refName string - s Server - closeCalled bool - sockets map[int64]string - listenSockets map[int64]string - id int64 - cm *channelMap -} - -func (s *server) addChild(id int64, e entry) { - switch v := e.(type) { - case *normalSocket: - s.sockets[id] = v.refName - case *listenSocket: - s.listenSockets[id] = v.refName - default: - logger.Errorf("cannot add a child (id = %d) of type %T to a server", id, e) - } -} - -func (s *server) deleteChild(id int64) { - delete(s.sockets, id) - delete(s.listenSockets, id) - s.deleteSelfIfReady() -} - -func (s *server) triggerDelete() { - s.closeCalled = true - s.deleteSelfIfReady() -} - -func (s *server) deleteSelfIfReady() { - if !s.closeCalled || len(s.sockets)+len(s.listenSockets) != 0 { - return - } - s.cm.deleteEntry(s.id) -} - -func (s *server) getParentID() int64 { - return 0 -} - -type tracedChannel interface { - getChannelTrace() *channelTrace - incrTraceRefCount() - decrTraceRefCount() - getRefName() string -} - -type channelTrace struct { - cm *channelMap - clearCalled bool - createdTime time.Time - eventCount int64 - mu sync.Mutex - events []*TraceEvent -} - -func (c *channelTrace) append(e *TraceEvent) { - c.mu.Lock() - if len(c.events) == getMaxTraceEntry() { - del := c.events[0] - c.events = c.events[1:] - if del.RefID != 0 { - // start recursive cleanup in a goroutine to not block the call originated from grpc. - go func() { - // need to acquire c.cm.mu lock to call the unlocked attemptCleanup func. - c.cm.mu.Lock() - c.cm.decrTraceRefCount(del.RefID) - c.cm.mu.Unlock() - }() - } - } - e.Timestamp = time.Now() - c.events = append(c.events, e) - c.eventCount++ - c.mu.Unlock() -} - -func (c *channelTrace) clear() { - if c.clearCalled { - return - } - c.clearCalled = true - c.mu.Lock() - for _, e := range c.events { - if e.RefID != 0 { - // caller should have already held the c.cm.mu lock. - c.cm.decrTraceRefCount(e.RefID) - } - } - c.mu.Unlock() -} - -// Severity is the severity level of a trace event. -// The canonical enumeration of all valid values is here: -// https://github.com/grpc/grpc-proto/blob/9b13d199cc0d4703c7ea26c9c330ba695866eb23/grpc/channelz/v1/channelz.proto#L126. -type Severity int - -const ( - // CtUnknown indicates unknown severity of a trace event. - CtUnknown Severity = iota - // CtInfo indicates info level severity of a trace event. - CtInfo - // CtWarning indicates warning level severity of a trace event. - CtWarning - // CtError indicates error level severity of a trace event. - CtError -) - -// RefChannelType is the type of the entity being referenced in a trace event. -type RefChannelType int - -const ( - // RefUnknown indicates an unknown entity type, the zero value for this type. - RefUnknown RefChannelType = iota - // RefChannel indicates the referenced entity is a Channel. - RefChannel - // RefSubChannel indicates the referenced entity is a SubChannel. - RefSubChannel - // RefServer indicates the referenced entity is a Server. - RefServer - // RefListenSocket indicates the referenced entity is a ListenSocket. - RefListenSocket - // RefNormalSocket indicates the referenced entity is a NormalSocket. - RefNormalSocket -) - -var refChannelTypeToString = map[RefChannelType]string{ - RefUnknown: "Unknown", - RefChannel: "Channel", - RefSubChannel: "SubChannel", - RefServer: "Server", - RefListenSocket: "ListenSocket", - RefNormalSocket: "NormalSocket", -} - -func (r RefChannelType) String() string { - return refChannelTypeToString[r] -} - -func (c *channelTrace) dumpData() *ChannelTrace { - c.mu.Lock() - ct := &ChannelTrace{EventNum: c.eventCount, CreationTime: c.createdTime} - ct.Events = c.events[:len(c.events)] - c.mu.Unlock() - return ct -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go deleted file mode 100644 index 98288c3f..00000000 --- a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -import ( - "syscall" -) - -// GetSocketOption gets the socket option info of the conn. -func GetSocketOption(socket any) *SocketOptionData { - c, ok := socket.(syscall.Conn) - if !ok { - return nil - } - data := &SocketOptionData{} - if rawConn, err := c.SyscallConn(); err == nil { - rawConn.Control(data.Getsockopt) - return data - } - return nil -} diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go deleted file mode 100644 index b5568b22..00000000 --- a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go +++ /dev/null @@ -1,27 +0,0 @@ -//go:build !linux -// +build !linux - -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package channelz - -// GetSocketOption gets the socket option info of the conn. -func GetSocketOption(c any) *SocketOptionData { - return nil -} diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index 6c7ea6a5..48d24bdb 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -190,12 +190,16 @@ var ( // function makes events more predictable than relying on timer events. TriggerXDSResourceNameNotFoundForTesting any // func(func(xdsresource.Type, string), string, string) error - // TriggerXDSResourceNotFoundClient invokes the testing xDS Client singleton - // to invoke resource not found for a resource type name and resource name. + // TriggerXDSResourceNameNotFoundClient invokes the testing xDS Client + // singleton to invoke resource not found for a resource type name and + // resource name. TriggerXDSResourceNameNotFoundClient any // func(string, string) error // FromOutgoingContextRaw returns the un-merged, intermediary contents of metadata.rawMD. FromOutgoingContextRaw any // func(context.Context) (metadata.MD, [][]string, bool) + + // UserSetDefaultScheme is set to true if the user has overridden the default resolver scheme. + UserSetDefaultScheme bool = false ) // HealthChecker defines the signature of the client-side LB channel health checking function. diff --git a/vendor/google.golang.org/grpc/internal/pretty/pretty.go b/vendor/google.golang.org/grpc/internal/pretty/pretty.go index 52cfab1b..dbee7a60 100644 --- a/vendor/google.golang.org/grpc/internal/pretty/pretty.go +++ b/vendor/google.golang.org/grpc/internal/pretty/pretty.go @@ -24,9 +24,8 @@ import ( "encoding/json" "fmt" - protov1 "github.com/golang/protobuf/proto" "google.golang.org/protobuf/encoding/protojson" - protov2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/protoadapt" ) const jsonIndent = " " @@ -35,21 +34,14 @@ const jsonIndent = " " // // If marshal fails, it falls back to fmt.Sprintf("%+v"). func ToJSON(e any) string { - switch ee := e.(type) { - case protov1.Message: - mm := protojson.MarshalOptions{Indent: jsonIndent} - ret, err := mm.Marshal(protov1.MessageV2(ee)) - if err != nil { - // This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2 - // messages are not imported, and this will fail because the message - // is not found. - return fmt.Sprintf("%+v", ee) - } - return string(ret) - case protov2.Message: + if ee, ok := e.(protoadapt.MessageV1); ok { + e = protoadapt.MessageV2Of(ee) + } + + if ee, ok := e.(protoadapt.MessageV2); ok { mm := protojson.MarshalOptions{ - Multiline: true, Indent: jsonIndent, + Multiline: true, } ret, err := mm.Marshal(ee) if err != nil { @@ -59,13 +51,13 @@ func ToJSON(e any) string { return fmt.Sprintf("%+v", ee) } return string(ret) - default: - ret, err := json.MarshalIndent(ee, "", jsonIndent) - if err != nil { - return fmt.Sprintf("%+v", ee) - } - return string(ret) } + + ret, err := json.MarshalIndent(e, "", jsonIndent) + if err != nil { + return fmt.Sprintf("%+v", e) + } + return string(ret) } // FormatJSON formats the input json bytes with indentation. diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index b66dcb21..abab35e2 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -45,6 +45,13 @@ import ( // addresses from SRV records. Must not be changed after init time. var EnableSRVLookups = false +// ResolvingTimeout specifies the maximum duration for a DNS resolution request. +// If the timeout expires before a response is received, the request will be canceled. +// +// It is recommended to set this value at application startup. Avoid modifying this variable +// after initialization as it's not thread-safe for concurrent modification. +var ResolvingTimeout = 30 * time.Second + var logger = grpclog.Component("dns") func init() { @@ -221,18 +228,18 @@ func (d *dnsResolver) watcher() { } } -func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) { +func (d *dnsResolver) lookupSRV(ctx context.Context) ([]resolver.Address, error) { if !EnableSRVLookups { return nil, nil } var newAddrs []resolver.Address - _, srvs, err := d.resolver.LookupSRV(d.ctx, "grpclb", "tcp", d.host) + _, srvs, err := d.resolver.LookupSRV(ctx, "grpclb", "tcp", d.host) if err != nil { err = handleDNSError(err, "SRV") // may become nil return nil, err } for _, s := range srvs { - lbAddrs, err := d.resolver.LookupHost(d.ctx, s.Target) + lbAddrs, err := d.resolver.LookupHost(ctx, s.Target) if err != nil { err = handleDNSError(err, "A") // may become nil if err == nil { @@ -269,8 +276,8 @@ func handleDNSError(err error, lookupType string) error { return err } -func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult { - ss, err := d.resolver.LookupTXT(d.ctx, txtPrefix+d.host) +func (d *dnsResolver) lookupTXT(ctx context.Context) *serviceconfig.ParseResult { + ss, err := d.resolver.LookupTXT(ctx, txtPrefix+d.host) if err != nil { if envconfig.TXTErrIgnore { return nil @@ -297,8 +304,8 @@ func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult { return d.cc.ParseServiceConfig(sc) } -func (d *dnsResolver) lookupHost() ([]resolver.Address, error) { - addrs, err := d.resolver.LookupHost(d.ctx, d.host) +func (d *dnsResolver) lookupHost(ctx context.Context) ([]resolver.Address, error) { + addrs, err := d.resolver.LookupHost(ctx, d.host) if err != nil { err = handleDNSError(err, "A") return nil, err @@ -316,8 +323,10 @@ func (d *dnsResolver) lookupHost() ([]resolver.Address, error) { } func (d *dnsResolver) lookup() (*resolver.State, error) { - srv, srvErr := d.lookupSRV() - addrs, hostErr := d.lookupHost() + ctx, cancel := context.WithTimeout(d.ctx, ResolvingTimeout) + defer cancel() + srv, srvErr := d.lookupSRV(ctx) + addrs, hostErr := d.lookupHost(ctx) if hostErr != nil && (srvErr != nil || len(srv) == 0) { return nil, hostErr } @@ -327,7 +336,7 @@ func (d *dnsResolver) lookup() (*resolver.State, error) { state = grpclbstate.Set(state, &grpclbstate.State{BalancerAddresses: srv}) } if !d.disableServiceConfig { - state.ServiceConfig = d.lookupTXT() + state.ServiceConfig = d.lookupTXT(ctx) } return &state, nil } diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index bd39ff9a..4a3ddce2 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -51,14 +51,10 @@ import ( // inside an http.Handler, or writes an HTTP error to w and returns an error. // It requires that the http Server supports HTTP/2. func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []stats.Handler) (ServerTransport, error) { - if r.ProtoMajor != 2 { - msg := "gRPC requires HTTP/2" - http.Error(w, msg, http.StatusBadRequest) - return nil, errors.New(msg) - } - if r.Method != "POST" { + if r.Method != http.MethodPost { + w.Header().Set("Allow", http.MethodPost) msg := fmt.Sprintf("invalid gRPC request method %q", r.Method) - http.Error(w, msg, http.StatusBadRequest) + http.Error(w, msg, http.StatusMethodNotAllowed) return nil, errors.New(msg) } contentType := r.Header.Get("Content-Type") @@ -69,6 +65,11 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s http.Error(w, msg, http.StatusUnsupportedMediaType) return nil, errors.New(msg) } + if r.ProtoMajor != 2 { + msg := "gRPC requires HTTP/2" + http.Error(w, msg, http.StatusHTTPVersionNotSupported) + return nil, errors.New(msg) + } if _, ok := w.(http.Flusher); !ok { msg := "gRPC requires a ResponseWriter supporting http.Flusher" http.Error(w, msg, http.StatusInternalServerError) diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index eff87996..deba0c4d 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -140,9 +140,7 @@ type http2Client struct { // variable. kpDormant bool - // Fields below are for channelz metric collection. - channelzID *channelz.Identifier - czData *channelzData + channelz *channelz.Socket onClose func(GoAwayReason) @@ -319,6 +317,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts if opts.MaxHeaderListSize != nil { maxHeaderListSize = *opts.MaxHeaderListSize } + t := &http2Client{ ctx: ctx, ctxDone: ctx.Done(), // Cache Done chan. @@ -346,11 +345,25 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts maxConcurrentStreams: defaultMaxStreamsClient, streamQuota: defaultMaxStreamsClient, streamsQuotaAvailable: make(chan struct{}, 1), - czData: new(channelzData), keepaliveEnabled: keepaliveEnabled, bufferPool: newBufferPool(), onClose: onClose, } + var czSecurity credentials.ChannelzSecurityValue + if au, ok := authInfo.(credentials.ChannelzSecurityInfo); ok { + czSecurity = au.GetSecurityValue() + } + t.channelz = channelz.RegisterSocket( + &channelz.Socket{ + SocketType: channelz.SocketTypeNormal, + Parent: opts.ChannelzParent, + SocketMetrics: channelz.SocketMetrics{}, + EphemeralMetrics: t.socketMetrics, + LocalAddr: t.localAddr, + RemoteAddr: t.remoteAddr, + SocketOptions: channelz.GetSocketOption(t.conn), + Security: czSecurity, + }) t.logger = prefixLoggerForClientTransport(t) // Add peer information to the http2client context. t.ctx = peer.NewContext(t.ctx, t.getPeer()) @@ -381,10 +394,6 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } sh.HandleConn(t.ctx, connBegin) } - t.channelzID, err = channelz.RegisterNormalSocket(t, opts.ChannelzParentID, fmt.Sprintf("%s -> %s", t.localAddr, t.remoteAddr)) - if err != nil { - return nil, err - } if t.keepaliveEnabled { t.kpDormancyCond = sync.NewCond(&t.mu) go t.keepalive() @@ -756,8 +765,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return ErrConnClosing } if channelz.IsOn() { - atomic.AddInt64(&t.czData.streamsStarted, 1) - atomic.StoreInt64(&t.czData.lastStreamCreatedTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.StreamsStarted.Add(1) + t.channelz.SocketMetrics.LastLocalStreamCreatedTimestamp.Store(time.Now().UnixNano()) } // If the keepalive goroutine has gone dormant, wake it up. if t.kpDormant { @@ -928,9 +937,9 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. t.mu.Unlock() if channelz.IsOn() { if eosReceived { - atomic.AddInt64(&t.czData.streamsSucceeded, 1) + t.channelz.SocketMetrics.StreamsSucceeded.Add(1) } else { - atomic.AddInt64(&t.czData.streamsFailed, 1) + t.channelz.SocketMetrics.StreamsFailed.Add(1) } } }, @@ -985,7 +994,7 @@ func (t *http2Client) Close(err error) { t.controlBuf.finish() t.cancel() t.conn.Close() - channelz.RemoveEntry(t.channelzID) + channelz.RemoveEntry(t.channelz.ID) // Append info about previous goaways if there were any, since this may be important // for understanding the root cause for this connection to be closed. _, goAwayDebugMessage := t.GetGoAwayReason() @@ -1708,7 +1717,7 @@ func (t *http2Client) keepalive() { // keepalive timer expired. In both cases, we need to send a ping. if !outstandingPing { if channelz.IsOn() { - atomic.AddInt64(&t.czData.kpCount, 1) + t.channelz.SocketMetrics.KeepAlivesSent.Add(1) } t.controlBuf.put(p) timeoutLeft = t.kp.Timeout @@ -1738,40 +1747,23 @@ func (t *http2Client) GoAway() <-chan struct{} { return t.goAway } -func (t *http2Client) ChannelzMetric() *channelz.SocketInternalMetric { - s := channelz.SocketInternalMetric{ - StreamsStarted: atomic.LoadInt64(&t.czData.streamsStarted), - StreamsSucceeded: atomic.LoadInt64(&t.czData.streamsSucceeded), - StreamsFailed: atomic.LoadInt64(&t.czData.streamsFailed), - MessagesSent: atomic.LoadInt64(&t.czData.msgSent), - MessagesReceived: atomic.LoadInt64(&t.czData.msgRecv), - KeepAlivesSent: atomic.LoadInt64(&t.czData.kpCount), - LastLocalStreamCreatedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastStreamCreatedTime)), - LastMessageSentTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgSentTime)), - LastMessageReceivedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgRecvTime)), - LocalFlowControlWindow: int64(t.fc.getSize()), - SocketOptions: channelz.GetSocketOption(t.conn), - LocalAddr: t.localAddr, - RemoteAddr: t.remoteAddr, - // RemoteName : - } - if au, ok := t.authInfo.(credentials.ChannelzSecurityInfo); ok { - s.Security = au.GetSecurityValue() - } - s.RemoteFlowControlWindow = t.getOutFlowWindow() - return &s +func (t *http2Client) socketMetrics() *channelz.EphemeralSocketMetrics { + return &channelz.EphemeralSocketMetrics{ + LocalFlowControlWindow: int64(t.fc.getSize()), + RemoteFlowControlWindow: t.getOutFlowWindow(), + } } func (t *http2Client) RemoteAddr() net.Addr { return t.remoteAddr } func (t *http2Client) IncrMsgSent() { - atomic.AddInt64(&t.czData.msgSent, 1) - atomic.StoreInt64(&t.czData.lastMsgSentTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.MessagesSent.Add(1) + t.channelz.SocketMetrics.LastMessageSentTimestamp.Store(time.Now().UnixNano()) } func (t *http2Client) IncrMsgRecv() { - atomic.AddInt64(&t.czData.msgRecv, 1) - atomic.StoreInt64(&t.czData.lastMsgRecvTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.MessagesReceived.Add(1) + t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Store(time.Now().UnixNano()) } func (t *http2Client) getOutFlowWindow() int64 { diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index 3839c1ad..d582e047 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -118,8 +118,7 @@ type http2Server struct { idle time.Time // Fields below are for channelz metric collection. - channelzID *channelz.Identifier - czData *channelzData + channelz *channelz.Socket bufferPool *bufferPool connectionID uint64 @@ -262,9 +261,24 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, idle: time.Now(), kep: kep, initialWindowSize: iwz, - czData: new(channelzData), bufferPool: newBufferPool(), } + var czSecurity credentials.ChannelzSecurityValue + if au, ok := authInfo.(credentials.ChannelzSecurityInfo); ok { + czSecurity = au.GetSecurityValue() + } + t.channelz = channelz.RegisterSocket( + &channelz.Socket{ + SocketType: channelz.SocketTypeNormal, + Parent: config.ChannelzParent, + SocketMetrics: channelz.SocketMetrics{}, + EphemeralMetrics: t.socketMetrics, + LocalAddr: t.peer.LocalAddr, + RemoteAddr: t.peer.Addr, + SocketOptions: channelz.GetSocketOption(t.conn), + Security: czSecurity, + }, + ) t.logger = prefixLoggerForServerTransport(t) t.controlBuf = newControlBuffer(t.done) @@ -274,10 +288,6 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, updateFlowControl: t.updateFlowControl, } } - t.channelzID, err = channelz.RegisterNormalSocket(t, config.ChannelzParentID, fmt.Sprintf("%s -> %s", t.peer.Addr, t.peer.LocalAddr)) - if err != nil { - return nil, err - } t.connectionID = atomic.AddUint64(&serverConnectionCounter, 1) t.framer.writer.Flush() @@ -334,9 +344,11 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, // closed, would lead to a TCP RST instead of FIN, and the client // encountering errors. For more info: // https://github.com/grpc/grpc-go/issues/5358 + timer := time.NewTimer(time.Second) + defer timer.Stop() select { case <-t.readerDone: - case <-time.After(time.Second): + case <-timer.C: } t.conn.Close() } @@ -592,8 +604,8 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade } t.mu.Unlock() if channelz.IsOn() { - atomic.AddInt64(&t.czData.streamsStarted, 1) - atomic.StoreInt64(&t.czData.lastStreamCreatedTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.StreamsStarted.Add(1) + t.channelz.SocketMetrics.LastRemoteStreamCreatedTimestamp.Store(time.Now().UnixNano()) } s.requestRead = func(n int) { t.adjustWindow(s, uint32(n)) @@ -658,8 +670,14 @@ func (t *http2Server) HandleStreams(ctx context.Context, handle func(*Stream)) { switch frame := frame.(type) { case *http2.MetaHeadersFrame: if err := t.operateHeaders(ctx, frame, handle); err != nil { - t.Close(err) - break + // Any error processing client headers, e.g. invalid stream ID, + // is considered a protocol violation. + t.controlBuf.put(&goAway{ + code: http2.ErrCodeProtocol, + debugData: []byte(err.Error()), + closeConn: err, + }) + continue } case *http2.DataFrame: t.handleData(frame) @@ -1195,7 +1213,7 @@ func (t *http2Server) keepalive() { } if !outstandingPing { if channelz.IsOn() { - atomic.AddInt64(&t.czData.kpCount, 1) + t.channelz.SocketMetrics.KeepAlivesSent.Add(1) } t.controlBuf.put(p) kpTimeoutLeft = t.kp.Timeout @@ -1235,7 +1253,7 @@ func (t *http2Server) Close(err error) { if err := t.conn.Close(); err != nil && t.logger.V(logLevel) { t.logger.Infof("Error closing underlying net.Conn during Close: %v", err) } - channelz.RemoveEntry(t.channelzID) + channelz.RemoveEntry(t.channelz.ID) // Cancel all active streams. for _, s := range streams { s.cancel() @@ -1256,9 +1274,9 @@ func (t *http2Server) deleteStream(s *Stream, eosReceived bool) { if channelz.IsOn() { if eosReceived { - atomic.AddInt64(&t.czData.streamsSucceeded, 1) + t.channelz.SocketMetrics.StreamsSucceeded.Add(1) } else { - atomic.AddInt64(&t.czData.streamsFailed, 1) + t.channelz.SocketMetrics.StreamsFailed.Add(1) } } } @@ -1375,38 +1393,21 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { return false, nil } -func (t *http2Server) ChannelzMetric() *channelz.SocketInternalMetric { - s := channelz.SocketInternalMetric{ - StreamsStarted: atomic.LoadInt64(&t.czData.streamsStarted), - StreamsSucceeded: atomic.LoadInt64(&t.czData.streamsSucceeded), - StreamsFailed: atomic.LoadInt64(&t.czData.streamsFailed), - MessagesSent: atomic.LoadInt64(&t.czData.msgSent), - MessagesReceived: atomic.LoadInt64(&t.czData.msgRecv), - KeepAlivesSent: atomic.LoadInt64(&t.czData.kpCount), - LastRemoteStreamCreatedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastStreamCreatedTime)), - LastMessageSentTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgSentTime)), - LastMessageReceivedTimestamp: time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgRecvTime)), - LocalFlowControlWindow: int64(t.fc.getSize()), - SocketOptions: channelz.GetSocketOption(t.conn), - LocalAddr: t.peer.LocalAddr, - RemoteAddr: t.peer.Addr, - // RemoteName : - } - if au, ok := t.peer.AuthInfo.(credentials.ChannelzSecurityInfo); ok { - s.Security = au.GetSecurityValue() - } - s.RemoteFlowControlWindow = t.getOutFlowWindow() - return &s +func (t *http2Server) socketMetrics() *channelz.EphemeralSocketMetrics { + return &channelz.EphemeralSocketMetrics{ + LocalFlowControlWindow: int64(t.fc.getSize()), + RemoteFlowControlWindow: t.getOutFlowWindow(), + } } func (t *http2Server) IncrMsgSent() { - atomic.AddInt64(&t.czData.msgSent, 1) - atomic.StoreInt64(&t.czData.lastMsgSentTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.MessagesSent.Add(1) + t.channelz.SocketMetrics.LastMessageSentTimestamp.Add(1) } func (t *http2Server) IncrMsgRecv() { - atomic.AddInt64(&t.czData.msgRecv, 1) - atomic.StoreInt64(&t.czData.lastMsgRecvTime, time.Now().UnixNano()) + t.channelz.SocketMetrics.MessagesReceived.Add(1) + t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Add(1) } func (t *http2Server) getOutFlowWindow() int64 { diff --git a/vendor/google.golang.org/grpc/internal/transport/http_util.go b/vendor/google.golang.org/grpc/internal/transport/http_util.go index dc29d590..39cef3bd 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http_util.go +++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -418,10 +418,9 @@ func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, sharedWriteBu return f } -func getWriteBufferPool(writeBufferSize int) *sync.Pool { +func getWriteBufferPool(size int) *sync.Pool { writeBufferMutex.Lock() defer writeBufferMutex.Unlock() - size := writeBufferSize * 2 pool, ok := writeBufferPoolMap[size] if ok { return pool diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index d3796c25..0d2a6e47 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -571,7 +571,7 @@ type ServerConfig struct { WriteBufferSize int ReadBufferSize int SharedWriteBuffer bool - ChannelzParentID *channelz.Identifier + ChannelzParent *channelz.Server MaxHeaderListSize *uint32 HeaderTableSize *uint32 } @@ -606,8 +606,8 @@ type ConnectOptions struct { ReadBufferSize int // SharedWriteBuffer indicates whether connections should reuse write buffer SharedWriteBuffer bool - // ChannelzParentID sets the addrConn id which initiate the creation of this client transport. - ChannelzParentID *channelz.Identifier + // ChannelzParent sets the addrConn id which initiated the creation of this client transport. + ChannelzParent *channelz.SubChannel // MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received. MaxHeaderListSize *uint32 // UseProxy specifies if a proxy should be used. @@ -820,30 +820,6 @@ const ( GoAwayTooManyPings GoAwayReason = 2 ) -// channelzData is used to store channelz related data for http2Client and http2Server. -// These fields cannot be embedded in the original structs (e.g. http2Client), since to do atomic -// operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment. -// Here, by grouping those int64 fields inside a struct, we are enforcing the alignment. -type channelzData struct { - kpCount int64 - // The number of streams that have started, including already finished ones. - streamsStarted int64 - // Client side: The number of streams that have ended successfully by receiving - // EoS bit set frame from server. - // Server side: The number of streams that have ended successfully by sending - // frame with EoS bit set. - streamsSucceeded int64 - streamsFailed int64 - // lastStreamCreatedTime stores the timestamp that the last stream gets created. It is of int64 type - // instead of time.Time since it's more costly to atomically update time.Time variable than int64 - // variable. The same goes for lastMsgSentTime and lastMsgRecvTime. - lastStreamCreatedTime int64 - msgSent int64 - msgRecv int64 - lastMsgSentTime int64 - lastMsgRecvTime int64 -} - // ContextErr converts the error from context package into a status error. func ContextErr(err error) error { switch err { diff --git a/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go b/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go deleted file mode 100644 index e8b49277..00000000 --- a/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package internal - -import ( - "google.golang.org/grpc/attributes" - "google.golang.org/grpc/resolver" -) - -// handshakeClusterNameKey is the type used as the key to store cluster name in -// the Attributes field of resolver.Address. -type handshakeClusterNameKey struct{} - -// SetXDSHandshakeClusterName returns a copy of addr in which the Attributes field -// is updated with the cluster name. -func SetXDSHandshakeClusterName(addr resolver.Address, clusterName string) resolver.Address { - addr.Attributes = addr.Attributes.WithValue(handshakeClusterNameKey{}, clusterName) - return addr -} - -// GetXDSHandshakeClusterName returns cluster name stored in attr. -func GetXDSHandshakeClusterName(attr *attributes.Attributes) (string, bool) { - v := attr.Value(handshakeClusterNameKey{}) - name, ok := v.(string) - return name, ok -} diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/pickfirst.go index 5128f936..e3ea42ba 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/pickfirst.go @@ -38,19 +38,15 @@ const ( logPrefix = "[pick-first-lb %p] " ) -func newPickfirstBuilder() balancer.Builder { - return &pickfirstBuilder{} -} - type pickfirstBuilder struct{} -func (*pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { +func (pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { b := &pickfirstBalancer{cc: cc} b.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf(logPrefix, b)) return b } -func (*pickfirstBuilder) Name() string { +func (pickfirstBuilder) Name() string { return PickFirstBalancerName } @@ -63,7 +59,7 @@ type pfConfig struct { ShuffleAddressList bool `json:"shuffleAddressList"` } -func (*pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { +func (pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { var cfg pfConfig if err := json.Unmarshal(js, &cfg); err != nil { return nil, fmt.Errorf("pickfirst: unable to unmarshal LB policy config: %s, error: %v", string(js), err) @@ -243,7 +239,3 @@ func (i *idlePicker) Pick(balancer.PickInfo) (balancer.PickResult, error) { i.subConn.Connect() return balancer.PickResult{}, balancer.ErrNoSubConnAvailable } - -func init() { - balancer.Register(newPickfirstBuilder()) -} diff --git a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go index 14aa6f20..b54a3a32 100644 --- a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go @@ -24,10 +24,28 @@ package dns import ( + "time" + "google.golang.org/grpc/internal/resolver/dns" "google.golang.org/grpc/resolver" ) +// SetResolvingTimeout sets the maximum duration for DNS resolution requests. +// +// This function affects the global timeout used by all channels using the DNS +// name resolver scheme. +// +// It must be called only at application startup, before any gRPC calls are +// made. Modifying this value after initialization is not thread-safe. +// +// The default value is 30 seconds. Setting the timeout too low may result in +// premature timeouts during resolution, while setting it too high may lead to +// unnecessary delays in service discovery. Choose a value appropriate for your +// specific needs and network environment. +func SetResolvingTimeout(timeout time.Duration) { + dns.ResolvingTimeout = timeout +} + // NewBuilder creates a dnsBuilder which is used to factory DNS resolvers. // // Deprecated: import grpc and use resolver.Get("dns") instead. diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index d72f21c1..20285451 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -29,6 +29,7 @@ import ( "google.golang.org/grpc/attributes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/internal" "google.golang.org/grpc/serviceconfig" ) @@ -63,16 +64,18 @@ func Get(scheme string) Builder { } // SetDefaultScheme sets the default scheme that will be used. The default -// default scheme is "passthrough". +// scheme is initially set to "passthrough". // // NOTE: this function must only be called during initialization time (i.e. in // an init() function), and is not thread-safe. The scheme set last overrides // previously set values. func SetDefaultScheme(scheme string) { defaultScheme = scheme + internal.UserSetDefaultScheme = true } -// GetDefaultScheme gets the default scheme that will be used. +// GetDefaultScheme gets the default scheme that will be used by grpc.Dial. If +// SetDefaultScheme is never called, the default scheme used by grpc.NewClient is "dns" instead. func GetDefaultScheme() string { return defaultScheme } @@ -284,9 +287,9 @@ func (t Target) Endpoint() string { return strings.TrimPrefix(endpoint, "/") } -// String returns a string representation of Target. +// String returns the canonical string representation of Target. func (t Target) String() string { - return t.URL.String() + return t.URL.Scheme + "://" + t.URL.Host + "/" + t.Endpoint() } // Builder creates a resolver that will be used to watch name resolution updates. diff --git a/vendor/google.golang.org/grpc/resolver_wrapper.go b/vendor/google.golang.org/grpc/resolver_wrapper.go index f845ac95..9dcc9780 100644 --- a/vendor/google.golang.org/grpc/resolver_wrapper.go +++ b/vendor/google.golang.org/grpc/resolver_wrapper.go @@ -97,7 +97,7 @@ func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) { // finished shutting down, the channel should block on ccr.serializer.Done() // without cc.mu held. func (ccr *ccResolverWrapper) close() { - channelz.Info(logger, ccr.cc.channelzID, "Closing the name resolver") + channelz.Info(logger, ccr.cc.channelz, "Closing the name resolver") ccr.mu.Lock() ccr.closed = true ccr.mu.Unlock() @@ -147,7 +147,7 @@ func (ccr *ccResolverWrapper) ReportError(err error) { return } ccr.mu.Unlock() - channelz.Warningf(logger, ccr.cc.channelzID, "ccResolverWrapper: reporting error to cc: %v", err) + channelz.Warningf(logger, ccr.cc.channelz, "ccResolverWrapper: reporting error to cc: %v", err) ccr.cc.updateResolverStateAndUnlock(resolver.State{}, err) } @@ -194,5 +194,5 @@ func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { } else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 { updates = append(updates, "resolver returned new addresses") } - channelz.Infof(logger, ccr.cc.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; ")) + channelz.Infof(logger, ccr.cc.channelz, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; ")) } diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 82493d23..998e251d 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -962,19 +962,6 @@ func setCallInfoCodec(c *callInfo) error { return nil } -// channelzData is used to store channelz related data for ClientConn, addrConn and Server. -// These fields cannot be embedded in the original structs (e.g. ClientConn), since to do atomic -// operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment. -// Here, by grouping those int64 fields inside a struct, we are enforcing the alignment. -type channelzData struct { - callsStarted int64 - callsFailed int64 - callsSucceeded int64 - // lastCallStartedTime stores the timestamp that last call starts. It is of int64 type instead of - // time.Time since it's more costly to atomically update time.Time variable than int64 variable. - lastCallStartedTime int64 -} - // The SupportPackageIsVersion variables are referenced from generated protocol // buffer files to ensure compatibility with the gRPC version used. The latest // support package version is 7. diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index a6a11704..fd4558da 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -137,8 +137,7 @@ type Server struct { serveWG sync.WaitGroup // counts active Serve goroutines for Stop/GracefulStop handlersWG sync.WaitGroup // counts active method handler goroutines - channelzID *channelz.Identifier - czData *channelzData + channelz *channelz.Server serverWorkerChannel chan func() serverWorkerChannelClose func() @@ -249,11 +248,9 @@ func SharedWriteBuffer(val bool) ServerOption { } // WriteBufferSize determines how much data can be batched before doing a write -// on the wire. The corresponding memory allocation for this buffer will be -// twice the size to keep syscalls low. The default value for this buffer is -// 32KB. Zero or negative values will disable the write buffer such that each -// write will be on underlying connection. -// Note: A Send call may not directly translate to a write. +// on the wire. The default value for this buffer is 32KB. Zero or negative +// values will disable the write buffer such that each write will be on underlying +// connection. Note: A Send call may not directly translate to a write. func WriteBufferSize(s int) ServerOption { return newFuncServerOption(func(o *serverOptions) { o.writeBufferSize = s @@ -661,7 +658,7 @@ func NewServer(opt ...ServerOption) *Server { services: make(map[string]*serviceInfo), quit: grpcsync.NewEvent(), done: grpcsync.NewEvent(), - czData: new(channelzData), + channelz: channelz.RegisterServer(""), } chainUnaryServerInterceptors(s) chainStreamServerInterceptors(s) @@ -675,8 +672,7 @@ func NewServer(opt ...ServerOption) *Server { s.initServerWorkers() } - s.channelzID = channelz.RegisterServer(&channelzServer{s}, "") - channelz.Info(logger, s.channelzID, "Server created") + channelz.Info(logger, s.channelz, "Server created") return s } @@ -802,20 +798,13 @@ var ErrServerStopped = errors.New("grpc: the server has been stopped") type listenSocket struct { net.Listener - channelzID *channelz.Identifier -} - -func (l *listenSocket) ChannelzMetric() *channelz.SocketInternalMetric { - return &channelz.SocketInternalMetric{ - SocketOptions: channelz.GetSocketOption(l.Listener), - LocalAddr: l.Listener.Addr(), - } + channelz *channelz.Socket } func (l *listenSocket) Close() error { err := l.Listener.Close() - channelz.RemoveEntry(l.channelzID) - channelz.Info(logger, l.channelzID, "ListenSocket deleted") + channelz.RemoveEntry(l.channelz.ID) + channelz.Info(logger, l.channelz, "ListenSocket deleted") return err } @@ -857,7 +846,16 @@ func (s *Server) Serve(lis net.Listener) error { } }() - ls := &listenSocket{Listener: lis} + ls := &listenSocket{ + Listener: lis, + channelz: channelz.RegisterSocket(&channelz.Socket{ + SocketType: channelz.SocketTypeListen, + Parent: s.channelz, + RefName: lis.Addr().String(), + LocalAddr: lis.Addr(), + SocketOptions: channelz.GetSocketOption(lis)}, + ), + } s.lis[ls] = true defer func() { @@ -869,14 +867,8 @@ func (s *Server) Serve(lis net.Listener) error { s.mu.Unlock() }() - var err error - ls.channelzID, err = channelz.RegisterListenSocket(ls, s.channelzID, lis.Addr().String()) - if err != nil { - s.mu.Unlock() - return err - } s.mu.Unlock() - channelz.Info(logger, ls.channelzID, "ListenSocket created") + channelz.Info(logger, ls.channelz, "ListenSocket created") var tempDelay time.Duration // how long to sleep on accept failure for { @@ -975,7 +967,7 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { WriteBufferSize: s.opts.writeBufferSize, ReadBufferSize: s.opts.readBufferSize, SharedWriteBuffer: s.opts.sharedWriteBuffer, - ChannelzParentID: s.channelzID, + ChannelzParent: s.channelz, MaxHeaderListSize: s.opts.maxHeaderListSize, HeaderTableSize: s.opts.headerTableSize, } @@ -989,7 +981,7 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { if err != credentials.ErrConnDispatched { // Don't log on ErrConnDispatched and io.EOF to prevent log spam. if err != io.EOF { - channelz.Info(logger, s.channelzID, "grpc: Server.Serve failed to create ServerTransport: ", err) + channelz.Info(logger, s.channelz, "grpc: Server.Serve failed to create ServerTransport: ", err) } c.Close() } @@ -1121,37 +1113,28 @@ func (s *Server) removeConn(addr string, st transport.ServerTransport) { } } -func (s *Server) channelzMetric() *channelz.ServerInternalMetric { - return &channelz.ServerInternalMetric{ - CallsStarted: atomic.LoadInt64(&s.czData.callsStarted), - CallsSucceeded: atomic.LoadInt64(&s.czData.callsSucceeded), - CallsFailed: atomic.LoadInt64(&s.czData.callsFailed), - LastCallStartedTimestamp: time.Unix(0, atomic.LoadInt64(&s.czData.lastCallStartedTime)), - } -} - func (s *Server) incrCallsStarted() { - atomic.AddInt64(&s.czData.callsStarted, 1) - atomic.StoreInt64(&s.czData.lastCallStartedTime, time.Now().UnixNano()) + s.channelz.ServerMetrics.CallsStarted.Add(1) + s.channelz.ServerMetrics.LastCallStartedTimestamp.Store(time.Now().UnixNano()) } func (s *Server) incrCallsSucceeded() { - atomic.AddInt64(&s.czData.callsSucceeded, 1) + s.channelz.ServerMetrics.CallsSucceeded.Add(1) } func (s *Server) incrCallsFailed() { - atomic.AddInt64(&s.czData.callsFailed, 1) + s.channelz.ServerMetrics.CallsFailed.Add(1) } func (s *Server) sendResponse(ctx context.Context, t transport.ServerTransport, stream *transport.Stream, msg any, cp Compressor, opts *transport.Options, comp encoding.Compressor) error { data, err := encode(s.getCodec(stream.ContentSubtype()), msg) if err != nil { - channelz.Error(logger, s.channelzID, "grpc: server failed to encode response: ", err) + channelz.Error(logger, s.channelz, "grpc: server failed to encode response: ", err) return err } compData, err := compress(data, cp, comp) if err != nil { - channelz.Error(logger, s.channelzID, "grpc: server failed to compress response: ", err) + channelz.Error(logger, s.channelz, "grpc: server failed to compress response: ", err) return err } hdr, payload := msgHeader(data, compData) @@ -1346,7 +1329,7 @@ func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTranspor d, cancel, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) if err != nil { if e := t.WriteStatus(stream, status.Convert(err)); e != nil { - channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) + channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) } return err } @@ -1397,7 +1380,7 @@ func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTranspor trInfo.tr.SetError() } if e := t.WriteStatus(stream, appStatus); e != nil { - channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) + channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) } if len(binlogs) != 0 { if h, _ := stream.Header(); h.Len() > 0 { @@ -1437,7 +1420,7 @@ func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTranspor } if sts, ok := status.FromError(err); ok { if e := t.WriteStatus(stream, sts); e != nil { - channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) + channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) } } else { switch st := err.(type) { @@ -1765,7 +1748,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str ti.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) ti.tr.SetError() } - channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err) + channelz.Warningf(logger, s.channelz, "grpc: Server.handleStream failed to write status: %v", err) } if ti != nil { ti.tr.Finish() @@ -1822,7 +1805,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str ti.tr.LazyLog(&fmtStringer{"%v", []any{err}}, true) ti.tr.SetError() } - channelz.Warningf(logger, s.channelzID, "grpc: Server.handleStream failed to write status: %v", err) + channelz.Warningf(logger, s.channelz, "grpc: Server.handleStream failed to write status: %v", err) } if ti != nil { ti.tr.Finish() @@ -1894,8 +1877,7 @@ func (s *Server) stop(graceful bool) { s.quit.Fire() defer s.done.Fire() - s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelzID) }) - + s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelz.ID) }) s.mu.Lock() s.closeListenersLocked() // Wait for serving threads to be ready to exit. Only then can we be sure no @@ -2150,14 +2132,6 @@ func Method(ctx context.Context) (string, bool) { return s.Method(), true } -type channelzServer struct { - s *Server -} - -func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric { - return c.s.channelzMetric() -} - // validateSendCompressor returns an error when given compressor name cannot be // handled by the server or the client based on the advertised compressors. func validateSendCompressor(name string, clientCompressors []string) error { diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index 0df11fc0..2b35c5d2 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -25,8 +25,10 @@ import ( "reflect" "time" + "google.golang.org/grpc/balancer" "google.golang.org/grpc/codes" "google.golang.org/grpc/internal" + "google.golang.org/grpc/internal/balancer/gracefulswitch" internalserviceconfig "google.golang.org/grpc/internal/serviceconfig" "google.golang.org/grpc/serviceconfig" ) @@ -41,11 +43,6 @@ const maxInt = int(^uint(0) >> 1) // https://github.com/grpc/grpc/blob/master/doc/service_config.md type MethodConfig = internalserviceconfig.MethodConfig -type lbConfig struct { - name string - cfg serviceconfig.LoadBalancingConfig -} - // ServiceConfig is provided by the service provider and contains parameters for how // clients that connect to the service should behave. // @@ -55,14 +52,9 @@ type lbConfig struct { type ServiceConfig struct { serviceconfig.Config - // LB is the load balancer the service providers recommends. This is - // deprecated; lbConfigs is preferred. If lbConfig and LB are both present, - // lbConfig will be used. - LB *string - // lbConfig is the service config's load balancing configuration. If // lbConfig and LB are both present, lbConfig will be used. - lbConfig *lbConfig + lbConfig serviceconfig.LoadBalancingConfig // Methods contains a map for the methods in this service. If there is an // exact match for a method (i.e. /service/method) in the map, use the @@ -164,7 +156,7 @@ type jsonMC struct { // TODO(lyuxuan): delete this struct after cleaning up old service config implementation. type jsonSC struct { LoadBalancingPolicy *string - LoadBalancingConfig *internalserviceconfig.BalancerConfig + LoadBalancingConfig *json.RawMessage MethodConfig *[]jsonMC RetryThrottling *retryThrottlingPolicy HealthCheckConfig *healthCheckConfig @@ -184,18 +176,33 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { return &serviceconfig.ParseResult{Err: err} } sc := ServiceConfig{ - LB: rsc.LoadBalancingPolicy, Methods: make(map[string]MethodConfig), retryThrottling: rsc.RetryThrottling, healthCheckConfig: rsc.HealthCheckConfig, rawJSONString: js, } - if c := rsc.LoadBalancingConfig; c != nil { - sc.lbConfig = &lbConfig{ - name: c.Name, - cfg: c.Config, + c := rsc.LoadBalancingConfig + if c == nil { + name := PickFirstBalancerName + if rsc.LoadBalancingPolicy != nil { + name = *rsc.LoadBalancingPolicy + } + if balancer.Get(name) == nil { + name = PickFirstBalancerName } + cfg := []map[string]any{{name: struct{}{}}} + strCfg, err := json.Marshal(cfg) + if err != nil { + return &serviceconfig.ParseResult{Err: fmt.Errorf("unexpected error marshaling simple LB config: %w", err)} + } + r := json.RawMessage(strCfg) + c = &r + } + cfg, err := gracefulswitch.ParseConfig(*c) + if err != nil { + return &serviceconfig.ParseResult{Err: err} } + sc.lbConfig = cfg if rsc.MethodConfig == nil { return &serviceconfig.ParseResult{Config: &sc} diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 814e9983..d939ffc6 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -655,13 +655,13 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) { if len(sps) == 1 { var e error if pushback, e = strconv.Atoi(sps[0]); e != nil || pushback < 0 { - channelz.Infof(logger, cs.cc.channelzID, "Server retry pushback specified to abort (%q).", sps[0]) + channelz.Infof(logger, cs.cc.channelz, "Server retry pushback specified to abort (%q).", sps[0]) cs.retryThrottler.throttle() // This counts as a failure for throttling. return false, err } hasPushback = true } else if len(sps) > 1 { - channelz.Warningf(logger, cs.cc.channelzID, "Server retry pushback specified multiple values (%q); not retrying.", sps) + channelz.Warningf(logger, cs.cc.channelz, "Server retry pushback specified multiple values (%q); not retrying.", sps) cs.retryThrottler.throttle() // This counts as a failure for throttling. return false, err } diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 46ad8113..eaf5dbce 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.62.1" +const Version = "1.63.0" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index 7a33c215..7e6b92e4 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -83,6 +83,10 @@ git grep 'func [A-Z]' -- "*_test.go" | not grep -v 'func Test\|Benchmark\|Exampl # - Do not import x/net/context. not git grep -l 'x/net/context' -- "*.go" +# - Do not use time.After except in tests. It has the potential to leak the +# timer since there is no way to stop it early. +git grep -l 'time.After(' -- "*.go" | not grep -v '_test.go\|test_utils\|testutils' + # - Do not import math/rand for real library code. Use internal/grpcrand for # thread safety. git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^interop/stress\|grpcrand\|^benchmark\|wrr_test' @@ -172,6 +176,7 @@ UpdateAddresses is deprecated: UpdateSubConnState is deprecated: balancer.ErrTransientFailure is deprecated: grpc/reflection/v1alpha/reflection.proto +SwitchTo is deprecated: XXXXX xDS deprecated fields we support .ExactMatch .PrefixMatch diff --git a/vendor/modules.txt b/vendor/modules.txt index fe23f5df..7fb10db5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -26,7 +26,7 @@ github.com/hashicorp/go-cty/cty/gocty github.com/hashicorp/go-cty/cty/json github.com/hashicorp/go-cty/cty/msgpack github.com/hashicorp/go-cty/cty/set -# github.com/hashicorp/go-hclog v1.6.2 +# github.com/hashicorp/go-hclog v1.6.3 ## explicit; go 1.13 github.com/hashicorp/go-hclog # github.com/hashicorp/go-plugin v1.6.0 @@ -42,7 +42,7 @@ github.com/hashicorp/go-uuid # github.com/hashicorp/go-version v1.6.0 ## explicit github.com/hashicorp/go-version -# github.com/hashicorp/hcl/v2 v2.20.0 +# github.com/hashicorp/hcl/v2 v2.20.1 ## explicit; go 1.18 github.com/hashicorp/hcl/v2 github.com/hashicorp/hcl/v2/ext/customdecode @@ -126,7 +126,7 @@ github.com/mitchellh/reflectwalk # github.com/oklog/run v1.1.0 ## explicit; go 1.13 github.com/oklog/run -# github.com/stripe/stripe-go/v76 v76.21.0 +# github.com/stripe/stripe-go/v76 v76.23.0 ## explicit; go 1.13 github.com/stripe/stripe-go/v76 github.com/stripe/stripe-go/v76/account @@ -138,6 +138,10 @@ github.com/stripe/stripe-go/v76/apps/secret github.com/stripe/stripe-go/v76/balance github.com/stripe/stripe-go/v76/balancetransaction github.com/stripe/stripe-go/v76/bankaccount +github.com/stripe/stripe-go/v76/billing/meter +github.com/stripe/stripe-go/v76/billing/meterevent +github.com/stripe/stripe-go/v76/billing/metereventadjustment +github.com/stripe/stripe-go/v76/billing/metereventsummary github.com/stripe/stripe-go/v76/billingportal/configuration github.com/stripe/stripe-go/v76/billingportal/session github.com/stripe/stripe-go/v76/capability @@ -149,6 +153,7 @@ github.com/stripe/stripe-go/v76/client github.com/stripe/stripe-go/v76/climate/order github.com/stripe/stripe-go/v76/climate/product github.com/stripe/stripe-go/v76/climate/supplier +github.com/stripe/stripe-go/v76/confirmationtoken github.com/stripe/stripe-go/v76/countryspec github.com/stripe/stripe-go/v76/coupon github.com/stripe/stripe-go/v76/creditnote @@ -166,6 +171,7 @@ github.com/stripe/stripe-go/v76/financialconnections/account github.com/stripe/stripe-go/v76/financialconnections/session github.com/stripe/stripe-go/v76/financialconnections/transaction github.com/stripe/stripe-go/v76/form +github.com/stripe/stripe-go/v76/forwarding/request github.com/stripe/stripe-go/v76/identity/verificationreport github.com/stripe/stripe-go/v76/identity/verificationsession github.com/stripe/stripe-go/v76/invoice @@ -222,6 +228,7 @@ github.com/stripe/stripe-go/v76/terminal/configuration github.com/stripe/stripe-go/v76/terminal/connectiontoken github.com/stripe/stripe-go/v76/terminal/location github.com/stripe/stripe-go/v76/terminal/reader +github.com/stripe/stripe-go/v76/testhelpers/confirmationtoken github.com/stripe/stripe-go/v76/testhelpers/customer github.com/stripe/stripe-go/v76/testhelpers/issuing/authorization github.com/stripe/stripe-go/v76/testhelpers/issuing/card @@ -265,7 +272,7 @@ github.com/vmihailenco/msgpack/v5/msgpcode github.com/vmihailenco/tagparser/v2 github.com/vmihailenco/tagparser/v2/internal github.com/vmihailenco/tagparser/v2/internal/parser -# github.com/zclconf/go-cty v1.14.3 +# github.com/zclconf/go-cty v1.14.4 ## explicit; go 1.18 github.com/zclconf/go-cty/cty github.com/zclconf/go-cty/cty/convert @@ -278,7 +285,7 @@ github.com/zclconf/go-cty/cty/set # golang.org/x/mod v0.16.0 ## explicit; go 1.18 golang.org/x/mod/semver -# golang.org/x/net v0.22.0 +# golang.org/x/net v0.23.0 ## explicit; go 1.18 golang.org/x/net/http/httpguts golang.org/x/net/http2 @@ -330,10 +337,10 @@ google.golang.org/appengine/internal/datastore google.golang.org/appengine/internal/log google.golang.org/appengine/internal/modules google.golang.org/appengine/internal/remote_api -# google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 +# google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda ## explicit; go 1.19 google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.62.1 +# google.golang.org/grpc v1.63.0 ## explicit; go 1.19 google.golang.org/grpc google.golang.org/grpc/attributes