mirror of https://github.com/knative/caching.git
Auto-update dependencies (#181)
Produced via: `dep ensure -update knative.dev/test-infra knative.dev/pkg` /assign n3wscott /cc n3wscott
This commit is contained in:
parent
1a95d9fc04
commit
ca4e85213b
|
@ -15,6 +15,14 @@
|
|||
revision = "775730d6e48254a2430366162cf6298e5368833c"
|
||||
version = "v0.39.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0a936e17f4fc0c65615913199ce0a387a67a4c72e017747b6f38c898168b1b75"
|
||||
name = "contrib.go.opencensus.io/exporter/ocagent"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "a8a6f458bbc1d5042322ad1f9b65eeb0b69be9ea"
|
||||
version = "v0.6.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:642cf8e80572f9dc0677b0f241c8ab2e715c9dccc215270ea873c86ddca0062c"
|
||||
name = "contrib.go.opencensus.io/exporter/prometheus"
|
||||
|
@ -81,12 +89,15 @@
|
|||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e7d26760c4e7d67a443b082153c4b473ad0b8f7388302a2f788b1360f751abb8"
|
||||
digest = "1:8f5acd4d4462b5136af644d25101f0968a7a94ee90fcb2059cec5b7cc42e0b20"
|
||||
name = "github.com/census-instrumentation/opencensus-proto"
|
||||
packages = [
|
||||
"gen-go/agent/common/v1",
|
||||
"gen-go/agent/metrics/v1",
|
||||
"gen-go/agent/trace/v1",
|
||||
"gen-go/metrics/v1",
|
||||
"gen-go/resource/v1",
|
||||
"gen-go/trace/v1",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "d89fa54de508111353cb0b06403c00569be780d8"
|
||||
|
@ -128,9 +139,11 @@
|
|||
revision = "5b532d6fd5efaf7fa130d4e859a2fde0fc3a9e1b"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f5a98770ab68c1146ee5cc14ed24aafa2bb1a2b3c89cbeadc9eb913b1f9d930a"
|
||||
digest = "1:a677057cef8b68b66003c2775ed1126bbd7e9e372b54b7c1a7c5201a2f1f3eb0"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"descriptor",
|
||||
"jsonpb",
|
||||
"proto",
|
||||
"protoc-gen-go/descriptor",
|
||||
"ptypes",
|
||||
|
@ -210,6 +223,18 @@
|
|||
revision = "7c663266750e7d82587642f65e60bc4083f1f84e"
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e9c0bf861ea69dd6de1ff7ac2a0485e84743e163853ca973177fba7a50d1b769"
|
||||
name = "github.com/grpc-ecosystem/grpc-gateway"
|
||||
packages = [
|
||||
"internal",
|
||||
"runtime",
|
||||
"utilities",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "f7120437bb4f6c71f7f5076ad65a45310de2c009"
|
||||
version = "v1.12.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b42cde0e1f3c816dd57f57f7bbcf05ca40263ad96f168714c130c611fc0856a6"
|
||||
name = "github.com/hashicorp/golang-lru"
|
||||
|
@ -526,12 +551,13 @@
|
|||
version = "v1.4.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3689f4cc57cc55b4631efc4b778c47d2a888a7060b4108f42cf289a2033be5ba"
|
||||
digest = "1:cdd51a140120ceb49a810515f07666763a30da9e2506bb592c9924401dd4ff7c"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = [
|
||||
"googleapis/api",
|
||||
"googleapis/api/annotations",
|
||||
"googleapis/api/distribution",
|
||||
"googleapis/api/httpbody",
|
||||
"googleapis/api/label",
|
||||
"googleapis/api/metric",
|
||||
"googleapis/api/monitoredres",
|
||||
|
@ -940,7 +966,7 @@
|
|||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:9ef7bffae626f41005f2a2514ade223263b3ba2566baabd257b924bdf5dbb428"
|
||||
digest = "1:048b68ed41f274d9f9c663076f987bb4be938273ba13bc68088910ad634a354b"
|
||||
name = "knative.dev/pkg"
|
||||
packages = [
|
||||
"apis",
|
||||
|
@ -959,7 +985,7 @@
|
|||
"metrics/metricskey",
|
||||
]
|
||||
pruneopts = "T"
|
||||
revision = "79d67498c2c48baf2b8cd114f23cef3f55f91262"
|
||||
revision = "b8dc5fbc6d2f4717a69d15382921a51f93ab4cbb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
@ -970,7 +996,7 @@
|
|||
"tools/dep-collector",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "ce144eee3f441f9810581755d291ecbc4765a06e"
|
||||
revision = "bcc2cb77b27d57e02b77156cf3bf59b71680c993"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c"
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2018, OpenCensus 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 ocagent
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
var randSrc = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
// retries function fn upto n times, if fn returns an error lest it returns nil early.
|
||||
// It applies exponential backoff in units of (1<<n) + jitter microsends.
|
||||
func nTriesWithExponentialBackoff(nTries int64, timeBaseUnit time.Duration, fn func() error) (err error) {
|
||||
for i := int64(0); i < nTries; i++ {
|
||||
err = fn()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
// Backoff for a time period with a pseudo-random jitter
|
||||
jitter := time.Duration(randSrc.Float64()*100) * time.Microsecond
|
||||
ts := jitter + ((1 << uint64(i)) * timeBaseUnit)
|
||||
<-time.After(ts)
|
||||
}
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright 2018, OpenCensus 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 ocagent
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (ae *Exporter) lastConnectError() error {
|
||||
errPtr := (*error)(atomic.LoadPointer(&ae.lastConnectErrPtr))
|
||||
if errPtr == nil {
|
||||
return nil
|
||||
}
|
||||
return *errPtr
|
||||
}
|
||||
|
||||
func (ae *Exporter) saveLastConnectError(err error) {
|
||||
var errPtr *error
|
||||
if err != nil {
|
||||
errPtr = &err
|
||||
}
|
||||
atomic.StorePointer(&ae.lastConnectErrPtr, unsafe.Pointer(errPtr))
|
||||
}
|
||||
|
||||
func (ae *Exporter) setStateDisconnected(err error) {
|
||||
ae.saveLastConnectError(err)
|
||||
select {
|
||||
case ae.disconnectedCh <- true:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func (ae *Exporter) setStateConnected() {
|
||||
ae.saveLastConnectError(nil)
|
||||
}
|
||||
|
||||
func (ae *Exporter) connected() bool {
|
||||
return ae.lastConnectError() == nil
|
||||
}
|
||||
|
||||
const defaultConnReattemptPeriod = 10 * time.Second
|
||||
|
||||
func (ae *Exporter) indefiniteBackgroundConnection() error {
|
||||
defer func() {
|
||||
ae.backgroundConnectionDoneCh <- true
|
||||
}()
|
||||
|
||||
connReattemptPeriod := ae.reconnectionPeriod
|
||||
if connReattemptPeriod <= 0 {
|
||||
connReattemptPeriod = defaultConnReattemptPeriod
|
||||
}
|
||||
|
||||
// No strong seeding required, nano time can
|
||||
// already help with pseudo uniqueness.
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano() + rand.Int63n(1024)))
|
||||
|
||||
// maxJitter: 1 + (70% of the connectionReattemptPeriod)
|
||||
maxJitter := int64(1 + 0.7*float64(connReattemptPeriod))
|
||||
|
||||
for {
|
||||
// Otherwise these will be the normal scenarios to enable
|
||||
// reconnections if we trip out.
|
||||
// 1. If we've stopped, return entirely
|
||||
// 2. Otherwise block until we are disconnected, and
|
||||
// then retry connecting
|
||||
select {
|
||||
case <-ae.stopCh:
|
||||
return errStopped
|
||||
|
||||
case <-ae.disconnectedCh:
|
||||
// Normal scenario that we'll wait for
|
||||
}
|
||||
|
||||
if err := ae.connect(); err == nil {
|
||||
ae.setStateConnected()
|
||||
} else {
|
||||
ae.setStateDisconnected(err)
|
||||
}
|
||||
|
||||
// Apply some jitter to avoid lockstep retrials of other
|
||||
// agent-exporters. Lockstep retrials could result in an
|
||||
// innocent DDOS, by clogging the machine's resources and network.
|
||||
jitter := time.Duration(rng.Int63n(maxJitter))
|
||||
select {
|
||||
case <-ae.stopCh:
|
||||
return errStopped
|
||||
case <-time.After(connReattemptPeriod + jitter):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ae *Exporter) connect() error {
|
||||
cc, err := ae.dialToAgent()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ae.enableConnectionStreams(cc)
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2018, OpenCensus 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 ocagent
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
commonpb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1"
|
||||
"go.opencensus.io"
|
||||
)
|
||||
|
||||
// NodeWithStartTime creates a node using nodeName and derives:
|
||||
// Hostname from the environment
|
||||
// Pid from the current process
|
||||
// StartTimestamp from the start time of this process
|
||||
// Language and library information.
|
||||
func NodeWithStartTime(nodeName string) *commonpb.Node {
|
||||
return &commonpb.Node{
|
||||
Identifier: &commonpb.ProcessIdentifier{
|
||||
HostName: os.Getenv("HOSTNAME"),
|
||||
Pid: uint32(os.Getpid()),
|
||||
StartTimestamp: timeToTimestamp(startTime),
|
||||
},
|
||||
LibraryInfo: &commonpb.LibraryInfo{
|
||||
Language: commonpb.LibraryInfo_GO_LANG,
|
||||
ExporterVersion: Version,
|
||||
CoreLibraryVersion: opencensus.Version(),
|
||||
},
|
||||
ServiceInfo: &commonpb.ServiceInfo{
|
||||
Name: nodeName,
|
||||
},
|
||||
Attributes: make(map[string]string),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,572 @@
|
|||
// Copyright 2018, OpenCensus 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 ocagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"google.golang.org/api/support/bundler"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"go.opencensus.io/resource"
|
||||
"go.opencensus.io/stats/view"
|
||||
"go.opencensus.io/trace"
|
||||
|
||||
commonpb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1"
|
||||
agentmetricspb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1"
|
||||
agenttracepb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1"
|
||||
metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1"
|
||||
resourcepb "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1"
|
||||
tracepb "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1"
|
||||
)
|
||||
|
||||
var startupMu sync.Mutex
|
||||
var startTime time.Time
|
||||
|
||||
func init() {
|
||||
startupMu.Lock()
|
||||
startTime = time.Now()
|
||||
startupMu.Unlock()
|
||||
}
|
||||
|
||||
var _ trace.Exporter = (*Exporter)(nil)
|
||||
var _ view.Exporter = (*Exporter)(nil)
|
||||
|
||||
type Exporter struct {
|
||||
// mu protects the non-atomic and non-channel variables
|
||||
mu sync.RWMutex
|
||||
// senderMu protects the concurrent unsafe send on traceExporter client
|
||||
senderMu sync.Mutex
|
||||
// recvMu protects the concurrent unsafe recv on traceExporter client
|
||||
recvMu sync.Mutex
|
||||
started bool
|
||||
stopped bool
|
||||
agentAddress string
|
||||
serviceName string
|
||||
canDialInsecure bool
|
||||
traceExporter agenttracepb.TraceService_ExportClient
|
||||
metricsExporter agentmetricspb.MetricsService_ExportClient
|
||||
nodeInfo *commonpb.Node
|
||||
grpcClientConn *grpc.ClientConn
|
||||
reconnectionPeriod time.Duration
|
||||
resourceDetector resource.Detector
|
||||
resource *resourcepb.Resource
|
||||
compressor string
|
||||
headers map[string]string
|
||||
lastConnectErrPtr unsafe.Pointer
|
||||
|
||||
startOnce sync.Once
|
||||
stopCh chan bool
|
||||
disconnectedCh chan bool
|
||||
|
||||
backgroundConnectionDoneCh chan bool
|
||||
|
||||
traceBundler *bundler.Bundler
|
||||
|
||||
// viewDataBundler is the bundler to enable conversion
|
||||
// from OpenCensus-Go view.Data to metricspb.Metric.
|
||||
// Please do not confuse it with metricsBundler!
|
||||
viewDataBundler *bundler.Bundler
|
||||
|
||||
clientTransportCredentials credentials.TransportCredentials
|
||||
|
||||
grpcDialOptions []grpc.DialOption
|
||||
}
|
||||
|
||||
func NewExporter(opts ...ExporterOption) (*Exporter, error) {
|
||||
exp, err := NewUnstartedExporter(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := exp.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return exp, nil
|
||||
}
|
||||
|
||||
const spanDataBufferSize = 300
|
||||
|
||||
func NewUnstartedExporter(opts ...ExporterOption) (*Exporter, error) {
|
||||
e := new(Exporter)
|
||||
for _, opt := range opts {
|
||||
opt.withExporter(e)
|
||||
}
|
||||
traceBundler := bundler.NewBundler((*trace.SpanData)(nil), func(bundle interface{}) {
|
||||
e.uploadTraces(bundle.([]*trace.SpanData))
|
||||
})
|
||||
traceBundler.DelayThreshold = 2 * time.Second
|
||||
traceBundler.BundleCountThreshold = spanDataBufferSize
|
||||
e.traceBundler = traceBundler
|
||||
|
||||
viewDataBundler := bundler.NewBundler((*view.Data)(nil), func(bundle interface{}) {
|
||||
e.uploadViewData(bundle.([]*view.Data))
|
||||
})
|
||||
viewDataBundler.DelayThreshold = 2 * time.Second
|
||||
viewDataBundler.BundleCountThreshold = 500 // TODO: (@odeke-em) make this configurable.
|
||||
e.viewDataBundler = viewDataBundler
|
||||
e.nodeInfo = NodeWithStartTime(e.serviceName)
|
||||
if e.resourceDetector != nil {
|
||||
res, err := e.resourceDetector(context.Background())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Error detecting resource. err:%v\n", err))
|
||||
}
|
||||
if res != nil {
|
||||
e.resource = resourceToResourcePb(res)
|
||||
}
|
||||
} else {
|
||||
e.resource = resourceProtoFromEnv()
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
||||
|
||||
const (
|
||||
maxInitialConfigRetries = 10
|
||||
maxInitialTracesRetries = 10
|
||||
)
|
||||
|
||||
var (
|
||||
errAlreadyStarted = errors.New("already started")
|
||||
errNotStarted = errors.New("not started")
|
||||
errStopped = errors.New("stopped")
|
||||
)
|
||||
|
||||
// Start dials to the agent, establishing a connection to it. It also
|
||||
// initiates the Config and Trace services by sending over the initial
|
||||
// messages that consist of the node identifier. Start invokes a background
|
||||
// connector that will reattempt connections to the agent periodically
|
||||
// if the connection dies.
|
||||
func (ae *Exporter) Start() error {
|
||||
var err = errAlreadyStarted
|
||||
ae.startOnce.Do(func() {
|
||||
ae.mu.Lock()
|
||||
ae.started = true
|
||||
ae.disconnectedCh = make(chan bool, 1)
|
||||
ae.stopCh = make(chan bool)
|
||||
ae.backgroundConnectionDoneCh = make(chan bool)
|
||||
ae.mu.Unlock()
|
||||
|
||||
// An optimistic first connection attempt to ensure that
|
||||
// applications under heavy load can immediately process
|
||||
// data. See https://github.com/census-ecosystem/opencensus-go-exporter-ocagent/pull/63
|
||||
if err := ae.connect(); err == nil {
|
||||
ae.setStateConnected()
|
||||
} else {
|
||||
ae.setStateDisconnected(err)
|
||||
}
|
||||
go ae.indefiniteBackgroundConnection()
|
||||
|
||||
err = nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (ae *Exporter) prepareAgentAddress() string {
|
||||
if ae.agentAddress != "" {
|
||||
return ae.agentAddress
|
||||
}
|
||||
return fmt.Sprintf("%s:%d", DefaultAgentHost, DefaultAgentPort)
|
||||
}
|
||||
|
||||
func (ae *Exporter) enableConnectionStreams(cc *grpc.ClientConn) error {
|
||||
ae.mu.RLock()
|
||||
started := ae.started
|
||||
nodeInfo := ae.nodeInfo
|
||||
ae.mu.RUnlock()
|
||||
|
||||
if !started {
|
||||
return errNotStarted
|
||||
}
|
||||
|
||||
ae.mu.Lock()
|
||||
// If the previous clientConn was non-nil, close it
|
||||
if ae.grpcClientConn != nil {
|
||||
_ = ae.grpcClientConn.Close()
|
||||
}
|
||||
ae.grpcClientConn = cc
|
||||
ae.mu.Unlock()
|
||||
|
||||
if err := ae.createTraceServiceConnection(ae.grpcClientConn, nodeInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ae.createMetricsServiceConnection(ae.grpcClientConn, nodeInfo)
|
||||
}
|
||||
|
||||
func (ae *Exporter) createTraceServiceConnection(cc *grpc.ClientConn, node *commonpb.Node) error {
|
||||
// Initiate the trace service by sending over node identifier info.
|
||||
traceSvcClient := agenttracepb.NewTraceServiceClient(cc)
|
||||
ctx := context.Background()
|
||||
if len(ae.headers) > 0 {
|
||||
ctx = metadata.NewOutgoingContext(ctx, metadata.New(ae.headers))
|
||||
}
|
||||
traceExporter, err := traceSvcClient.Export(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Exporter.Start:: TraceServiceClient: %v", err)
|
||||
}
|
||||
|
||||
firstTraceMessage := &agenttracepb.ExportTraceServiceRequest{
|
||||
Node: node,
|
||||
Resource: ae.resource,
|
||||
}
|
||||
if err := traceExporter.Send(firstTraceMessage); err != nil {
|
||||
return fmt.Errorf("Exporter.Start:: Failed to initiate the Config service: %v", err)
|
||||
}
|
||||
|
||||
ae.mu.Lock()
|
||||
ae.traceExporter = traceExporter
|
||||
ae.mu.Unlock()
|
||||
|
||||
// Initiate the config service by sending over node identifier info.
|
||||
configStream, err := traceSvcClient.Config(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Exporter.Start:: ConfigStream: %v", err)
|
||||
}
|
||||
firstCfgMessage := &agenttracepb.CurrentLibraryConfig{Node: node}
|
||||
if err := configStream.Send(firstCfgMessage); err != nil {
|
||||
return fmt.Errorf("Exporter.Start:: Failed to initiate the Config service: %v", err)
|
||||
}
|
||||
|
||||
// In the background, handle trace configurations that are beamed down
|
||||
// by the agent, but also reply to it with the applied configuration.
|
||||
go ae.handleConfigStreaming(configStream)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ae *Exporter) createMetricsServiceConnection(cc *grpc.ClientConn, node *commonpb.Node) error {
|
||||
metricsSvcClient := agentmetricspb.NewMetricsServiceClient(cc)
|
||||
metricsExporter, err := metricsSvcClient.Export(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("MetricsExporter: failed to start the service client: %v", err)
|
||||
}
|
||||
// Initiate the metrics service by sending over the first message just containing the Node and Resource.
|
||||
firstMetricsMessage := &agentmetricspb.ExportMetricsServiceRequest{
|
||||
Node: node,
|
||||
Resource: ae.resource,
|
||||
}
|
||||
if err := metricsExporter.Send(firstMetricsMessage); err != nil {
|
||||
return fmt.Errorf("MetricsExporter:: failed to send the first message: %v", err)
|
||||
}
|
||||
|
||||
ae.mu.Lock()
|
||||
ae.metricsExporter = metricsExporter
|
||||
ae.mu.Unlock()
|
||||
|
||||
// With that we are good to go and can start sending metrics
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ae *Exporter) dialToAgent() (*grpc.ClientConn, error) {
|
||||
addr := ae.prepareAgentAddress()
|
||||
var dialOpts []grpc.DialOption
|
||||
if ae.clientTransportCredentials != nil {
|
||||
dialOpts = append(dialOpts, grpc.WithTransportCredentials(ae.clientTransportCredentials))
|
||||
} else if ae.canDialInsecure {
|
||||
dialOpts = append(dialOpts, grpc.WithInsecure())
|
||||
}
|
||||
if ae.compressor != "" {
|
||||
dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.UseCompressor(ae.compressor)))
|
||||
}
|
||||
dialOpts = append(dialOpts, grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
|
||||
if len(ae.grpcDialOptions) != 0 {
|
||||
dialOpts = append(dialOpts, ae.grpcDialOptions...)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if len(ae.headers) > 0 {
|
||||
ctx = metadata.NewOutgoingContext(ctx, metadata.New(ae.headers))
|
||||
}
|
||||
return grpc.DialContext(ctx, addr, dialOpts...)
|
||||
}
|
||||
|
||||
func (ae *Exporter) handleConfigStreaming(configStream agenttracepb.TraceService_ConfigClient) error {
|
||||
// Note: We haven't yet implemented configuration sending so we
|
||||
// should NOT be changing connection states within this function for now.
|
||||
for {
|
||||
recv, err := configStream.Recv()
|
||||
if err != nil {
|
||||
// TODO: Check if this is a transient error or exponential backoff-able.
|
||||
return err
|
||||
}
|
||||
cfg := recv.Config
|
||||
if cfg == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Otherwise now apply the trace configuration sent down from the agent
|
||||
if psamp := cfg.GetProbabilitySampler(); psamp != nil {
|
||||
trace.ApplyConfig(trace.Config{DefaultSampler: trace.ProbabilitySampler(psamp.SamplingProbability)})
|
||||
} else if csamp := cfg.GetConstantSampler(); csamp != nil {
|
||||
alwaysSample := csamp.Decision == tracepb.ConstantSampler_ALWAYS_ON
|
||||
if alwaysSample {
|
||||
trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
|
||||
} else {
|
||||
trace.ApplyConfig(trace.Config{DefaultSampler: trace.NeverSample()})
|
||||
}
|
||||
} else { // TODO: Add the rate limiting sampler here
|
||||
}
|
||||
|
||||
// Then finally send back to upstream the newly applied configuration
|
||||
err = configStream.Send(&agenttracepb.CurrentLibraryConfig{Config: &tracepb.TraceConfig{Sampler: cfg.Sampler}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stop shuts down all the connections and resources
|
||||
// related to the exporter.
|
||||
func (ae *Exporter) Stop() error {
|
||||
ae.mu.RLock()
|
||||
cc := ae.grpcClientConn
|
||||
started := ae.started
|
||||
stopped := ae.stopped
|
||||
ae.mu.RUnlock()
|
||||
|
||||
if !started {
|
||||
return errNotStarted
|
||||
}
|
||||
if stopped {
|
||||
// TODO: tell the user that we've already stopped, so perhaps a sentinel error?
|
||||
return nil
|
||||
}
|
||||
|
||||
ae.Flush()
|
||||
|
||||
// Now close the underlying gRPC connection.
|
||||
var err error
|
||||
if cc != nil {
|
||||
err = cc.Close()
|
||||
}
|
||||
|
||||
// At this point we can change the state variables: started and stopped
|
||||
ae.mu.Lock()
|
||||
ae.started = false
|
||||
ae.stopped = true
|
||||
ae.mu.Unlock()
|
||||
close(ae.stopCh)
|
||||
|
||||
// Ensure that the backgroundConnector returns
|
||||
<-ae.backgroundConnectionDoneCh
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (ae *Exporter) ExportSpan(sd *trace.SpanData) {
|
||||
if sd == nil {
|
||||
return
|
||||
}
|
||||
_ = ae.traceBundler.Add(sd, 1)
|
||||
}
|
||||
|
||||
func (ae *Exporter) ExportTraceServiceRequest(batch *agenttracepb.ExportTraceServiceRequest) error {
|
||||
if batch == nil || len(batch.Spans) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ae.stopCh:
|
||||
return errStopped
|
||||
|
||||
default:
|
||||
if lastConnectErr := ae.lastConnectError(); lastConnectErr != nil {
|
||||
return fmt.Errorf("ExportTraceServiceRequest: no active connection, last connection error: %v", lastConnectErr)
|
||||
}
|
||||
|
||||
ae.senderMu.Lock()
|
||||
err := ae.traceExporter.Send(batch)
|
||||
ae.senderMu.Unlock()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
ae.recvMu.Lock()
|
||||
// Perform a .Recv to try to find out why the RPC actually ended.
|
||||
// See:
|
||||
// * https://github.com/grpc/grpc-go/blob/d389f9fac68eea0dcc49957d0b4cca5b3a0a7171/stream.go#L98-L100
|
||||
// * https://groups.google.com/forum/#!msg/grpc-io/XcN4hA9HonI/F_UDiejTAwAJ
|
||||
for {
|
||||
_, err = ae.traceExporter.Recv()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
ae.recvMu.Unlock()
|
||||
}
|
||||
|
||||
ae.setStateDisconnected(err)
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (ae *Exporter) ExportView(vd *view.Data) {
|
||||
if vd == nil {
|
||||
return
|
||||
}
|
||||
_ = ae.viewDataBundler.Add(vd, 1)
|
||||
}
|
||||
|
||||
// ExportMetricsServiceRequest sends proto metrics with the metrics service client.
|
||||
func (ae *Exporter) ExportMetricsServiceRequest(batch *agentmetricspb.ExportMetricsServiceRequest) error {
|
||||
if batch == nil || len(batch.Metrics) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ae.stopCh:
|
||||
return errStopped
|
||||
|
||||
default:
|
||||
if lastConnectErr := ae.lastConnectError(); lastConnectErr != nil {
|
||||
return fmt.Errorf("ExportMetricsServiceRequest: no active connection, last connection error: %v", lastConnectErr)
|
||||
}
|
||||
|
||||
ae.senderMu.Lock()
|
||||
err := ae.metricsExporter.Send(batch)
|
||||
ae.senderMu.Unlock()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
ae.recvMu.Lock()
|
||||
// Perform a .Recv to try to find out why the RPC actually ended.
|
||||
// See:
|
||||
// * https://github.com/grpc/grpc-go/blob/d389f9fac68eea0dcc49957d0b4cca5b3a0a7171/stream.go#L98-L100
|
||||
// * https://groups.google.com/forum/#!msg/grpc-io/XcN4hA9HonI/F_UDiejTAwAJ
|
||||
for {
|
||||
_, err = ae.metricsExporter.Recv()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
ae.recvMu.Unlock()
|
||||
}
|
||||
|
||||
ae.setStateDisconnected(err)
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ocSpanDataToPbSpans(sdl []*trace.SpanData) []*tracepb.Span {
|
||||
if len(sdl) == 0 {
|
||||
return nil
|
||||
}
|
||||
protoSpans := make([]*tracepb.Span, 0, len(sdl))
|
||||
for _, sd := range sdl {
|
||||
if sd != nil {
|
||||
protoSpans = append(protoSpans, ocSpanToProtoSpan(sd))
|
||||
}
|
||||
}
|
||||
return protoSpans
|
||||
}
|
||||
|
||||
func (ae *Exporter) uploadTraces(sdl []*trace.SpanData) {
|
||||
select {
|
||||
case <-ae.stopCh:
|
||||
return
|
||||
|
||||
default:
|
||||
if !ae.connected() {
|
||||
return
|
||||
}
|
||||
|
||||
protoSpans := ocSpanDataToPbSpans(sdl)
|
||||
if len(protoSpans) == 0 {
|
||||
return
|
||||
}
|
||||
ae.senderMu.Lock()
|
||||
err := ae.traceExporter.Send(&agenttracepb.ExportTraceServiceRequest{
|
||||
Spans: protoSpans,
|
||||
Resource: resourceProtoFromEnv(),
|
||||
})
|
||||
ae.senderMu.Unlock()
|
||||
if err != nil {
|
||||
ae.setStateDisconnected(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ocViewDataToPbMetrics(vdl []*view.Data) []*metricspb.Metric {
|
||||
if len(vdl) == 0 {
|
||||
return nil
|
||||
}
|
||||
metrics := make([]*metricspb.Metric, 0, len(vdl))
|
||||
for _, vd := range vdl {
|
||||
if vd != nil {
|
||||
vmetric, err := viewDataToMetric(vd)
|
||||
// TODO: (@odeke-em) somehow report this error, if it is non-nil.
|
||||
if err == nil && vmetric != nil {
|
||||
metrics = append(metrics, vmetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
return metrics
|
||||
}
|
||||
|
||||
func (ae *Exporter) uploadViewData(vdl []*view.Data) {
|
||||
protoMetrics := ocViewDataToPbMetrics(vdl)
|
||||
if len(protoMetrics) == 0 {
|
||||
return
|
||||
}
|
||||
req := &agentmetricspb.ExportMetricsServiceRequest{
|
||||
Metrics: protoMetrics,
|
||||
Resource: resourceProtoFromEnv(),
|
||||
// TODO:(@odeke-em)
|
||||
// a) Figure out how to derive a Node from the environment
|
||||
// or better letting users of the exporter configure it.
|
||||
}
|
||||
ae.ExportMetricsServiceRequest(req)
|
||||
}
|
||||
|
||||
func (ae *Exporter) Flush() {
|
||||
ae.traceBundler.Flush()
|
||||
ae.viewDataBundler.Flush()
|
||||
}
|
||||
|
||||
func resourceProtoFromEnv() *resourcepb.Resource {
|
||||
rs, _ := resource.FromEnv(context.Background())
|
||||
if rs == nil {
|
||||
return nil
|
||||
}
|
||||
return resourceToResourcePb(rs)
|
||||
}
|
||||
|
||||
func resourceToResourcePb(rs *resource.Resource) *resourcepb.Resource {
|
||||
rprs := &resourcepb.Resource{
|
||||
Type: rs.Type,
|
||||
}
|
||||
if rs.Labels != nil {
|
||||
rprs.Labels = make(map[string]string)
|
||||
for k, v := range rs.Labels {
|
||||
rprs.Labels[k] = v
|
||||
}
|
||||
}
|
||||
return rprs
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
// Copyright 2018, OpenCensus 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 ocagent
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.opencensus.io/resource"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultAgentPort uint16 = 55678
|
||||
DefaultAgentHost string = "localhost"
|
||||
)
|
||||
|
||||
type ExporterOption interface {
|
||||
withExporter(e *Exporter)
|
||||
}
|
||||
|
||||
type resourceDetector resource.Detector
|
||||
|
||||
var _ ExporterOption = (*resourceDetector)(nil)
|
||||
|
||||
func (rd resourceDetector) withExporter(e *Exporter) {
|
||||
e.resourceDetector = resource.Detector(rd)
|
||||
}
|
||||
|
||||
// WithResourceDetector allows one to register a resource detector. Resource Detector is used
|
||||
// to detect resources associated with the application. Detected resource is exported
|
||||
// along with the metrics. If the detector fails then it panics.
|
||||
// If a resource detector is not provided then by default it detects from the environment.
|
||||
func WithResourceDetector(rd resource.Detector) ExporterOption {
|
||||
return resourceDetector(rd)
|
||||
}
|
||||
|
||||
type insecureGrpcConnection int
|
||||
|
||||
var _ ExporterOption = (*insecureGrpcConnection)(nil)
|
||||
|
||||
func (igc *insecureGrpcConnection) withExporter(e *Exporter) {
|
||||
e.canDialInsecure = true
|
||||
}
|
||||
|
||||
// WithInsecure disables client transport security for the exporter's gRPC connection
|
||||
// just like grpc.WithInsecure() https://godoc.org/google.golang.org/grpc#WithInsecure
|
||||
// does. Note, by default, client security is required unless WithInsecure is used.
|
||||
func WithInsecure() ExporterOption { return new(insecureGrpcConnection) }
|
||||
|
||||
type addressSetter string
|
||||
|
||||
func (as addressSetter) withExporter(e *Exporter) {
|
||||
e.agentAddress = string(as)
|
||||
}
|
||||
|
||||
var _ ExporterOption = (*addressSetter)(nil)
|
||||
|
||||
// WithAddress allows one to set the address that the exporter will
|
||||
// connect to the agent on. If unset, it will instead try to use
|
||||
// connect to DefaultAgentHost:DefaultAgentPort
|
||||
func WithAddress(addr string) ExporterOption {
|
||||
return addressSetter(addr)
|
||||
}
|
||||
|
||||
type serviceNameSetter string
|
||||
|
||||
func (sns serviceNameSetter) withExporter(e *Exporter) {
|
||||
e.serviceName = string(sns)
|
||||
}
|
||||
|
||||
var _ ExporterOption = (*serviceNameSetter)(nil)
|
||||
|
||||
// WithServiceName allows one to set/override the service name
|
||||
// that the exporter will report to the agent.
|
||||
func WithServiceName(serviceName string) ExporterOption {
|
||||
return serviceNameSetter(serviceName)
|
||||
}
|
||||
|
||||
type reconnectionPeriod time.Duration
|
||||
|
||||
func (rp reconnectionPeriod) withExporter(e *Exporter) {
|
||||
e.reconnectionPeriod = time.Duration(rp)
|
||||
}
|
||||
|
||||
func WithReconnectionPeriod(rp time.Duration) ExporterOption {
|
||||
return reconnectionPeriod(rp)
|
||||
}
|
||||
|
||||
type compressorSetter string
|
||||
|
||||
func (c compressorSetter) withExporter(e *Exporter) {
|
||||
e.compressor = string(c)
|
||||
}
|
||||
|
||||
// UseCompressor will set the compressor for the gRPC client to use when sending requests.
|
||||
// It is the responsibility of the caller to ensure that the compressor set has been registered
|
||||
// with google.golang.org/grpc/encoding. This can be done by encoding.RegisterCompressor. Some
|
||||
// compressors auto-register on import, such as gzip, which can be registered by calling
|
||||
// `import _ "google.golang.org/grpc/encoding/gzip"`
|
||||
func UseCompressor(compressorName string) ExporterOption {
|
||||
return compressorSetter(compressorName)
|
||||
}
|
||||
|
||||
type headerSetter map[string]string
|
||||
|
||||
func (h headerSetter) withExporter(e *Exporter) {
|
||||
e.headers = map[string]string(h)
|
||||
}
|
||||
|
||||
// WithHeaders will send the provided headers when the gRPC stream connection
|
||||
// is instantiated
|
||||
func WithHeaders(headers map[string]string) ExporterOption {
|
||||
return headerSetter(headers)
|
||||
}
|
||||
|
||||
type clientCredentials struct {
|
||||
credentials.TransportCredentials
|
||||
}
|
||||
|
||||
var _ ExporterOption = (*clientCredentials)(nil)
|
||||
|
||||
// WithTLSCredentials allows the connection to use TLS credentials
|
||||
// when talking to the server. It takes in grpc.TransportCredentials instead
|
||||
// of say a Certificate file or a tls.Certificate, because the retrieving
|
||||
// these credentials can be done in many ways e.g. plain file, in code tls.Config
|
||||
// or by certificate rotation, so it is up to the caller to decide what to use.
|
||||
func WithTLSCredentials(creds credentials.TransportCredentials) ExporterOption {
|
||||
return &clientCredentials{TransportCredentials: creds}
|
||||
}
|
||||
|
||||
func (cc *clientCredentials) withExporter(e *Exporter) {
|
||||
e.clientTransportCredentials = cc.TransportCredentials
|
||||
}
|
||||
|
||||
type grpcDialOptions []grpc.DialOption
|
||||
|
||||
var _ ExporterOption = (*grpcDialOptions)(nil)
|
||||
|
||||
// WithGRPCDialOption opens support to any grpc.DialOption to be used. If it conflicts
|
||||
// with some other configuration the GRPC specified via the agent the ones here will
|
||||
// take preference since they are set last.
|
||||
func WithGRPCDialOption(opts ...grpc.DialOption) ExporterOption {
|
||||
return grpcDialOptions(opts)
|
||||
}
|
||||
|
||||
func (opts grpcDialOptions) withExporter(e *Exporter) {
|
||||
e.grpcDialOptions = opts
|
||||
}
|
248
vendor/contrib.go.opencensus.io/exporter/ocagent/transform_spans.go
generated
vendored
Normal file
248
vendor/contrib.go.opencensus.io/exporter/ocagent/transform_spans.go
generated
vendored
Normal file
|
@ -0,0 +1,248 @@
|
|||
// Copyright 2018, OpenCensus 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 ocagent
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"go.opencensus.io/trace"
|
||||
"go.opencensus.io/trace/tracestate"
|
||||
|
||||
tracepb "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1"
|
||||
"github.com/golang/protobuf/ptypes/timestamp"
|
||||
)
|
||||
|
||||
const (
|
||||
maxAnnotationEventsPerSpan = 32
|
||||
maxMessageEventsPerSpan = 128
|
||||
)
|
||||
|
||||
func ocSpanToProtoSpan(sd *trace.SpanData) *tracepb.Span {
|
||||
if sd == nil {
|
||||
return nil
|
||||
}
|
||||
var namePtr *tracepb.TruncatableString
|
||||
if sd.Name != "" {
|
||||
namePtr = &tracepb.TruncatableString{Value: sd.Name}
|
||||
}
|
||||
return &tracepb.Span{
|
||||
TraceId: sd.TraceID[:],
|
||||
SpanId: sd.SpanID[:],
|
||||
ParentSpanId: sd.ParentSpanID[:],
|
||||
Status: ocStatusToProtoStatus(sd.Status),
|
||||
StartTime: timeToTimestamp(sd.StartTime),
|
||||
EndTime: timeToTimestamp(sd.EndTime),
|
||||
Links: ocLinksToProtoLinks(sd.Links),
|
||||
Kind: ocSpanKindToProtoSpanKind(sd.SpanKind),
|
||||
Name: namePtr,
|
||||
Attributes: ocAttributesToProtoAttributes(sd.Attributes),
|
||||
TimeEvents: ocTimeEventsToProtoTimeEvents(sd.Annotations, sd.MessageEvents),
|
||||
Tracestate: ocTracestateToProtoTracestate(sd.Tracestate),
|
||||
}
|
||||
}
|
||||
|
||||
var blankStatus trace.Status
|
||||
|
||||
func ocStatusToProtoStatus(status trace.Status) *tracepb.Status {
|
||||
if status == blankStatus {
|
||||
return nil
|
||||
}
|
||||
return &tracepb.Status{
|
||||
Code: status.Code,
|
||||
Message: status.Message,
|
||||
}
|
||||
}
|
||||
|
||||
func ocLinksToProtoLinks(links []trace.Link) *tracepb.Span_Links {
|
||||
if len(links) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
sl := make([]*tracepb.Span_Link, 0, len(links))
|
||||
for _, ocLink := range links {
|
||||
// This redefinition is necessary to prevent ocLink.*ID[:] copies
|
||||
// being reused -- in short we need a new ocLink per iteration.
|
||||
ocLink := ocLink
|
||||
|
||||
sl = append(sl, &tracepb.Span_Link{
|
||||
TraceId: ocLink.TraceID[:],
|
||||
SpanId: ocLink.SpanID[:],
|
||||
Type: ocLinkTypeToProtoLinkType(ocLink.Type),
|
||||
})
|
||||
}
|
||||
|
||||
return &tracepb.Span_Links{
|
||||
Link: sl,
|
||||
}
|
||||
}
|
||||
|
||||
func ocLinkTypeToProtoLinkType(oct trace.LinkType) tracepb.Span_Link_Type {
|
||||
switch oct {
|
||||
case trace.LinkTypeChild:
|
||||
return tracepb.Span_Link_CHILD_LINKED_SPAN
|
||||
case trace.LinkTypeParent:
|
||||
return tracepb.Span_Link_PARENT_LINKED_SPAN
|
||||
default:
|
||||
return tracepb.Span_Link_TYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func ocAttributesToProtoAttributes(attrs map[string]interface{}) *tracepb.Span_Attributes {
|
||||
if len(attrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
outMap := make(map[string]*tracepb.AttributeValue)
|
||||
for k, v := range attrs {
|
||||
switch v := v.(type) {
|
||||
case bool:
|
||||
outMap[k] = &tracepb.AttributeValue{Value: &tracepb.AttributeValue_BoolValue{BoolValue: v}}
|
||||
|
||||
case int:
|
||||
outMap[k] = &tracepb.AttributeValue{Value: &tracepb.AttributeValue_IntValue{IntValue: int64(v)}}
|
||||
|
||||
case int64:
|
||||
outMap[k] = &tracepb.AttributeValue{Value: &tracepb.AttributeValue_IntValue{IntValue: v}}
|
||||
|
||||
case string:
|
||||
outMap[k] = &tracepb.AttributeValue{
|
||||
Value: &tracepb.AttributeValue_StringValue{
|
||||
StringValue: &tracepb.TruncatableString{Value: v},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
return &tracepb.Span_Attributes{
|
||||
AttributeMap: outMap,
|
||||
}
|
||||
}
|
||||
|
||||
// This code is mostly copied from
|
||||
// https://github.com/census-ecosystem/opencensus-go-exporter-stackdriver/blob/master/trace_proto.go#L46
|
||||
func ocTimeEventsToProtoTimeEvents(as []trace.Annotation, es []trace.MessageEvent) *tracepb.Span_TimeEvents {
|
||||
if len(as) == 0 && len(es) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
timeEvents := &tracepb.Span_TimeEvents{}
|
||||
var annotations, droppedAnnotationsCount int
|
||||
var messageEvents, droppedMessageEventsCount int
|
||||
|
||||
// Transform annotations
|
||||
for i, a := range as {
|
||||
if annotations >= maxAnnotationEventsPerSpan {
|
||||
droppedAnnotationsCount = len(as) - i
|
||||
break
|
||||
}
|
||||
annotations++
|
||||
timeEvents.TimeEvent = append(timeEvents.TimeEvent,
|
||||
&tracepb.Span_TimeEvent{
|
||||
Time: timeToTimestamp(a.Time),
|
||||
Value: transformAnnotationToTimeEvent(&a),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Transform message events
|
||||
for i, e := range es {
|
||||
if messageEvents >= maxMessageEventsPerSpan {
|
||||
droppedMessageEventsCount = len(es) - i
|
||||
break
|
||||
}
|
||||
messageEvents++
|
||||
timeEvents.TimeEvent = append(timeEvents.TimeEvent,
|
||||
&tracepb.Span_TimeEvent{
|
||||
Time: timeToTimestamp(e.Time),
|
||||
Value: transformMessageEventToTimeEvent(&e),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Process dropped counter
|
||||
timeEvents.DroppedAnnotationsCount = clip32(droppedAnnotationsCount)
|
||||
timeEvents.DroppedMessageEventsCount = clip32(droppedMessageEventsCount)
|
||||
|
||||
return timeEvents
|
||||
}
|
||||
|
||||
func transformAnnotationToTimeEvent(a *trace.Annotation) *tracepb.Span_TimeEvent_Annotation_ {
|
||||
return &tracepb.Span_TimeEvent_Annotation_{
|
||||
Annotation: &tracepb.Span_TimeEvent_Annotation{
|
||||
Description: &tracepb.TruncatableString{Value: a.Message},
|
||||
Attributes: ocAttributesToProtoAttributes(a.Attributes),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func transformMessageEventToTimeEvent(e *trace.MessageEvent) *tracepb.Span_TimeEvent_MessageEvent_ {
|
||||
return &tracepb.Span_TimeEvent_MessageEvent_{
|
||||
MessageEvent: &tracepb.Span_TimeEvent_MessageEvent{
|
||||
Type: tracepb.Span_TimeEvent_MessageEvent_Type(e.EventType),
|
||||
Id: uint64(e.MessageID),
|
||||
UncompressedSize: uint64(e.UncompressedByteSize),
|
||||
CompressedSize: uint64(e.CompressedByteSize),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// clip32 clips an int to the range of an int32.
|
||||
func clip32(x int) int32 {
|
||||
if x < math.MinInt32 {
|
||||
return math.MinInt32
|
||||
}
|
||||
if x > math.MaxInt32 {
|
||||
return math.MaxInt32
|
||||
}
|
||||
return int32(x)
|
||||
}
|
||||
|
||||
func timeToTimestamp(t time.Time) *timestamp.Timestamp {
|
||||
nanoTime := t.UnixNano()
|
||||
return ×tamp.Timestamp{
|
||||
Seconds: nanoTime / 1e9,
|
||||
Nanos: int32(nanoTime % 1e9),
|
||||
}
|
||||
}
|
||||
|
||||
func ocSpanKindToProtoSpanKind(kind int) tracepb.Span_SpanKind {
|
||||
switch kind {
|
||||
case trace.SpanKindClient:
|
||||
return tracepb.Span_CLIENT
|
||||
case trace.SpanKindServer:
|
||||
return tracepb.Span_SERVER
|
||||
default:
|
||||
return tracepb.Span_SPAN_KIND_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func ocTracestateToProtoTracestate(ts *tracestate.Tracestate) *tracepb.Span_Tracestate {
|
||||
if ts == nil {
|
||||
return nil
|
||||
}
|
||||
return &tracepb.Span_Tracestate{
|
||||
Entries: ocTracestateEntriesToProtoTracestateEntries(ts.Entries()),
|
||||
}
|
||||
}
|
||||
|
||||
func ocTracestateEntriesToProtoTracestateEntries(entries []tracestate.Entry) []*tracepb.Span_Tracestate_Entry {
|
||||
protoEntries := make([]*tracepb.Span_Tracestate_Entry, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
protoEntries = append(protoEntries, &tracepb.Span_Tracestate_Entry{
|
||||
Key: entry.Key,
|
||||
Value: entry.Value,
|
||||
})
|
||||
}
|
||||
return protoEntries
|
||||
}
|
274
vendor/contrib.go.opencensus.io/exporter/ocagent/transform_stats_to_metrics.go
generated
vendored
Normal file
274
vendor/contrib.go.opencensus.io/exporter/ocagent/transform_stats_to_metrics.go
generated
vendored
Normal file
|
@ -0,0 +1,274 @@
|
|||
// Copyright 2018, OpenCensus 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 ocagent
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"go.opencensus.io/stats"
|
||||
"go.opencensus.io/stats/view"
|
||||
"go.opencensus.io/tag"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/timestamp"
|
||||
|
||||
metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1"
|
||||
)
|
||||
|
||||
var (
|
||||
errNilMeasure = errors.New("expecting a non-nil stats.Measure")
|
||||
errNilView = errors.New("expecting a non-nil view.View")
|
||||
errNilViewData = errors.New("expecting a non-nil view.Data")
|
||||
)
|
||||
|
||||
func viewDataToMetric(vd *view.Data) (*metricspb.Metric, error) {
|
||||
if vd == nil {
|
||||
return nil, errNilViewData
|
||||
}
|
||||
|
||||
descriptor, err := viewToMetricDescriptor(vd.View)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
timeseries, err := viewDataToTimeseries(vd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metric := &metricspb.Metric{
|
||||
MetricDescriptor: descriptor,
|
||||
Timeseries: timeseries,
|
||||
}
|
||||
return metric, nil
|
||||
}
|
||||
|
||||
func viewToMetricDescriptor(v *view.View) (*metricspb.MetricDescriptor, error) {
|
||||
if v == nil {
|
||||
return nil, errNilView
|
||||
}
|
||||
if v.Measure == nil {
|
||||
return nil, errNilMeasure
|
||||
}
|
||||
|
||||
desc := &metricspb.MetricDescriptor{
|
||||
Name: stringOrCall(v.Name, v.Measure.Name),
|
||||
Description: stringOrCall(v.Description, v.Measure.Description),
|
||||
Unit: v.Measure.Unit(),
|
||||
Type: aggregationToMetricDescriptorType(v),
|
||||
LabelKeys: tagKeysToLabelKeys(v.TagKeys),
|
||||
}
|
||||
return desc, nil
|
||||
}
|
||||
|
||||
func stringOrCall(first string, call func() string) string {
|
||||
if first != "" {
|
||||
return first
|
||||
}
|
||||
return call()
|
||||
}
|
||||
|
||||
type measureType uint
|
||||
|
||||
const (
|
||||
measureUnknown measureType = iota
|
||||
measureInt64
|
||||
measureFloat64
|
||||
)
|
||||
|
||||
func measureTypeFromMeasure(m stats.Measure) measureType {
|
||||
switch m.(type) {
|
||||
default:
|
||||
return measureUnknown
|
||||
case *stats.Float64Measure:
|
||||
return measureFloat64
|
||||
case *stats.Int64Measure:
|
||||
return measureInt64
|
||||
}
|
||||
}
|
||||
|
||||
func aggregationToMetricDescriptorType(v *view.View) metricspb.MetricDescriptor_Type {
|
||||
if v == nil || v.Aggregation == nil {
|
||||
return metricspb.MetricDescriptor_UNSPECIFIED
|
||||
}
|
||||
if v.Measure == nil {
|
||||
return metricspb.MetricDescriptor_UNSPECIFIED
|
||||
}
|
||||
|
||||
switch v.Aggregation.Type {
|
||||
case view.AggTypeCount:
|
||||
// Cumulative on int64
|
||||
return metricspb.MetricDescriptor_CUMULATIVE_INT64
|
||||
|
||||
case view.AggTypeDistribution:
|
||||
// Cumulative types
|
||||
return metricspb.MetricDescriptor_CUMULATIVE_DISTRIBUTION
|
||||
|
||||
case view.AggTypeLastValue:
|
||||
// Gauge types
|
||||
switch measureTypeFromMeasure(v.Measure) {
|
||||
case measureFloat64:
|
||||
return metricspb.MetricDescriptor_GAUGE_DOUBLE
|
||||
case measureInt64:
|
||||
return metricspb.MetricDescriptor_GAUGE_INT64
|
||||
}
|
||||
|
||||
case view.AggTypeSum:
|
||||
// Cumulative types
|
||||
switch measureTypeFromMeasure(v.Measure) {
|
||||
case measureFloat64:
|
||||
return metricspb.MetricDescriptor_CUMULATIVE_DOUBLE
|
||||
case measureInt64:
|
||||
return metricspb.MetricDescriptor_CUMULATIVE_INT64
|
||||
}
|
||||
}
|
||||
|
||||
// For all other cases, return unspecified.
|
||||
return metricspb.MetricDescriptor_UNSPECIFIED
|
||||
}
|
||||
|
||||
func tagKeysToLabelKeys(tagKeys []tag.Key) []*metricspb.LabelKey {
|
||||
labelKeys := make([]*metricspb.LabelKey, 0, len(tagKeys))
|
||||
for _, tagKey := range tagKeys {
|
||||
labelKeys = append(labelKeys, &metricspb.LabelKey{
|
||||
Key: tagKey.Name(),
|
||||
})
|
||||
}
|
||||
return labelKeys
|
||||
}
|
||||
|
||||
func viewDataToTimeseries(vd *view.Data) ([]*metricspb.TimeSeries, error) {
|
||||
if vd == nil || len(vd.Rows) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Given that view.Data only contains Start, End
|
||||
// the timestamps for all the row data will be the exact same
|
||||
// per aggregation. However, the values will differ.
|
||||
// Each row has its own tags.
|
||||
startTimestamp := timeToProtoTimestamp(vd.Start)
|
||||
endTimestamp := timeToProtoTimestamp(vd.End)
|
||||
|
||||
mType := measureTypeFromMeasure(vd.View.Measure)
|
||||
timeseries := make([]*metricspb.TimeSeries, 0, len(vd.Rows))
|
||||
// It is imperative that the ordering of "LabelValues" matches those
|
||||
// of the Label keys in the metric descriptor.
|
||||
for _, row := range vd.Rows {
|
||||
labelValues := labelValuesFromTags(row.Tags)
|
||||
point := rowToPoint(vd.View, row, endTimestamp, mType)
|
||||
timeseries = append(timeseries, &metricspb.TimeSeries{
|
||||
StartTimestamp: startTimestamp,
|
||||
LabelValues: labelValues,
|
||||
Points: []*metricspb.Point{point},
|
||||
})
|
||||
}
|
||||
|
||||
if len(timeseries) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return timeseries, nil
|
||||
}
|
||||
|
||||
func timeToProtoTimestamp(t time.Time) *timestamp.Timestamp {
|
||||
unixNano := t.UnixNano()
|
||||
return ×tamp.Timestamp{
|
||||
Seconds: int64(unixNano / 1e9),
|
||||
Nanos: int32(unixNano % 1e9),
|
||||
}
|
||||
}
|
||||
|
||||
func rowToPoint(v *view.View, row *view.Row, endTimestamp *timestamp.Timestamp, mType measureType) *metricspb.Point {
|
||||
pt := &metricspb.Point{
|
||||
Timestamp: endTimestamp,
|
||||
}
|
||||
|
||||
switch data := row.Data.(type) {
|
||||
case *view.CountData:
|
||||
pt.Value = &metricspb.Point_Int64Value{Int64Value: data.Value}
|
||||
|
||||
case *view.DistributionData:
|
||||
pt.Value = &metricspb.Point_DistributionValue{
|
||||
DistributionValue: &metricspb.DistributionValue{
|
||||
Count: data.Count,
|
||||
Sum: float64(data.Count) * data.Mean, // because Mean := Sum/Count
|
||||
// TODO: Add Exemplar
|
||||
Buckets: bucketsToProtoBuckets(data.CountPerBucket),
|
||||
BucketOptions: &metricspb.DistributionValue_BucketOptions{
|
||||
Type: &metricspb.DistributionValue_BucketOptions_Explicit_{
|
||||
Explicit: &metricspb.DistributionValue_BucketOptions_Explicit{
|
||||
Bounds: v.Aggregation.Buckets,
|
||||
},
|
||||
},
|
||||
},
|
||||
SumOfSquaredDeviation: data.SumOfSquaredDev,
|
||||
}}
|
||||
|
||||
case *view.LastValueData:
|
||||
setPointValue(pt, data.Value, mType)
|
||||
|
||||
case *view.SumData:
|
||||
setPointValue(pt, data.Value, mType)
|
||||
}
|
||||
|
||||
return pt
|
||||
}
|
||||
|
||||
// Not returning anything from this function because metricspb.Point.is_Value is an unexported
|
||||
// interface hence we just have to set its value by pointer.
|
||||
func setPointValue(pt *metricspb.Point, value float64, mType measureType) {
|
||||
if mType == measureInt64 {
|
||||
pt.Value = &metricspb.Point_Int64Value{Int64Value: int64(value)}
|
||||
} else {
|
||||
pt.Value = &metricspb.Point_DoubleValue{DoubleValue: value}
|
||||
}
|
||||
}
|
||||
|
||||
func bucketsToProtoBuckets(countPerBucket []int64) []*metricspb.DistributionValue_Bucket {
|
||||
distBuckets := make([]*metricspb.DistributionValue_Bucket, len(countPerBucket))
|
||||
for i := 0; i < len(countPerBucket); i++ {
|
||||
count := countPerBucket[i]
|
||||
|
||||
distBuckets[i] = &metricspb.DistributionValue_Bucket{
|
||||
Count: count,
|
||||
}
|
||||
}
|
||||
|
||||
return distBuckets
|
||||
}
|
||||
|
||||
func labelValuesFromTags(tags []tag.Tag) []*metricspb.LabelValue {
|
||||
if len(tags) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
labelValues := make([]*metricspb.LabelValue, 0, len(tags))
|
||||
for _, tag_ := range tags {
|
||||
labelValues = append(labelValues, &metricspb.LabelValue{
|
||||
Value: tag_.Value,
|
||||
|
||||
// It is imperative that we set the "HasValue" attribute,
|
||||
// in order to distinguish missing a label from the empty string.
|
||||
// https://godoc.org/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1#LabelValue.HasValue
|
||||
//
|
||||
// OpenCensus-Go uses non-pointers for tags as seen by this function's arguments,
|
||||
// so the best case that we can use to distinguish missing labels/tags from the
|
||||
// empty string is by checking if the Tag.Key.Name() != "" to indicate that we have
|
||||
// a value.
|
||||
HasValue: tag_.Key.Name() != "",
|
||||
})
|
||||
}
|
||||
return labelValues
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2018, OpenCensus 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 ocagent
|
||||
|
||||
const Version = "0.0.1"
|
275
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go
generated
vendored
Normal file
275
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,275 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: opencensus/proto/agent/metrics/v1/metrics_service.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
v1 "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1"
|
||||
v11 "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1"
|
||||
v12 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type ExportMetricsServiceRequest struct {
|
||||
// This is required only in the first message on the stream or if the
|
||||
// previous sent ExportMetricsServiceRequest message has a different Node (e.g.
|
||||
// when the same RPC is used to send Metrics from multiple Applications).
|
||||
Node *v1.Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
|
||||
// A list of metrics that belong to the last received Node.
|
||||
Metrics []*v11.Metric `protobuf:"bytes,2,rep,name=metrics,proto3" json:"metrics,omitempty"`
|
||||
// The resource for the metrics in this message that do not have an explicit
|
||||
// resource set.
|
||||
// If unset, the most recently set resource in the RPC stream applies. It is
|
||||
// valid to never be set within a stream, e.g. when no resource info is known
|
||||
// at all or when all sent metrics have an explicit resource set.
|
||||
Resource *v12.Resource `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ExportMetricsServiceRequest) Reset() { *m = ExportMetricsServiceRequest{} }
|
||||
func (m *ExportMetricsServiceRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExportMetricsServiceRequest) ProtoMessage() {}
|
||||
func (*ExportMetricsServiceRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_47e253a956287d04, []int{0}
|
||||
}
|
||||
|
||||
func (m *ExportMetricsServiceRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ExportMetricsServiceRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ExportMetricsServiceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ExportMetricsServiceRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ExportMetricsServiceRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ExportMetricsServiceRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ExportMetricsServiceRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ExportMetricsServiceRequest.Size(m)
|
||||
}
|
||||
func (m *ExportMetricsServiceRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ExportMetricsServiceRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ExportMetricsServiceRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ExportMetricsServiceRequest) GetNode() *v1.Node {
|
||||
if m != nil {
|
||||
return m.Node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ExportMetricsServiceRequest) GetMetrics() []*v11.Metric {
|
||||
if m != nil {
|
||||
return m.Metrics
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ExportMetricsServiceRequest) GetResource() *v12.Resource {
|
||||
if m != nil {
|
||||
return m.Resource
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExportMetricsServiceResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ExportMetricsServiceResponse) Reset() { *m = ExportMetricsServiceResponse{} }
|
||||
func (m *ExportMetricsServiceResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExportMetricsServiceResponse) ProtoMessage() {}
|
||||
func (*ExportMetricsServiceResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_47e253a956287d04, []int{1}
|
||||
}
|
||||
|
||||
func (m *ExportMetricsServiceResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ExportMetricsServiceResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ExportMetricsServiceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ExportMetricsServiceResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ExportMetricsServiceResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ExportMetricsServiceResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ExportMetricsServiceResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ExportMetricsServiceResponse.Size(m)
|
||||
}
|
||||
func (m *ExportMetricsServiceResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ExportMetricsServiceResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ExportMetricsServiceResponse proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ExportMetricsServiceRequest)(nil), "opencensus.proto.agent.metrics.v1.ExportMetricsServiceRequest")
|
||||
proto.RegisterType((*ExportMetricsServiceResponse)(nil), "opencensus.proto.agent.metrics.v1.ExportMetricsServiceResponse")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("opencensus/proto/agent/metrics/v1/metrics_service.proto", fileDescriptor_47e253a956287d04)
|
||||
}
|
||||
|
||||
var fileDescriptor_47e253a956287d04 = []byte{
|
||||
// 361 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x41, 0x4a, 0xc3, 0x40,
|
||||
0x14, 0x86, 0x9d, 0x56, 0xaa, 0x4c, 0xc1, 0x45, 0xdc, 0x94, 0x2a, 0xd2, 0x56, 0x91, 0x8a, 0x64,
|
||||
0x62, 0xea, 0x42, 0x10, 0x54, 0xac, 0xb8, 0x11, 0xd4, 0x12, 0xc1, 0x85, 0x1b, 0x69, 0xd3, 0x47,
|
||||
0xcc, 0x22, 0x33, 0x71, 0x66, 0x12, 0xbc, 0x85, 0x77, 0x70, 0xef, 0x8d, 0x3c, 0x81, 0xa7, 0x90,
|
||||
0xe4, 0x4d, 0x5a, 0x4a, 0x8c, 0x05, 0x77, 0x8f, 0xe4, 0xff, 0xfe, 0xf7, 0xff, 0x33, 0x43, 0x4f,
|
||||
0x44, 0x0c, 0xdc, 0x07, 0xae, 0x12, 0xe5, 0xc4, 0x52, 0x68, 0xe1, 0x8c, 0x03, 0xe0, 0xda, 0x89,
|
||||
0x40, 0xcb, 0xd0, 0x57, 0x4e, 0xea, 0x16, 0xe3, 0xb3, 0x02, 0x99, 0x86, 0x3e, 0xb0, 0x5c, 0x66,
|
||||
0x75, 0xe7, 0x20, 0x7e, 0x61, 0x39, 0xc8, 0x8c, 0x9a, 0xa5, 0x6e, 0xdb, 0xae, 0xf0, 0xf6, 0x45,
|
||||
0x14, 0x09, 0x9e, 0x59, 0xe3, 0x84, 0x7c, 0xfb, 0xa0, 0x24, 0x2f, 0x87, 0x30, 0xd2, 0xc3, 0x92,
|
||||
0x54, 0x82, 0x12, 0x89, 0xf4, 0x21, 0xd3, 0x16, 0x33, 0x8a, 0x7b, 0x5f, 0x84, 0x6e, 0x5d, 0xbf,
|
||||
0xc5, 0x42, 0xea, 0x5b, 0x34, 0x79, 0xc0, 0x22, 0x1e, 0xbc, 0x26, 0xa0, 0xb4, 0x75, 0x4a, 0x57,
|
||||
0xb9, 0x98, 0x42, 0x8b, 0x74, 0x48, 0xbf, 0x39, 0xd8, 0x67, 0x15, 0xc5, 0x4c, 0xd6, 0xd4, 0x65,
|
||||
0x77, 0x62, 0x0a, 0x5e, 0xce, 0x58, 0x67, 0x74, 0xcd, 0x24, 0x6b, 0xd5, 0x3a, 0xf5, 0x7e, 0x73,
|
||||
0xb0, 0x5b, 0xc6, 0xe7, 0x27, 0xc2, 0x30, 0x80, 0x57, 0x30, 0xd6, 0x90, 0xae, 0x17, 0x61, 0x5b,
|
||||
0xf5, 0xaa, 0xf5, 0xb3, 0x3a, 0xa9, 0xcb, 0x3c, 0x33, 0x7b, 0x33, 0xae, 0xb7, 0x43, 0xb7, 0x7f,
|
||||
0x6f, 0xa7, 0x62, 0xc1, 0x15, 0x0c, 0x3e, 0x08, 0xdd, 0x58, 0xfc, 0x65, 0xbd, 0x13, 0xda, 0x40,
|
||||
0xc6, 0x3a, 0x67, 0x4b, 0xef, 0x91, 0xfd, 0x71, 0x78, 0xed, 0x8b, 0x7f, 0xf3, 0x18, 0xaf, 0xb7,
|
||||
0xd2, 0x27, 0x47, 0x64, 0xf8, 0x49, 0xe8, 0x5e, 0x28, 0x96, 0x7b, 0x0d, 0x37, 0x17, 0x6d, 0x46,
|
||||
0x99, 0x6a, 0x44, 0x9e, 0x6e, 0x82, 0x50, 0xbf, 0x24, 0x93, 0xec, 0x92, 0x1c, 0x34, 0xb0, 0x43,
|
||||
0xae, 0xb4, 0x4c, 0x22, 0xe0, 0x7a, 0xac, 0x43, 0xc1, 0x9d, 0xb9, 0xb7, 0x8d, 0x4f, 0x26, 0x00,
|
||||
0x6e, 0x07, 0xe5, 0xf7, 0xfe, 0x5d, 0xeb, 0xde, 0xc7, 0xc0, 0xaf, 0x30, 0x46, 0xbe, 0x80, 0x5d,
|
||||
0xe6, 0x31, 0xcc, 0x6a, 0xf6, 0xe8, 0x4e, 0x1a, 0xb9, 0xc5, 0xf1, 0x4f, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x19, 0x28, 0xa4, 0x50, 0x3f, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// MetricsServiceClient is the client API for MetricsService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type MetricsServiceClient interface {
|
||||
// For performance reasons, it is recommended to keep this RPC
|
||||
// alive for the entire life of the application.
|
||||
Export(ctx context.Context, opts ...grpc.CallOption) (MetricsService_ExportClient, error)
|
||||
}
|
||||
|
||||
type metricsServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewMetricsServiceClient(cc *grpc.ClientConn) MetricsServiceClient {
|
||||
return &metricsServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *metricsServiceClient) Export(ctx context.Context, opts ...grpc.CallOption) (MetricsService_ExportClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_MetricsService_serviceDesc.Streams[0], "/opencensus.proto.agent.metrics.v1.MetricsService/Export", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &metricsServiceExportClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type MetricsService_ExportClient interface {
|
||||
Send(*ExportMetricsServiceRequest) error
|
||||
Recv() (*ExportMetricsServiceResponse, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type metricsServiceExportClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *metricsServiceExportClient) Send(m *ExportMetricsServiceRequest) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *metricsServiceExportClient) Recv() (*ExportMetricsServiceResponse, error) {
|
||||
m := new(ExportMetricsServiceResponse)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// MetricsServiceServer is the server API for MetricsService service.
|
||||
type MetricsServiceServer interface {
|
||||
// For performance reasons, it is recommended to keep this RPC
|
||||
// alive for the entire life of the application.
|
||||
Export(MetricsService_ExportServer) error
|
||||
}
|
||||
|
||||
// UnimplementedMetricsServiceServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedMetricsServiceServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedMetricsServiceServer) Export(srv MetricsService_ExportServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method Export not implemented")
|
||||
}
|
||||
|
||||
func RegisterMetricsServiceServer(s *grpc.Server, srv MetricsServiceServer) {
|
||||
s.RegisterService(&_MetricsService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _MetricsService_Export_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(MetricsServiceServer).Export(&metricsServiceExportServer{stream})
|
||||
}
|
||||
|
||||
type MetricsService_ExportServer interface {
|
||||
Send(*ExportMetricsServiceResponse) error
|
||||
Recv() (*ExportMetricsServiceRequest, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type metricsServiceExportServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *metricsServiceExportServer) Send(m *ExportMetricsServiceResponse) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *metricsServiceExportServer) Recv() (*ExportMetricsServiceRequest, error) {
|
||||
m := new(ExportMetricsServiceRequest)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
var _MetricsService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "opencensus.proto.agent.metrics.v1.MetricsService",
|
||||
HandlerType: (*MetricsServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "Export",
|
||||
Handler: _MetricsService_Export_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "opencensus/proto/agent/metrics/v1/metrics_service.proto",
|
||||
}
|
150
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.gw.go
generated
vendored
Normal file
150
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.gw.go
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: opencensus/proto/agent/metrics/v1/metrics_service.proto
|
||||
|
||||
/*
|
||||
Package v1 is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
|
||||
func request_MetricsService_Export_0(ctx context.Context, marshaler runtime.Marshaler, client MetricsServiceClient, req *http.Request, pathParams map[string]string) (MetricsService_ExportClient, runtime.ServerMetadata, error) {
|
||||
var metadata runtime.ServerMetadata
|
||||
stream, err := client.Export(ctx)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to start streaming: %v", err)
|
||||
return nil, metadata, err
|
||||
}
|
||||
dec := marshaler.NewDecoder(req.Body)
|
||||
handleSend := func() error {
|
||||
var protoReq ExportMetricsServiceRequest
|
||||
err := dec.Decode(&protoReq)
|
||||
if err == io.EOF {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to decode request: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := stream.Send(&protoReq); err != nil {
|
||||
grpclog.Infof("Failed to send request: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := handleSend(); err != nil {
|
||||
if cerr := stream.CloseSend(); cerr != nil {
|
||||
grpclog.Infof("Failed to terminate client stream: %v", cerr)
|
||||
}
|
||||
if err == io.EOF {
|
||||
return stream, metadata, nil
|
||||
}
|
||||
return nil, metadata, err
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
if err := handleSend(); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err := stream.CloseSend(); err != nil {
|
||||
grpclog.Infof("Failed to terminate client stream: %v", err)
|
||||
}
|
||||
}()
|
||||
header, err := stream.Header()
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to get header from client: %v", err)
|
||||
return nil, metadata, err
|
||||
}
|
||||
metadata.HeaderMD = header
|
||||
return stream, metadata, nil
|
||||
}
|
||||
|
||||
// RegisterMetricsServiceHandlerFromEndpoint is same as RegisterMetricsServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterMetricsServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterMetricsServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterMetricsServiceHandler registers the http handlers for service MetricsService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterMetricsServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterMetricsServiceHandlerClient(ctx, mux, NewMetricsServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterMetricsServiceHandlerClient registers the http handlers for service MetricsService
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MetricsServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MetricsServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "MetricsServiceClient" to call the correct interceptors.
|
||||
func RegisterMetricsServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MetricsServiceClient) error {
|
||||
|
||||
mux.Handle("POST", pattern_MetricsService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_MetricsService_Export_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_MetricsService_Export_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_MetricsService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "metrics"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_MetricsService_Export_0 = runtime.ForwardResponseStream
|
||||
)
|
457
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go
generated
vendored
Normal file
457
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,457 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: opencensus/proto/agent/trace/v1/trace_service.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
v1 "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1"
|
||||
v12 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1"
|
||||
v11 "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type CurrentLibraryConfig struct {
|
||||
// This is required only in the first message on the stream or if the
|
||||
// previous sent CurrentLibraryConfig message has a different Node (e.g.
|
||||
// when the same RPC is used to configure multiple Applications).
|
||||
Node *v1.Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
|
||||
// Current configuration.
|
||||
Config *v11.TraceConfig `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CurrentLibraryConfig) Reset() { *m = CurrentLibraryConfig{} }
|
||||
func (m *CurrentLibraryConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*CurrentLibraryConfig) ProtoMessage() {}
|
||||
func (*CurrentLibraryConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7027f99caf7ac6a5, []int{0}
|
||||
}
|
||||
|
||||
func (m *CurrentLibraryConfig) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CurrentLibraryConfig.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CurrentLibraryConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CurrentLibraryConfig.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CurrentLibraryConfig) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CurrentLibraryConfig.Merge(m, src)
|
||||
}
|
||||
func (m *CurrentLibraryConfig) XXX_Size() int {
|
||||
return xxx_messageInfo_CurrentLibraryConfig.Size(m)
|
||||
}
|
||||
func (m *CurrentLibraryConfig) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CurrentLibraryConfig.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CurrentLibraryConfig proto.InternalMessageInfo
|
||||
|
||||
func (m *CurrentLibraryConfig) GetNode() *v1.Node {
|
||||
if m != nil {
|
||||
return m.Node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CurrentLibraryConfig) GetConfig() *v11.TraceConfig {
|
||||
if m != nil {
|
||||
return m.Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UpdatedLibraryConfig struct {
|
||||
// This field is ignored when the RPC is used to configure only one Application.
|
||||
// This is required only in the first message on the stream or if the
|
||||
// previous sent UpdatedLibraryConfig message has a different Node.
|
||||
Node *v1.Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
|
||||
// Requested updated configuration.
|
||||
Config *v11.TraceConfig `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *UpdatedLibraryConfig) Reset() { *m = UpdatedLibraryConfig{} }
|
||||
func (m *UpdatedLibraryConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*UpdatedLibraryConfig) ProtoMessage() {}
|
||||
func (*UpdatedLibraryConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7027f99caf7ac6a5, []int{1}
|
||||
}
|
||||
|
||||
func (m *UpdatedLibraryConfig) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_UpdatedLibraryConfig.Unmarshal(m, b)
|
||||
}
|
||||
func (m *UpdatedLibraryConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_UpdatedLibraryConfig.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *UpdatedLibraryConfig) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_UpdatedLibraryConfig.Merge(m, src)
|
||||
}
|
||||
func (m *UpdatedLibraryConfig) XXX_Size() int {
|
||||
return xxx_messageInfo_UpdatedLibraryConfig.Size(m)
|
||||
}
|
||||
func (m *UpdatedLibraryConfig) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_UpdatedLibraryConfig.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_UpdatedLibraryConfig proto.InternalMessageInfo
|
||||
|
||||
func (m *UpdatedLibraryConfig) GetNode() *v1.Node {
|
||||
if m != nil {
|
||||
return m.Node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdatedLibraryConfig) GetConfig() *v11.TraceConfig {
|
||||
if m != nil {
|
||||
return m.Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExportTraceServiceRequest struct {
|
||||
// This is required only in the first message on the stream or if the
|
||||
// previous sent ExportTraceServiceRequest message has a different Node (e.g.
|
||||
// when the same RPC is used to send Spans from multiple Applications).
|
||||
Node *v1.Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
|
||||
// A list of Spans that belong to the last received Node.
|
||||
Spans []*v11.Span `protobuf:"bytes,2,rep,name=spans,proto3" json:"spans,omitempty"`
|
||||
// The resource for the spans in this message that do not have an explicit
|
||||
// resource set.
|
||||
// If unset, the most recently set resource in the RPC stream applies. It is
|
||||
// valid to never be set within a stream, e.g. when no resource info is known.
|
||||
Resource *v12.Resource `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ExportTraceServiceRequest) Reset() { *m = ExportTraceServiceRequest{} }
|
||||
func (m *ExportTraceServiceRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExportTraceServiceRequest) ProtoMessage() {}
|
||||
func (*ExportTraceServiceRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7027f99caf7ac6a5, []int{2}
|
||||
}
|
||||
|
||||
func (m *ExportTraceServiceRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ExportTraceServiceRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ExportTraceServiceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ExportTraceServiceRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ExportTraceServiceRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ExportTraceServiceRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ExportTraceServiceRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ExportTraceServiceRequest.Size(m)
|
||||
}
|
||||
func (m *ExportTraceServiceRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ExportTraceServiceRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ExportTraceServiceRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ExportTraceServiceRequest) GetNode() *v1.Node {
|
||||
if m != nil {
|
||||
return m.Node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ExportTraceServiceRequest) GetSpans() []*v11.Span {
|
||||
if m != nil {
|
||||
return m.Spans
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ExportTraceServiceRequest) GetResource() *v12.Resource {
|
||||
if m != nil {
|
||||
return m.Resource
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExportTraceServiceResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ExportTraceServiceResponse) Reset() { *m = ExportTraceServiceResponse{} }
|
||||
func (m *ExportTraceServiceResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ExportTraceServiceResponse) ProtoMessage() {}
|
||||
func (*ExportTraceServiceResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_7027f99caf7ac6a5, []int{3}
|
||||
}
|
||||
|
||||
func (m *ExportTraceServiceResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ExportTraceServiceResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ExportTraceServiceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ExportTraceServiceResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ExportTraceServiceResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ExportTraceServiceResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ExportTraceServiceResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ExportTraceServiceResponse.Size(m)
|
||||
}
|
||||
func (m *ExportTraceServiceResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ExportTraceServiceResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ExportTraceServiceResponse proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*CurrentLibraryConfig)(nil), "opencensus.proto.agent.trace.v1.CurrentLibraryConfig")
|
||||
proto.RegisterType((*UpdatedLibraryConfig)(nil), "opencensus.proto.agent.trace.v1.UpdatedLibraryConfig")
|
||||
proto.RegisterType((*ExportTraceServiceRequest)(nil), "opencensus.proto.agent.trace.v1.ExportTraceServiceRequest")
|
||||
proto.RegisterType((*ExportTraceServiceResponse)(nil), "opencensus.proto.agent.trace.v1.ExportTraceServiceResponse")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("opencensus/proto/agent/trace/v1/trace_service.proto", fileDescriptor_7027f99caf7ac6a5)
|
||||
}
|
||||
|
||||
var fileDescriptor_7027f99caf7ac6a5 = []byte{
|
||||
// 442 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x94, 0xcf, 0xaa, 0xd4, 0x30,
|
||||
0x14, 0xc6, 0x4d, 0xaf, 0x16, 0xc9, 0x75, 0x63, 0x71, 0x51, 0x8b, 0x30, 0x97, 0x82, 0x32, 0xa0,
|
||||
0x4d, 0xed, 0x5c, 0xee, 0xe6, 0x0a, 0x82, 0x33, 0x08, 0x2e, 0x44, 0x2f, 0x1d, 0x75, 0xe1, 0x66,
|
||||
0xe8, 0xb4, 0xc7, 0xda, 0xc5, 0x24, 0x31, 0x49, 0x8b, 0x82, 0x7b, 0xf7, 0x2e, 0x7c, 0x03, 0x5f,
|
||||
0xc8, 0xc7, 0xf0, 0x29, 0xa4, 0x39, 0x9d, 0x3f, 0x3a, 0x53, 0x0b, 0xba, 0xb9, 0xbb, 0x43, 0xf3,
|
||||
0xfd, 0xbe, 0xf3, 0x25, 0x39, 0x29, 0x3d, 0x15, 0x12, 0x78, 0x0e, 0x5c, 0xd7, 0x3a, 0x96, 0x4a,
|
||||
0x18, 0x11, 0x67, 0x25, 0x70, 0x13, 0x1b, 0x95, 0xe5, 0x10, 0x37, 0x09, 0x16, 0x0b, 0x0d, 0xaa,
|
||||
0xa9, 0x72, 0x60, 0x56, 0xe2, 0x8d, 0xb6, 0x10, 0x7e, 0x61, 0x16, 0x62, 0x56, 0xcb, 0x9a, 0x24,
|
||||
0x88, 0x7a, 0x5c, 0x73, 0xb1, 0x5a, 0x09, 0xde, 0xda, 0x62, 0x85, 0x74, 0x70, 0x7f, 0x4f, 0xae,
|
||||
0x40, 0x8b, 0x5a, 0x61, 0x82, 0x75, 0xdd, 0x89, 0xef, 0xee, 0x89, 0x7f, 0xcf, 0xda, 0xc9, 0x1e,
|
||||
0x0c, 0xc8, 0x16, 0xb9, 0xe0, 0xef, 0xaa, 0x12, 0xd5, 0xe1, 0x57, 0x42, 0x6f, 0xcd, 0x6a, 0xa5,
|
||||
0x80, 0x9b, 0xe7, 0xd5, 0x52, 0x65, 0xea, 0xd3, 0xcc, 0x2e, 0x7b, 0xe7, 0xf4, 0x2a, 0x17, 0x05,
|
||||
0xf8, 0xe4, 0x84, 0x8c, 0x8f, 0x27, 0xf7, 0x58, 0xcf, 0xce, 0xbb, 0xed, 0x34, 0x09, 0x7b, 0x21,
|
||||
0x0a, 0x48, 0x2d, 0xe3, 0x3d, 0xa6, 0x2e, 0x36, 0xf1, 0x9d, 0x3e, 0x7a, 0x7d, 0x62, 0xec, 0x55,
|
||||
0x5b, 0x60, 0xcf, 0xb4, 0xa3, 0x6c, 0xa8, 0xd7, 0xb2, 0xc8, 0x0c, 0x14, 0x97, 0x27, 0xd4, 0x0f,
|
||||
0x42, 0x6f, 0x3f, 0xfd, 0x28, 0x85, 0x32, 0x76, 0x75, 0x8e, 0x83, 0x91, 0xc2, 0x87, 0x1a, 0xb4,
|
||||
0xf9, 0xaf, 0x64, 0x67, 0xf4, 0x9a, 0x96, 0x19, 0xd7, 0xbe, 0x73, 0x72, 0x34, 0x3e, 0x9e, 0x8c,
|
||||
0xfe, 0x12, 0x6c, 0x2e, 0x33, 0x9e, 0xa2, 0xda, 0x9b, 0xd2, 0xeb, 0xeb, 0x09, 0xf1, 0x8f, 0xfa,
|
||||
0xda, 0x6e, 0x66, 0xa8, 0x49, 0x58, 0xda, 0xd5, 0xe9, 0x86, 0x0b, 0xef, 0xd0, 0xe0, 0xd0, 0x9e,
|
||||
0xb4, 0x14, 0x5c, 0xc3, 0xe4, 0x9b, 0x43, 0x6f, 0xec, 0x2e, 0x78, 0x9f, 0xa9, 0xdb, 0xdd, 0xc4,
|
||||
0x19, 0x1b, 0x78, 0x0a, 0xec, 0xd0, 0x54, 0x05, 0xc3, 0xd8, 0xa1, 0x7b, 0x0f, 0xaf, 0x8c, 0xc9,
|
||||
0x43, 0xe2, 0x7d, 0x21, 0xd4, 0xc5, 0xb4, 0xde, 0xf9, 0xa0, 0x4f, 0xef, 0x55, 0x05, 0x8f, 0xfe,
|
||||
0x89, 0xc5, 0x23, 0xc1, 0x24, 0xd3, 0xef, 0x84, 0x86, 0x95, 0x18, 0xf2, 0x99, 0xde, 0xdc, 0xb5,
|
||||
0xb8, 0x68, 0x15, 0x17, 0xe4, 0xed, 0xb3, 0xb2, 0x32, 0xef, 0xeb, 0x65, 0x3b, 0x0a, 0x31, 0xc2,
|
||||
0x51, 0xc5, 0xb5, 0x51, 0xf5, 0x0a, 0xb8, 0xc9, 0x4c, 0x25, 0x78, 0xbc, 0xf5, 0x8d, 0xf0, 0x05,
|
||||
0x97, 0xc0, 0xa3, 0xf2, 0xcf, 0x3f, 0xd4, 0x4f, 0x67, 0xf4, 0x52, 0x02, 0x9f, 0x61, 0x00, 0x6b,
|
||||
0xcf, 0x9e, 0xd8, 0x00, 0xb6, 0x2d, 0x7b, 0x93, 0x2c, 0x5d, 0x8b, 0x9f, 0xfe, 0x0a, 0x00, 0x00,
|
||||
0xff, 0xff, 0x65, 0x76, 0xd7, 0xb9, 0xed, 0x04, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// TraceServiceClient is the client API for TraceService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type TraceServiceClient interface {
|
||||
// After initialization, this RPC must be kept alive for the entire life of
|
||||
// the application. The agent pushes configs down to applications via a
|
||||
// stream.
|
||||
Config(ctx context.Context, opts ...grpc.CallOption) (TraceService_ConfigClient, error)
|
||||
// For performance reasons, it is recommended to keep this RPC
|
||||
// alive for the entire life of the application.
|
||||
Export(ctx context.Context, opts ...grpc.CallOption) (TraceService_ExportClient, error)
|
||||
}
|
||||
|
||||
type traceServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewTraceServiceClient(cc *grpc.ClientConn) TraceServiceClient {
|
||||
return &traceServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *traceServiceClient) Config(ctx context.Context, opts ...grpc.CallOption) (TraceService_ConfigClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_TraceService_serviceDesc.Streams[0], "/opencensus.proto.agent.trace.v1.TraceService/Config", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &traceServiceConfigClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type TraceService_ConfigClient interface {
|
||||
Send(*CurrentLibraryConfig) error
|
||||
Recv() (*UpdatedLibraryConfig, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type traceServiceConfigClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *traceServiceConfigClient) Send(m *CurrentLibraryConfig) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *traceServiceConfigClient) Recv() (*UpdatedLibraryConfig, error) {
|
||||
m := new(UpdatedLibraryConfig)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *traceServiceClient) Export(ctx context.Context, opts ...grpc.CallOption) (TraceService_ExportClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_TraceService_serviceDesc.Streams[1], "/opencensus.proto.agent.trace.v1.TraceService/Export", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &traceServiceExportClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type TraceService_ExportClient interface {
|
||||
Send(*ExportTraceServiceRequest) error
|
||||
Recv() (*ExportTraceServiceResponse, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type traceServiceExportClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *traceServiceExportClient) Send(m *ExportTraceServiceRequest) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *traceServiceExportClient) Recv() (*ExportTraceServiceResponse, error) {
|
||||
m := new(ExportTraceServiceResponse)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// TraceServiceServer is the server API for TraceService service.
|
||||
type TraceServiceServer interface {
|
||||
// After initialization, this RPC must be kept alive for the entire life of
|
||||
// the application. The agent pushes configs down to applications via a
|
||||
// stream.
|
||||
Config(TraceService_ConfigServer) error
|
||||
// For performance reasons, it is recommended to keep this RPC
|
||||
// alive for the entire life of the application.
|
||||
Export(TraceService_ExportServer) error
|
||||
}
|
||||
|
||||
// UnimplementedTraceServiceServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedTraceServiceServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedTraceServiceServer) Config(srv TraceService_ConfigServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method Config not implemented")
|
||||
}
|
||||
func (*UnimplementedTraceServiceServer) Export(srv TraceService_ExportServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method Export not implemented")
|
||||
}
|
||||
|
||||
func RegisterTraceServiceServer(s *grpc.Server, srv TraceServiceServer) {
|
||||
s.RegisterService(&_TraceService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _TraceService_Config_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(TraceServiceServer).Config(&traceServiceConfigServer{stream})
|
||||
}
|
||||
|
||||
type TraceService_ConfigServer interface {
|
||||
Send(*UpdatedLibraryConfig) error
|
||||
Recv() (*CurrentLibraryConfig, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type traceServiceConfigServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *traceServiceConfigServer) Send(m *UpdatedLibraryConfig) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *traceServiceConfigServer) Recv() (*CurrentLibraryConfig, error) {
|
||||
m := new(CurrentLibraryConfig)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func _TraceService_Export_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(TraceServiceServer).Export(&traceServiceExportServer{stream})
|
||||
}
|
||||
|
||||
type TraceService_ExportServer interface {
|
||||
Send(*ExportTraceServiceResponse) error
|
||||
Recv() (*ExportTraceServiceRequest, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type traceServiceExportServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *traceServiceExportServer) Send(m *ExportTraceServiceResponse) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *traceServiceExportServer) Recv() (*ExportTraceServiceRequest, error) {
|
||||
m := new(ExportTraceServiceRequest)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
var _TraceService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "opencensus.proto.agent.trace.v1.TraceService",
|
||||
HandlerType: (*TraceServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "Config",
|
||||
Handler: _TraceService_Config_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "Export",
|
||||
Handler: _TraceService_Export_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "opencensus/proto/agent/trace/v1/trace_service.proto",
|
||||
}
|
150
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go
generated
vendored
Normal file
150
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: opencensus/proto/agent/trace/v1/trace_service.proto
|
||||
|
||||
/*
|
||||
Package v1 is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
|
||||
func request_TraceService_Export_0(ctx context.Context, marshaler runtime.Marshaler, client TraceServiceClient, req *http.Request, pathParams map[string]string) (TraceService_ExportClient, runtime.ServerMetadata, error) {
|
||||
var metadata runtime.ServerMetadata
|
||||
stream, err := client.Export(ctx)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to start streaming: %v", err)
|
||||
return nil, metadata, err
|
||||
}
|
||||
dec := marshaler.NewDecoder(req.Body)
|
||||
handleSend := func() error {
|
||||
var protoReq ExportTraceServiceRequest
|
||||
err := dec.Decode(&protoReq)
|
||||
if err == io.EOF {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to decode request: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := stream.Send(&protoReq); err != nil {
|
||||
grpclog.Infof("Failed to send request: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := handleSend(); err != nil {
|
||||
if cerr := stream.CloseSend(); cerr != nil {
|
||||
grpclog.Infof("Failed to terminate client stream: %v", cerr)
|
||||
}
|
||||
if err == io.EOF {
|
||||
return stream, metadata, nil
|
||||
}
|
||||
return nil, metadata, err
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
if err := handleSend(); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err := stream.CloseSend(); err != nil {
|
||||
grpclog.Infof("Failed to terminate client stream: %v", err)
|
||||
}
|
||||
}()
|
||||
header, err := stream.Header()
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to get header from client: %v", err)
|
||||
return nil, metadata, err
|
||||
}
|
||||
metadata.HeaderMD = header
|
||||
return stream, metadata, nil
|
||||
}
|
||||
|
||||
// RegisterTraceServiceHandlerFromEndpoint is same as RegisterTraceServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterTraceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterTraceServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterTraceServiceHandler registers the http handlers for service TraceService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterTraceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterTraceServiceHandlerClient(ctx, mux, NewTraceServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterTraceServiceHandlerClient registers the http handlers for service TraceService
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "TraceServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "TraceServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "TraceServiceClient" to call the correct interceptors.
|
||||
func RegisterTraceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client TraceServiceClient) error {
|
||||
|
||||
mux.Handle("POST", pattern_TraceService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_TraceService_Export_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_TraceService_Export_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_TraceService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "trace"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_TraceService_Export_0 = runtime.ForwardResponseStream
|
||||
)
|
1553
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go
generated
vendored
Normal file
1553
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
359
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go
generated
vendored
Normal file
359
vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,359 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: opencensus/proto/trace/v1/trace_config.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// How spans should be sampled:
|
||||
// - Always off
|
||||
// - Always on
|
||||
// - Always follow the parent Span's decision (off if no parent).
|
||||
type ConstantSampler_ConstantDecision int32
|
||||
|
||||
const (
|
||||
ConstantSampler_ALWAYS_OFF ConstantSampler_ConstantDecision = 0
|
||||
ConstantSampler_ALWAYS_ON ConstantSampler_ConstantDecision = 1
|
||||
ConstantSampler_ALWAYS_PARENT ConstantSampler_ConstantDecision = 2
|
||||
)
|
||||
|
||||
var ConstantSampler_ConstantDecision_name = map[int32]string{
|
||||
0: "ALWAYS_OFF",
|
||||
1: "ALWAYS_ON",
|
||||
2: "ALWAYS_PARENT",
|
||||
}
|
||||
|
||||
var ConstantSampler_ConstantDecision_value = map[string]int32{
|
||||
"ALWAYS_OFF": 0,
|
||||
"ALWAYS_ON": 1,
|
||||
"ALWAYS_PARENT": 2,
|
||||
}
|
||||
|
||||
func (x ConstantSampler_ConstantDecision) String() string {
|
||||
return proto.EnumName(ConstantSampler_ConstantDecision_name, int32(x))
|
||||
}
|
||||
|
||||
func (ConstantSampler_ConstantDecision) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5359209b41ff50c5, []int{2, 0}
|
||||
}
|
||||
|
||||
// Global configuration of the trace service. All fields must be specified, or
|
||||
// the default (zero) values will be used for each type.
|
||||
type TraceConfig struct {
|
||||
// The global default sampler used to make decisions on span sampling.
|
||||
//
|
||||
// Types that are valid to be assigned to Sampler:
|
||||
// *TraceConfig_ProbabilitySampler
|
||||
// *TraceConfig_ConstantSampler
|
||||
// *TraceConfig_RateLimitingSampler
|
||||
Sampler isTraceConfig_Sampler `protobuf_oneof:"sampler"`
|
||||
// The global default max number of attributes per span.
|
||||
MaxNumberOfAttributes int64 `protobuf:"varint,4,opt,name=max_number_of_attributes,json=maxNumberOfAttributes,proto3" json:"max_number_of_attributes,omitempty"`
|
||||
// The global default max number of annotation events per span.
|
||||
MaxNumberOfAnnotations int64 `protobuf:"varint,5,opt,name=max_number_of_annotations,json=maxNumberOfAnnotations,proto3" json:"max_number_of_annotations,omitempty"`
|
||||
// The global default max number of message events per span.
|
||||
MaxNumberOfMessageEvents int64 `protobuf:"varint,6,opt,name=max_number_of_message_events,json=maxNumberOfMessageEvents,proto3" json:"max_number_of_message_events,omitempty"`
|
||||
// The global default max number of link entries per span.
|
||||
MaxNumberOfLinks int64 `protobuf:"varint,7,opt,name=max_number_of_links,json=maxNumberOfLinks,proto3" json:"max_number_of_links,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TraceConfig) Reset() { *m = TraceConfig{} }
|
||||
func (m *TraceConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*TraceConfig) ProtoMessage() {}
|
||||
func (*TraceConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5359209b41ff50c5, []int{0}
|
||||
}
|
||||
|
||||
func (m *TraceConfig) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_TraceConfig.Unmarshal(m, b)
|
||||
}
|
||||
func (m *TraceConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_TraceConfig.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *TraceConfig) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_TraceConfig.Merge(m, src)
|
||||
}
|
||||
func (m *TraceConfig) XXX_Size() int {
|
||||
return xxx_messageInfo_TraceConfig.Size(m)
|
||||
}
|
||||
func (m *TraceConfig) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_TraceConfig.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_TraceConfig proto.InternalMessageInfo
|
||||
|
||||
type isTraceConfig_Sampler interface {
|
||||
isTraceConfig_Sampler()
|
||||
}
|
||||
|
||||
type TraceConfig_ProbabilitySampler struct {
|
||||
ProbabilitySampler *ProbabilitySampler `protobuf:"bytes,1,opt,name=probability_sampler,json=probabilitySampler,proto3,oneof"`
|
||||
}
|
||||
|
||||
type TraceConfig_ConstantSampler struct {
|
||||
ConstantSampler *ConstantSampler `protobuf:"bytes,2,opt,name=constant_sampler,json=constantSampler,proto3,oneof"`
|
||||
}
|
||||
|
||||
type TraceConfig_RateLimitingSampler struct {
|
||||
RateLimitingSampler *RateLimitingSampler `protobuf:"bytes,3,opt,name=rate_limiting_sampler,json=rateLimitingSampler,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*TraceConfig_ProbabilitySampler) isTraceConfig_Sampler() {}
|
||||
|
||||
func (*TraceConfig_ConstantSampler) isTraceConfig_Sampler() {}
|
||||
|
||||
func (*TraceConfig_RateLimitingSampler) isTraceConfig_Sampler() {}
|
||||
|
||||
func (m *TraceConfig) GetSampler() isTraceConfig_Sampler {
|
||||
if m != nil {
|
||||
return m.Sampler
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TraceConfig) GetProbabilitySampler() *ProbabilitySampler {
|
||||
if x, ok := m.GetSampler().(*TraceConfig_ProbabilitySampler); ok {
|
||||
return x.ProbabilitySampler
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TraceConfig) GetConstantSampler() *ConstantSampler {
|
||||
if x, ok := m.GetSampler().(*TraceConfig_ConstantSampler); ok {
|
||||
return x.ConstantSampler
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TraceConfig) GetRateLimitingSampler() *RateLimitingSampler {
|
||||
if x, ok := m.GetSampler().(*TraceConfig_RateLimitingSampler); ok {
|
||||
return x.RateLimitingSampler
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TraceConfig) GetMaxNumberOfAttributes() int64 {
|
||||
if m != nil {
|
||||
return m.MaxNumberOfAttributes
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TraceConfig) GetMaxNumberOfAnnotations() int64 {
|
||||
if m != nil {
|
||||
return m.MaxNumberOfAnnotations
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TraceConfig) GetMaxNumberOfMessageEvents() int64 {
|
||||
if m != nil {
|
||||
return m.MaxNumberOfMessageEvents
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TraceConfig) GetMaxNumberOfLinks() int64 {
|
||||
if m != nil {
|
||||
return m.MaxNumberOfLinks
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// XXX_OneofWrappers is for the internal use of the proto package.
|
||||
func (*TraceConfig) XXX_OneofWrappers() []interface{} {
|
||||
return []interface{}{
|
||||
(*TraceConfig_ProbabilitySampler)(nil),
|
||||
(*TraceConfig_ConstantSampler)(nil),
|
||||
(*TraceConfig_RateLimitingSampler)(nil),
|
||||
}
|
||||
}
|
||||
|
||||
// Sampler that tries to uniformly sample traces with a given probability.
|
||||
// The probability of sampling a trace is equal to that of the specified probability.
|
||||
type ProbabilitySampler struct {
|
||||
// The desired probability of sampling. Must be within [0.0, 1.0].
|
||||
SamplingProbability float64 `protobuf:"fixed64,1,opt,name=samplingProbability,proto3" json:"samplingProbability,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ProbabilitySampler) Reset() { *m = ProbabilitySampler{} }
|
||||
func (m *ProbabilitySampler) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProbabilitySampler) ProtoMessage() {}
|
||||
func (*ProbabilitySampler) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5359209b41ff50c5, []int{1}
|
||||
}
|
||||
|
||||
func (m *ProbabilitySampler) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ProbabilitySampler.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ProbabilitySampler) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ProbabilitySampler.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ProbabilitySampler) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ProbabilitySampler.Merge(m, src)
|
||||
}
|
||||
func (m *ProbabilitySampler) XXX_Size() int {
|
||||
return xxx_messageInfo_ProbabilitySampler.Size(m)
|
||||
}
|
||||
func (m *ProbabilitySampler) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ProbabilitySampler.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ProbabilitySampler proto.InternalMessageInfo
|
||||
|
||||
func (m *ProbabilitySampler) GetSamplingProbability() float64 {
|
||||
if m != nil {
|
||||
return m.SamplingProbability
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Sampler that always makes a constant decision on span sampling.
|
||||
type ConstantSampler struct {
|
||||
Decision ConstantSampler_ConstantDecision `protobuf:"varint,1,opt,name=decision,proto3,enum=opencensus.proto.trace.v1.ConstantSampler_ConstantDecision" json:"decision,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ConstantSampler) Reset() { *m = ConstantSampler{} }
|
||||
func (m *ConstantSampler) String() string { return proto.CompactTextString(m) }
|
||||
func (*ConstantSampler) ProtoMessage() {}
|
||||
func (*ConstantSampler) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5359209b41ff50c5, []int{2}
|
||||
}
|
||||
|
||||
func (m *ConstantSampler) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ConstantSampler.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ConstantSampler) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ConstantSampler.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ConstantSampler) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ConstantSampler.Merge(m, src)
|
||||
}
|
||||
func (m *ConstantSampler) XXX_Size() int {
|
||||
return xxx_messageInfo_ConstantSampler.Size(m)
|
||||
}
|
||||
func (m *ConstantSampler) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ConstantSampler.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ConstantSampler proto.InternalMessageInfo
|
||||
|
||||
func (m *ConstantSampler) GetDecision() ConstantSampler_ConstantDecision {
|
||||
if m != nil {
|
||||
return m.Decision
|
||||
}
|
||||
return ConstantSampler_ALWAYS_OFF
|
||||
}
|
||||
|
||||
// Sampler that tries to sample with a rate per time window.
|
||||
type RateLimitingSampler struct {
|
||||
// Rate per second.
|
||||
Qps int64 `protobuf:"varint,1,opt,name=qps,proto3" json:"qps,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *RateLimitingSampler) Reset() { *m = RateLimitingSampler{} }
|
||||
func (m *RateLimitingSampler) String() string { return proto.CompactTextString(m) }
|
||||
func (*RateLimitingSampler) ProtoMessage() {}
|
||||
func (*RateLimitingSampler) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5359209b41ff50c5, []int{3}
|
||||
}
|
||||
|
||||
func (m *RateLimitingSampler) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_RateLimitingSampler.Unmarshal(m, b)
|
||||
}
|
||||
func (m *RateLimitingSampler) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_RateLimitingSampler.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *RateLimitingSampler) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_RateLimitingSampler.Merge(m, src)
|
||||
}
|
||||
func (m *RateLimitingSampler) XXX_Size() int {
|
||||
return xxx_messageInfo_RateLimitingSampler.Size(m)
|
||||
}
|
||||
func (m *RateLimitingSampler) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_RateLimitingSampler.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_RateLimitingSampler proto.InternalMessageInfo
|
||||
|
||||
func (m *RateLimitingSampler) GetQps() int64 {
|
||||
if m != nil {
|
||||
return m.Qps
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("opencensus.proto.trace.v1.ConstantSampler_ConstantDecision", ConstantSampler_ConstantDecision_name, ConstantSampler_ConstantDecision_value)
|
||||
proto.RegisterType((*TraceConfig)(nil), "opencensus.proto.trace.v1.TraceConfig")
|
||||
proto.RegisterType((*ProbabilitySampler)(nil), "opencensus.proto.trace.v1.ProbabilitySampler")
|
||||
proto.RegisterType((*ConstantSampler)(nil), "opencensus.proto.trace.v1.ConstantSampler")
|
||||
proto.RegisterType((*RateLimitingSampler)(nil), "opencensus.proto.trace.v1.RateLimitingSampler")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("opencensus/proto/trace/v1/trace_config.proto", fileDescriptor_5359209b41ff50c5)
|
||||
}
|
||||
|
||||
var fileDescriptor_5359209b41ff50c5 = []byte{
|
||||
// 506 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xc1, 0x6e, 0xd3, 0x30,
|
||||
0x18, 0xc7, 0x97, 0x76, 0x6c, 0xec, 0x9b, 0xb6, 0x05, 0x57, 0x43, 0xa9, 0xb4, 0xc3, 0x94, 0x0b,
|
||||
0x13, 0x22, 0x09, 0x1d, 0x07, 0x84, 0x90, 0x90, 0xda, 0x6e, 0x15, 0x87, 0xd2, 0x56, 0xd9, 0x44,
|
||||
0x05, 0x97, 0xe0, 0x64, 0x6e, 0xb0, 0x68, 0xec, 0x60, 0x3b, 0xd5, 0x78, 0x0d, 0xce, 0x3c, 0x04,
|
||||
0xcf, 0xc5, 0x53, 0xa0, 0x3a, 0x21, 0x49, 0xdb, 0x6d, 0xe2, 0x96, 0xef, 0xfb, 0x7f, 0xbf, 0x9f,
|
||||
0xad, 0xd8, 0x86, 0x17, 0x3c, 0x25, 0x2c, 0x22, 0x4c, 0x66, 0xd2, 0x4b, 0x05, 0x57, 0xdc, 0x53,
|
||||
0x02, 0x47, 0xc4, 0x5b, 0x74, 0xf2, 0x8f, 0x20, 0xe2, 0x6c, 0x46, 0x63, 0x57, 0x67, 0xa8, 0x5d,
|
||||
0x4d, 0xe7, 0x1d, 0x57, 0x0f, 0xb9, 0x8b, 0x8e, 0xfd, 0x6b, 0x1b, 0xf6, 0xaf, 0x97, 0x45, 0x5f,
|
||||
0x03, 0xe8, 0x0b, 0xb4, 0x52, 0xc1, 0x43, 0x1c, 0xd2, 0x39, 0x55, 0x3f, 0x02, 0x89, 0x93, 0x74,
|
||||
0x4e, 0x84, 0x65, 0x9c, 0x1a, 0x67, 0xfb, 0xe7, 0x8e, 0x7b, 0xaf, 0xc8, 0x9d, 0x54, 0xd4, 0x55,
|
||||
0x0e, 0xbd, 0xdf, 0xf2, 0x51, 0xba, 0xd1, 0x45, 0x53, 0x30, 0x23, 0xce, 0xa4, 0xc2, 0x4c, 0x95,
|
||||
0xfa, 0x86, 0xd6, 0x3f, 0x7f, 0x40, 0xdf, 0x2f, 0x90, 0xca, 0x7d, 0x14, 0xad, 0xb6, 0xd0, 0x0d,
|
||||
0x1c, 0x0b, 0xac, 0x48, 0x30, 0xa7, 0x09, 0x55, 0x94, 0xc5, 0xa5, 0xbd, 0xa9, 0xed, 0xee, 0x03,
|
||||
0x76, 0x1f, 0x2b, 0x32, 0x2c, 0xb0, 0x6a, 0x85, 0x96, 0xd8, 0x6c, 0xa3, 0xd7, 0x60, 0x25, 0xf8,
|
||||
0x36, 0x60, 0x59, 0x12, 0x12, 0x11, 0xf0, 0x59, 0x80, 0x95, 0x12, 0x34, 0xcc, 0x14, 0x91, 0xd6,
|
||||
0xf6, 0xa9, 0x71, 0xd6, 0xf4, 0x8f, 0x13, 0x7c, 0x3b, 0xd2, 0xf1, 0x78, 0xd6, 0x2d, 0x43, 0xf4,
|
||||
0x06, 0xda, 0x6b, 0x20, 0x63, 0x5c, 0x61, 0x45, 0x39, 0x93, 0xd6, 0x23, 0x4d, 0x3e, 0xad, 0x93,
|
||||
0x55, 0x8a, 0xde, 0xc1, 0xc9, 0x2a, 0x9a, 0x10, 0x29, 0x71, 0x4c, 0x02, 0xb2, 0x20, 0x4c, 0x49,
|
||||
0x6b, 0x47, 0xd3, 0x56, 0x8d, 0xfe, 0x90, 0x0f, 0x5c, 0xea, 0x1c, 0x39, 0xd0, 0x5a, 0xe5, 0xe7,
|
||||
0x94, 0x7d, 0x93, 0xd6, 0xae, 0xc6, 0xcc, 0x1a, 0x36, 0x5c, 0xf6, 0x7b, 0x7b, 0xb0, 0x5b, 0xfc,
|
||||
0x3a, 0x7b, 0x00, 0x68, 0xf3, 0x60, 0xd1, 0x4b, 0x68, 0xe9, 0x01, 0xca, 0xe2, 0x5a, 0xaa, 0x2f,
|
||||
0x89, 0xe1, 0xdf, 0x15, 0xd9, 0xbf, 0x0d, 0x38, 0x5a, 0x3b, 0x42, 0x34, 0x85, 0xc7, 0x37, 0x24,
|
||||
0xa2, 0x92, 0x72, 0xa6, 0xd1, 0xc3, 0xf3, 0xb7, 0xff, 0x7f, 0x01, 0xca, 0xfa, 0xa2, 0x50, 0xf8,
|
||||
0xa5, 0xcc, 0xbe, 0x00, 0x73, 0x3d, 0x45, 0x87, 0x00, 0xdd, 0xe1, 0xb4, 0xfb, 0xe9, 0x2a, 0x18,
|
||||
0x0f, 0x06, 0xe6, 0x16, 0x3a, 0x80, 0xbd, 0x7f, 0xf5, 0xc8, 0x34, 0xd0, 0x13, 0x38, 0x28, 0xca,
|
||||
0x49, 0xd7, 0xbf, 0x1c, 0x5d, 0x9b, 0x0d, 0xfb, 0x19, 0xb4, 0xee, 0xb8, 0x16, 0xc8, 0x84, 0xe6,
|
||||
0xf7, 0x54, 0xea, 0x0d, 0x37, 0xfd, 0xe5, 0x67, 0xef, 0xa7, 0x01, 0x27, 0x94, 0xdf, 0xbf, 0xf5,
|
||||
0x9e, 0x59, 0x7b, 0x60, 0x93, 0x65, 0x34, 0x31, 0x3e, 0xf7, 0x62, 0xaa, 0xbe, 0x66, 0xa1, 0x1b,
|
||||
0xf1, 0xc4, 0xcb, 0x29, 0x87, 0x32, 0xa9, 0x44, 0x96, 0x10, 0x96, 0x1f, 0xbb, 0x57, 0x09, 0x9d,
|
||||
0xfc, 0x89, 0xc7, 0x84, 0x39, 0x71, 0xf5, 0xd2, 0xff, 0x34, 0xda, 0xe3, 0x94, 0xb0, 0x7e, 0xbe,
|
||||
0xa6, 0x16, 0xbb, 0x7a, 0x25, 0xf7, 0x63, 0x27, 0xdc, 0xd1, 0xc8, 0xab, 0xbf, 0x01, 0x00, 0x00,
|
||||
0xff, 0xff, 0x50, 0x0c, 0xfe, 0x32, 0x29, 0x04, 0x00, 0x00,
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Package descriptor provides functions for obtaining protocol buffer
|
||||
// descriptors for generated Go types.
|
||||
//
|
||||
// These functions cannot go in package proto because they depend on the
|
||||
// generated protobuf descriptor messages, which themselves depend on proto.
|
||||
package descriptor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor"
|
||||
)
|
||||
|
||||
// extractFile extracts a FileDescriptorProto from a gzip'd buffer.
|
||||
func extractFile(gz []byte) (*protobuf.FileDescriptorProto, error) {
|
||||
r, err := gzip.NewReader(bytes.NewReader(gz))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open gzip reader: %v", err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to uncompress descriptor: %v", err)
|
||||
}
|
||||
|
||||
fd := new(protobuf.FileDescriptorProto)
|
||||
if err := proto.Unmarshal(b, fd); err != nil {
|
||||
return nil, fmt.Errorf("malformed FileDescriptorProto: %v", err)
|
||||
}
|
||||
|
||||
return fd, nil
|
||||
}
|
||||
|
||||
// Message is a proto.Message with a method to return its descriptor.
|
||||
//
|
||||
// Message types generated by the protocol compiler always satisfy
|
||||
// the Message interface.
|
||||
type Message interface {
|
||||
proto.Message
|
||||
Descriptor() ([]byte, []int)
|
||||
}
|
||||
|
||||
// ForMessage returns a FileDescriptorProto and a DescriptorProto from within it
|
||||
// describing the given message.
|
||||
func ForMessage(msg Message) (fd *protobuf.FileDescriptorProto, md *protobuf.DescriptorProto) {
|
||||
gz, path := msg.Descriptor()
|
||||
fd, err := extractFile(gz)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("invalid FileDescriptorProto for %T: %v", msg, err))
|
||||
}
|
||||
|
||||
md = fd.MessageType[path[0]]
|
||||
for _, i := range path[1:] {
|
||||
md = md.NestedType[i]
|
||||
}
|
||||
return fd, md
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2015, Gengo, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Gengo, Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
119
vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go
generated
vendored
Normal file
119
vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: internal/stream_chunk.proto
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
any "github.com/golang/protobuf/ptypes/any"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// StreamError is a response type which is returned when
|
||||
// streaming rpc returns an error.
|
||||
type StreamError struct {
|
||||
GrpcCode int32 `protobuf:"varint,1,opt,name=grpc_code,json=grpcCode,proto3" json:"grpc_code,omitempty"`
|
||||
HttpCode int32 `protobuf:"varint,2,opt,name=http_code,json=httpCode,proto3" json:"http_code,omitempty"`
|
||||
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
|
||||
HttpStatus string `protobuf:"bytes,4,opt,name=http_status,json=httpStatus,proto3" json:"http_status,omitempty"`
|
||||
Details []*any.Any `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *StreamError) Reset() { *m = StreamError{} }
|
||||
func (m *StreamError) String() string { return proto.CompactTextString(m) }
|
||||
func (*StreamError) ProtoMessage() {}
|
||||
func (*StreamError) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_9d15b670e96bbb5a, []int{0}
|
||||
}
|
||||
|
||||
func (m *StreamError) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_StreamError.Unmarshal(m, b)
|
||||
}
|
||||
func (m *StreamError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_StreamError.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *StreamError) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_StreamError.Merge(m, src)
|
||||
}
|
||||
func (m *StreamError) XXX_Size() int {
|
||||
return xxx_messageInfo_StreamError.Size(m)
|
||||
}
|
||||
func (m *StreamError) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_StreamError.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_StreamError proto.InternalMessageInfo
|
||||
|
||||
func (m *StreamError) GetGrpcCode() int32 {
|
||||
if m != nil {
|
||||
return m.GrpcCode
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StreamError) GetHttpCode() int32 {
|
||||
if m != nil {
|
||||
return m.HttpCode
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StreamError) GetMessage() string {
|
||||
if m != nil {
|
||||
return m.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *StreamError) GetHttpStatus() string {
|
||||
if m != nil {
|
||||
return m.HttpStatus
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *StreamError) GetDetails() []*any.Any {
|
||||
if m != nil {
|
||||
return m.Details
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*StreamError)(nil), "grpc.gateway.runtime.StreamError")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("internal/stream_chunk.proto", fileDescriptor_9d15b670e96bbb5a) }
|
||||
|
||||
var fileDescriptor_9d15b670e96bbb5a = []byte{
|
||||
// 223 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0x90, 0x41, 0x4e, 0xc3, 0x30,
|
||||
0x10, 0x45, 0x15, 0x4a, 0x69, 0x3b, 0xd9, 0x45, 0x5d, 0x18, 0xba, 0x20, 0x62, 0x95, 0x95, 0x23,
|
||||
0xc1, 0x09, 0x00, 0x71, 0x81, 0x74, 0xc7, 0xa6, 0x9a, 0x26, 0x83, 0x13, 0x91, 0xd8, 0xd1, 0x78,
|
||||
0x22, 0x94, 0x6b, 0x71, 0xc2, 0xca, 0x8e, 0xb2, 0xf4, 0x7b, 0x7f, 0xbe, 0xbe, 0x0c, 0xa7, 0xce,
|
||||
0x0a, 0xb1, 0xc5, 0xbe, 0xf4, 0xc2, 0x84, 0xc3, 0xa5, 0x6e, 0x27, 0xfb, 0xab, 0x47, 0x76, 0xe2,
|
||||
0xb2, 0xa3, 0xe1, 0xb1, 0xd6, 0x06, 0x85, 0xfe, 0x70, 0xd6, 0x3c, 0x59, 0xe9, 0x06, 0x7a, 0x7a,
|
||||
0x34, 0xce, 0x99, 0x9e, 0xca, 0x98, 0xb9, 0x4e, 0x3f, 0x25, 0xda, 0x79, 0x39, 0x78, 0xf9, 0x4f,
|
||||
0x20, 0x3d, 0xc7, 0x9e, 0x2f, 0x66, 0xc7, 0xd9, 0x09, 0x0e, 0xa1, 0xe2, 0x52, 0xbb, 0x86, 0x54,
|
||||
0x92, 0x27, 0xc5, 0xb6, 0xda, 0x07, 0xf0, 0xe9, 0x1a, 0x0a, 0xb2, 0x15, 0x19, 0x17, 0x79, 0xb7,
|
||||
0xc8, 0x00, 0xa2, 0x54, 0xb0, 0x1b, 0xc8, 0x7b, 0x34, 0xa4, 0x36, 0x79, 0x52, 0x1c, 0xaa, 0xf5,
|
||||
0x99, 0x3d, 0x43, 0x1a, 0xcf, 0xbc, 0xa0, 0x4c, 0x5e, 0xdd, 0x47, 0x0b, 0x01, 0x9d, 0x23, 0xc9,
|
||||
0x34, 0xec, 0x1a, 0x12, 0xec, 0x7a, 0xaf, 0xb6, 0xf9, 0xa6, 0x48, 0x5f, 0x8f, 0x7a, 0x59, 0xac,
|
||||
0xd7, 0xc5, 0xfa, 0xdd, 0xce, 0xd5, 0x1a, 0xfa, 0x80, 0xef, 0xfd, 0xfa, 0x09, 0xd7, 0x87, 0x18,
|
||||
0x79, 0xbb, 0x05, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x7d, 0xa5, 0x18, 0x17, 0x01, 0x00, 0x00,
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// MetadataHeaderPrefix is the http prefix that represents custom metadata
|
||||
// parameters to or from a gRPC call.
|
||||
const MetadataHeaderPrefix = "Grpc-Metadata-"
|
||||
|
||||
// MetadataPrefix is prepended to permanent HTTP header keys (as specified
|
||||
// by the IANA) when added to the gRPC context.
|
||||
const MetadataPrefix = "grpcgateway-"
|
||||
|
||||
// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to
|
||||
// HTTP headers in a response handled by grpc-gateway
|
||||
const MetadataTrailerPrefix = "Grpc-Trailer-"
|
||||
|
||||
const metadataGrpcTimeout = "Grpc-Timeout"
|
||||
const metadataHeaderBinarySuffix = "-Bin"
|
||||
|
||||
const xForwardedFor = "X-Forwarded-For"
|
||||
const xForwardedHost = "X-Forwarded-Host"
|
||||
|
||||
var (
|
||||
// DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound
|
||||
// header isn't present. If the value is 0 the sent `context` will not have a timeout.
|
||||
DefaultContextTimeout = 0 * time.Second
|
||||
)
|
||||
|
||||
func decodeBinHeader(v string) ([]byte, error) {
|
||||
if len(v)%4 == 0 {
|
||||
// Input was padded, or padding was not necessary.
|
||||
return base64.StdEncoding.DecodeString(v)
|
||||
}
|
||||
return base64.RawStdEncoding.DecodeString(v)
|
||||
}
|
||||
|
||||
/*
|
||||
AnnotateContext adds context information such as metadata from the request.
|
||||
|
||||
At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For",
|
||||
except that the forwarded destination is not another HTTP service but rather
|
||||
a gRPC service.
|
||||
*/
|
||||
func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) {
|
||||
ctx, md, err := annotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if md == nil {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
return metadata.NewOutgoingContext(ctx, md), nil
|
||||
}
|
||||
|
||||
// AnnotateIncomingContext adds context information such as metadata from the request.
|
||||
// Attach metadata as incoming context.
|
||||
func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) {
|
||||
ctx, md, err := annotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if md == nil {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
return metadata.NewIncomingContext(ctx, md), nil
|
||||
}
|
||||
|
||||
func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, metadata.MD, error) {
|
||||
var pairs []string
|
||||
timeout := DefaultContextTimeout
|
||||
if tm := req.Header.Get(metadataGrpcTimeout); tm != "" {
|
||||
var err error
|
||||
timeout, err = timeoutDecode(tm)
|
||||
if err != nil {
|
||||
return nil, nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm)
|
||||
}
|
||||
}
|
||||
|
||||
for key, vals := range req.Header {
|
||||
for _, val := range vals {
|
||||
key = textproto.CanonicalMIMEHeaderKey(key)
|
||||
// For backwards-compatibility, pass through 'authorization' header with no prefix.
|
||||
if key == "Authorization" {
|
||||
pairs = append(pairs, "authorization", val)
|
||||
}
|
||||
if h, ok := mux.incomingHeaderMatcher(key); ok {
|
||||
// Handles "-bin" metadata in grpc, since grpc will do another base64
|
||||
// encode before sending to server, we need to decode it first.
|
||||
if strings.HasSuffix(key, metadataHeaderBinarySuffix) {
|
||||
b, err := decodeBinHeader(val)
|
||||
if err != nil {
|
||||
return nil, nil, status.Errorf(codes.InvalidArgument, "invalid binary header %s: %s", key, err)
|
||||
}
|
||||
|
||||
val = string(b)
|
||||
}
|
||||
pairs = append(pairs, h, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
if host := req.Header.Get(xForwardedHost); host != "" {
|
||||
pairs = append(pairs, strings.ToLower(xForwardedHost), host)
|
||||
} else if req.Host != "" {
|
||||
pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host)
|
||||
}
|
||||
|
||||
if addr := req.RemoteAddr; addr != "" {
|
||||
if remoteIP, _, err := net.SplitHostPort(addr); err == nil {
|
||||
if fwd := req.Header.Get(xForwardedFor); fwd == "" {
|
||||
pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP)
|
||||
} else {
|
||||
pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP))
|
||||
}
|
||||
} else {
|
||||
grpclog.Infof("invalid remote addr: %s", addr)
|
||||
}
|
||||
}
|
||||
|
||||
if timeout != 0 {
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
}
|
||||
if len(pairs) == 0 {
|
||||
return ctx, nil, nil
|
||||
}
|
||||
md := metadata.Pairs(pairs...)
|
||||
for _, mda := range mux.metadataAnnotators {
|
||||
md = metadata.Join(md, mda(ctx, req))
|
||||
}
|
||||
return ctx, md, nil
|
||||
}
|
||||
|
||||
// ServerMetadata consists of metadata sent from gRPC server.
|
||||
type ServerMetadata struct {
|
||||
HeaderMD metadata.MD
|
||||
TrailerMD metadata.MD
|
||||
}
|
||||
|
||||
type serverMetadataKey struct{}
|
||||
|
||||
// NewServerMetadataContext creates a new context with ServerMetadata
|
||||
func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context {
|
||||
return context.WithValue(ctx, serverMetadataKey{}, md)
|
||||
}
|
||||
|
||||
// ServerMetadataFromContext returns the ServerMetadata in ctx
|
||||
func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) {
|
||||
md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata)
|
||||
return
|
||||
}
|
||||
|
||||
func timeoutDecode(s string) (time.Duration, error) {
|
||||
size := len(s)
|
||||
if size < 2 {
|
||||
return 0, fmt.Errorf("timeout string is too short: %q", s)
|
||||
}
|
||||
d, ok := timeoutUnitToDuration(s[size-1])
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("timeout unit is not recognized: %q", s)
|
||||
}
|
||||
t, err := strconv.ParseInt(s[:size-1], 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return d * time.Duration(t), nil
|
||||
}
|
||||
|
||||
func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) {
|
||||
switch u {
|
||||
case 'H':
|
||||
return time.Hour, true
|
||||
case 'M':
|
||||
return time.Minute, true
|
||||
case 'S':
|
||||
return time.Second, true
|
||||
case 'm':
|
||||
return time.Millisecond, true
|
||||
case 'u':
|
||||
return time.Microsecond, true
|
||||
case 'n':
|
||||
return time.Nanosecond, true
|
||||
default:
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// isPermanentHTTPHeader checks whether hdr belongs to the list of
|
||||
// permenant request headers maintained by IANA.
|
||||
// http://www.iana.org/assignments/message-headers/message-headers.xml
|
||||
func isPermanentHTTPHeader(hdr string) bool {
|
||||
switch hdr {
|
||||
case
|
||||
"Accept",
|
||||
"Accept-Charset",
|
||||
"Accept-Language",
|
||||
"Accept-Ranges",
|
||||
"Authorization",
|
||||
"Cache-Control",
|
||||
"Content-Type",
|
||||
"Cookie",
|
||||
"Date",
|
||||
"Expect",
|
||||
"From",
|
||||
"Host",
|
||||
"If-Match",
|
||||
"If-Modified-Since",
|
||||
"If-None-Match",
|
||||
"If-Schedule-Tag-Match",
|
||||
"If-Unmodified-Since",
|
||||
"Max-Forwards",
|
||||
"Origin",
|
||||
"Pragma",
|
||||
"Referer",
|
||||
"User-Agent",
|
||||
"Via",
|
||||
"Warning":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/jsonpb"
|
||||
"github.com/golang/protobuf/ptypes/duration"
|
||||
"github.com/golang/protobuf/ptypes/timestamp"
|
||||
"github.com/golang/protobuf/ptypes/wrappers"
|
||||
)
|
||||
|
||||
// String just returns the given string.
|
||||
// It is just for compatibility to other types.
|
||||
func String(val string) (string, error) {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// StringSlice converts 'val' where individual strings are separated by
|
||||
// 'sep' into a string slice.
|
||||
func StringSlice(val, sep string) ([]string, error) {
|
||||
return strings.Split(val, sep), nil
|
||||
}
|
||||
|
||||
// Bool converts the given string representation of a boolean value into bool.
|
||||
func Bool(val string) (bool, error) {
|
||||
return strconv.ParseBool(val)
|
||||
}
|
||||
|
||||
// BoolSlice converts 'val' where individual booleans are separated by
|
||||
// 'sep' into a bool slice.
|
||||
func BoolSlice(val, sep string) ([]bool, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([]bool, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Bool(v)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// Float64 converts the given string representation into representation of a floating point number into float64.
|
||||
func Float64(val string) (float64, error) {
|
||||
return strconv.ParseFloat(val, 64)
|
||||
}
|
||||
|
||||
// Float64Slice converts 'val' where individual floating point numbers are separated by
|
||||
// 'sep' into a float64 slice.
|
||||
func Float64Slice(val, sep string) ([]float64, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([]float64, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Float64(v)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// Float32 converts the given string representation of a floating point number into float32.
|
||||
func Float32(val string) (float32, error) {
|
||||
f, err := strconv.ParseFloat(val, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return float32(f), nil
|
||||
}
|
||||
|
||||
// Float32Slice converts 'val' where individual floating point numbers are separated by
|
||||
// 'sep' into a float32 slice.
|
||||
func Float32Slice(val, sep string) ([]float32, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([]float32, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Float32(v)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// Int64 converts the given string representation of an integer into int64.
|
||||
func Int64(val string) (int64, error) {
|
||||
return strconv.ParseInt(val, 0, 64)
|
||||
}
|
||||
|
||||
// Int64Slice converts 'val' where individual integers are separated by
|
||||
// 'sep' into a int64 slice.
|
||||
func Int64Slice(val, sep string) ([]int64, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([]int64, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Int64(v)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// Int32 converts the given string representation of an integer into int32.
|
||||
func Int32(val string) (int32, error) {
|
||||
i, err := strconv.ParseInt(val, 0, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(i), nil
|
||||
}
|
||||
|
||||
// Int32Slice converts 'val' where individual integers are separated by
|
||||
// 'sep' into a int32 slice.
|
||||
func Int32Slice(val, sep string) ([]int32, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([]int32, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Int32(v)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// Uint64 converts the given string representation of an integer into uint64.
|
||||
func Uint64(val string) (uint64, error) {
|
||||
return strconv.ParseUint(val, 0, 64)
|
||||
}
|
||||
|
||||
// Uint64Slice converts 'val' where individual integers are separated by
|
||||
// 'sep' into a uint64 slice.
|
||||
func Uint64Slice(val, sep string) ([]uint64, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([]uint64, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Uint64(v)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// Uint32 converts the given string representation of an integer into uint32.
|
||||
func Uint32(val string) (uint32, error) {
|
||||
i, err := strconv.ParseUint(val, 0, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(i), nil
|
||||
}
|
||||
|
||||
// Uint32Slice converts 'val' where individual integers are separated by
|
||||
// 'sep' into a uint32 slice.
|
||||
func Uint32Slice(val, sep string) ([]uint32, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([]uint32, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Uint32(v)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// Bytes converts the given string representation of a byte sequence into a slice of bytes
|
||||
// A bytes sequence is encoded in URL-safe base64 without padding
|
||||
func Bytes(val string) ([]byte, error) {
|
||||
b, err := base64.StdEncoding.DecodeString(val)
|
||||
if err != nil {
|
||||
b, err = base64.URLEncoding.DecodeString(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// BytesSlice converts 'val' where individual bytes sequences, encoded in URL-safe
|
||||
// base64 without padding, are separated by 'sep' into a slice of bytes slices slice.
|
||||
func BytesSlice(val, sep string) ([][]byte, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([][]byte, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Bytes(v)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp.
|
||||
func Timestamp(val string) (*timestamp.Timestamp, error) {
|
||||
var r timestamp.Timestamp
|
||||
err := jsonpb.UnmarshalString(val, &r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// Duration converts the given string into a timestamp.Duration.
|
||||
func Duration(val string) (*duration.Duration, error) {
|
||||
var r duration.Duration
|
||||
err := jsonpb.UnmarshalString(val, &r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// Enum converts the given string into an int32 that should be type casted into the
|
||||
// correct enum proto type.
|
||||
func Enum(val string, enumValMap map[string]int32) (int32, error) {
|
||||
e, ok := enumValMap[val]
|
||||
if ok {
|
||||
return e, nil
|
||||
}
|
||||
|
||||
i, err := Int32(val)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("%s is not valid", val)
|
||||
}
|
||||
for _, v := range enumValMap {
|
||||
if v == i {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("%s is not valid", val)
|
||||
}
|
||||
|
||||
// EnumSlice converts 'val' where individual enums are separated by 'sep'
|
||||
// into a int32 slice. Each individual int32 should be type casted into the
|
||||
// correct enum proto type.
|
||||
func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) {
|
||||
s := strings.Split(val, sep)
|
||||
values := make([]int32, len(s))
|
||||
for i, v := range s {
|
||||
value, err := Enum(v, enumValMap)
|
||||
if err != nil {
|
||||
return values, err
|
||||
}
|
||||
values[i] = value
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Support fot google.protobuf.wrappers on top of primitive types
|
||||
*/
|
||||
|
||||
// StringValue well-known type support as wrapper around string type
|
||||
func StringValue(val string) (*wrappers.StringValue, error) {
|
||||
return &wrappers.StringValue{Value: val}, nil
|
||||
}
|
||||
|
||||
// FloatValue well-known type support as wrapper around float32 type
|
||||
func FloatValue(val string) (*wrappers.FloatValue, error) {
|
||||
parsedVal, err := Float32(val)
|
||||
return &wrappers.FloatValue{Value: parsedVal}, err
|
||||
}
|
||||
|
||||
// DoubleValue well-known type support as wrapper around float64 type
|
||||
func DoubleValue(val string) (*wrappers.DoubleValue, error) {
|
||||
parsedVal, err := Float64(val)
|
||||
return &wrappers.DoubleValue{Value: parsedVal}, err
|
||||
}
|
||||
|
||||
// BoolValue well-known type support as wrapper around bool type
|
||||
func BoolValue(val string) (*wrappers.BoolValue, error) {
|
||||
parsedVal, err := Bool(val)
|
||||
return &wrappers.BoolValue{Value: parsedVal}, err
|
||||
}
|
||||
|
||||
// Int32Value well-known type support as wrapper around int32 type
|
||||
func Int32Value(val string) (*wrappers.Int32Value, error) {
|
||||
parsedVal, err := Int32(val)
|
||||
return &wrappers.Int32Value{Value: parsedVal}, err
|
||||
}
|
||||
|
||||
// UInt32Value well-known type support as wrapper around uint32 type
|
||||
func UInt32Value(val string) (*wrappers.UInt32Value, error) {
|
||||
parsedVal, err := Uint32(val)
|
||||
return &wrappers.UInt32Value{Value: parsedVal}, err
|
||||
}
|
||||
|
||||
// Int64Value well-known type support as wrapper around int64 type
|
||||
func Int64Value(val string) (*wrappers.Int64Value, error) {
|
||||
parsedVal, err := Int64(val)
|
||||
return &wrappers.Int64Value{Value: parsedVal}, err
|
||||
}
|
||||
|
||||
// UInt64Value well-known type support as wrapper around uint64 type
|
||||
func UInt64Value(val string) (*wrappers.UInt64Value, error) {
|
||||
parsedVal, err := Uint64(val)
|
||||
return &wrappers.UInt64Value{Value: parsedVal}, err
|
||||
}
|
||||
|
||||
// BytesValue well-known type support as wrapper around bytes[] type
|
||||
func BytesValue(val string) (*wrappers.BytesValue, error) {
|
||||
parsedVal, err := Bytes(val)
|
||||
return &wrappers.BytesValue{Value: parsedVal}, err
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
/*
|
||||
Package runtime contains runtime helper functions used by
|
||||
servers which protoc-gen-grpc-gateway generates.
|
||||
*/
|
||||
package runtime
|
|
@ -0,0 +1,146 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status.
|
||||
// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
|
||||
func HTTPStatusFromCode(code codes.Code) int {
|
||||
switch code {
|
||||
case codes.OK:
|
||||
return http.StatusOK
|
||||
case codes.Canceled:
|
||||
return http.StatusRequestTimeout
|
||||
case codes.Unknown:
|
||||
return http.StatusInternalServerError
|
||||
case codes.InvalidArgument:
|
||||
return http.StatusBadRequest
|
||||
case codes.DeadlineExceeded:
|
||||
return http.StatusGatewayTimeout
|
||||
case codes.NotFound:
|
||||
return http.StatusNotFound
|
||||
case codes.AlreadyExists:
|
||||
return http.StatusConflict
|
||||
case codes.PermissionDenied:
|
||||
return http.StatusForbidden
|
||||
case codes.Unauthenticated:
|
||||
return http.StatusUnauthorized
|
||||
case codes.ResourceExhausted:
|
||||
return http.StatusTooManyRequests
|
||||
case codes.FailedPrecondition:
|
||||
// Note, this deliberately doesn't translate to the similarly named '412 Precondition Failed' HTTP response status.
|
||||
return http.StatusBadRequest
|
||||
case codes.Aborted:
|
||||
return http.StatusConflict
|
||||
case codes.OutOfRange:
|
||||
return http.StatusBadRequest
|
||||
case codes.Unimplemented:
|
||||
return http.StatusNotImplemented
|
||||
case codes.Internal:
|
||||
return http.StatusInternalServerError
|
||||
case codes.Unavailable:
|
||||
return http.StatusServiceUnavailable
|
||||
case codes.DataLoss:
|
||||
return http.StatusInternalServerError
|
||||
}
|
||||
|
||||
grpclog.Infof("Unknown gRPC error code: %v", code)
|
||||
return http.StatusInternalServerError
|
||||
}
|
||||
|
||||
var (
|
||||
// HTTPError replies to the request with the error.
|
||||
// You can set a custom function to this variable to customize error format.
|
||||
HTTPError = DefaultHTTPError
|
||||
// OtherErrorHandler handles the following error used by the gateway: StatusMethodNotAllowed StatusNotFound and StatusBadRequest
|
||||
OtherErrorHandler = DefaultOtherErrorHandler
|
||||
)
|
||||
|
||||
type errorBody struct {
|
||||
Error string `protobuf:"bytes,100,name=error" json:"error"`
|
||||
// This is to make the error more compatible with users that expect errors to be Status objects:
|
||||
// https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto
|
||||
// It should be the exact same message as the Error field.
|
||||
Code int32 `protobuf:"varint,1,name=code" json:"code"`
|
||||
Message string `protobuf:"bytes,2,name=message" json:"message"`
|
||||
Details []*any.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// Make this also conform to proto.Message for builtin JSONPb Marshaler
|
||||
func (e *errorBody) Reset() { *e = errorBody{} }
|
||||
func (e *errorBody) String() string { return proto.CompactTextString(e) }
|
||||
func (*errorBody) ProtoMessage() {}
|
||||
|
||||
// DefaultHTTPError is the default implementation of HTTPError.
|
||||
// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
|
||||
// If otherwise, it replies with http.StatusInternalServerError.
|
||||
//
|
||||
// The response body returned by this function is a JSON object,
|
||||
// which contains a member whose key is "error" and whose value is err.Error().
|
||||
func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
|
||||
const fallback = `{"error": "failed to marshal error message"}`
|
||||
|
||||
s, ok := status.FromError(err)
|
||||
if !ok {
|
||||
s = status.New(codes.Unknown, err.Error())
|
||||
}
|
||||
|
||||
w.Header().Del("Trailer")
|
||||
|
||||
contentType := marshaler.ContentType()
|
||||
// Check marshaler on run time in order to keep backwards compatability
|
||||
// An interface param needs to be added to the ContentType() function on
|
||||
// the Marshal interface to be able to remove this check
|
||||
if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
|
||||
pb := s.Proto()
|
||||
contentType = httpBodyMarshaler.ContentTypeFromMessage(pb)
|
||||
}
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
body := &errorBody{
|
||||
Error: s.Message(),
|
||||
Message: s.Message(),
|
||||
Code: int32(s.Code()),
|
||||
Details: s.Proto().GetDetails(),
|
||||
}
|
||||
|
||||
buf, merr := marshaler.Marshal(body)
|
||||
if merr != nil {
|
||||
grpclog.Infof("Failed to marshal error message %q: %v", body, merr)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
if _, err := io.WriteString(w, fallback); err != nil {
|
||||
grpclog.Infof("Failed to write response: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
md, ok := ServerMetadataFromContext(ctx)
|
||||
if !ok {
|
||||
grpclog.Infof("Failed to extract ServerMetadata from context")
|
||||
}
|
||||
|
||||
handleForwardResponseServerMetadata(w, mux, md)
|
||||
handleForwardResponseTrailerHeader(w, md)
|
||||
st := HTTPStatusFromCode(s.Code())
|
||||
w.WriteHeader(st)
|
||||
if _, err := w.Write(buf); err != nil {
|
||||
grpclog.Infof("Failed to write response: %v", err)
|
||||
}
|
||||
|
||||
handleForwardResponseTrailer(w, md)
|
||||
}
|
||||
|
||||
// DefaultOtherErrorHandler is the default implementation of OtherErrorHandler.
|
||||
// It simply writes a string representation of the given error into "w".
|
||||
func DefaultOtherErrorHandler(w http.ResponseWriter, _ *http.Request, msg string, code int) {
|
||||
http.Error(w, msg, code)
|
||||
}
|
82
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go
generated
vendored
Normal file
82
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
descriptor2 "github.com/golang/protobuf/descriptor"
|
||||
"github.com/golang/protobuf/protoc-gen-go/descriptor"
|
||||
"google.golang.org/genproto/protobuf/field_mask"
|
||||
)
|
||||
|
||||
func translateName(name string, md *descriptor.DescriptorProto) (string, *descriptor.DescriptorProto) {
|
||||
// TODO - should really gate this with a test that the marshaller has used json names
|
||||
if md != nil {
|
||||
for _, f := range md.Field {
|
||||
if f.JsonName != nil && f.Name != nil && *f.JsonName == name {
|
||||
var subType *descriptor.DescriptorProto
|
||||
|
||||
// If the field has a TypeName then we retrieve the nested type for translating the embedded message names.
|
||||
if f.TypeName != nil {
|
||||
typeSplit := strings.Split(*f.TypeName, ".")
|
||||
typeName := typeSplit[len(typeSplit)-1]
|
||||
for _, t := range md.NestedType {
|
||||
if typeName == *t.Name {
|
||||
subType = t
|
||||
}
|
||||
}
|
||||
}
|
||||
return *f.Name, subType
|
||||
}
|
||||
}
|
||||
}
|
||||
return name, nil
|
||||
}
|
||||
|
||||
// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body.
|
||||
func FieldMaskFromRequestBody(r io.Reader, md *descriptor.DescriptorProto) (*field_mask.FieldMask, error) {
|
||||
fm := &field_mask.FieldMask{}
|
||||
var root interface{}
|
||||
if err := json.NewDecoder(r).Decode(&root); err != nil {
|
||||
if err == io.EOF {
|
||||
return fm, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
queue := []fieldMaskPathItem{{node: root, md: md}}
|
||||
for len(queue) > 0 {
|
||||
// dequeue an item
|
||||
item := queue[0]
|
||||
queue = queue[1:]
|
||||
|
||||
if m, ok := item.node.(map[string]interface{}); ok {
|
||||
// if the item is an object, then enqueue all of its children
|
||||
for k, v := range m {
|
||||
protoName, subMd := translateName(k, item.md)
|
||||
if subMsg, ok := v.(descriptor2.Message); ok {
|
||||
_, subMd = descriptor2.ForMessage(subMsg)
|
||||
}
|
||||
queue = append(queue, fieldMaskPathItem{path: append(item.path, protoName), node: v, md: subMd})
|
||||
}
|
||||
} else if len(item.path) > 0 {
|
||||
// otherwise, it's a leaf node so print its path
|
||||
fm.Paths = append(fm.Paths, strings.Join(item.path, "."))
|
||||
}
|
||||
}
|
||||
|
||||
return fm, nil
|
||||
}
|
||||
|
||||
// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask
|
||||
type fieldMaskPathItem struct {
|
||||
// the list of prior fields leading up to node
|
||||
path []string
|
||||
|
||||
// a generic decoded json object the current item to inspect for further path extraction
|
||||
node interface{}
|
||||
|
||||
// descriptor for parent message
|
||||
md *descriptor.DescriptorProto
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
|
||||
"context"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/internal"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
var errEmptyResponse = errors.New("empty response")
|
||||
|
||||
// ForwardResponseStream forwards the stream from gRPC server to REST client.
|
||||
func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
|
||||
f, ok := w.(http.Flusher)
|
||||
if !ok {
|
||||
grpclog.Infof("Flush not supported in %T", w)
|
||||
http.Error(w, "unexpected type of web server", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
md, ok := ServerMetadataFromContext(ctx)
|
||||
if !ok {
|
||||
grpclog.Infof("Failed to extract ServerMetadata from context")
|
||||
http.Error(w, "unexpected error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
handleForwardResponseServerMetadata(w, mux, md)
|
||||
|
||||
w.Header().Set("Transfer-Encoding", "chunked")
|
||||
w.Header().Set("Content-Type", marshaler.ContentType())
|
||||
if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil {
|
||||
HTTPError(ctx, mux, marshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
var delimiter []byte
|
||||
if d, ok := marshaler.(Delimited); ok {
|
||||
delimiter = d.Delimiter()
|
||||
} else {
|
||||
delimiter = []byte("\n")
|
||||
}
|
||||
|
||||
var wroteHeader bool
|
||||
for {
|
||||
resp, err := recv()
|
||||
if err == io.EOF {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err)
|
||||
return
|
||||
}
|
||||
if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {
|
||||
handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err)
|
||||
return
|
||||
}
|
||||
|
||||
buf, err := marshaler.Marshal(streamChunk(ctx, resp, mux.streamErrorHandler))
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to marshal response chunk: %v", err)
|
||||
handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err)
|
||||
return
|
||||
}
|
||||
if _, err = w.Write(buf); err != nil {
|
||||
grpclog.Infof("Failed to send response chunk: %v", err)
|
||||
return
|
||||
}
|
||||
wroteHeader = true
|
||||
if _, err = w.Write(delimiter); err != nil {
|
||||
grpclog.Infof("Failed to send delimiter chunk: %v", err)
|
||||
return
|
||||
}
|
||||
f.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
func handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) {
|
||||
for k, vs := range md.HeaderMD {
|
||||
if h, ok := mux.outgoingHeaderMatcher(k); ok {
|
||||
for _, v := range vs {
|
||||
w.Header().Add(h, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) {
|
||||
for k := range md.TrailerMD {
|
||||
tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k))
|
||||
w.Header().Add("Trailer", tKey)
|
||||
}
|
||||
}
|
||||
|
||||
func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) {
|
||||
for k, vs := range md.TrailerMD {
|
||||
tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)
|
||||
for _, v := range vs {
|
||||
w.Header().Add(tKey, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// responseBody interface contains method for getting field for marshaling to the response body
|
||||
// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule`
|
||||
type responseBody interface {
|
||||
XXX_ResponseBody() interface{}
|
||||
}
|
||||
|
||||
// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client.
|
||||
func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
|
||||
md, ok := ServerMetadataFromContext(ctx)
|
||||
if !ok {
|
||||
grpclog.Infof("Failed to extract ServerMetadata from context")
|
||||
}
|
||||
|
||||
handleForwardResponseServerMetadata(w, mux, md)
|
||||
handleForwardResponseTrailerHeader(w, md)
|
||||
|
||||
contentType := marshaler.ContentType()
|
||||
// Check marshaler on run time in order to keep backwards compatability
|
||||
// An interface param needs to be added to the ContentType() function on
|
||||
// the Marshal interface to be able to remove this check
|
||||
if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
|
||||
contentType = httpBodyMarshaler.ContentTypeFromMessage(resp)
|
||||
}
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {
|
||||
HTTPError(ctx, mux, marshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
var buf []byte
|
||||
var err error
|
||||
if rb, ok := resp.(responseBody); ok {
|
||||
buf, err = marshaler.Marshal(rb.XXX_ResponseBody())
|
||||
} else {
|
||||
buf, err = marshaler.Marshal(resp)
|
||||
}
|
||||
if err != nil {
|
||||
grpclog.Infof("Marshal error: %v", err)
|
||||
HTTPError(ctx, mux, marshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = w.Write(buf); err != nil {
|
||||
grpclog.Infof("Failed to write response: %v", err)
|
||||
}
|
||||
|
||||
handleForwardResponseTrailer(w, md)
|
||||
}
|
||||
|
||||
func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error {
|
||||
if len(opts) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, opt := range opts {
|
||||
if err := opt(ctx, w, resp); err != nil {
|
||||
grpclog.Infof("Error handling ForwardResponseOptions: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error) {
|
||||
serr := streamError(ctx, mux.streamErrorHandler, err)
|
||||
if !wroteHeader {
|
||||
w.WriteHeader(int(serr.HttpCode))
|
||||
}
|
||||
buf, merr := marshaler.Marshal(errorChunk(serr))
|
||||
if merr != nil {
|
||||
grpclog.Infof("Failed to marshal an error: %v", merr)
|
||||
return
|
||||
}
|
||||
if _, werr := w.Write(buf); werr != nil {
|
||||
grpclog.Infof("Failed to notify error to client: %v", werr)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// streamChunk returns a chunk in a response stream for the given result. The
|
||||
// given errHandler is used to render an error chunk if result is nil.
|
||||
func streamChunk(ctx context.Context, result proto.Message, errHandler StreamErrorHandlerFunc) map[string]proto.Message {
|
||||
if result == nil {
|
||||
return errorChunk(streamError(ctx, errHandler, errEmptyResponse))
|
||||
}
|
||||
return map[string]proto.Message{"result": result}
|
||||
}
|
||||
|
||||
// streamError returns the payload for the final message in a response stream
|
||||
// that represents the given err.
|
||||
func streamError(ctx context.Context, errHandler StreamErrorHandlerFunc, err error) *StreamError {
|
||||
serr := errHandler(ctx, err)
|
||||
if serr != nil {
|
||||
return serr
|
||||
}
|
||||
// TODO: log about misbehaving stream error handler?
|
||||
return DefaultHTTPStreamErrorHandler(ctx, err)
|
||||
}
|
||||
|
||||
func errorChunk(err *StreamError) map[string]proto.Message {
|
||||
return map[string]proto.Message{"error": (*internal.StreamError)(err)}
|
||||
}
|
43
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go
generated
vendored
Normal file
43
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"google.golang.org/genproto/googleapis/api/httpbody"
|
||||
)
|
||||
|
||||
// SetHTTPBodyMarshaler overwrite the default marshaler with the HTTPBodyMarshaler
|
||||
func SetHTTPBodyMarshaler(serveMux *ServeMux) {
|
||||
serveMux.marshalers.mimeMap[MIMEWildcard] = &HTTPBodyMarshaler{
|
||||
Marshaler: &JSONPb{OrigName: true},
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPBodyMarshaler is a Marshaler which supports marshaling of a
|
||||
// google.api.HttpBody message as the full response body if it is
|
||||
// the actual message used as the response. If not, then this will
|
||||
// simply fallback to the Marshaler specified as its default Marshaler.
|
||||
type HTTPBodyMarshaler struct {
|
||||
Marshaler
|
||||
}
|
||||
|
||||
// ContentType implementation to keep backwards compatability with marshal interface
|
||||
func (h *HTTPBodyMarshaler) ContentType() string {
|
||||
return h.ContentTypeFromMessage(nil)
|
||||
}
|
||||
|
||||
// ContentTypeFromMessage in case v is a google.api.HttpBody message it returns
|
||||
// its specified content type otherwise fall back to the default Marshaler.
|
||||
func (h *HTTPBodyMarshaler) ContentTypeFromMessage(v interface{}) string {
|
||||
if httpBody, ok := v.(*httpbody.HttpBody); ok {
|
||||
return httpBody.GetContentType()
|
||||
}
|
||||
return h.Marshaler.ContentType()
|
||||
}
|
||||
|
||||
// Marshal marshals "v" by returning the body bytes if v is a
|
||||
// google.api.HttpBody message, otherwise it falls back to the default Marshaler.
|
||||
func (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) {
|
||||
if httpBody, ok := v.(*httpbody.HttpBody); ok {
|
||||
return httpBody.Data, nil
|
||||
}
|
||||
return h.Marshaler.Marshal(v)
|
||||
}
|
45
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go
generated
vendored
Normal file
45
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// JSONBuiltin is a Marshaler which marshals/unmarshals into/from JSON
|
||||
// with the standard "encoding/json" package of Golang.
|
||||
// Although it is generally faster for simple proto messages than JSONPb,
|
||||
// it does not support advanced features of protobuf, e.g. map, oneof, ....
|
||||
//
|
||||
// The NewEncoder and NewDecoder types return *json.Encoder and
|
||||
// *json.Decoder respectively.
|
||||
type JSONBuiltin struct{}
|
||||
|
||||
// ContentType always Returns "application/json".
|
||||
func (*JSONBuiltin) ContentType() string {
|
||||
return "application/json"
|
||||
}
|
||||
|
||||
// Marshal marshals "v" into JSON
|
||||
func (j *JSONBuiltin) Marshal(v interface{}) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals JSON data into "v".
|
||||
func (j *JSONBuiltin) Unmarshal(data []byte, v interface{}) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// NewDecoder returns a Decoder which reads JSON stream from "r".
|
||||
func (j *JSONBuiltin) NewDecoder(r io.Reader) Decoder {
|
||||
return json.NewDecoder(r)
|
||||
}
|
||||
|
||||
// NewEncoder returns an Encoder which writes JSON stream into "w".
|
||||
func (j *JSONBuiltin) NewEncoder(w io.Writer) Encoder {
|
||||
return json.NewEncoder(w)
|
||||
}
|
||||
|
||||
// Delimiter for newline encoded JSON streams.
|
||||
func (j *JSONBuiltin) Delimiter() []byte {
|
||||
return []byte("\n")
|
||||
}
|
262
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go
generated
vendored
Normal file
262
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go
generated
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
"github.com/golang/protobuf/jsonpb"
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
// JSONPb is a Marshaler which marshals/unmarshals into/from JSON
|
||||
// with the "github.com/golang/protobuf/jsonpb".
|
||||
// It supports fully functionality of protobuf unlike JSONBuiltin.
|
||||
//
|
||||
// The NewDecoder method returns a DecoderWrapper, so the underlying
|
||||
// *json.Decoder methods can be used.
|
||||
type JSONPb jsonpb.Marshaler
|
||||
|
||||
// ContentType always returns "application/json".
|
||||
func (*JSONPb) ContentType() string {
|
||||
return "application/json"
|
||||
}
|
||||
|
||||
// Marshal marshals "v" into JSON.
|
||||
func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
|
||||
if _, ok := v.(proto.Message); !ok {
|
||||
return j.marshalNonProtoField(v)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := j.marshalTo(&buf, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
|
||||
p, ok := v.(proto.Message)
|
||||
if !ok {
|
||||
buf, err := j.marshalNonProtoField(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(buf)
|
||||
return err
|
||||
}
|
||||
return (*jsonpb.Marshaler)(j).Marshal(w, p)
|
||||
}
|
||||
|
||||
var (
|
||||
// protoMessageType is stored to prevent constant lookup of the same type at runtime.
|
||||
protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem()
|
||||
)
|
||||
|
||||
// marshalNonProto marshals a non-message field of a protobuf message.
|
||||
// This function does not correctly marshals arbitrary data structure into JSON,
|
||||
// but it is only capable of marshaling non-message field values of protobuf,
|
||||
// i.e. primitive types, enums; pointers to primitives or enums; maps from
|
||||
// integer/string types to primitives/enums/pointers to messages.
|
||||
func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
|
||||
if v == nil {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
rv := reflect.ValueOf(v)
|
||||
for rv.Kind() == reflect.Ptr {
|
||||
if rv.IsNil() {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
rv = rv.Elem()
|
||||
}
|
||||
|
||||
if rv.Kind() == reflect.Slice {
|
||||
if rv.IsNil() {
|
||||
if j.EmitDefaults {
|
||||
return []byte("[]"), nil
|
||||
}
|
||||
return []byte("null"), nil
|
||||
}
|
||||
|
||||
if rv.Type().Elem().Implements(protoMessageType) {
|
||||
var buf bytes.Buffer
|
||||
err := buf.WriteByte('[')
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
if i != 0 {
|
||||
err = buf.WriteByte(',')
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err = (*jsonpb.Marshaler)(j).Marshal(&buf, rv.Index(i).Interface().(proto.Message)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
err = buf.WriteByte(']')
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
}
|
||||
|
||||
if rv.Kind() == reflect.Map {
|
||||
m := make(map[string]*json.RawMessage)
|
||||
for _, k := range rv.MapKeys() {
|
||||
buf, err := j.Marshal(rv.MapIndex(k).Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf)
|
||||
}
|
||||
if j.Indent != "" {
|
||||
return json.MarshalIndent(m, "", j.Indent)
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts {
|
||||
return json.Marshal(enum.String())
|
||||
}
|
||||
return json.Marshal(rv.Interface())
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals JSON "data" into "v"
|
||||
func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
|
||||
return unmarshalJSONPb(data, v)
|
||||
}
|
||||
|
||||
// NewDecoder returns a Decoder which reads JSON stream from "r".
|
||||
func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
|
||||
d := json.NewDecoder(r)
|
||||
return DecoderWrapper{Decoder: d}
|
||||
}
|
||||
|
||||
// DecoderWrapper is a wrapper around a *json.Decoder that adds
|
||||
// support for protos to the Decode method.
|
||||
type DecoderWrapper struct {
|
||||
*json.Decoder
|
||||
}
|
||||
|
||||
// Decode wraps the embedded decoder's Decode method to support
|
||||
// protos using a jsonpb.Unmarshaler.
|
||||
func (d DecoderWrapper) Decode(v interface{}) error {
|
||||
return decodeJSONPb(d.Decoder, v)
|
||||
}
|
||||
|
||||
// NewEncoder returns an Encoder which writes JSON stream into "w".
|
||||
func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
|
||||
return EncoderFunc(func(v interface{}) error {
|
||||
if err := j.marshalTo(w, v); err != nil {
|
||||
return err
|
||||
}
|
||||
// mimic json.Encoder by adding a newline (makes output
|
||||
// easier to read when it contains multiple encoded items)
|
||||
_, err := w.Write(j.Delimiter())
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func unmarshalJSONPb(data []byte, v interface{}) error {
|
||||
d := json.NewDecoder(bytes.NewReader(data))
|
||||
return decodeJSONPb(d, v)
|
||||
}
|
||||
|
||||
func decodeJSONPb(d *json.Decoder, v interface{}) error {
|
||||
p, ok := v.(proto.Message)
|
||||
if !ok {
|
||||
return decodeNonProtoField(d, v)
|
||||
}
|
||||
unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields}
|
||||
return unmarshaler.UnmarshalNext(d, p)
|
||||
}
|
||||
|
||||
func decodeNonProtoField(d *json.Decoder, v interface{}) error {
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("%T is not a pointer", v)
|
||||
}
|
||||
for rv.Kind() == reflect.Ptr {
|
||||
if rv.IsNil() {
|
||||
rv.Set(reflect.New(rv.Type().Elem()))
|
||||
}
|
||||
if rv.Type().ConvertibleTo(typeProtoMessage) {
|
||||
unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields}
|
||||
return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message))
|
||||
}
|
||||
rv = rv.Elem()
|
||||
}
|
||||
if rv.Kind() == reflect.Map {
|
||||
if rv.IsNil() {
|
||||
rv.Set(reflect.MakeMap(rv.Type()))
|
||||
}
|
||||
conv, ok := convFromType[rv.Type().Key().Kind()]
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key())
|
||||
}
|
||||
|
||||
m := make(map[string]*json.RawMessage)
|
||||
if err := d.Decode(&m); err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range m {
|
||||
result := conv.Call([]reflect.Value{reflect.ValueOf(k)})
|
||||
if err := result[1].Interface(); err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
bk := result[0]
|
||||
bv := reflect.New(rv.Type().Elem())
|
||||
if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil {
|
||||
return err
|
||||
}
|
||||
rv.SetMapIndex(bk, bv.Elem())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if _, ok := rv.Interface().(protoEnum); ok {
|
||||
var repr interface{}
|
||||
if err := d.Decode(&repr); err != nil {
|
||||
return err
|
||||
}
|
||||
switch repr.(type) {
|
||||
case string:
|
||||
// TODO(yugui) Should use proto.StructProperties?
|
||||
return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
|
||||
case float64:
|
||||
rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type()))
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
|
||||
}
|
||||
}
|
||||
return d.Decode(v)
|
||||
}
|
||||
|
||||
type protoEnum interface {
|
||||
fmt.Stringer
|
||||
EnumDescriptor() ([]byte, []int)
|
||||
}
|
||||
|
||||
var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
|
||||
|
||||
// Delimiter for newline encoded JSON streams.
|
||||
func (j *JSONPb) Delimiter() []byte {
|
||||
return []byte("\n")
|
||||
}
|
||||
|
||||
// allowUnknownFields helps not to return an error when the destination
|
||||
// is a struct and the input contains object keys which do not match any
|
||||
// non-ignored, exported fields in the destination.
|
||||
var allowUnknownFields = true
|
||||
|
||||
// DisallowUnknownFields enables option in decoder (unmarshaller) to
|
||||
// return an error when it finds an unknown field. This function must be
|
||||
// called before using the JSON marshaller.
|
||||
func DisallowUnknownFields() {
|
||||
allowUnknownFields = false
|
||||
}
|
62
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go
generated
vendored
Normal file
62
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"errors"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes
|
||||
type ProtoMarshaller struct{}
|
||||
|
||||
// ContentType always returns "application/octet-stream".
|
||||
func (*ProtoMarshaller) ContentType() string {
|
||||
return "application/octet-stream"
|
||||
}
|
||||
|
||||
// Marshal marshals "value" into Proto
|
||||
func (*ProtoMarshaller) Marshal(value interface{}) ([]byte, error) {
|
||||
message, ok := value.(proto.Message)
|
||||
if !ok {
|
||||
return nil, errors.New("unable to marshal non proto field")
|
||||
}
|
||||
return proto.Marshal(message)
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals proto "data" into "value"
|
||||
func (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error {
|
||||
message, ok := value.(proto.Message)
|
||||
if !ok {
|
||||
return errors.New("unable to unmarshal non proto field")
|
||||
}
|
||||
return proto.Unmarshal(data, message)
|
||||
}
|
||||
|
||||
// NewDecoder returns a Decoder which reads proto stream from "reader".
|
||||
func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder {
|
||||
return DecoderFunc(func(value interface{}) error {
|
||||
buffer, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return marshaller.Unmarshal(buffer, value)
|
||||
})
|
||||
}
|
||||
|
||||
// NewEncoder returns an Encoder which writes proto stream into "writer".
|
||||
func (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder {
|
||||
return EncoderFunc(func(value interface{}) error {
|
||||
buffer, err := marshaller.Marshal(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = writer.Write(buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
48
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go
generated
vendored
Normal file
48
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// Marshaler defines a conversion between byte sequence and gRPC payloads / fields.
|
||||
type Marshaler interface {
|
||||
// Marshal marshals "v" into byte sequence.
|
||||
Marshal(v interface{}) ([]byte, error)
|
||||
// Unmarshal unmarshals "data" into "v".
|
||||
// "v" must be a pointer value.
|
||||
Unmarshal(data []byte, v interface{}) error
|
||||
// NewDecoder returns a Decoder which reads byte sequence from "r".
|
||||
NewDecoder(r io.Reader) Decoder
|
||||
// NewEncoder returns an Encoder which writes bytes sequence into "w".
|
||||
NewEncoder(w io.Writer) Encoder
|
||||
// ContentType returns the Content-Type which this marshaler is responsible for.
|
||||
ContentType() string
|
||||
}
|
||||
|
||||
// Decoder decodes a byte sequence
|
||||
type Decoder interface {
|
||||
Decode(v interface{}) error
|
||||
}
|
||||
|
||||
// Encoder encodes gRPC payloads / fields into byte sequence.
|
||||
type Encoder interface {
|
||||
Encode(v interface{}) error
|
||||
}
|
||||
|
||||
// DecoderFunc adapts an decoder function into Decoder.
|
||||
type DecoderFunc func(v interface{}) error
|
||||
|
||||
// Decode delegates invocations to the underlying function itself.
|
||||
func (f DecoderFunc) Decode(v interface{}) error { return f(v) }
|
||||
|
||||
// EncoderFunc adapts an encoder function into Encoder
|
||||
type EncoderFunc func(v interface{}) error
|
||||
|
||||
// Encode delegates invocations to the underlying function itself.
|
||||
func (f EncoderFunc) Encode(v interface{}) error { return f(v) }
|
||||
|
||||
// Delimited defines the streaming delimiter.
|
||||
type Delimited interface {
|
||||
// Delimiter returns the record seperator for the stream.
|
||||
Delimiter() []byte
|
||||
}
|
91
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go
generated
vendored
Normal file
91
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// MIMEWildcard is the fallback MIME type used for requests which do not match
|
||||
// a registered MIME type.
|
||||
const MIMEWildcard = "*"
|
||||
|
||||
var (
|
||||
acceptHeader = http.CanonicalHeaderKey("Accept")
|
||||
contentTypeHeader = http.CanonicalHeaderKey("Content-Type")
|
||||
|
||||
defaultMarshaler = &JSONPb{OrigName: true}
|
||||
)
|
||||
|
||||
// MarshalerForRequest returns the inbound/outbound marshalers for this request.
|
||||
// It checks the registry on the ServeMux for the MIME type set by the Content-Type header.
|
||||
// If it isn't set (or the request Content-Type is empty), checks for "*".
|
||||
// If there are multiple Content-Type headers set, choose the first one that it can
|
||||
// exactly match in the registry.
|
||||
// Otherwise, it follows the above logic for "*"/InboundMarshaler/OutboundMarshaler.
|
||||
func MarshalerForRequest(mux *ServeMux, r *http.Request) (inbound Marshaler, outbound Marshaler) {
|
||||
for _, acceptVal := range r.Header[acceptHeader] {
|
||||
if m, ok := mux.marshalers.mimeMap[acceptVal]; ok {
|
||||
outbound = m
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, contentTypeVal := range r.Header[contentTypeHeader] {
|
||||
if m, ok := mux.marshalers.mimeMap[contentTypeVal]; ok {
|
||||
inbound = m
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if inbound == nil {
|
||||
inbound = mux.marshalers.mimeMap[MIMEWildcard]
|
||||
}
|
||||
if outbound == nil {
|
||||
outbound = inbound
|
||||
}
|
||||
|
||||
return inbound, outbound
|
||||
}
|
||||
|
||||
// marshalerRegistry is a mapping from MIME types to Marshalers.
|
||||
type marshalerRegistry struct {
|
||||
mimeMap map[string]Marshaler
|
||||
}
|
||||
|
||||
// add adds a marshaler for a case-sensitive MIME type string ("*" to match any
|
||||
// MIME type).
|
||||
func (m marshalerRegistry) add(mime string, marshaler Marshaler) error {
|
||||
if len(mime) == 0 {
|
||||
return errors.New("empty MIME type")
|
||||
}
|
||||
|
||||
m.mimeMap[mime] = marshaler
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeMarshalerMIMERegistry returns a new registry of marshalers.
|
||||
// It allows for a mapping of case-sensitive Content-Type MIME type string to runtime.Marshaler interfaces.
|
||||
//
|
||||
// For example, you could allow the client to specify the use of the runtime.JSONPb marshaler
|
||||
// with a "application/jsonpb" Content-Type and the use of the runtime.JSONBuiltin marshaler
|
||||
// with a "application/json" Content-Type.
|
||||
// "*" can be used to match any Content-Type.
|
||||
// This can be attached to a ServerMux with the marshaler option.
|
||||
func makeMarshalerMIMERegistry() marshalerRegistry {
|
||||
return marshalerRegistry{
|
||||
mimeMap: map[string]Marshaler{
|
||||
MIMEWildcard: defaultMarshaler,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// WithMarshalerOption returns a ServeMuxOption which associates inbound and outbound
|
||||
// Marshalers to a MIME type in mux.
|
||||
func WithMarshalerOption(mime string, marshaler Marshaler) ServeMuxOption {
|
||||
return func(mux *ServeMux) {
|
||||
if err := mux.marshalers.add(mime, marshaler); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// A HandlerFunc handles a specific pair of path pattern and HTTP method.
|
||||
type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string)
|
||||
|
||||
// ErrUnknownURI is the error supplied to a custom ProtoErrorHandlerFunc when
|
||||
// a request is received with a URI path that does not match any registered
|
||||
// service method.
|
||||
//
|
||||
// Since gRPC servers return an "Unimplemented" code for requests with an
|
||||
// unrecognized URI path, this error also has a gRPC "Unimplemented" code.
|
||||
var ErrUnknownURI = status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented))
|
||||
|
||||
// ServeMux is a request multiplexer for grpc-gateway.
|
||||
// It matches http requests to patterns and invokes the corresponding handler.
|
||||
type ServeMux struct {
|
||||
// handlers maps HTTP method to a list of handlers.
|
||||
handlers map[string][]handler
|
||||
forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error
|
||||
marshalers marshalerRegistry
|
||||
incomingHeaderMatcher HeaderMatcherFunc
|
||||
outgoingHeaderMatcher HeaderMatcherFunc
|
||||
metadataAnnotators []func(context.Context, *http.Request) metadata.MD
|
||||
streamErrorHandler StreamErrorHandlerFunc
|
||||
protoErrorHandler ProtoErrorHandlerFunc
|
||||
disablePathLengthFallback bool
|
||||
lastMatchWins bool
|
||||
}
|
||||
|
||||
// ServeMuxOption is an option that can be given to a ServeMux on construction.
|
||||
type ServeMuxOption func(*ServeMux)
|
||||
|
||||
// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption.
|
||||
//
|
||||
// forwardResponseOption is an option that will be called on the relevant context.Context,
|
||||
// http.ResponseWriter, and proto.Message before every forwarded response.
|
||||
//
|
||||
// The message may be nil in the case where just a header is being sent.
|
||||
func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption {
|
||||
return func(serveMux *ServeMux) {
|
||||
serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption)
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context.
|
||||
type HeaderMatcherFunc func(string) (string, bool)
|
||||
|
||||
// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header
|
||||
// keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with
|
||||
// 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'.
|
||||
func DefaultHeaderMatcher(key string) (string, bool) {
|
||||
key = textproto.CanonicalMIMEHeaderKey(key)
|
||||
if isPermanentHTTPHeader(key) {
|
||||
return MetadataPrefix + key, true
|
||||
} else if strings.HasPrefix(key, MetadataHeaderPrefix) {
|
||||
return key[len(MetadataHeaderPrefix):], true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway.
|
||||
//
|
||||
// This matcher will be called with each header in http.Request. If matcher returns true, that header will be
|
||||
// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header.
|
||||
func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {
|
||||
return func(mux *ServeMux) {
|
||||
mux.incomingHeaderMatcher = fn
|
||||
}
|
||||
}
|
||||
|
||||
// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway.
|
||||
//
|
||||
// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be
|
||||
// passed to http response returned from gateway. To transform the header before passing to response,
|
||||
// matcher should return modified header.
|
||||
func WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {
|
||||
return func(mux *ServeMux) {
|
||||
mux.outgoingHeaderMatcher = fn
|
||||
}
|
||||
}
|
||||
|
||||
// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context.
|
||||
//
|
||||
// This can be used by services that need to read from http.Request and modify gRPC context. A common use case
|
||||
// is reading token from cookie and adding it in gRPC context.
|
||||
func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption {
|
||||
return func(serveMux *ServeMux) {
|
||||
serveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator)
|
||||
}
|
||||
}
|
||||
|
||||
// WithProtoErrorHandler returns a ServeMuxOption for passing metadata to a gRPC context.
|
||||
//
|
||||
// This can be used to handle an error as general proto message defined by gRPC.
|
||||
// The response including body and status is not backward compatible with the default error handler.
|
||||
// When this option is used, HTTPError and OtherErrorHandler are overwritten on initialization.
|
||||
func WithProtoErrorHandler(fn ProtoErrorHandlerFunc) ServeMuxOption {
|
||||
return func(serveMux *ServeMux) {
|
||||
serveMux.protoErrorHandler = fn
|
||||
}
|
||||
}
|
||||
|
||||
// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback.
|
||||
func WithDisablePathLengthFallback() ServeMuxOption {
|
||||
return func(serveMux *ServeMux) {
|
||||
serveMux.disablePathLengthFallback = true
|
||||
}
|
||||
}
|
||||
|
||||
// WithStreamErrorHandler returns a ServeMuxOption that will use the given custom stream
|
||||
// error handler, which allows for customizing the error trailer for server-streaming
|
||||
// calls.
|
||||
//
|
||||
// For stream errors that occur before any response has been written, the mux's
|
||||
// ProtoErrorHandler will be invoked. However, once data has been written, the errors must
|
||||
// be handled differently: they must be included in the response body. The response body's
|
||||
// final message will include the error details returned by the stream error handler.
|
||||
func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption {
|
||||
return func(serveMux *ServeMux) {
|
||||
serveMux.streamErrorHandler = fn
|
||||
}
|
||||
}
|
||||
|
||||
// WithLastMatchWins returns a ServeMuxOption that will enable "last
|
||||
// match wins" behavior, where if multiple path patterns match a
|
||||
// request path, the last one defined in the .proto file will be used.
|
||||
func WithLastMatchWins() ServeMuxOption {
|
||||
return func(serveMux *ServeMux) {
|
||||
serveMux.lastMatchWins = true
|
||||
}
|
||||
}
|
||||
|
||||
// NewServeMux returns a new ServeMux whose internal mapping is empty.
|
||||
func NewServeMux(opts ...ServeMuxOption) *ServeMux {
|
||||
serveMux := &ServeMux{
|
||||
handlers: make(map[string][]handler),
|
||||
forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0),
|
||||
marshalers: makeMarshalerMIMERegistry(),
|
||||
streamErrorHandler: DefaultHTTPStreamErrorHandler,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(serveMux)
|
||||
}
|
||||
|
||||
if serveMux.protoErrorHandler != nil {
|
||||
HTTPError = serveMux.protoErrorHandler
|
||||
// OtherErrorHandler is no longer used when protoErrorHandler is set.
|
||||
// Overwritten by a special error handler to return Unknown.
|
||||
OtherErrorHandler = func(w http.ResponseWriter, r *http.Request, _ string, _ int) {
|
||||
ctx := context.Background()
|
||||
_, outboundMarshaler := MarshalerForRequest(serveMux, r)
|
||||
sterr := status.Error(codes.Unknown, "unexpected use of OtherErrorHandler")
|
||||
serveMux.protoErrorHandler(ctx, serveMux, outboundMarshaler, w, r, sterr)
|
||||
}
|
||||
}
|
||||
|
||||
if serveMux.incomingHeaderMatcher == nil {
|
||||
serveMux.incomingHeaderMatcher = DefaultHeaderMatcher
|
||||
}
|
||||
|
||||
if serveMux.outgoingHeaderMatcher == nil {
|
||||
serveMux.outgoingHeaderMatcher = func(key string) (string, bool) {
|
||||
return fmt.Sprintf("%s%s", MetadataHeaderPrefix, key), true
|
||||
}
|
||||
}
|
||||
|
||||
return serveMux
|
||||
}
|
||||
|
||||
// Handle associates "h" to the pair of HTTP method and path pattern.
|
||||
func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) {
|
||||
if s.lastMatchWins {
|
||||
s.handlers[meth] = append([]handler{handler{pat: pat, h: h}}, s.handlers[meth]...)
|
||||
} else {
|
||||
s.handlers[meth] = append(s.handlers[meth], handler{pat: pat, h: h})
|
||||
}
|
||||
}
|
||||
|
||||
// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path.
|
||||
func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
path := r.URL.Path
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
if s.protoErrorHandler != nil {
|
||||
_, outboundMarshaler := MarshalerForRequest(s, r)
|
||||
sterr := status.Error(codes.InvalidArgument, http.StatusText(http.StatusBadRequest))
|
||||
s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
|
||||
} else {
|
||||
OtherErrorHandler(w, r, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
components := strings.Split(path[1:], "/")
|
||||
l := len(components)
|
||||
var verb string
|
||||
if idx := strings.LastIndex(components[l-1], ":"); idx == 0 {
|
||||
if s.protoErrorHandler != nil {
|
||||
_, outboundMarshaler := MarshalerForRequest(s, r)
|
||||
s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
|
||||
} else {
|
||||
OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
}
|
||||
return
|
||||
} else if idx > 0 {
|
||||
c := components[l-1]
|
||||
components[l-1], verb = c[:idx], c[idx+1:]
|
||||
}
|
||||
|
||||
if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) {
|
||||
r.Method = strings.ToUpper(override)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
if s.protoErrorHandler != nil {
|
||||
_, outboundMarshaler := MarshalerForRequest(s, r)
|
||||
sterr := status.Error(codes.InvalidArgument, err.Error())
|
||||
s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
|
||||
} else {
|
||||
OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, h := range s.handlers[r.Method] {
|
||||
pathParams, err := h.pat.Match(components, verb)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
h.h(w, r, pathParams)
|
||||
return
|
||||
}
|
||||
|
||||
// lookup other methods to handle fallback from GET to POST and
|
||||
// to determine if it is MethodNotAllowed or NotFound.
|
||||
for m, handlers := range s.handlers {
|
||||
if m == r.Method {
|
||||
continue
|
||||
}
|
||||
for _, h := range handlers {
|
||||
pathParams, err := h.pat.Match(components, verb)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
// X-HTTP-Method-Override is optional. Always allow fallback to POST.
|
||||
if s.isPathLengthFallback(r) {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
if s.protoErrorHandler != nil {
|
||||
_, outboundMarshaler := MarshalerForRequest(s, r)
|
||||
sterr := status.Error(codes.InvalidArgument, err.Error())
|
||||
s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
|
||||
} else {
|
||||
OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
return
|
||||
}
|
||||
h.h(w, r, pathParams)
|
||||
return
|
||||
}
|
||||
if s.protoErrorHandler != nil {
|
||||
_, outboundMarshaler := MarshalerForRequest(s, r)
|
||||
s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
|
||||
} else {
|
||||
OtherErrorHandler(w, r, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if s.protoErrorHandler != nil {
|
||||
_, outboundMarshaler := MarshalerForRequest(s, r)
|
||||
s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
|
||||
} else {
|
||||
OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux.
|
||||
func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error {
|
||||
return s.forwardResponseOptions
|
||||
}
|
||||
|
||||
func (s *ServeMux) isPathLengthFallback(r *http.Request) bool {
|
||||
return !s.disablePathLengthFallback && r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded"
|
||||
}
|
||||
|
||||
type handler struct {
|
||||
pat Pattern
|
||||
h HandlerFunc
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNotMatch indicates that the given HTTP request path does not match to the pattern.
|
||||
ErrNotMatch = errors.New("not match to the path pattern")
|
||||
// ErrInvalidPattern indicates that the given definition of Pattern is not valid.
|
||||
ErrInvalidPattern = errors.New("invalid pattern")
|
||||
)
|
||||
|
||||
type op struct {
|
||||
code utilities.OpCode
|
||||
operand int
|
||||
}
|
||||
|
||||
// Pattern is a template pattern of http request paths defined in github.com/googleapis/googleapis/google/api/http.proto.
|
||||
type Pattern struct {
|
||||
// ops is a list of operations
|
||||
ops []op
|
||||
// pool is a constant pool indexed by the operands or vars.
|
||||
pool []string
|
||||
// vars is a list of variables names to be bound by this pattern
|
||||
vars []string
|
||||
// stacksize is the max depth of the stack
|
||||
stacksize int
|
||||
// tailLen is the length of the fixed-size segments after a deep wildcard
|
||||
tailLen int
|
||||
// verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part.
|
||||
verb string
|
||||
// assumeColonVerb indicates whether a path suffix after a final
|
||||
// colon may only be interpreted as a verb.
|
||||
assumeColonVerb bool
|
||||
}
|
||||
|
||||
type patternOptions struct {
|
||||
assumeColonVerb bool
|
||||
}
|
||||
|
||||
// PatternOpt is an option for creating Patterns.
|
||||
type PatternOpt func(*patternOptions)
|
||||
|
||||
// NewPattern returns a new Pattern from the given definition values.
|
||||
// "ops" is a sequence of op codes. "pool" is a constant pool.
|
||||
// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part.
|
||||
// "version" must be 1 for now.
|
||||
// It returns an error if the given definition is invalid.
|
||||
func NewPattern(version int, ops []int, pool []string, verb string, opts ...PatternOpt) (Pattern, error) {
|
||||
options := patternOptions{
|
||||
assumeColonVerb: true,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
if version != 1 {
|
||||
grpclog.Infof("unsupported version: %d", version)
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
|
||||
l := len(ops)
|
||||
if l%2 != 0 {
|
||||
grpclog.Infof("odd number of ops codes: %d", l)
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
|
||||
var (
|
||||
typedOps []op
|
||||
stack, maxstack int
|
||||
tailLen int
|
||||
pushMSeen bool
|
||||
vars []string
|
||||
)
|
||||
for i := 0; i < l; i += 2 {
|
||||
op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]}
|
||||
switch op.code {
|
||||
case utilities.OpNop:
|
||||
continue
|
||||
case utilities.OpPush:
|
||||
if pushMSeen {
|
||||
tailLen++
|
||||
}
|
||||
stack++
|
||||
case utilities.OpPushM:
|
||||
if pushMSeen {
|
||||
grpclog.Infof("pushM appears twice")
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
pushMSeen = true
|
||||
stack++
|
||||
case utilities.OpLitPush:
|
||||
if op.operand < 0 || len(pool) <= op.operand {
|
||||
grpclog.Infof("negative literal index: %d", op.operand)
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
if pushMSeen {
|
||||
tailLen++
|
||||
}
|
||||
stack++
|
||||
case utilities.OpConcatN:
|
||||
if op.operand <= 0 {
|
||||
grpclog.Infof("negative concat size: %d", op.operand)
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
stack -= op.operand
|
||||
if stack < 0 {
|
||||
grpclog.Print("stack underflow")
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
stack++
|
||||
case utilities.OpCapture:
|
||||
if op.operand < 0 || len(pool) <= op.operand {
|
||||
grpclog.Infof("variable name index out of bound: %d", op.operand)
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
v := pool[op.operand]
|
||||
op.operand = len(vars)
|
||||
vars = append(vars, v)
|
||||
stack--
|
||||
if stack < 0 {
|
||||
grpclog.Infof("stack underflow")
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
default:
|
||||
grpclog.Infof("invalid opcode: %d", op.code)
|
||||
return Pattern{}, ErrInvalidPattern
|
||||
}
|
||||
|
||||
if maxstack < stack {
|
||||
maxstack = stack
|
||||
}
|
||||
typedOps = append(typedOps, op)
|
||||
}
|
||||
return Pattern{
|
||||
ops: typedOps,
|
||||
pool: pool,
|
||||
vars: vars,
|
||||
stacksize: maxstack,
|
||||
tailLen: tailLen,
|
||||
verb: verb,
|
||||
assumeColonVerb: options.assumeColonVerb,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization.
|
||||
func MustPattern(p Pattern, err error) Pattern {
|
||||
if err != nil {
|
||||
grpclog.Fatalf("Pattern initialization failed: %v", err)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Match examines components if it matches to the Pattern.
|
||||
// If it matches, the function returns a mapping from field paths to their captured values.
|
||||
// If otherwise, the function returns an error.
|
||||
func (p Pattern) Match(components []string, verb string) (map[string]string, error) {
|
||||
if p.verb != verb {
|
||||
if p.assumeColonVerb || p.verb != "" {
|
||||
return nil, ErrNotMatch
|
||||
}
|
||||
if len(components) == 0 {
|
||||
components = []string{":" + verb}
|
||||
} else {
|
||||
components = append([]string{}, components...)
|
||||
components[len(components)-1] += ":" + verb
|
||||
}
|
||||
verb = ""
|
||||
}
|
||||
|
||||
var pos int
|
||||
stack := make([]string, 0, p.stacksize)
|
||||
captured := make([]string, len(p.vars))
|
||||
l := len(components)
|
||||
for _, op := range p.ops {
|
||||
switch op.code {
|
||||
case utilities.OpNop:
|
||||
continue
|
||||
case utilities.OpPush, utilities.OpLitPush:
|
||||
if pos >= l {
|
||||
return nil, ErrNotMatch
|
||||
}
|
||||
c := components[pos]
|
||||
if op.code == utilities.OpLitPush {
|
||||
if lit := p.pool[op.operand]; c != lit {
|
||||
return nil, ErrNotMatch
|
||||
}
|
||||
}
|
||||
stack = append(stack, c)
|
||||
pos++
|
||||
case utilities.OpPushM:
|
||||
end := len(components)
|
||||
if end < pos+p.tailLen {
|
||||
return nil, ErrNotMatch
|
||||
}
|
||||
end -= p.tailLen
|
||||
stack = append(stack, strings.Join(components[pos:end], "/"))
|
||||
pos = end
|
||||
case utilities.OpConcatN:
|
||||
n := op.operand
|
||||
l := len(stack) - n
|
||||
stack = append(stack[:l], strings.Join(stack[l:], "/"))
|
||||
case utilities.OpCapture:
|
||||
n := len(stack) - 1
|
||||
captured[op.operand] = stack[n]
|
||||
stack = stack[:n]
|
||||
}
|
||||
}
|
||||
if pos < l {
|
||||
return nil, ErrNotMatch
|
||||
}
|
||||
bindings := make(map[string]string)
|
||||
for i, val := range captured {
|
||||
bindings[p.vars[i]] = val
|
||||
}
|
||||
return bindings, nil
|
||||
}
|
||||
|
||||
// Verb returns the verb part of the Pattern.
|
||||
func (p Pattern) Verb() string { return p.verb }
|
||||
|
||||
func (p Pattern) String() string {
|
||||
var stack []string
|
||||
for _, op := range p.ops {
|
||||
switch op.code {
|
||||
case utilities.OpNop:
|
||||
continue
|
||||
case utilities.OpPush:
|
||||
stack = append(stack, "*")
|
||||
case utilities.OpLitPush:
|
||||
stack = append(stack, p.pool[op.operand])
|
||||
case utilities.OpPushM:
|
||||
stack = append(stack, "**")
|
||||
case utilities.OpConcatN:
|
||||
n := op.operand
|
||||
l := len(stack) - n
|
||||
stack = append(stack[:l], strings.Join(stack[l:], "/"))
|
||||
case utilities.OpCapture:
|
||||
n := len(stack) - 1
|
||||
stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n])
|
||||
}
|
||||
}
|
||||
segs := strings.Join(stack, "/")
|
||||
if p.verb != "" {
|
||||
return fmt.Sprintf("/%s:%s", segs, p.verb)
|
||||
}
|
||||
return "/" + segs
|
||||
}
|
||||
|
||||
// AssumeColonVerbOpt indicates whether a path suffix after a final
|
||||
// colon may only be interpreted as a verb.
|
||||
func AssumeColonVerbOpt(val bool) PatternOpt {
|
||||
return PatternOpt(func(o *patternOptions) {
|
||||
o.assumeColonVerb = val
|
||||
})
|
||||
}
|
80
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go
generated
vendored
Normal file
80
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
// StringP returns a pointer to a string whose pointee is same as the given string value.
|
||||
func StringP(val string) (*string, error) {
|
||||
return proto.String(val), nil
|
||||
}
|
||||
|
||||
// BoolP parses the given string representation of a boolean value,
|
||||
// and returns a pointer to a bool whose value is same as the parsed value.
|
||||
func BoolP(val string) (*bool, error) {
|
||||
b, err := Bool(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Bool(b), nil
|
||||
}
|
||||
|
||||
// Float64P parses the given string representation of a floating point number,
|
||||
// and returns a pointer to a float64 whose value is same as the parsed number.
|
||||
func Float64P(val string) (*float64, error) {
|
||||
f, err := Float64(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Float64(f), nil
|
||||
}
|
||||
|
||||
// Float32P parses the given string representation of a floating point number,
|
||||
// and returns a pointer to a float32 whose value is same as the parsed number.
|
||||
func Float32P(val string) (*float32, error) {
|
||||
f, err := Float32(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Float32(f), nil
|
||||
}
|
||||
|
||||
// Int64P parses the given string representation of an integer
|
||||
// and returns a pointer to a int64 whose value is same as the parsed integer.
|
||||
func Int64P(val string) (*int64, error) {
|
||||
i, err := Int64(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Int64(i), nil
|
||||
}
|
||||
|
||||
// Int32P parses the given string representation of an integer
|
||||
// and returns a pointer to a int32 whose value is same as the parsed integer.
|
||||
func Int32P(val string) (*int32, error) {
|
||||
i, err := Int32(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Int32(i), err
|
||||
}
|
||||
|
||||
// Uint64P parses the given string representation of an integer
|
||||
// and returns a pointer to a uint64 whose value is same as the parsed integer.
|
||||
func Uint64P(val string) (*uint64, error) {
|
||||
i, err := Uint64(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Uint64(i), err
|
||||
}
|
||||
|
||||
// Uint32P parses the given string representation of an integer
|
||||
// and returns a pointer to a uint32 whose value is same as the parsed integer.
|
||||
func Uint32P(val string) (*uint32, error) {
|
||||
i, err := Uint32(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Uint32(i), err
|
||||
}
|
106
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go
generated
vendored
Normal file
106
vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/internal"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// StreamErrorHandlerFunc accepts an error as a gRPC error generated via status package and translates it into a
|
||||
// a proto struct used to represent error at the end of a stream.
|
||||
type StreamErrorHandlerFunc func(context.Context, error) *StreamError
|
||||
|
||||
// StreamError is the payload for the final message in a server stream in the event that the server returns an
|
||||
// error after a response message has already been sent.
|
||||
type StreamError internal.StreamError
|
||||
|
||||
// ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request.
|
||||
type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error)
|
||||
|
||||
var _ ProtoErrorHandlerFunc = DefaultHTTPProtoErrorHandler
|
||||
|
||||
// DefaultHTTPProtoErrorHandler is an implementation of HTTPError.
|
||||
// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
|
||||
// If otherwise, it replies with http.StatusInternalServerError.
|
||||
//
|
||||
// The response body returned by this function is a Status message marshaled by a Marshaler.
|
||||
//
|
||||
// Do not set this function to HTTPError variable directly, use WithProtoErrorHandler option instead.
|
||||
func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
|
||||
// return Internal when Marshal failed
|
||||
const fallback = `{"code": 13, "message": "failed to marshal error message"}`
|
||||
|
||||
s, ok := status.FromError(err)
|
||||
if !ok {
|
||||
s = status.New(codes.Unknown, err.Error())
|
||||
}
|
||||
|
||||
w.Header().Del("Trailer")
|
||||
|
||||
contentType := marshaler.ContentType()
|
||||
// Check marshaler on run time in order to keep backwards compatability
|
||||
// An interface param needs to be added to the ContentType() function on
|
||||
// the Marshal interface to be able to remove this check
|
||||
if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
|
||||
pb := s.Proto()
|
||||
contentType = httpBodyMarshaler.ContentTypeFromMessage(pb)
|
||||
}
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
buf, merr := marshaler.Marshal(s.Proto())
|
||||
if merr != nil {
|
||||
grpclog.Infof("Failed to marshal error message %q: %v", s.Proto(), merr)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
if _, err := io.WriteString(w, fallback); err != nil {
|
||||
grpclog.Infof("Failed to write response: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
md, ok := ServerMetadataFromContext(ctx)
|
||||
if !ok {
|
||||
grpclog.Infof("Failed to extract ServerMetadata from context")
|
||||
}
|
||||
|
||||
handleForwardResponseServerMetadata(w, mux, md)
|
||||
handleForwardResponseTrailerHeader(w, md)
|
||||
st := HTTPStatusFromCode(s.Code())
|
||||
w.WriteHeader(st)
|
||||
if _, err := w.Write(buf); err != nil {
|
||||
grpclog.Infof("Failed to write response: %v", err)
|
||||
}
|
||||
|
||||
handleForwardResponseTrailer(w, md)
|
||||
}
|
||||
|
||||
// DefaultHTTPStreamErrorHandler converts the given err into a *StreamError via
|
||||
// default logic.
|
||||
//
|
||||
// It extracts the gRPC status from err if possible. The fields of the status are
|
||||
// used to populate the returned StreamError, and the HTTP status code is derived
|
||||
// from the gRPC code via HTTPStatusFromCode. If the given err does not contain a
|
||||
// gRPC status, an "Unknown" gRPC code is used and "Internal Server Error" HTTP code.
|
||||
func DefaultHTTPStreamErrorHandler(_ context.Context, err error) *StreamError {
|
||||
grpcCode := codes.Unknown
|
||||
grpcMessage := err.Error()
|
||||
var grpcDetails []*any.Any
|
||||
if s, ok := status.FromError(err); ok {
|
||||
grpcCode = s.Code()
|
||||
grpcMessage = s.Message()
|
||||
grpcDetails = s.Proto().GetDetails()
|
||||
}
|
||||
httpCode := HTTPStatusFromCode(grpcCode)
|
||||
return &StreamError{
|
||||
GrpcCode: int32(grpcCode),
|
||||
HttpCode: int32(httpCode),
|
||||
Message: grpcMessage,
|
||||
HttpStatus: http.StatusText(httpCode),
|
||||
Details: grpcDetails,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,389 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
var valuesKeyRegexp = regexp.MustCompile("^(.*)\\[(.*)\\]$")
|
||||
|
||||
// PopulateQueryParameters populates "values" into "msg".
|
||||
// A value is ignored if its key starts with one of the elements in "filter".
|
||||
func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error {
|
||||
for key, values := range values {
|
||||
match := valuesKeyRegexp.FindStringSubmatch(key)
|
||||
if len(match) == 3 {
|
||||
key = match[1]
|
||||
values = append([]string{match[2]}, values...)
|
||||
}
|
||||
fieldPath := strings.Split(key, ".")
|
||||
if filter.HasCommonPrefix(fieldPath) {
|
||||
continue
|
||||
}
|
||||
if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PopulateFieldFromPath sets a value in a nested Protobuf structure.
|
||||
// It instantiates missing protobuf fields as it goes.
|
||||
func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error {
|
||||
fieldPath := strings.Split(fieldPathString, ".")
|
||||
return populateFieldValueFromPath(msg, fieldPath, []string{value})
|
||||
}
|
||||
|
||||
func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error {
|
||||
m := reflect.ValueOf(msg)
|
||||
if m.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("unexpected type %T: %v", msg, msg)
|
||||
}
|
||||
var props *proto.Properties
|
||||
m = m.Elem()
|
||||
for i, fieldName := range fieldPath {
|
||||
isLast := i == len(fieldPath)-1
|
||||
if !isLast && m.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, "."))
|
||||
}
|
||||
var f reflect.Value
|
||||
var err error
|
||||
f, props, err = fieldByProtoName(m, fieldName)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !f.IsValid() {
|
||||
grpclog.Infof("field not found in %T: %s", msg, strings.Join(fieldPath, "."))
|
||||
return nil
|
||||
}
|
||||
|
||||
switch f.Kind() {
|
||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64:
|
||||
if !isLast {
|
||||
return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], "."))
|
||||
}
|
||||
m = f
|
||||
case reflect.Slice:
|
||||
if !isLast {
|
||||
return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, "."))
|
||||
}
|
||||
// Handle []byte
|
||||
if f.Type().Elem().Kind() == reflect.Uint8 {
|
||||
m = f
|
||||
break
|
||||
}
|
||||
return populateRepeatedField(f, values, props)
|
||||
case reflect.Ptr:
|
||||
if f.IsNil() {
|
||||
m = reflect.New(f.Type().Elem())
|
||||
f.Set(m.Convert(f.Type()))
|
||||
}
|
||||
m = f.Elem()
|
||||
continue
|
||||
case reflect.Struct:
|
||||
m = f
|
||||
continue
|
||||
case reflect.Map:
|
||||
if !isLast {
|
||||
return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], "."))
|
||||
}
|
||||
return populateMapField(f, values, props)
|
||||
default:
|
||||
return fmt.Errorf("unexpected type %s in %T", f.Type(), msg)
|
||||
}
|
||||
}
|
||||
switch len(values) {
|
||||
case 0:
|
||||
return fmt.Errorf("no value of field: %s", strings.Join(fieldPath, "."))
|
||||
case 1:
|
||||
default:
|
||||
grpclog.Infof("too many field values: %s", strings.Join(fieldPath, "."))
|
||||
}
|
||||
return populateField(m, values[0], props)
|
||||
}
|
||||
|
||||
// fieldByProtoName looks up a field whose corresponding protobuf field name is "name".
|
||||
// "m" must be a struct value. It returns zero reflect.Value if no such field found.
|
||||
func fieldByProtoName(m reflect.Value, name string) (reflect.Value, *proto.Properties, error) {
|
||||
props := proto.GetProperties(m.Type())
|
||||
|
||||
// look up field name in oneof map
|
||||
if op, ok := props.OneofTypes[name]; ok {
|
||||
v := reflect.New(op.Type.Elem())
|
||||
field := m.Field(op.Field)
|
||||
if !field.IsNil() {
|
||||
return reflect.Value{}, nil, fmt.Errorf("field already set for %s oneof", props.Prop[op.Field].OrigName)
|
||||
}
|
||||
field.Set(v)
|
||||
return v.Elem().Field(0), op.Prop, nil
|
||||
}
|
||||
|
||||
for _, p := range props.Prop {
|
||||
if p.OrigName == name {
|
||||
return m.FieldByName(p.Name), p, nil
|
||||
}
|
||||
if p.JSONName == name {
|
||||
return m.FieldByName(p.Name), p, nil
|
||||
}
|
||||
}
|
||||
return reflect.Value{}, nil, nil
|
||||
}
|
||||
|
||||
func populateMapField(f reflect.Value, values []string, props *proto.Properties) error {
|
||||
if len(values) != 2 {
|
||||
return fmt.Errorf("more than one value provided for key %s in map %s", values[0], props.Name)
|
||||
}
|
||||
|
||||
key, value := values[0], values[1]
|
||||
keyType := f.Type().Key()
|
||||
valueType := f.Type().Elem()
|
||||
if f.IsNil() {
|
||||
f.Set(reflect.MakeMap(f.Type()))
|
||||
}
|
||||
|
||||
keyConv, ok := convFromType[keyType.Kind()]
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported key type %s in map %s", keyType, props.Name)
|
||||
}
|
||||
valueConv, ok := convFromType[valueType.Kind()]
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported value type %s in map %s", valueType, props.Name)
|
||||
}
|
||||
|
||||
keyV := keyConv.Call([]reflect.Value{reflect.ValueOf(key)})
|
||||
if err := keyV[1].Interface(); err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
valueV := valueConv.Call([]reflect.Value{reflect.ValueOf(value)})
|
||||
if err := valueV[1].Interface(); err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
|
||||
f.SetMapIndex(keyV[0].Convert(keyType), valueV[0].Convert(valueType))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func populateRepeatedField(f reflect.Value, values []string, props *proto.Properties) error {
|
||||
elemType := f.Type().Elem()
|
||||
|
||||
// is the destination field a slice of an enumeration type?
|
||||
if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil {
|
||||
return populateFieldEnumRepeated(f, values, enumValMap)
|
||||
}
|
||||
|
||||
conv, ok := convFromType[elemType.Kind()]
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported field type %s", elemType)
|
||||
}
|
||||
f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type()))
|
||||
for i, v := range values {
|
||||
result := conv.Call([]reflect.Value{reflect.ValueOf(v)})
|
||||
if err := result[1].Interface(); err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
f.Index(i).Set(result[0].Convert(f.Index(i).Type()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func populateField(f reflect.Value, value string, props *proto.Properties) error {
|
||||
i := f.Addr().Interface()
|
||||
|
||||
// Handle protobuf well known types
|
||||
var name string
|
||||
switch m := i.(type) {
|
||||
case interface{ XXX_WellKnownType() string }:
|
||||
name = m.XXX_WellKnownType()
|
||||
case proto.Message:
|
||||
const wktPrefix = "google.protobuf."
|
||||
if fullName := proto.MessageName(m); strings.HasPrefix(fullName, wktPrefix) {
|
||||
name = fullName[len(wktPrefix):]
|
||||
}
|
||||
}
|
||||
switch name {
|
||||
case "Timestamp":
|
||||
if value == "null" {
|
||||
f.FieldByName("Seconds").SetInt(0)
|
||||
f.FieldByName("Nanos").SetInt(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339Nano, value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad Timestamp: %v", err)
|
||||
}
|
||||
f.FieldByName("Seconds").SetInt(int64(t.Unix()))
|
||||
f.FieldByName("Nanos").SetInt(int64(t.Nanosecond()))
|
||||
return nil
|
||||
case "Duration":
|
||||
if value == "null" {
|
||||
f.FieldByName("Seconds").SetInt(0)
|
||||
f.FieldByName("Nanos").SetInt(0)
|
||||
return nil
|
||||
}
|
||||
d, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad Duration: %v", err)
|
||||
}
|
||||
|
||||
ns := d.Nanoseconds()
|
||||
s := ns / 1e9
|
||||
ns %= 1e9
|
||||
f.FieldByName("Seconds").SetInt(s)
|
||||
f.FieldByName("Nanos").SetInt(ns)
|
||||
return nil
|
||||
case "DoubleValue":
|
||||
fallthrough
|
||||
case "FloatValue":
|
||||
float64Val, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad DoubleValue: %s", value)
|
||||
}
|
||||
f.FieldByName("Value").SetFloat(float64Val)
|
||||
return nil
|
||||
case "Int64Value":
|
||||
fallthrough
|
||||
case "Int32Value":
|
||||
int64Val, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad DoubleValue: %s", value)
|
||||
}
|
||||
f.FieldByName("Value").SetInt(int64Val)
|
||||
return nil
|
||||
case "UInt64Value":
|
||||
fallthrough
|
||||
case "UInt32Value":
|
||||
uint64Val, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad DoubleValue: %s", value)
|
||||
}
|
||||
f.FieldByName("Value").SetUint(uint64Val)
|
||||
return nil
|
||||
case "BoolValue":
|
||||
if value == "true" {
|
||||
f.FieldByName("Value").SetBool(true)
|
||||
} else if value == "false" {
|
||||
f.FieldByName("Value").SetBool(false)
|
||||
} else {
|
||||
return fmt.Errorf("bad BoolValue: %s", value)
|
||||
}
|
||||
return nil
|
||||
case "StringValue":
|
||||
f.FieldByName("Value").SetString(value)
|
||||
return nil
|
||||
case "BytesValue":
|
||||
bytesVal, err := base64.StdEncoding.DecodeString(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad BytesValue: %s", value)
|
||||
}
|
||||
f.FieldByName("Value").SetBytes(bytesVal)
|
||||
return nil
|
||||
case "FieldMask":
|
||||
p := f.FieldByName("Paths")
|
||||
for _, v := range strings.Split(value, ",") {
|
||||
if v != "" {
|
||||
p.Set(reflect.Append(p, reflect.ValueOf(v)))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle Time and Duration stdlib types
|
||||
switch t := i.(type) {
|
||||
case *time.Time:
|
||||
pt, err := time.Parse(time.RFC3339Nano, value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad Timestamp: %v", err)
|
||||
}
|
||||
*t = pt
|
||||
return nil
|
||||
case *time.Duration:
|
||||
d, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad Duration: %v", err)
|
||||
}
|
||||
*t = d
|
||||
return nil
|
||||
}
|
||||
|
||||
// is the destination field an enumeration type?
|
||||
if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil {
|
||||
return populateFieldEnum(f, value, enumValMap)
|
||||
}
|
||||
|
||||
conv, ok := convFromType[f.Kind()]
|
||||
if !ok {
|
||||
return fmt.Errorf("field type %T is not supported in query parameters", i)
|
||||
}
|
||||
result := conv.Call([]reflect.Value{reflect.ValueOf(value)})
|
||||
if err := result[1].Interface(); err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
f.Set(result[0].Convert(f.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertEnum(value string, t reflect.Type, enumValMap map[string]int32) (reflect.Value, error) {
|
||||
// see if it's an enumeration string
|
||||
if enumVal, ok := enumValMap[value]; ok {
|
||||
return reflect.ValueOf(enumVal).Convert(t), nil
|
||||
}
|
||||
|
||||
// check for an integer that matches an enumeration value
|
||||
eVal, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t)
|
||||
}
|
||||
for _, v := range enumValMap {
|
||||
if v == int32(eVal) {
|
||||
return reflect.ValueOf(eVal).Convert(t), nil
|
||||
}
|
||||
}
|
||||
return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t)
|
||||
}
|
||||
|
||||
func populateFieldEnum(f reflect.Value, value string, enumValMap map[string]int32) error {
|
||||
cval, err := convertEnum(value, f.Type(), enumValMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Set(cval)
|
||||
return nil
|
||||
}
|
||||
|
||||
func populateFieldEnumRepeated(f reflect.Value, values []string, enumValMap map[string]int32) error {
|
||||
elemType := f.Type().Elem()
|
||||
f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type()))
|
||||
for i, v := range values {
|
||||
result, err := convertEnum(v, elemType, enumValMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Index(i).Set(result)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
convFromType = map[reflect.Kind]reflect.Value{
|
||||
reflect.String: reflect.ValueOf(String),
|
||||
reflect.Bool: reflect.ValueOf(Bool),
|
||||
reflect.Float64: reflect.ValueOf(Float64),
|
||||
reflect.Float32: reflect.ValueOf(Float32),
|
||||
reflect.Int64: reflect.ValueOf(Int64),
|
||||
reflect.Int32: reflect.ValueOf(Int32),
|
||||
reflect.Uint64: reflect.ValueOf(Uint64),
|
||||
reflect.Uint32: reflect.ValueOf(Uint32),
|
||||
reflect.Slice: reflect.ValueOf(Bytes),
|
||||
}
|
||||
)
|
201
vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/LICENSE
generated
vendored
Normal file
201
vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
|
@ -0,0 +1,2 @@
|
|||
// Package utilities provides members for internal use in grpc-gateway.
|
||||
package utilities
|
22
vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go
generated
vendored
Normal file
22
vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
package utilities
|
||||
|
||||
// An OpCode is a opcode of compiled path patterns.
|
||||
type OpCode int
|
||||
|
||||
// These constants are the valid values of OpCode.
|
||||
const (
|
||||
// OpNop does nothing
|
||||
OpNop = OpCode(iota)
|
||||
// OpPush pushes a component to stack
|
||||
OpPush
|
||||
// OpLitPush pushes a component to stack if it matches to the literal
|
||||
OpLitPush
|
||||
// OpPushM concatenates the remaining components and pushes it to stack
|
||||
OpPushM
|
||||
// OpConcatN pops N items from stack, concatenates them and pushes it back to stack
|
||||
OpConcatN
|
||||
// OpCapture pops an item and binds it to the variable
|
||||
OpCapture
|
||||
// OpEnd is the least positive invalid opcode.
|
||||
OpEnd
|
||||
)
|
20
vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go
generated
vendored
Normal file
20
vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
package utilities
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// IOReaderFactory takes in an io.Reader and returns a function that will allow you to create a new reader that begins
|
||||
// at the start of the stream
|
||||
func IOReaderFactory(r io.Reader) (func() io.Reader, error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return func() io.Reader {
|
||||
return bytes.NewReader(b)
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
package utilities
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// DoubleArray is a Double Array implementation of trie on sequences of strings.
|
||||
type DoubleArray struct {
|
||||
// Encoding keeps an encoding from string to int
|
||||
Encoding map[string]int
|
||||
// Base is the base array of Double Array
|
||||
Base []int
|
||||
// Check is the check array of Double Array
|
||||
Check []int
|
||||
}
|
||||
|
||||
// NewDoubleArray builds a DoubleArray from a set of sequences of strings.
|
||||
func NewDoubleArray(seqs [][]string) *DoubleArray {
|
||||
da := &DoubleArray{Encoding: make(map[string]int)}
|
||||
if len(seqs) == 0 {
|
||||
return da
|
||||
}
|
||||
|
||||
encoded := registerTokens(da, seqs)
|
||||
sort.Sort(byLex(encoded))
|
||||
|
||||
root := node{row: -1, col: -1, left: 0, right: len(encoded)}
|
||||
addSeqs(da, encoded, 0, root)
|
||||
|
||||
for i := len(da.Base); i > 0; i-- {
|
||||
if da.Check[i-1] != 0 {
|
||||
da.Base = da.Base[:i]
|
||||
da.Check = da.Check[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
return da
|
||||
}
|
||||
|
||||
func registerTokens(da *DoubleArray, seqs [][]string) [][]int {
|
||||
var result [][]int
|
||||
for _, seq := range seqs {
|
||||
var encoded []int
|
||||
for _, token := range seq {
|
||||
if _, ok := da.Encoding[token]; !ok {
|
||||
da.Encoding[token] = len(da.Encoding)
|
||||
}
|
||||
encoded = append(encoded, da.Encoding[token])
|
||||
}
|
||||
result = append(result, encoded)
|
||||
}
|
||||
for i := range result {
|
||||
result[i] = append(result[i], len(da.Encoding))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
type node struct {
|
||||
row, col int
|
||||
left, right int
|
||||
}
|
||||
|
||||
func (n node) value(seqs [][]int) int {
|
||||
return seqs[n.row][n.col]
|
||||
}
|
||||
|
||||
func (n node) children(seqs [][]int) []*node {
|
||||
var result []*node
|
||||
lastVal := int(-1)
|
||||
last := new(node)
|
||||
for i := n.left; i < n.right; i++ {
|
||||
if lastVal == seqs[i][n.col+1] {
|
||||
continue
|
||||
}
|
||||
last.right = i
|
||||
last = &node{
|
||||
row: i,
|
||||
col: n.col + 1,
|
||||
left: i,
|
||||
}
|
||||
result = append(result, last)
|
||||
}
|
||||
last.right = n.right
|
||||
return result
|
||||
}
|
||||
|
||||
func addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) {
|
||||
ensureSize(da, pos)
|
||||
|
||||
children := n.children(seqs)
|
||||
var i int
|
||||
for i = 1; ; i++ {
|
||||
ok := func() bool {
|
||||
for _, child := range children {
|
||||
code := child.value(seqs)
|
||||
j := i + code
|
||||
ensureSize(da, j)
|
||||
if da.Check[j] != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}()
|
||||
if ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
da.Base[pos] = i
|
||||
for _, child := range children {
|
||||
code := child.value(seqs)
|
||||
j := i + code
|
||||
da.Check[j] = pos + 1
|
||||
}
|
||||
terminator := len(da.Encoding)
|
||||
for _, child := range children {
|
||||
code := child.value(seqs)
|
||||
if code == terminator {
|
||||
continue
|
||||
}
|
||||
j := i + code
|
||||
addSeqs(da, seqs, j, *child)
|
||||
}
|
||||
}
|
||||
|
||||
func ensureSize(da *DoubleArray, i int) {
|
||||
for i >= len(da.Base) {
|
||||
da.Base = append(da.Base, make([]int, len(da.Base)+1)...)
|
||||
da.Check = append(da.Check, make([]int, len(da.Check)+1)...)
|
||||
}
|
||||
}
|
||||
|
||||
type byLex [][]int
|
||||
|
||||
func (l byLex) Len() int { return len(l) }
|
||||
func (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
|
||||
func (l byLex) Less(i, j int) bool {
|
||||
si := l[i]
|
||||
sj := l[j]
|
||||
var k int
|
||||
for k = 0; k < len(si) && k < len(sj); k++ {
|
||||
if si[k] < sj[k] {
|
||||
return true
|
||||
}
|
||||
if si[k] > sj[k] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if k < len(sj) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence.
|
||||
func (da *DoubleArray) HasCommonPrefix(seq []string) bool {
|
||||
if len(da.Base) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var i int
|
||||
for _, t := range seq {
|
||||
code, ok := da.Encoding[t]
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
j := da.Base[i] + code
|
||||
if len(da.Check) <= j || da.Check[j] != i+1 {
|
||||
break
|
||||
}
|
||||
i = j
|
||||
}
|
||||
j := da.Base[i] + len(da.Encoding)
|
||||
if len(da.Check) <= j || da.Check[j] != i+1 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
142
vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go
generated
vendored
Normal file
142
vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: google/api/httpbody.proto
|
||||
|
||||
package httpbody // import "google.golang.org/genproto/googleapis/api/httpbody"
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import any "github.com/golang/protobuf/ptypes/any"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
// Message that represents an arbitrary HTTP body. It should only be used for
|
||||
// payload formats that can't be represented as JSON, such as raw binary or
|
||||
// an HTML page.
|
||||
//
|
||||
//
|
||||
// This message can be used both in streaming and non-streaming API methods in
|
||||
// the request as well as the response.
|
||||
//
|
||||
// It can be used as a top-level request field, which is convenient if one
|
||||
// wants to extract parameters from either the URL or HTTP template into the
|
||||
// request fields and also want access to the raw HTTP body.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// message GetResourceRequest {
|
||||
// // A unique request id.
|
||||
// string request_id = 1;
|
||||
//
|
||||
// // The raw HTTP body is bound to this field.
|
||||
// google.api.HttpBody http_body = 2;
|
||||
// }
|
||||
//
|
||||
// service ResourceService {
|
||||
// rpc GetResource(GetResourceRequest) returns (google.api.HttpBody);
|
||||
// rpc UpdateResource(google.api.HttpBody) returns
|
||||
// (google.protobuf.Empty);
|
||||
// }
|
||||
//
|
||||
// Example with streaming methods:
|
||||
//
|
||||
// service CaldavService {
|
||||
// rpc GetCalendar(stream google.api.HttpBody)
|
||||
// returns (stream google.api.HttpBody);
|
||||
// rpc UpdateCalendar(stream google.api.HttpBody)
|
||||
// returns (stream google.api.HttpBody);
|
||||
// }
|
||||
//
|
||||
// Use of this type only changes how the request and response bodies are
|
||||
// handled, all other features will continue to work unchanged.
|
||||
type HttpBody struct {
|
||||
// The HTTP Content-Type header value specifying the content type of the body.
|
||||
ContentType string `protobuf:"bytes,1,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"`
|
||||
// The HTTP request/response body as raw binary.
|
||||
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
|
||||
// Application specific response metadata. Must be set in the first response
|
||||
// for streaming APIs.
|
||||
Extensions []*any.Any `protobuf:"bytes,3,rep,name=extensions,proto3" json:"extensions,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *HttpBody) Reset() { *m = HttpBody{} }
|
||||
func (m *HttpBody) String() string { return proto.CompactTextString(m) }
|
||||
func (*HttpBody) ProtoMessage() {}
|
||||
func (*HttpBody) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_httpbody_45db50668f1dc1dc, []int{0}
|
||||
}
|
||||
func (m *HttpBody) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_HttpBody.Unmarshal(m, b)
|
||||
}
|
||||
func (m *HttpBody) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_HttpBody.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *HttpBody) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_HttpBody.Merge(dst, src)
|
||||
}
|
||||
func (m *HttpBody) XXX_Size() int {
|
||||
return xxx_messageInfo_HttpBody.Size(m)
|
||||
}
|
||||
func (m *HttpBody) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_HttpBody.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_HttpBody proto.InternalMessageInfo
|
||||
|
||||
func (m *HttpBody) GetContentType() string {
|
||||
if m != nil {
|
||||
return m.ContentType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *HttpBody) GetData() []byte {
|
||||
if m != nil {
|
||||
return m.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *HttpBody) GetExtensions() []*any.Any {
|
||||
if m != nil {
|
||||
return m.Extensions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*HttpBody)(nil), "google.api.HttpBody")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("google/api/httpbody.proto", fileDescriptor_httpbody_45db50668f1dc1dc) }
|
||||
|
||||
var fileDescriptor_httpbody_45db50668f1dc1dc = []byte{
|
||||
// 229 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x8f, 0x31, 0x4f, 0xc3, 0x30,
|
||||
0x10, 0x85, 0xe5, 0xb6, 0x42, 0x70, 0x2d, 0x0c, 0x16, 0x43, 0x60, 0x0a, 0x4c, 0x99, 0x6c, 0x09,
|
||||
0xd8, 0x3a, 0x35, 0x0b, 0xb0, 0x45, 0x11, 0x13, 0x0b, 0x72, 0x1a, 0xe3, 0x46, 0x2a, 0x77, 0xa7,
|
||||
0xe6, 0x10, 0xf8, 0xef, 0xf0, 0x2b, 0x19, 0x11, 0x69, 0x2c, 0xe8, 0xf6, 0xe4, 0xef, 0x3d, 0xbf,
|
||||
0x77, 0x70, 0x11, 0x88, 0xc2, 0xd6, 0x5b, 0xc7, 0x9d, 0xdd, 0x88, 0x70, 0x43, 0x6d, 0x34, 0xbc,
|
||||
0x23, 0x21, 0x0d, 0x7b, 0x64, 0x1c, 0x77, 0x97, 0xc9, 0x36, 0x90, 0xe6, 0xfd, 0xd5, 0x3a, 0x1c,
|
||||
0x6d, 0xd7, 0x1f, 0x70, 0xfc, 0x20, 0xc2, 0x25, 0xb5, 0x51, 0x5f, 0xc1, 0x62, 0x4d, 0x28, 0x1e,
|
||||
0xe5, 0x45, 0x22, 0xfb, 0x4c, 0xe5, 0xaa, 0x38, 0xa9, 0xe7, 0xe3, 0xdb, 0x53, 0x64, 0xaf, 0x35,
|
||||
0xcc, 0x5a, 0x27, 0x2e, 0x9b, 0xe4, 0xaa, 0x58, 0xd4, 0x83, 0xd6, 0x77, 0x00, 0xfe, 0x53, 0x3c,
|
||||
0xf6, 0x1d, 0x61, 0x9f, 0x4d, 0xf3, 0x69, 0x31, 0xbf, 0x39, 0x37, 0x63, 0x7d, 0xaa, 0x34, 0x2b,
|
||||
0x8c, 0xf5, 0x3f, 0x5f, 0xb9, 0x81, 0xb3, 0x35, 0xbd, 0x99, 0xbf, 0x95, 0xe5, 0x69, 0x1a, 0x52,
|
||||
0xfd, 0x66, 0x2a, 0xf5, 0xbc, 0x1c, 0x61, 0xa0, 0xad, 0xc3, 0x60, 0x68, 0x17, 0x6c, 0xf0, 0x38,
|
||||
0xfc, 0x68, 0xf7, 0xc8, 0x71, 0xd7, 0x1f, 0x1c, 0xbf, 0x4c, 0xe2, 0x5b, 0xa9, 0xaf, 0xc9, 0xec,
|
||||
0x7e, 0x55, 0x3d, 0x36, 0x47, 0x43, 0xe2, 0xf6, 0x27, 0x00, 0x00, 0xff, 0xff, 0x78, 0xb9, 0x16,
|
||||
0x2b, 0x2d, 0x01, 0x00, 0x00,
|
||||
}
|
|
@ -20,6 +20,14 @@
|
|||
revision = "cf81fad90a1a1de334c4fc27e23eb9a4224b627a"
|
||||
version = "v0.41.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0a936e17f4fc0c65615913199ce0a387a67a4c72e017747b6f38c898168b1b75"
|
||||
name = "contrib.go.opencensus.io/exporter/ocagent"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "a8a6f458bbc1d5042322ad1f9b65eeb0b69be9ea"
|
||||
version = "v0.6.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:642cf8e80572f9dc0677b0f241c8ab2e715c9dccc215270ea873c86ddca0062c"
|
||||
name = "contrib.go.opencensus.io/exporter/prometheus"
|
||||
|
@ -94,12 +102,15 @@
|
|||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:06bd9f98d7cf2097c16f820f980709eb4d04e1c7369132c351fbf1ffb54d3117"
|
||||
digest = "1:fdb4ed936abeecb46a8c27dcac83f75c05c87a46d9ec7711411eb785c213fa02"
|
||||
name = "github.com/census-instrumentation/opencensus-proto"
|
||||
packages = [
|
||||
"gen-go/agent/common/v1",
|
||||
"gen-go/agent/metrics/v1",
|
||||
"gen-go/agent/trace/v1",
|
||||
"gen-go/metrics/v1",
|
||||
"gen-go/resource/v1",
|
||||
"gen-go/trace/v1",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "a105b96453fe85139acc07b68de48f2cbdd71249"
|
||||
|
@ -165,9 +176,10 @@
|
|||
revision = "869f871628b6baa9cfbc11732cdf6546b17c1298"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f6a318b1ad1b366c91f50dfbdfa7ee27b745b261e56cef7da53a21941f65a2b0"
|
||||
digest = "1:a677057cef8b68b66003c2775ed1126bbd7e9e372b54b7c1a7c5201a2f1f3eb0"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"descriptor",
|
||||
"jsonpb",
|
||||
"proto",
|
||||
"protoc-gen-go/descriptor",
|
||||
|
@ -289,6 +301,18 @@
|
|||
revision = "66b9c49e59c6c48f0ffce28c2d8b8a5678502c6d"
|
||||
version = "v1.4.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e9c0bf861ea69dd6de1ff7ac2a0485e84743e163853ca973177fba7a50d1b769"
|
||||
name = "github.com/grpc-ecosystem/grpc-gateway"
|
||||
packages = [
|
||||
"internal",
|
||||
"runtime",
|
||||
"utilities",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "f7120437bb4f6c71f7f5076ad65a45310de2c009"
|
||||
version = "v1.12.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f0d9d74edbd40fdeada436d5ac9cb5197407899af3fef85ff0137077ffe8ae19"
|
||||
name = "github.com/hashicorp/errwrap"
|
||||
|
@ -766,12 +790,13 @@
|
|||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:445a47089d0c1013621851ca7fa2992a499871e7b239fc3e904c404ab72f6a04"
|
||||
digest = "1:62fcff012dfad4d05ac33b4c353d933d34edafb4497b686b2289039e0c290245"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = [
|
||||
"googleapis/api",
|
||||
"googleapis/api/annotations",
|
||||
"googleapis/api/distribution",
|
||||
"googleapis/api/httpbody",
|
||||
"googleapis/api/label",
|
||||
"googleapis/api/metric",
|
||||
"googleapis/api/monitoredres",
|
||||
|
@ -1309,6 +1334,7 @@
|
|||
input-imports = [
|
||||
"cloud.google.com/go/compute/metadata",
|
||||
"cloud.google.com/go/storage",
|
||||
"contrib.go.opencensus.io/exporter/ocagent",
|
||||
"contrib.go.opencensus.io/exporter/prometheus",
|
||||
"contrib.go.opencensus.io/exporter/stackdriver",
|
||||
"contrib.go.opencensus.io/exporter/stackdriver/monitoredresource",
|
||||
|
@ -1406,6 +1432,7 @@
|
|||
"k8s.io/client-go/informers/batch/v1",
|
||||
"k8s.io/client-go/informers/batch/v1beta1",
|
||||
"k8s.io/client-go/informers/core/v1",
|
||||
"k8s.io/client-go/informers/internalinterfaces",
|
||||
"k8s.io/client-go/informers/rbac/v1",
|
||||
"k8s.io/client-go/kubernetes",
|
||||
"k8s.io/client-go/kubernetes/fake",
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
)
|
||||
|
||||
// URL is an alias of url.URL.
|
||||
|
@ -126,3 +128,13 @@ func (u *URL) ResolveReference(ref *URL) *URL {
|
|||
ret := URL(*newU)
|
||||
return &ret
|
||||
}
|
||||
|
||||
func init() {
|
||||
equality.Semantic.AddFunc(
|
||||
// url.URL has an unexported type (UserInfo) which causes semantic
|
||||
// equality to panic unless we add a custom equality function
|
||||
func(a, b URL) bool {
|
||||
return a.String() == b.String()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -18,12 +18,17 @@ package configmap
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
informers "k8s.io/client-go/informers"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/client-go/informers"
|
||||
corev1informers "k8s.io/client-go/informers/core/v1"
|
||||
"k8s.io/client-go/informers/internalinterfaces"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
@ -35,7 +40,7 @@ func NewDefaultWatcher(kc kubernetes.Interface, namespace string) *InformedWatch
|
|||
return NewInformedWatcher(kc, namespace)
|
||||
}
|
||||
|
||||
// NewInformedWatcherFromFactory watches a Kubernetes namespace for configmap changes.
|
||||
// NewInformedWatcherFromFactory watches a Kubernetes namespace for ConfigMap changes.
|
||||
func NewInformedWatcherFromFactory(sif informers.SharedInformerFactory, namespace string) *InformedWatcher {
|
||||
return &InformedWatcher{
|
||||
sif: sif,
|
||||
|
@ -47,17 +52,46 @@ func NewInformedWatcherFromFactory(sif informers.SharedInformerFactory, namespac
|
|||
}
|
||||
}
|
||||
|
||||
// NewInformedWatcher watches a Kubernetes namespace for configmap changes.
|
||||
func NewInformedWatcher(kc kubernetes.Interface, namespace string) *InformedWatcher {
|
||||
// NewInformedWatcher watches a Kubernetes namespace for ConfigMap changes.
|
||||
// Optional label requirements allow restricting the list of ConfigMap objects
|
||||
// that is tracked by the underlying Informer.
|
||||
func NewInformedWatcher(kc kubernetes.Interface, namespace string, lr ...labels.Requirement) *InformedWatcher {
|
||||
return NewInformedWatcherFromFactory(informers.NewSharedInformerFactoryWithOptions(
|
||||
kc,
|
||||
// We noticed that we're getting updates all the time anyway, due to the
|
||||
// watches being terminated and re-spawned.
|
||||
0,
|
||||
informers.WithNamespace(namespace),
|
||||
informers.WithTweakListOptions(addLabelRequirementsToListOptions(lr)),
|
||||
), namespace)
|
||||
}
|
||||
|
||||
// addLabelRequirementsToListOptions returns a function which injects label
|
||||
// requirements to existing metav1.ListOptions.
|
||||
func addLabelRequirementsToListOptions(lr []labels.Requirement) internalinterfaces.TweakListOptionsFunc {
|
||||
if len(lr) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return func(lo *metav1.ListOptions) {
|
||||
sel, err := labels.Parse(lo.LabelSelector)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("could not parse label selector %q: %w", lo.LabelSelector, err))
|
||||
}
|
||||
lo.LabelSelector = sel.Add(lr...).String()
|
||||
}
|
||||
}
|
||||
|
||||
// FilterConfigByLabelExists returns an "exists" label requirement for the
|
||||
// given label key.
|
||||
func FilterConfigByLabelExists(labelKey string) (*labels.Requirement, error) {
|
||||
req, err := labels.NewRequirement(labelKey, selection.Exists, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not construct label requirement: %w", err)
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// InformedWatcher provides an informer-based implementation of Watcher.
|
||||
type InformedWatcher struct {
|
||||
sif informers.SharedInformerFactory
|
||||
|
|
|
@ -45,10 +45,12 @@ func (w *ManualWatcher) Watch(name string, o ...Observer) {
|
|||
w.observers[name] = append(w.observers[name], o...)
|
||||
}
|
||||
|
||||
// Start implements Watcher
|
||||
func (w *ManualWatcher) Start(<-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnChange invokes the callbacks of all observers of the given ConfigMap.
|
||||
func (w *ManualWatcher) OnChange(configMap *corev1.ConfigMap) {
|
||||
if configMap.Namespace != w.Namespace {
|
||||
return
|
||||
|
|
|
@ -30,6 +30,7 @@ import (
|
|||
"go.opencensus.io/stats/view"
|
||||
"golang.org/x/sync/errgroup"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
|
@ -99,8 +100,10 @@ func Main(component string, ctors ...injection.ControllerConstructor) {
|
|||
|
||||
func MainWithContext(ctx context.Context, component string, ctors ...injection.ControllerConstructor) {
|
||||
var (
|
||||
masterURL = flag.String("master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
|
||||
kubeconfig = flag.String("kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
|
||||
masterURL = flag.String("master", "",
|
||||
"The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
|
||||
kubeconfig = flag.String("kubeconfig", "",
|
||||
"Path to a kubeconfig. Only required if out-of-cluster.")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
|
@ -140,13 +143,24 @@ func MainWithConfig(ctx context.Context, component string, cfg *rest.Config, cto
|
|||
defer flush(logger)
|
||||
ctx = logging.WithLogger(ctx, logger)
|
||||
|
||||
// Obtain K8s clientset.
|
||||
kc := kubeclient.Get(ctx)
|
||||
if err := version.CheckMinimumVersion(kc.Discovery()); err != nil {
|
||||
logger.Fatalw("Version check failed", zap.Error(err))
|
||||
}
|
||||
|
||||
// Create ConfigMaps watcher with optional label-based filter.
|
||||
var cmLabelReqs []labels.Requirement
|
||||
if cmLabel := system.ResourceLabel(); cmLabel != "" {
|
||||
req, err := configmap.FilterConfigByLabelExists(cmLabel)
|
||||
if err != nil {
|
||||
logger.With(zap.Error(err)).Fatalf("Failed to generate requirement for label %q")
|
||||
}
|
||||
logger.Infof("Setting up ConfigMap watcher with label selector %q", req)
|
||||
cmLabelReqs = append(cmLabelReqs, *req)
|
||||
}
|
||||
// TODO(mattmoor): This should itself take a context and be injection-based.
|
||||
cmw := configmap.NewInformedWatcher(kc, system.Namespace())
|
||||
cmw := configmap.NewInformedWatcher(kc, system.Namespace(), cmLabelReqs...)
|
||||
|
||||
// Based on the reconcilers we have linked, build up the set of controllers to run.
|
||||
controllers := make([]*controller.Impl, 0, len(ctors))
|
||||
|
|
|
@ -57,9 +57,15 @@ const (
|
|||
Stackdriver metricsBackend = "stackdriver"
|
||||
// Prometheus is used for Prometheus backend
|
||||
Prometheus metricsBackend = "prometheus"
|
||||
// OpenCensus is used to export to the OpenCensus Agent / Collector,
|
||||
// which can send to many other services.
|
||||
OpenCensus metricsBackend = "opencensus"
|
||||
|
||||
defaultBackendEnvName = "DEFAULT_METRICS_BACKEND"
|
||||
|
||||
CollectorAddressKey = "metrics.opencensus-address"
|
||||
CollectorSecureKey = "metrics.opencensus-require-tls"
|
||||
|
||||
defaultPrometheusPort = 9090
|
||||
maxPrometheusPort = 65535
|
||||
minPrometheusPort = 1024
|
||||
|
@ -80,6 +86,12 @@ type metricsConfig struct {
|
|||
// writing the metrics to the stats.RecordWithOptions interface.
|
||||
recorder func(context.Context, stats.Measurement, ...stats.Options) error
|
||||
|
||||
// ---- OpenCensus specific below ----
|
||||
// collectorAddress is the address of the collector, if not `localhost:55678`
|
||||
collectorAddress string
|
||||
// Require mutual TLS. Defaults to "false" because mutual TLS is hard to set up.
|
||||
requireSecure bool
|
||||
|
||||
// ---- Prometheus specific below ----
|
||||
// prometheusPort is the port where metrics are exposed in Prometheus
|
||||
// format. It defaults to 9090.
|
||||
|
@ -164,18 +176,28 @@ func createMetricsConfig(ops ExporterOptions, logger *zap.SugaredLogger) (*metri
|
|||
// Use Prometheus if DEFAULT_METRICS_BACKEND does not exist or is empty
|
||||
backend = string(Prometheus)
|
||||
}
|
||||
// Override backend if it is setting in config map.
|
||||
// Override backend if it is set in the config map.
|
||||
if backendFromConfig, ok := m[BackendDestinationKey]; ok {
|
||||
backend = backendFromConfig
|
||||
}
|
||||
lb := metricsBackend(strings.ToLower(backend))
|
||||
switch lb {
|
||||
case Stackdriver, Prometheus:
|
||||
case Stackdriver, Prometheus, OpenCensus:
|
||||
mc.backendDestination = lb
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported metrics backend value %q", backend)
|
||||
}
|
||||
|
||||
if mc.backendDestination == OpenCensus {
|
||||
mc.collectorAddress = ops.ConfigMap[CollectorAddressKey]
|
||||
if isSecure := ops.ConfigMap[CollectorSecureKey]; isSecure != "" {
|
||||
var err error
|
||||
if mc.requireSecure, err = strconv.ParseBool(isSecure); err != nil {
|
||||
return nil, fmt.Errorf("invalid %s value %q", CollectorSecureKey, isSecure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if mc.backendDestination == Prometheus {
|
||||
pp := ops.PrometheusPort
|
||||
if pp == 0 {
|
||||
|
|
|
@ -121,6 +121,12 @@ func isNewExporterRequired(newConfig *metricsConfig) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// If the OpenCensus address has changed, restart the exporter.
|
||||
// TODO(evankanderson): Should we just always restart the opencensus agent?
|
||||
if newConfig.backendDestination == OpenCensus {
|
||||
return newConfig.collectorAddress != cc.collectorAddress || newConfig.requireSecure != cc.requireSecure
|
||||
}
|
||||
|
||||
return newConfig.backendDestination == Stackdriver && newConfig.stackdriverClientConfig != cc.stackdriverClientConfig
|
||||
}
|
||||
|
||||
|
@ -140,6 +146,8 @@ func newMetricsExporter(config *metricsConfig, logger *zap.SugaredLogger) (view.
|
|||
var err error
|
||||
var e view.Exporter
|
||||
switch config.backendDestination {
|
||||
case OpenCensus:
|
||||
e, err = newOpenCensusExporter(config, logger)
|
||||
case Stackdriver:
|
||||
e, err = newStackdriverExporter(config, logger)
|
||||
case Prometheus:
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright 2020 The Knative 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 metrics
|
||||
|
||||
import (
|
||||
"contrib.go.opencensus.io/exporter/ocagent"
|
||||
"go.opencensus.io/stats/view"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func newOpenCensusExporter(config *metricsConfig, logger *zap.SugaredLogger) (view.Exporter, error) {
|
||||
opts := []ocagent.ExporterOption{ocagent.WithServiceName(config.component)}
|
||||
if config.collectorAddress != "" {
|
||||
opts = append(opts, ocagent.WithAddress(config.collectorAddress))
|
||||
}
|
||||
if !config.requireSecure {
|
||||
opts = append(opts, ocagent.WithInsecure())
|
||||
}
|
||||
e, err := ocagent.NewExporter(opts...)
|
||||
if err != nil {
|
||||
logger.Errorw("Failed to create the OpenCensus exporter.", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
logger.Infof("Created OpenCensus exporter with config: %+v.", *config)
|
||||
view.RegisterExporter(e)
|
||||
return e, nil
|
||||
}
|
|
@ -22,11 +22,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
NamespaceEnvKey = "SYSTEM_NAMESPACE"
|
||||
NamespaceEnvKey = "SYSTEM_NAMESPACE"
|
||||
ResourceLabelEnvKey = "SYSTEM_RESOURCE_LABEL"
|
||||
)
|
||||
|
||||
// Namespace holds the K8s namespace where our serving system
|
||||
// components run.
|
||||
// Namespace returns the name of the K8s namespace where our system components
|
||||
// run.
|
||||
func Namespace() string {
|
||||
if ns := os.Getenv(NamespaceEnvKey); ns != "" {
|
||||
return ns
|
||||
|
@ -50,3 +51,9 @@ import (
|
|||
_ "knative.dev/pkg/system/testing"
|
||||
)`, NamespaceEnvKey, NamespaceEnvKey))
|
||||
}
|
||||
|
||||
// ResourceLabel returns the label key identifying K8s objects our system
|
||||
// components source their configuration from.
|
||||
func ResourceLabel() string {
|
||||
return os.Getenv(ResourceLabelEnvKey)
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
Copyright 2020 The Knative 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 gke
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const (
|
||||
testEnv = "test"
|
||||
stagingEnv = "staging"
|
||||
staging2Env = "staging2"
|
||||
prodEnv = "prod"
|
||||
|
||||
testEndpoint = "https://test-container.sandbox.googleapis.com/"
|
||||
stagingEndpoint = "https://staging-container.sandbox.googleapis.com/"
|
||||
staging2Endpoint = "https://staging2-container.sandbox.googleapis.com/"
|
||||
prodEndpoint = "https://container.googleapis.com/"
|
||||
)
|
||||
|
||||
var urlRe = regexp.MustCompile(`https://.*/`)
|
||||
|
||||
// ServiceEndpoint returns the container service endpoint for the given environment.
|
||||
func ServiceEndpoint(environment string) (string, error) {
|
||||
var endpoint string
|
||||
switch env := environment; {
|
||||
case env == testEnv:
|
||||
endpoint = testEndpoint
|
||||
case env == stagingEnv:
|
||||
endpoint = stagingEndpoint
|
||||
case env == staging2Env:
|
||||
endpoint = staging2Endpoint
|
||||
case env == prodEnv:
|
||||
endpoint = prodEndpoint
|
||||
case urlRe.MatchString(env):
|
||||
endpoint = env
|
||||
default:
|
||||
return "", fmt.Errorf("the environment '%s' is invalid, must be one of 'test', 'staging', 'staging2', 'prod', or a custom https:// URL", environment)
|
||||
}
|
||||
return endpoint, nil
|
||||
}
|
|
@ -30,10 +30,12 @@ var (
|
|||
gcpProjectName string
|
||||
repoName string
|
||||
benchmarkRootFolder string
|
||||
gkeEnvironment string
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.StringVar(&gcpProjectName, "gcp-project", "", "name of the GCP project for cluster operations")
|
||||
flag.StringVar(&gkeEnvironment, "gke-environment", "prod", "Container API endpoint to use, one of 'test', 'staging', 'staging2', 'prod', or a custom https:// URL. Default to be prod.")
|
||||
flag.StringVar(&repoName, "repository", "", "name of the repository")
|
||||
flag.StringVar(&benchmarkRootFolder, "benchmark-root", "", "root folder of the benchmarks")
|
||||
flag.BoolVar(&isRecreate, "recreate", false, "is recreate operation or not")
|
||||
|
@ -44,7 +46,7 @@ func main() {
|
|||
log.Fatal("Only one operation can be specified, either recreate or reconcile")
|
||||
}
|
||||
|
||||
client, err := testPkg.NewClient()
|
||||
client, err := testPkg.NewClient(gkeEnvironment)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed setting up GKE client, cannot proceed: %v", err)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/api/option"
|
||||
|
||||
"knative.dev/pkg/test/gke"
|
||||
"knative.dev/pkg/test/helpers"
|
||||
|
||||
|
@ -44,8 +46,13 @@ type gkeClient struct {
|
|||
}
|
||||
|
||||
// NewClient will create a new gkeClient.
|
||||
func NewClient() (*gkeClient, error) {
|
||||
operations, err := gke.NewSDKClient()
|
||||
func NewClient(environment string) (*gkeClient, error) {
|
||||
endpoint, err := gke.ServiceEndpoint(environment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endpointOption := option.WithEndpoint(endpoint)
|
||||
operations, err := gke.NewSDKClient(endpointOption)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set up GKE client: %v", err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue