vendor: update all dependencies

This commit is contained in:
Nick Craig-Wood 2018-06-17 17:59:12 +01:00
parent 3f0789e2db
commit 08021c4636
2474 changed files with 435818 additions and 282709 deletions

71
Gopkg.lock generated
View File

@ -14,8 +14,8 @@
[[projects]]
name = "cloud.google.com/go"
packages = ["compute/metadata"]
revision = "29f476ffa9c4cd4fd14336b6043090ac1ad76733"
version = "v0.21.0"
revision = "0fd7230b2a7505833d5f69b75cbd6c9582401479"
version = "v0.23.0"
[[projects]]
name = "github.com/Azure/azure-sdk-for-go"
@ -23,8 +23,8 @@
"storage",
"version"
]
revision = "4650843026a7fdec254a8d9cf893693a254edd0b"
version = "v16.2.1"
revision = "cd93ccfe0395e70031704ca68f14606588eec120"
version = "v17.3.0"
[[projects]]
name = "github.com/Azure/go-autorest"
@ -34,8 +34,8 @@
"autorest/azure",
"autorest/date"
]
revision = "eaa7994b2278094c904d31993d26f56324db3052"
version = "v10.8.1"
revision = "f04d503958a4fe854c1b41667c73f8813c9dd9c3"
version = "v10.11.2"
[[projects]]
branch = "master"
@ -74,6 +74,7 @@
"aws/credentials/ec2rolecreds",
"aws/credentials/endpointcreds",
"aws/credentials/stscreds",
"aws/csm",
"aws/defaults",
"aws/ec2metadata",
"aws/endpoints",
@ -84,6 +85,8 @@
"internal/sdkrand",
"internal/shareddefaults",
"private/protocol",
"private/protocol/eventstream",
"private/protocol/eventstream/eventstreamapi",
"private/protocol/query",
"private/protocol/query/queryutil",
"private/protocol/rest",
@ -94,8 +97,8 @@
"service/s3/s3manager",
"service/sts"
]
revision = "4f5d298bd2dcb34b06d944594f458d1f77ac4d66"
version = "v1.13.42"
revision = "bfc1a07cf158c30c41a3eefba8aae043d0bb5bff"
version = "v1.14.8"
[[projects]]
name = "github.com/billziss-gh/cgofuse"
@ -154,8 +157,8 @@
[[projects]]
name = "github.com/go-ini/ini"
packages = ["."]
revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
version = "v1.36.0"
revision = "06f5f3d67269ccec1fe5fe4134ba6e982984f7f5"
version = "v1.37.0"
[[projects]]
name = "github.com/golang/protobuf"
@ -193,10 +196,10 @@
revision = "ae77be60afb1dcacde03767a8c37337fad28ac14"
[[projects]]
branch = "master"
name = "github.com/kr/fs"
packages = ["."]
revision = "2788f0dbd16903de03cb8186e5c7d97b69ad387b"
revision = "1455def202f6e05b95cc7bfc7e8ae67ae5141eba"
version = "v0.1.0"
[[projects]]
name = "github.com/marstr/guid"
@ -217,16 +220,16 @@
revision = "887eb06ab6a255fbf5744b5812788e884078620a"
[[projects]]
branch = "master"
name = "github.com/ncw/swift"
packages = ["."]
revision = "b2a7479cf26fa841ff90dd932d0221cb5c50782d"
version = "v1.0.39"
[[projects]]
branch = "master"
name = "github.com/nsf/termbox-go"
packages = ["."]
revision = "5a49b82160547cc98fca189a677a1c14eff796f8"
revision = "5c94acc5e6eb520f1bcd183974e01171cc4c23b3"
[[projects]]
branch = "master"
@ -249,8 +252,8 @@
"log",
"reopen"
]
revision = "b98065a377794d577e2a0e32869378b9ce4b8952"
version = "v0.1.1"
revision = "807ee759d82c84982a89fb3dc875ef884942f1e5"
version = "v0.2.0"
[[projects]]
name = "github.com/pkg/errors"
@ -261,8 +264,8 @@
[[projects]]
name = "github.com/pkg/sftp"
packages = ["."]
revision = "5bf2a174b604c6b5549dd9740d924ff2f02e3ad7"
version = "1.6.0"
revision = "57673e38ea946592a59c26592b7e6fbda646975b"
version = "1.8.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
@ -292,7 +295,7 @@
branch = "master"
name = "github.com/sevlyar/go-daemon"
packages = ["."]
revision = "45a2ba1b7c6710a044163fa109bf08d060bc3afa"
revision = "f9261e73885de99b1647d68bedadf2b9a99ad11f"
[[projects]]
branch = "master"
@ -306,8 +309,8 @@
".",
"doc"
]
revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4"
version = "v0.0.2"
revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385"
version = "v0.0.3"
[[projects]]
name = "github.com/spf13/pflag"
@ -321,8 +324,8 @@
"assert",
"require"
]
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
version = "v1.2.1"
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
version = "v1.2.2"
[[projects]]
branch = "master"
@ -351,8 +354,8 @@
"service",
"utils"
]
revision = "9e88dc1b83728e1462fd74bb61b0f5e28ac95bb6"
version = "v2.2.12"
revision = "4f9ac88c5fec7350e960aabd0de1f1ede0ad2895"
version = "v2.2.14"
[[projects]]
branch = "master"
@ -364,6 +367,7 @@
"ed25519",
"ed25519/internal/edwards25519",
"internal/chacha20",
"internal/subtle",
"nacl/secretbox",
"pbkdf2",
"poly1305",
@ -373,7 +377,7 @@
"ssh/agent",
"ssh/terminal"
]
revision = "4ec37c66abab2c7e02ae775328b2ff001c3f025a"
revision = "027cca12c2d63e3d62b670d901e8a2c95854feec"
[[projects]]
branch = "master"
@ -387,13 +391,12 @@
"http2",
"http2/hpack",
"idna",
"lex/httplex",
"publicsuffix",
"webdav",
"webdav/internal/xml",
"websocket"
]
revision = "640f4622ab692b87c2f3a94265e6f579fe38263d"
revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196"
[[projects]]
branch = "master"
@ -405,7 +408,7 @@
"jws",
"jwt"
]
revision = "cdc340f7c179dbbfa4afd43b7614e8fcadde4269"
revision = "1e0a3fa8ba9a5c9eb35c271780101fdaf1b205d7"
[[projects]]
branch = "master"
@ -414,7 +417,7 @@
"unix",
"windows"
]
revision = "6f686a352de66814cdd080d970febae7767857a3"
revision = "6c888cc515d3ed83fc103cf1d84468aad274b0a7"
[[projects]]
name = "golang.org/x/text"
@ -453,7 +456,7 @@
"googleapi/internal/uritemplates",
"storage/v1"
]
revision = "bb395b674c9930450ea7243b3e3c8f43150f4c11"
revision = "2eea9ba0a3d94f6ab46508083e299a00bbbc65f6"
[[projects]]
name = "google.golang.org/appengine"
@ -470,8 +473,8 @@
"log",
"urlfetch"
]
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
version = "v1.0.0"
revision = "b1f26356af11148e710935ed1ac8a7f5702c7612"
version = "v1.1.0"
[[projects]]
name = "gopkg.in/yaml.v2"
@ -482,6 +485,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "e250c0e18b90fecd81621d7ffcc1580931e668bac9048de910fdf6df8e4a140c"
inputs-digest = "c1378c5fc821e27711155958ff64b3c74b56818ba4733dbfe0c86d518c32880e"
solver-name = "gps-cdcl"
solver-version = 1

View File

@ -1,20 +1,11 @@
# github.com/yunify/qingstor-sdk-go depends on an old version of
# github.com/pengsrc/go-shared - pin the version here
#
# When the version here moves on, we can unpin
# https://github.com/yunify/qingstor-sdk-go/blob/master/glide.yaml
[[override]]
version = "=v0.1.1"
name = "github.com/pengsrc/go-shared"
# pin this to master to pull in the macOS changes
# can likely remove for 1.42
# can likely remove for 1.43
[[override]]
branch = "master"
name = "github.com/sevlyar/go-daemon"
# pin this to master to pull in the fix for linux/mips
# can likely remove for 1.42
# can likely remove for 1.43
[[override]]
branch = "master"
name = "github.com/coreos/bbolt"

View File

@ -31,6 +31,7 @@ Making a release
* # announce with forum post, twitter post, G+ post
Early in the next release cycle update the vendored dependencies
* Review any pinned packages in Gopkg.toml and remove if possible
* make update
* git status
* git add new files

View File

@ -14,6 +14,7 @@ script:
GCLOUD_TESTS_GOLANG_KEY="$(pwd)/dulcet-port-762-key.json"
GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID="gcloud-golang-firestore-tests"
GCLOUD_TESTS_GOLANG_FIRESTORE_KEY="$(pwd)/gcloud-golang-firestore-tests-key.json"
GCLOUD_TESTS_GOLANG_KEYRING="projects/dulcet-port-762/locations/us/keyRings/go-integration-test"
./run-tests.sh $TRAVIS_COMMIT
env:
matrix:

View File

@ -31,11 +31,11 @@ To run the integrations tests, creating and configuration of a project in the
Google Developers Console is required.
After creating a project, you must [create a service account](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount).
Ensure the project-level **Owner**
Ensure the project-level **Owner**
[IAM role](console.cloud.google.com/iam-admin/iam/project) role is added to the
service account. Alternatively, the account can be granted all of the following roles:
- **Editor**
- **Logs Configuration Writer**
- **Editor**
- **Logs Configuration Writer**
- **PubSub Admin**
Once you create a project, set the following environment variables to be able to
@ -43,13 +43,19 @@ run the against the actual APIs.
- **GCLOUD_TESTS_GOLANG_PROJECT_ID**: Developers Console project's ID (e.g. bamboo-shift-455)
- **GCLOUD_TESTS_GOLANG_KEY**: The path to the JSON key file.
- **GCLOUD_TESTS_API_KEY**: Your API key.
Firestore requires a different project and key:
Some packages require additional environment variables to be set:
- **GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID**: Developers Console project's ID
supporting Firestore
- **GCLOUD_TESTS_GOLANG_FIRESTORE_KEY**: The path to the JSON key file.
- firestore
- **GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID**: project ID for Firestore.
- **GCLOUD_TESTS_GOLANG_FIRESTORE_KEY**: The path to the JSON key file.
- storage
- **GCLOUD_TESTS_GOLANG_KEYRING**: The full name of the keyring for the tests, in the
form "projects/P/locations/L/keyRings/R".
- translate
- **GCLOUD_TESTS_API_KEY**: API key for using the Translate API.
- profiler
- **GCLOUD_TESTS_GOLANG_ZONE**: Compute Engine zone.
Install the [gcloud command-line tool][gcloudcli] to your machine and use it
to create some resources used in integration tests.
@ -80,11 +86,20 @@ $ gcloud beta spanner instances create go-integration-test --config regional-us-
# NOTE: Spanner instances are priced by the node-hour, so you may want to delete
# the instance after testing with 'gcloud beta spanner instances delete'.
# For Storage integration tests:
# Enable KMS for your project in the Cloud Console.
# Create a KMS keyring, in the same location as the default location for your project's buckets.
$ gcloud kms keyrings create MY_KEYRING --location MY_LOCATION
# Create two keys in the keyring, named key1 and key2.
$ gcloud kms keys create key1 --keyring MY_KEYRING --location MY_LOCATION --purpose encryption
$ gcloud kms keys create key2 --keyring MY_KEYRING --location MY_LOCATION --purpose encryption
# As mentioned above, set the GCLOUD_TESTS_GOLANG_KEYRING environment variable.
$ export GCLOUD_TESTS_GOLANG_KEYRING=projects/$GCLOUD_TESTS_GOLANG_PROJECT_ID/locations/MY_LOCATION/keyRings/MY_KEYRING
# Authorize Google Cloud Storage to encrypt and decrypt using key1.
gsutil kms authorize -p $GCLOUD_TESTS_GOLANG_PROJECT_ID -k $GCLOUD_TESTS_GOLANG_KEYRING/cryptoKeys/key1
```
Once you've set the environment variables, you can run the integration tests by
running:
Once you've done the necessary setup, you can run the integration tests by running:
``` sh
$ go test -v cloud.google.com/go/...

67
vendor/cloud.google.com/go/README.md generated vendored
View File

@ -33,6 +33,73 @@ make backwards-incompatible changes.
## News
_May 18, 2018_
*v0.23.0*
- bigquery: Add DDL stats to query statistics.
- bigtable:
- cbt: Add cells-per-column limit for row lookup.
- cbt: Make it possible to combine read filters.
- dlp: v2beta2 client removed. Use the v2 client instead.
- firestore, spanner: Fix compilation errors due to protobuf changes.
_May 8, 2018_
*v0.22.0*
- bigtable:
- cbt: Support cells per column limit for row read.
- bttest: Correctly handle empty RowSet.
- Fix ReadModifyWrite operation in emulator.
- Fix API path in GetCluster.
- bigquery:
- BEHAVIOR CHANGE: Retry on 503 status code.
- Add dataset.DeleteWithContents.
- Add SchemaUpdateOptions for query jobs.
- Add Timeline to QueryStatistics.
- Add more stats to ExplainQueryStage.
- Support Parquet data format.
- datastore:
- Support omitempty for times.
- dlp:
- **BREAKING CHANGE:** Remove v1beta1 client. Please migrate to the v2 client,
which is now out of beta.
- Add v2 client.
- firestore:
- BEHAVIOR CHANGE: Treat set({}, MergeAll) as valid.
- iam:
- Support JWT signing via SignJwt callopt.
- profiler:
- BEHAVIOR CHANGE: PollForSerialOutput returns an error when context.Done.
- BEHAVIOR CHANGE: Increase the initial backoff to 1 minute.
- Avoid returning empty serial port output.
- pubsub:
- BEHAVIOR CHANGE: Don't backoff during next retryable error once stream is healthy.
- BEHAVIOR CHANGE: Don't backoff on EOF.
- pstest: Support Acknowledge and ModifyAckDeadline RPCs.
- redis:
- Add v1 beta Redis client.
- spanner:
- Support SessionLabels.
- speech:
- Add api v1 beta1 client.
- storage:
- BEHAVIOR CHANGE: Retry reads when retryable error occurs.
- Fix delete of object in requester-pays bucket.
- Support KMS integration.
_April 9, 2018_
*v0.21.0*

13
vendor/cloud.google.com/go/RELEASING.md generated vendored Normal file
View File

@ -0,0 +1,13 @@
# How to Release this Repo
1. Determine the current release version with `git tag -l`. It should look
something like `vX.Y.Z`. We'll call the current
version `$CV` and the new version `$NV`.
1. On master, run `git log $CV..` to list all the changes since the last
release.
1. Edit the News section of `README.md` to include a summary of the changes.
1. Mail the CL containing the `README.md` changes. When the CL is approved, submit it.
1. Without submitting any other CLs:
a. Switch to master.
b. Tag the repo with the next version: `git tag $NV`.
c. Push the tag: `git push origin $NV`.

View File

@ -16,16 +16,18 @@ package cloud_test
import (
"cloud.google.com/go/datastore"
"cloud.google.com/go/pubsub"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
"google.golang.org/api/option"
)
// Google Application Default Credentials is the recommended way to authorize
// and authenticate clients.
//
// For information on how to create and obtain Application Default Credentials, see
// https://developers.google.com/identity/protocols/application-default-credentials.
func Example_applicationDefaultCredentials() {
// Google Application Default Credentials is the recommended way to authorize
// and authenticate clients.
//
// See the following link on how to create and obtain Application Default Credentials:
// https://developers.google.com/identity/protocols/application-default-credentials.
client, err := datastore.NewClient(context.Background(), "project-id")
if err != nil {
// TODO: handle error.
@ -33,15 +35,36 @@ func Example_applicationDefaultCredentials() {
_ = client // Use the client.
}
func Example_serviceAccountFile() {
// Use a JSON key file associated with a Google service account to
// authenticate and authorize. Service Account keys can be created and
// downloaded from https://console.developers.google.com/permissions/serviceaccounts.
//
// Note: This example uses the datastore client, but the same steps apply to
// the other client libraries underneath this package.
// You can use a file with credentials to authenticate and authorize, such as a JSON
// key file associated with a Google service account. Service Account keys can be
// created and downloaded from
// https://console.developers.google.com/permissions/serviceaccounts.
//
// This example uses the Datastore client, but the same steps apply to
// the other client libraries underneath this package.
func Example_credentialsFile() {
client, err := datastore.NewClient(context.Background(),
"project-id", option.WithServiceAccountFile("/path/to/service-account-key.json"))
"project-id", option.WithCredentialsFile("/path/to/service-account-key.json"))
if err != nil {
// TODO: handle error.
}
_ = client // Use the client.
}
// In some cases (for instance, you don't want to store secrets on disk), you can
// create credentials from in-memory JSON and use the WithCredentials option.
//
// The google package in this example is at golang.org/x/oauth2/google.
//
// This example uses the PubSub client, but the same steps apply to
// the other client libraries underneath this package.
func Example_credentialsFromJSON() {
ctx := context.Background()
creds, err := google.CredentialsFromJSON(ctx, []byte("JSON creds"), pubsub.ScopePubSub)
if err != nil {
// TODO: handle error.
}
client, err := pubsub.NewClient(ctx, "project-id", option.WithCredentials(creds))
if err != nil {
// TODO: handle error.
}

View File

@ -147,7 +147,10 @@ func runWithRetry(ctx context.Context, call func() error) error {
})
}
// This is the correct definition of retryable according to the BigQuery team.
// This is the correct definition of retryable according to the BigQuery team. It
// also considers 502 ("Bad Gateway") and 503 ("Service Unavailable") errors
// retryable; these are returned by systems between the client and the BigQuery
// service.
func retryableError(err error) bool {
e, ok := err.(*googleapi.Error)
if !ok {
@ -157,5 +160,5 @@ func retryableError(err error) bool {
if len(e.Errors) > 0 {
reason = e.Errors[0].Reason
}
return e.Code == http.StatusBadGateway || reason == "backendError" || reason == "rateLimitExceeded"
return e.Code == http.StatusServiceUnavailable || e.Code == http.StatusBadGateway || reason == "backendError" || reason == "rateLimitExceeded"
}

View File

@ -147,12 +147,21 @@ func accessListToBQ(a []*AccessEntry) ([]*bq.DatasetAccess, error) {
return q, nil
}
// Delete deletes the dataset.
// Delete deletes the dataset. Delete will fail if the dataset is not empty.
func (d *Dataset) Delete(ctx context.Context) (err error) {
return d.deleteInternal(ctx, false)
}
// DeleteWithContents deletes the dataset, as well as contained resources.
func (d *Dataset) DeleteWithContents(ctx context.Context) (err error) {
return d.deleteInternal(ctx, true)
}
func (d *Dataset) deleteInternal(ctx context.Context, deleteContents bool) (err error) {
ctx = trace.StartSpan(ctx, "cloud.google.com/go/bigquery.Dataset.Delete")
defer func() { trace.EndSpan(ctx, err) }()
call := d.c.bqs.Datasets.Delete(d.ProjectID, d.DatasetID).Context(ctx)
call := d.c.bqs.Datasets.Delete(d.ProjectID, d.DatasetID).Context(ctx).DeleteContents(deleteContents)
setClientHeader(call.Header())
return call.Do()
}
@ -336,6 +345,9 @@ func (it *TableIterator) fetch(pageSize int, pageToken string) (string, error) {
}
func bqToTable(tr *bq.TableReference, c *Client) *Table {
if tr == nil {
return nil
}
return &Table{
ProjectID: tr.ProjectId,
DatasetID: tr.DatasetId,

View File

@ -20,6 +20,9 @@ Note: This package is in beta. Some backwards-incompatible changes may occur.
The following assumes a basic familiarity with BigQuery concepts.
See https://cloud.google.com/bigquery/docs.
See https://godoc.org/cloud.google.com/go for authentication, timeouts,
connection pooling and similar aspects of this package.
Creating a Client
@ -294,10 +297,5 @@ Extractor, then optionally configure it, and lastly call its Run method.
extractor.DisableHeader = true
job, err = extractor.Run(ctx)
// Poll the job for completion if desired, as above.
Authentication
See examples of authorization and authentication at
https://godoc.org/cloud.google.com/go#pkg-examples.
*/
package bigquery // import "cloud.google.com/go/bigquery"

View File

@ -32,6 +32,7 @@ const (
DatastoreBackup DataFormat = "DATASTORE_BACKUP"
GoogleSheets DataFormat = "GOOGLE_SHEETS"
Bigtable DataFormat = "BIGTABLE"
Parquet DataFormat = "PARQUET"
)
// ExternalData is a table which is stored outside of BigQuery. It is implemented by

View File

@ -48,8 +48,8 @@ func (r *ReaderSource) populateLoadConfig(lc *bq.JobConfigurationLoad) io.Reader
// file may live in Google Cloud Storage (see GCSReference), or it may be
// loaded into a table via the Table.LoaderFromReader.
type FileConfig struct {
// SourceFormat is the format of the GCS data to be read.
// Allowed values are: CSV, Avro, JSON, DatastoreBackup. The default is CSV.
// SourceFormat is the format of the data to be read.
// Allowed values are: CSV, Avro, Parquet, JSON, DatastoreBackup. The default is CSV.
SourceFormat DataFormat
// Indicates if we should automatically infer the options and

View File

@ -34,6 +34,7 @@ import (
"cloud.google.com/go/internal"
"cloud.google.com/go/internal/pretty"
"cloud.google.com/go/internal/testutil"
"cloud.google.com/go/internal/uid"
"cloud.google.com/go/storage"
"golang.org/x/net/context"
"google.golang.org/api/googleapi"
@ -55,8 +56,8 @@ var (
testTableExpiration time.Time
// BigQuery does not accept hyphens in dataset or table IDs, so we create IDs
// with underscores.
datasetIDs = testutil.NewUIDSpaceSep("dataset", '_')
tableIDs = testutil.NewUIDSpaceSep("table", '_')
datasetIDs = uid.NewSpace("dataset", &uid.Options{Sep: '_'})
tableIDs = uid.NewSpace("table", &uid.Options{Sep: '_'})
)
// Note: integration tests cannot be run in parallel, because TestIntegration_Location
@ -105,28 +106,12 @@ func initIntegrationTest() func() {
}
testTableExpiration = time.Now().Add(10 * time.Minute).Round(time.Second)
return func() {
if err := deleteDataset(ctx, dataset); err != nil {
if err := dataset.DeleteWithContents(ctx); err != nil {
log.Printf("could not delete %s", dataset.DatasetID)
}
}
}
func deleteDataset(ctx context.Context, ds *Dataset) error {
it := ds.Tables(ctx)
for {
tbl, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return err
}
if err := tbl.Delete(ctx); err != nil {
return err
}
}
return ds.Delete(ctx)
}
func TestIntegration_TableCreate(t *testing.T) {
// Check that creating a record field with an empty schema is an error.
if client == nil {
@ -167,7 +152,9 @@ func TestIntegration_TableCreateView(t *testing.T) {
if err != nil {
t.Fatalf("table.create: Did not expect an error, got: %v", err)
}
view.Delete(ctx)
if err := view.Delete(ctx); err != nil {
t.Fatal(err)
}
}
func TestIntegration_TableMetadata(t *testing.T) {
@ -312,6 +299,28 @@ func TestIntegration_DatasetDelete(t *testing.T) {
}
}
func TestIntegration_DatasetDeleteWithContents(t *testing.T) {
if client == nil {
t.Skip("Integration tests skipped")
}
ctx := context.Background()
ds := client.Dataset(datasetIDs.New())
if err := ds.Create(ctx, nil); err != nil {
t.Fatalf("creating dataset %s: %v", ds.DatasetID, err)
}
table := ds.Table(tableIDs.New())
if err := table.Create(ctx, nil); err != nil {
t.Fatalf("creating table %s in dataset %s: %v", table.TableID, table.DatasetID, err)
}
// We expect failure here
if err := ds.Delete(ctx); err == nil {
t.Fatalf("non-recursive delete of dataset %s succeeded unexpectedly.", ds.DatasetID)
}
if err := ds.DeleteWithContents(ctx); err != nil {
t.Fatalf("deleting recursively dataset %s: %v", ds.DatasetID, err)
}
}
func TestIntegration_DatasetUpdateETags(t *testing.T) {
if client == nil {
t.Skip("Integration tests skipped")
@ -1570,7 +1579,7 @@ func TestIntegration_TableUseLegacySQL(t *testing.T) {
} else if !gotErr && test.err {
t.Errorf("%+v:\nsucceeded, but want error", test)
}
view.Delete(ctx)
_ = view.Delete(ctx)
}
}

View File

@ -404,6 +404,9 @@ type QueryStatistics struct {
// statements INSERT, UPDATE or DELETE.
NumDMLAffectedRows int64
// Describes a timeline of job execution.
Timeline []*QueryTimelineSample
// ReferencedTables: [Output-only, Experimental] Referenced tables for
// the job. Queries that reference more than 50 tables will not have a
// complete list.
@ -413,25 +416,59 @@ type QueryStatistics struct {
// non-legacy SQL queries.
Schema Schema
// Slot-milliseconds consumed by this query job.
SlotMillis int64
// Standard SQL: list of undeclared query parameter names detected during a
// dry run validation.
UndeclaredQueryParameterNames []string
// DDL target table.
DDLTargetTable *Table
// DDL Operation performed on the target table. Used to report how the
// query impacted the DDL target table.
DDLOperationPerformed string
}
// ExplainQueryStage describes one stage of a query.
type ExplainQueryStage struct {
// CompletedParallelInputs: Number of parallel input segments completed.
CompletedParallelInputs int64
// ComputeAvg: Duration the average shard spent on CPU-bound tasks.
ComputeAvg time.Duration
// ComputeMax: Duration the slowest shard spent on CPU-bound tasks.
ComputeMax time.Duration
// Relative amount of the total time the average shard spent on CPU-bound tasks.
ComputeRatioAvg float64
// Relative amount of the total time the slowest shard spent on CPU-bound tasks.
ComputeRatioMax float64
// EndTime: Stage end time.
EndTime time.Time
// Unique ID for stage within plan.
ID int64
// InputStages: IDs for stages that are inputs to this stage.
InputStages []int64
// Human-readable name for stage.
Name string
// ParallelInputs: Number of parallel input segments to be processed.
ParallelInputs int64
// ReadAvg: Duration the average shard spent reading input.
ReadAvg time.Duration
// ReadMax: Duration the slowest shard spent reading input.
ReadMax time.Duration
// Relative amount of the total time the average shard spent reading input.
ReadRatioAvg float64
@ -444,6 +481,16 @@ type ExplainQueryStage struct {
// Number of records written by the stage.
RecordsWritten int64
// ShuffleOutputBytes: Total number of bytes written to shuffle.
ShuffleOutputBytes int64
// ShuffleOutputBytesSpilled: Total number of bytes written to shuffle
// and spilled to disk.
ShuffleOutputBytesSpilled int64
// StartTime: Stage start time.
StartTime time.Time
// Current status for the stage.
Status string
@ -451,12 +498,24 @@ type ExplainQueryStage struct {
// chronological).
Steps []*ExplainQueryStep
// WaitAvg: Duration the average shard spent waiting to be scheduled.
WaitAvg time.Duration
// WaitMax: Duration the slowest shard spent waiting to be scheduled.
WaitMax time.Duration
// Relative amount of the total time the average shard spent waiting to be scheduled.
WaitRatioAvg float64
// Relative amount of the total time the slowest shard spent waiting to be scheduled.
WaitRatioMax float64
// WriteAvg: Duration the average shard spent on writing output.
WriteAvg time.Duration
// WriteMax: Duration the slowest shard spent on writing output.
WriteMax time.Duration
// Relative amount of the total time the average shard spent on writing output.
WriteRatioAvg float64
@ -473,6 +532,25 @@ type ExplainQueryStep struct {
Substeps []string
}
// QueryTimelineSample represents a sample of execution statistics at a point in time.
type QueryTimelineSample struct {
// Total number of units currently being processed by workers, represented as largest value since last sample.
ActiveUnits int64
// Total parallel units of work completed by this query.
CompletedUnits int64
// Time elapsed since start of query execution.
Elapsed time.Duration
// Total parallel units of work remaining for the active stages.
PendingUnits int64
// Cumulative slot-milliseconds consumed by the query.
SlotMillis int64
}
func (*ExtractStatistics) implementsStatistics() {}
func (*LoadStatistics) implementsStatistics() {}
func (*QueryStatistics) implementsStatistics() {}
@ -667,12 +745,16 @@ func (j *Job) setStatistics(s *bq.JobStatistics, c *Client) {
js.Details = &QueryStatistics{
BillingTier: s.Query.BillingTier,
CacheHit: s.Query.CacheHit,
DDLTargetTable: bqToTable(s.Query.DdlTargetTable, c),
DDLOperationPerformed: s.Query.DdlOperationPerformed,
StatementType: s.Query.StatementType,
TotalBytesBilled: s.Query.TotalBytesBilled,
TotalBytesProcessed: s.Query.TotalBytesProcessed,
NumDMLAffectedRows: s.Query.NumDmlAffectedRows,
QueryPlan: queryPlanFromProto(s.Query.QueryPlan),
Schema: bqToSchema(s.Query.Schema),
SlotMillis: s.Query.TotalSlotMs,
Timeline: timelineFromProto(s.Query.Timeline),
ReferencedTables: tables,
UndeclaredQueryParameterNames: names,
}
@ -691,20 +773,49 @@ func queryPlanFromProto(stages []*bq.ExplainQueryStage) []*ExplainQueryStage {
})
}
res = append(res, &ExplainQueryStage{
ComputeRatioAvg: s.ComputeRatioAvg,
ComputeRatioMax: s.ComputeRatioMax,
ID: s.Id,
Name: s.Name,
ReadRatioAvg: s.ReadRatioAvg,
ReadRatioMax: s.ReadRatioMax,
RecordsRead: s.RecordsRead,
RecordsWritten: s.RecordsWritten,
Status: s.Status,
Steps: steps,
WaitRatioAvg: s.WaitRatioAvg,
WaitRatioMax: s.WaitRatioMax,
WriteRatioAvg: s.WriteRatioAvg,
WriteRatioMax: s.WriteRatioMax,
CompletedParallelInputs: s.CompletedParallelInputs,
ComputeAvg: time.Duration(s.ComputeMsAvg) * time.Millisecond,
ComputeMax: time.Duration(s.ComputeMsMax) * time.Millisecond,
ComputeRatioAvg: s.ComputeRatioAvg,
ComputeRatioMax: s.ComputeRatioMax,
EndTime: time.Unix(0, s.EndMs*1e6),
ID: s.Id,
InputStages: s.InputStages,
Name: s.Name,
ParallelInputs: s.ParallelInputs,
ReadAvg: time.Duration(s.ReadMsAvg) * time.Millisecond,
ReadMax: time.Duration(s.ReadMsMax) * time.Millisecond,
ReadRatioAvg: s.ReadRatioAvg,
ReadRatioMax: s.ReadRatioMax,
RecordsRead: s.RecordsRead,
RecordsWritten: s.RecordsWritten,
ShuffleOutputBytes: s.ShuffleOutputBytes,
ShuffleOutputBytesSpilled: s.ShuffleOutputBytesSpilled,
StartTime: time.Unix(0, s.StartMs*1e6),
Status: s.Status,
Steps: steps,
WaitAvg: time.Duration(s.WaitMsAvg) * time.Millisecond,
WaitMax: time.Duration(s.WaitMsMax) * time.Millisecond,
WaitRatioAvg: s.WaitRatioAvg,
WaitRatioMax: s.WaitRatioMax,
WriteAvg: time.Duration(s.WriteMsAvg) * time.Millisecond,
WriteMax: time.Duration(s.WriteMsMax) * time.Millisecond,
WriteRatioAvg: s.WriteRatioAvg,
WriteRatioMax: s.WriteRatioMax,
})
}
return res
}
func timelineFromProto(timeline []*bq.QueryTimelineSample) []*QueryTimelineSample {
var res []*QueryTimelineSample
for _, s := range timeline {
res = append(res, &QueryTimelineSample{
ActiveUnits: s.ActiveUnits,
CompletedUnits: s.CompletedUnits,
Elapsed: time.Duration(s.ElapsedMs) * time.Millisecond,
PendingUnits: s.PendingUnits,
SlotMillis: s.TotalSlotMs,
})
}
return res

View File

@ -47,8 +47,8 @@ type LoadConfig struct {
// Custom encryption configuration (e.g., Cloud KMS keys).
DestinationEncryptionConfig *EncryptionConfig
// SchemaUpdateOptions allows the schema of the destination table to be
// updated as a side effect of the load job.
// Allows the schema of the destination table to be updated as a side effect of
// the load job.
SchemaUpdateOptions []string
}

View File

@ -119,6 +119,10 @@ type QueryConfig struct {
// Custom encryption configuration (e.g., Cloud KMS keys).
DestinationEncryptionConfig *EncryptionConfig
// Allows the schema of the destination table to be updated as a side effect of
// the query job.
SchemaUpdateOptions []string
}
func (qc *QueryConfig) toBQ() (*bq.JobConfiguration, error) {
@ -131,6 +135,7 @@ func (qc *QueryConfig) toBQ() (*bq.JobConfiguration, error) {
MaximumBytesBilled: qc.MaxBytesBilled,
TimePartitioning: qc.TimePartitioning.toBQ(),
DestinationEncryptionConfiguration: qc.DestinationEncryptionConfig.toBQ(),
SchemaUpdateOptions: qc.SchemaUpdateOptions,
}
if len(qc.TableDefinitions) > 0 {
qconf.TableDefinitions = make(map[string]bq.ExternalDataConfiguration)
@ -162,11 +167,12 @@ func (qc *QueryConfig) toBQ() (*bq.JobConfiguration, error) {
if len(qc.Parameters) > 0 && qc.UseLegacySQL {
return nil, errors.New("bigquery: cannot provide both Parameters (implying standard SQL) and UseLegacySQL")
}
ptrue := true
pfalse := false
if qc.UseLegacySQL {
qconf.UseLegacySql = true
qconf.UseLegacySql = &ptrue
} else {
qconf.UseLegacySql = false
qconf.ForceSendFields = append(qconf.ForceSendFields, "UseLegacySql")
qconf.UseLegacySql = &pfalse
}
if qc.Dst != nil && !qc.Dst.implicitTable() {
qconf.DestinationTable = qc.Dst.toBQ()
@ -188,18 +194,21 @@ func (qc *QueryConfig) toBQ() (*bq.JobConfiguration, error) {
func bqToQueryConfig(q *bq.JobConfiguration, c *Client) (*QueryConfig, error) {
qq := q.Query
qc := &QueryConfig{
Labels: q.Labels,
DryRun: q.DryRun,
Q: qq.Query,
CreateDisposition: TableCreateDisposition(qq.CreateDisposition),
WriteDisposition: TableWriteDisposition(qq.WriteDisposition),
AllowLargeResults: qq.AllowLargeResults,
Priority: QueryPriority(qq.Priority),
MaxBytesBilled: qq.MaximumBytesBilled,
UseLegacySQL: qq.UseLegacySql,
UseStandardSQL: !qq.UseLegacySql,
TimePartitioning: bqToTimePartitioning(qq.TimePartitioning),
Labels: q.Labels,
DryRun: q.DryRun,
Q: qq.Query,
CreateDisposition: TableCreateDisposition(qq.CreateDisposition),
WriteDisposition: TableWriteDisposition(qq.WriteDisposition),
AllowLargeResults: qq.AllowLargeResults,
Priority: QueryPriority(qq.Priority),
MaxBytesBilled: qq.MaximumBytesBilled,
UseLegacySQL: qq.UseLegacySql == nil || *qq.UseLegacySql,
TimePartitioning: bqToTimePartitioning(qq.TimePartitioning),
DestinationEncryptionConfig: bqToEncryptionConfig(qq.DestinationEncryptionConfiguration),
SchemaUpdateOptions: qq.SchemaUpdateOptions,
}
qc.UseStandardSQL = !qc.UseLegacySQL
if len(qq.TableDefinitions) > 0 {
qc.TableDefinitions = make(map[string]ExternalData)
}

View File

@ -26,6 +26,7 @@ import (
)
func defaultQueryJob() *bq.Job {
pfalse := false
return &bq.Job{
JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"},
Configuration: &bq.JobConfiguration{
@ -40,8 +41,7 @@ func defaultQueryJob() *bq.Job {
ProjectId: "def-project-id",
DatasetId: "def-dataset-id",
},
UseLegacySql: false,
ForceSendFields: []string{"UseLegacySql"},
UseLegacySql: &pfalse,
},
},
}
@ -271,7 +271,8 @@ func TestQuery(t *testing.T) {
},
want: func() *bq.Job {
j := defaultQueryJob()
j.Configuration.Query.UseLegacySql = true
ptrue := true
j.Configuration.Query.UseLegacySql = &ptrue
j.Configuration.Query.ForceSendFields = nil
return j
}(),
@ -351,9 +352,12 @@ func TestConfiguringQuery(t *testing.T) {
query.DefaultDatasetID = "def-dataset-id"
query.TimePartitioning = &TimePartitioning{Expiration: 1234 * time.Second, Field: "f"}
query.DestinationEncryptionConfig = &EncryptionConfig{KMSKeyName: "keyName"}
query.SchemaUpdateOptions = []string{"ALLOW_FIELD_ADDITION"}
// Note: Other configuration fields are tested in other tests above.
// A lot of that can be consolidated once Client.Copy is gone.
pfalse := false
want := &bq.Job{
Configuration: &bq.JobConfiguration{
Query: &bq.JobConfigurationQuery{
@ -362,10 +366,10 @@ func TestConfiguringQuery(t *testing.T) {
ProjectId: "def-project-id",
DatasetId: "def-dataset-id",
},
UseLegacySql: false,
UseLegacySql: &pfalse,
TimePartitioning: &bq.TimePartitioning{ExpirationMs: 1234000, Field: "f", Type: "DAY"},
DestinationEncryptionConfiguration: &bq.EncryptionConfiguration{KmsKeyName: "keyName"},
ForceSendFields: []string{"UseLegacySql"},
SchemaUpdateOptions: []string{"ALLOW_FIELD_ADDITION"},
},
},
JobReference: &bq.JobReference{

View File

@ -867,7 +867,7 @@ func (iac *InstanceAdminClient) Clusters(ctx context.Context, instanceId string)
// GetCluster fetches a cluster in an instance
func (iac *InstanceAdminClient) GetCluster(ctx context.Context, instanceID, clusterID string) (*ClusterInfo, error) {
ctx = mergeOutgoingMetadata(ctx, iac.md)
req := &btapb.GetClusterRequest{Name: "projects/" + iac.project + "/instances/" + instanceID + "/clusters" + clusterID}
req := &btapb.GetClusterRequest{Name: "projects/" + iac.project + "/instances/" + instanceID + "/clusters/" + clusterID}
c, err := iac.iClient.GetCluster(ctx, req)
if err != nil {
return nil, err

View File

@ -15,18 +15,17 @@
package bigtable
import (
"fmt"
"math"
"sort"
"strings"
"testing"
"time"
"cloud.google.com/go/internal/testutil"
"fmt"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2"
"strings"
)
func TestAdminIntegration(t *testing.T) {
@ -102,7 +101,7 @@ func TestAdminIntegration(t *testing.T) {
t.Errorf("adminClient.Tables returned %#v, want %#v", got, want)
}
adminClient.WaitForReplication(ctx, "mytable")
must(adminClient.WaitForReplication(ctx, "mytable"))
if err := adminClient.DeleteTable(ctx, "myothertable"); err != nil {
t.Fatalf("Deleting table: %v", err)
@ -172,13 +171,13 @@ func TestAdminIntegration(t *testing.T) {
}
var gotRowCount int
tbl.ReadRows(ctx, RowRange{}, func(row Row) bool {
must(tbl.ReadRows(ctx, RowRange{}, func(row Row) bool {
gotRowCount += 1
if !strings.HasPrefix(row.Key(), "b") {
t.Errorf("Invalid row after dropping range: %v", row)
}
return true
})
}))
if gotRowCount != 5 {
t.Errorf("Invalid row count after dropping range: got %v, want %v", gotRowCount, 5)
}

View File

@ -192,6 +192,9 @@ func (t *Table) ReadRows(ctx context.Context, arg RowSet, f func(Row) bool, opts
tracePrintf(ctx, attrMap, "Retry details in ReadRows")
return err
}
attrMap["time_secs"] = time.Since(startTime).Seconds()
attrMap["rowCount"] = len(res.Chunks)
tracePrintf(ctx, attrMap, "Details in ReadRows")
for _, cc := range res.Chunks {
row, err := cr.Process(cc)

View File

@ -317,7 +317,8 @@ func (s *server) ReadRows(req *btpb.ReadRowsRequest, stream btpb.Bigtable_ReadRo
return true
}
if req.Rows != nil {
if req.Rows != nil &&
len(req.Rows.RowKeys)+len(req.Rows.RowRanges) > 0 {
// Add the explicitly given keys
for _, key := range req.Rows.RowKeys {
k := string(key)
@ -698,8 +699,7 @@ func (s *server) MutateRows(req *btpb.MutateRowsRequest, stream btpb.Bigtable_Mu
}
r.mu.Unlock()
}
stream.Send(res)
return nil
return stream.Send(res)
}
func (s *server) CheckAndMutateRow(ctx context.Context, req *btpb.CheckAndMutateRowRequest) (*btpb.CheckAndMutateRowResponse, error) {
@ -861,12 +861,13 @@ func (s *server) ReadModifyWriteRow(ctx context.Context, req *btpb.ReadModifyWri
if !ok {
return nil, status.Errorf(codes.NotFound, "table %q not found", req.TableName)
}
updates := make(map[string]cell) // copy of updated cells; keyed by full column name
fs := tbl.columnFamilies()
rowKey := string(req.RowKey)
r := tbl.mutableRow(rowKey)
resultRow := newRow(rowKey) // copy of updated cells
// This must be done before the row lock, acquired below, is released.
r.mu.Lock()
defer r.mu.Unlock()
@ -914,35 +915,37 @@ func (s *server) ReadModifyWriteRow(ctx context.Context, req *btpb.ReadModifyWri
binary.BigEndian.PutUint64(val[:], uint64(v))
newCell = cell{ts: ts, value: val[:]}
}
key := strings.Join([]string{fam, col}, ":")
updates[key] = newCell
// Store the new cell
f.cells[col] = appendOrReplaceCell(f.cellsByColumn(col), newCell)
// Store a copy for the result row
resultFamily := resultRow.getOrCreateFamily(fam, fs[fam].order)
resultFamily.cellsByColumn(col) // create the column
resultFamily.cells[col] = []cell{newCell} // overwrite the cells
}
// Build the response using the result row
res := &btpb.Row{
Key: req.RowKey,
Key: req.RowKey,
Families: make([]*btpb.Family, len(resultRow.families)),
}
for col, cell := range updates {
i := strings.Index(col, ":")
fam, qual := col[:i], col[i+1:]
var f *btpb.Family
for _, ff := range res.Families {
if ff.Name == fam {
f = ff
break
for i, family := range resultRow.sortedFamilies() {
res.Families[i] = &btpb.Family{
Name: family.name,
Columns: make([]*btpb.Column, len(family.colNames)),
}
for j, colName := range family.colNames {
res.Families[i].Columns[j] = &btpb.Column{
Qualifier: []byte(colName),
Cells: []*btpb.Cell{{
TimestampMicros: family.cells[colName][0].ts,
Value: family.cells[colName][0].value,
}},
}
}
if f == nil {
f = &btpb.Family{Name: fam}
res.Families = append(res.Families, f)
}
f.Columns = append(f.Columns, &btpb.Column{
Qualifier: []byte(qual),
Cells: []*btpb.Cell{{
TimestampMicros: cell.ts,
Value: cell.value,
}},
})
}
return &btpb.ReadModifyWriteRowResponse{Row: res}, nil
}

View File

@ -23,6 +23,8 @@ import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"golang.org/x/net/context"
btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2"
btpb "google.golang.org/genproto/googleapis/bigtable/v2"
@ -99,7 +101,9 @@ func TestConcurrentMutationsReadModifyAndGC(t *testing.T) {
RowKey: []byte(fmt.Sprint(rand.Intn(100))),
Mutations: ms(),
}
s.MutateRow(ctx, req)
if _, err := s.MutateRow(ctx, req); err != nil {
panic(err) // can't use t.Fatal in goroutine
}
}
}()
wg.Add(1)
@ -548,7 +552,9 @@ func TestReadRowsOrder(t *testing.T) {
}
}
for i := count; i > 0; i-- {
s.ReadModifyWriteRow(ctx, rmw(i))
if _, err := s.ReadModifyWriteRow(ctx, rmw(i)); err != nil {
t.Fatal(err)
}
}
req = &btpb.ReadRowsRequest{
TableName: tblInfo.Name,
@ -621,6 +627,87 @@ func TestCheckAndMutateRowWithoutPredicate(t *testing.T) {
}
}
func TestServer_ReadModifyWriteRow(t *testing.T) {
s := &server{
tables: make(map[string]*table),
}
ctx := context.Background()
newTbl := btapb.Table{
ColumnFamilies: map[string]*btapb.ColumnFamily{
"cf": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}},
},
}
tbl, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl})
if err != nil {
t.Fatalf("Creating table: %v", err)
}
req := &btpb.ReadModifyWriteRowRequest{
TableName: tbl.Name,
RowKey: []byte("row-key"),
Rules: []*btpb.ReadModifyWriteRule{
{
FamilyName: "cf",
ColumnQualifier: []byte("q1"),
Rule: &btpb.ReadModifyWriteRule_AppendValue{
AppendValue: []byte("a"),
},
},
// multiple ops for same cell
{
FamilyName: "cf",
ColumnQualifier: []byte("q1"),
Rule: &btpb.ReadModifyWriteRule_AppendValue{
AppendValue: []byte("b"),
},
},
// different cell whose qualifier should sort before the prior rules
{
FamilyName: "cf",
ColumnQualifier: []byte("q0"),
Rule: &btpb.ReadModifyWriteRule_IncrementAmount{
IncrementAmount: 1,
},
},
},
}
got, err := s.ReadModifyWriteRow(ctx, req)
if err != nil {
t.Fatalf("ReadModifyWriteRow error: %v", err)
}
want := &btpb.ReadModifyWriteRowResponse{
Row: &btpb.Row{
Key: []byte("row-key"),
Families: []*btpb.Family{{
Name: "cf",
Columns: []*btpb.Column{
{
Qualifier: []byte("q0"),
Cells: []*btpb.Cell{{
Value: []byte{0, 0, 0, 0, 0, 0, 0, 1},
}},
},
{
Qualifier: []byte("q1"),
Cells: []*btpb.Cell{{
Value: []byte("ab"),
}},
},
},
}},
},
}
diff := cmp.Diff(got, want, cmpopts.IgnoreFields(btpb.Cell{}, "TimestampMicros"))
if diff != "" {
t.Errorf("unexpected response: %s", diff)
}
}
// helper function to populate table data
func populateTable(ctx context.Context, s *server) (*btapb.Table, error) {
newTbl := btapb.Table{

View File

@ -332,7 +332,8 @@ var commands = []struct {
Name: "lookup",
Desc: "Read from a single row",
do: doLookup,
Usage: "cbt lookup <table> <row> [app-profile=<app profile id>]\n" +
Usage: "cbt lookup <table> <row> [cells-per-column=<n>] [app-profile=<app profile id>]\n" +
" cells-per-column=<n> Read only this many cells per column\n" +
" app-profile=<app profile id> The app profile id to use for the request (replication alpha)\n",
Required: cbtconfig.ProjectAndInstanceRequired,
},
@ -356,12 +357,13 @@ var commands = []struct {
Desc: "Read rows",
do: doRead,
Usage: "cbt read <table> [start=<row>] [end=<row>] [prefix=<prefix>]" +
" [regex=<regex>] [count=<n>] [app-profile=<app profile id>]\n" +
" [regex=<regex>] [count=<n>] [cells-per-column=<n>] [app-profile=<app profile id>]\n" +
" start=<row> Start reading at this row\n" +
" end=<row> Stop reading before this row\n" +
" prefix=<prefix> Read rows with this prefix\n" +
" regex=<regex> Read rows with keys matching this regex\n" +
" count=<n> Read only this many rows\n" +
" cells-per-column=<n> Read only this many cells per column\n" +
" app-profile=<app profile id> The app profile id to use for the request (replication alpha)\n",
Required: cbtconfig.ProjectAndInstanceRequired,
},
@ -850,19 +852,34 @@ func doListClusters(ctx context.Context, args ...string) {
func doLookup(ctx context.Context, args ...string) {
if len(args) < 2 {
log.Fatalf("usage: cbt lookup <table> <row> [app-profile=<app profile id>]")
log.Fatalf("usage: cbt lookup <table> <row> [cells-per-column=<n>] [app-profile=<app profile id>]")
}
var appProfile string
if len(args) > 2 {
i := strings.Index(args[2], "=")
parsed := make(map[string]string)
for _, arg := range args[2:] {
i := strings.Index(arg, "=")
if i < 0 {
log.Fatalf("Bad arg %q", args[2])
log.Fatalf("Bad arg %q", arg)
}
appProfile = strings.Split(args[2], "=")[1]
key, val := arg[:i], arg[i+1:]
switch key {
default:
log.Fatalf("Unknown arg key %q", key)
case "cells-per-column", "app-profile":
parsed[key] = val
}
}
var opts []bigtable.ReadOption
if cellsPerColumn := parsed["cells-per-column"]; cellsPerColumn != "" {
n, err := strconv.Atoi(cellsPerColumn)
if err != nil {
log.Fatalf("Bad number of cells per column %q: %v", cellsPerColumn, err)
}
opts = append(opts, bigtable.RowFilter(bigtable.LatestNFilter(n)))
}
table, row := args[0], args[1]
tbl := getClient(bigtable.ClientConfig{AppProfile: appProfile}).Open(table)
r, err := tbl.ReadRow(ctx, row)
tbl := getClient(bigtable.ClientConfig{AppProfile: parsed["app-profile"]}).Open(table)
r, err := tbl.ReadRow(ctx, row, opts...)
if err != nil {
log.Fatalf("Reading row: %v", err)
}
@ -995,7 +1012,7 @@ func doRead(ctx context.Context, args ...string) {
case "limit":
// Be nicer; we used to support this, but renamed it to "end".
log.Fatalf("Unknown arg key %q; did you mean %q?", key, "end")
case "start", "end", "prefix", "count", "regex", "app-profile":
case "start", "end", "prefix", "count", "cells-per-column", "regex", "app-profile":
parsed[key] = val
}
}
@ -1021,8 +1038,22 @@ func doRead(ctx context.Context, args ...string) {
}
opts = append(opts, bigtable.LimitRows(n))
}
var filters []bigtable.Filter
if cellsPerColumn := parsed["cells-per-column"]; cellsPerColumn != "" {
n, err := strconv.Atoi(cellsPerColumn)
if err != nil {
log.Fatalf("Bad number of cells per column %q: %v", cellsPerColumn, err)
}
filters = append(filters, bigtable.LatestNFilter(n))
}
if regex := parsed["regex"]; regex != "" {
opts = append(opts, bigtable.RowFilter(bigtable.RowKeyFilter(regex)))
filters = append(filters, bigtable.RowKeyFilter(regex))
}
if len(filters) > 1 {
opts = append(opts, bigtable.RowFilter(bigtable.ChainFilters(filters...)))
} else if len(filters) == 1 {
opts = append(opts, bigtable.RowFilter(filters[0]))
}
// TODO(dsymonds): Support filters.

View File

@ -123,7 +123,7 @@ func main() {
go func() {
s := <-c
log.Printf("Caught %v, cleaning scratch table.", s)
adminClient.DeleteTable(context.Background(), *scratchTable)
_ = adminClient.DeleteTable(context.Background(), *scratchTable)
os.Exit(1)
}()

View File

@ -19,6 +19,10 @@ Package bigtable is an API to Google Cloud Bigtable.
See https://cloud.google.com/bigtable/docs/ for general product documentation.
See https://godoc.org/cloud.google.com/go for authentication, timeouts,
connection pooling and similar aspects of this package.
Setup and Credentials
Use NewClient or NewAdminClient to create a client that can be used to access
@ -92,12 +96,6 @@ If a read or write operation encounters a transient error it will be retried unt
response, an unretryable error or the context deadline is reached. Non-idempotent writes (where
the timestamp is set to ServerTime) will not be retried. In the case of ReadRows, retried calls
will not re-scan rows that have already been processed.
Authentication
See examples of authorization and authentication at
https://godoc.org/cloud.google.com/go#pkg-examples.
*/
package bigtable // import "cloud.google.com/go/bigtable"

View File

@ -34,7 +34,7 @@ func TestRandomizedDelays(t *testing.T) {
deadline := time.Now().Add(1 * time.Second)
ctx, _ := context.WithDeadline(context.Background(), deadline)
var invokeTime time.Time
Invoke(ctx, func(childCtx context.Context) error {
_ = Invoke(ctx, func(childCtx context.Context) error {
// Keep failing, make sure we never slept more than max (plus a fudge factor)
if !invokeTime.IsZero() {
if got, want := time.Since(invokeTime), max; got > (want + 20*time.Millisecond) {

View File

@ -123,10 +123,15 @@ func (agg *Aggregate) String() string {
// WriteCSV writes a csv file to the given Writer,
// with a header row and one row per aggregate.
func WriteCSV(aggs []*Aggregate, iow io.Writer) error {
func WriteCSV(aggs []*Aggregate, iow io.Writer) (err error) {
w := csv.NewWriter(iow)
defer w.Flush()
err := w.Write([]string{"name", "count", "errors", "min", "median", "max", "p75", "p90", "p95", "p99"})
defer func() {
w.Flush()
if err == nil {
err = w.Error()
}
}()
err = w.Write([]string{"name", "count", "errors", "min", "median", "max", "p75", "p90", "p95", "p99"})
if err != nil {
return err
}

View File

@ -60,10 +60,10 @@ func TestSingleCell(t *testing.T) {
func TestMultipleCells(t *testing.T) {
cr := newChunkReader()
cr.Process(cc("rs", "fm1", "col1", 0, "val1", 0, false))
cr.Process(cc("rs", "fm1", "col1", 1, "val2", 0, false))
cr.Process(cc("rs", "fm1", "col2", 0, "val3", 0, false))
cr.Process(cc("rs", "fm2", "col1", 0, "val4", 0, false))
mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false))
mustProcess(t, cr, cc("rs", "fm1", "col1", 1, "val2", 0, false))
mustProcess(t, cr, cc("rs", "fm1", "col2", 0, "val3", 0, false))
mustProcess(t, cr, cc("rs", "fm2", "col1", 0, "val4", 0, false))
row, err := cr.Process(cc("rs", "fm2", "col2", 1, "extralongval5", 0, true))
if err != nil {
t.Fatalf("Processing chunk: %v", err)
@ -95,8 +95,8 @@ func TestMultipleCells(t *testing.T) {
func TestSplitCells(t *testing.T) {
cr := newChunkReader()
cr.Process(cc("rs", "fm1", "col1", 0, "hello ", 11, false))
cr.Process(ccData("world", 0, false))
mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "hello ", 11, false))
mustProcess(t, cr, ccData("world", 0, false))
row, err := cr.Process(cc("rs", "fm1", "col2", 0, "val2", 0, true))
if err != nil {
t.Fatalf("Processing chunk: %v", err)
@ -171,12 +171,11 @@ func TestBlankQualifier(t *testing.T) {
func TestReset(t *testing.T) {
cr := newChunkReader()
cr.Process(cc("rs", "fm1", "col1", 0, "val1", 0, false))
cr.Process(cc("rs", "fm1", "col1", 1, "val2", 0, false))
cr.Process(cc("rs", "fm1", "col2", 0, "val3", 0, false))
cr.Process(ccReset())
row, _ := cr.Process(cc("rs1", "fm1", "col1", 1, "val1", 0, true))
mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false))
mustProcess(t, cr, cc("rs", "fm1", "col1", 1, "val2", 0, false))
mustProcess(t, cr, cc("rs", "fm1", "col2", 0, "val3", 0, false))
mustProcess(t, cr, ccReset())
row := mustProcess(t, cr, cc("rs1", "fm1", "col1", 1, "val1", 0, true))
want := []ReadItem{ri("rs1", "fm1", "col1", 1, "val1")}
if !testutil.Equal(row["fm1"], want) {
t.Fatalf("Reset: got: %v\nwant: %v\n", row["fm1"], want)
@ -189,13 +188,21 @@ func TestReset(t *testing.T) {
func TestNewFamEmptyQualifier(t *testing.T) {
cr := newChunkReader()
cr.Process(cc("rs", "fm1", "col1", 0, "val1", 0, false))
mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false))
_, err := cr.Process(cc(nilStr, "fm2", nilStr, 0, "val2", 0, true))
if err == nil {
t.Fatalf("Expected error on second chunk with no qualifier set")
}
}
func mustProcess(t *testing.T, cr *chunkReader, cc *btspb.ReadRowsResponse_CellChunk) Row {
row, err := cr.Process(cc)
if err != nil {
t.Fatal(err)
}
return row
}
// The read rows acceptance test reads a json file specifying a number of tests,
// each consisting of one or more cell chunk text protos and one or more resulting
// cells or errors.

View File

@ -179,28 +179,28 @@ func TestRetryApplyBulk(t *testing.T) {
f = func(ss grpc.ServerStream) error {
var err error
req := new(btpb.MutateRowsRequest)
ss.RecvMsg(req)
must(ss.RecvMsg(req))
switch errCount {
case 0:
// Retryable request failure
err = status.Errorf(codes.Unavailable, "")
case 1:
// Two mutations fail
writeMutateRowsResponse(ss, codes.Unavailable, codes.OK, codes.Aborted)
must(writeMutateRowsResponse(ss, codes.Unavailable, codes.OK, codes.Aborted))
err = nil
case 2:
// Two failures were retried. One will succeed.
if want, got := 2, len(req.Entries); want != got {
t.Errorf("2 bulk retries, got: %d, want %d", got, want)
}
writeMutateRowsResponse(ss, codes.OK, codes.Aborted)
must(writeMutateRowsResponse(ss, codes.OK, codes.Aborted))
err = nil
case 3:
// One failure was retried and will succeed.
if want, got := 1, len(req.Entries); want != got {
t.Errorf("1 bulk retry, got: %d, want %d", got, want)
}
writeMutateRowsResponse(ss, codes.OK)
must(writeMutateRowsResponse(ss, codes.OK))
err = nil
}
errCount++
@ -218,12 +218,12 @@ func TestRetryApplyBulk(t *testing.T) {
f = func(ss grpc.ServerStream) error {
var err error
req := new(btpb.MutateRowsRequest)
ss.RecvMsg(req)
must(ss.RecvMsg(req))
switch errCount {
case 0:
// Give non-idempotent mutation a retryable error code.
// Nothing should be retried.
writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.Aborted)
must(writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.Aborted))
err = nil
case 1:
t.Errorf("unretryable errors: got one retry, want no retries")
@ -245,8 +245,7 @@ func TestRetryApplyBulk(t *testing.T) {
// Test individual errors and a deadline exceeded
f = func(ss grpc.ServerStream) error {
writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.OK, codes.Aborted)
return nil
return writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.OK, codes.Aborted)
}
ctx, _ = context.WithTimeout(ctx, 100*time.Millisecond)
errors, err = tbl.ApplyBulk(ctx, []string{"row1", "row2", "row3"}, []*Mutation{m1, m2, m3})
@ -320,7 +319,7 @@ func TestRetryReadRows(t *testing.T) {
f = func(ss grpc.ServerStream) error {
var err error
req := new(btpb.ReadRowsRequest)
ss.RecvMsg(req)
must(ss.RecvMsg(req))
switch errCount {
case 0:
// Retryable request failure
@ -330,7 +329,7 @@ func TestRetryReadRows(t *testing.T) {
if want, got := "a", string(req.Rows.RowRanges[0].GetStartKeyClosed()); want != got {
t.Errorf("first retry, no data received yet: got %q, want %q", got, want)
}
writeReadRowsResponse(ss, "a", "b")
must(writeReadRowsResponse(ss, "a", "b"))
err = status.Errorf(codes.Unavailable, "")
case 2:
// Retryable request failure
@ -340,7 +339,7 @@ func TestRetryReadRows(t *testing.T) {
err = status.Errorf(codes.Unavailable, "")
case 3:
// Write two more rows
writeReadRowsResponse(ss, "c", "d")
must(writeReadRowsResponse(ss, "c", "d"))
err = nil
}
errCount++
@ -348,10 +347,10 @@ func TestRetryReadRows(t *testing.T) {
}
var got []string
tbl.ReadRows(ctx, NewRange("a", "z"), func(r Row) bool {
must(tbl.ReadRows(ctx, NewRange("a", "z"), func(r Row) bool {
got = append(got, r.Key())
return true
})
}))
want := []string{"a", "b", "c", "d"}
if !testutil.Equal(got, want) {
t.Errorf("retry range integration: got %v, want %v", got, want)
@ -370,3 +369,9 @@ func writeReadRowsResponse(ss grpc.ServerStream, rowKeys ...string) error {
}
return ss.SendMsg(&btpb.ReadRowsResponse{Chunks: chunks})
}
func must(err error) {
if err != nil {
panic(err)
}
}

35
vendor/cloud.google.com/go/cloud.go generated vendored
View File

@ -17,8 +17,26 @@ Package cloud is the root of the packages used to access Google Cloud
Services. See https://godoc.org/cloud.google.com/go for a full list
of sub-packages.
Examples in this package show ways to authorize and authenticate the
sub packages.
Authentication and Authorization
All the clients in sub-packages support authentication via Google Application Default
Credentials (see https://cloud.google.com/docs/authentication/production), or
by providing a JSON key file for a Service Account. See the authentication examples
in this package for details.
Timeouts and Cancellation
By default, all requests in sub-packages will run indefinitely, retrying on transient
errors when correctness allows. To set timeouts or arrange for cancellation, use
contexts. See the examples for details.
Do not attempt to control the initial connection (dialing) of a service by setting a
timeout on the context passed to NewClient. Dialing is non-blocking, so timeouts
would be ineffective and would only interfere with credential refreshing, which uses
the same context.
Connection Pooling
@ -36,5 +54,18 @@ of cloud client libraries may specify option.WithGRPCConnectionPool(n) as a clie
option to NewClient calls. This configures the underlying gRPC connections to be
pooled and addressed in a round robin fashion.
Using the Libraries with Docker
Minimal docker images like Alpine lack CA certificates. This causes RPCs to appear to
hang, because gRPC retries indefinitely. See https://github.com/GoogleCloudPlatform/google-cloud-go/issues/928
for more information.
Debugging
To see gRPC logs, set the environment variable GRPC_GO_LOG_SEVERITY_LEVEL. See
https://godoc.org/google.golang.org/grpc/grpclog for more information.
For HTTP logging, set the GODEBUG environment variable to "http2debug=1" or "http2debug=2".
*/
package cloud // import "cloud.google.com/go"

View File

@ -0,0 +1,763 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package cloudtasks
import (
"math"
"time"
"cloud.google.com/go/internal/version"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/api/transport"
taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2beta2"
iampb "google.golang.org/genproto/googleapis/iam/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
)
// CallOptions contains the retry settings for each method of Client.
type CallOptions struct {
ListQueues []gax.CallOption
GetQueue []gax.CallOption
CreateQueue []gax.CallOption
UpdateQueue []gax.CallOption
DeleteQueue []gax.CallOption
PurgeQueue []gax.CallOption
PauseQueue []gax.CallOption
ResumeQueue []gax.CallOption
GetIamPolicy []gax.CallOption
SetIamPolicy []gax.CallOption
TestIamPermissions []gax.CallOption
ListTasks []gax.CallOption
GetTask []gax.CallOption
CreateTask []gax.CallOption
DeleteTask []gax.CallOption
LeaseTasks []gax.CallOption
AcknowledgeTask []gax.CallOption
RenewLease []gax.CallOption
CancelLease []gax.CallOption
RunTask []gax.CallOption
}
func defaultClientOptions() []option.ClientOption {
return []option.ClientOption{
option.WithEndpoint("cloudtasks.googleapis.com:443"),
option.WithScopes(DefaultAuthScopes()...),
}
}
func defaultCallOptions() *CallOptions {
retry := map[[2]string][]gax.CallOption{
{"default", "idempotent"}: {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.DeadlineExceeded,
codes.Unavailable,
}, gax.Backoff{
Initial: 100 * time.Millisecond,
Max: 60000 * time.Millisecond,
Multiplier: 1.3,
})
}),
},
}
return &CallOptions{
ListQueues: retry[[2]string{"default", "idempotent"}],
GetQueue: retry[[2]string{"default", "idempotent"}],
CreateQueue: retry[[2]string{"default", "non_idempotent"}],
UpdateQueue: retry[[2]string{"default", "non_idempotent"}],
DeleteQueue: retry[[2]string{"default", "non_idempotent"}],
PurgeQueue: retry[[2]string{"default", "non_idempotent"}],
PauseQueue: retry[[2]string{"default", "non_idempotent"}],
ResumeQueue: retry[[2]string{"default", "non_idempotent"}],
GetIamPolicy: retry[[2]string{"default", "idempotent"}],
SetIamPolicy: retry[[2]string{"default", "non_idempotent"}],
TestIamPermissions: retry[[2]string{"default", "idempotent"}],
ListTasks: retry[[2]string{"default", "idempotent"}],
GetTask: retry[[2]string{"default", "idempotent"}],
CreateTask: retry[[2]string{"default", "non_idempotent"}],
DeleteTask: retry[[2]string{"default", "idempotent"}],
LeaseTasks: retry[[2]string{"default", "non_idempotent"}],
AcknowledgeTask: retry[[2]string{"default", "non_idempotent"}],
RenewLease: retry[[2]string{"default", "non_idempotent"}],
CancelLease: retry[[2]string{"default", "non_idempotent"}],
RunTask: retry[[2]string{"default", "non_idempotent"}],
}
}
// Client is a client for interacting with Cloud Tasks API.
type Client struct {
// The connection to the service.
conn *grpc.ClientConn
// The gRPC API client.
client taskspb.CloudTasksClient
// The call options for this service.
CallOptions *CallOptions
// The x-goog-* metadata to be sent with each request.
xGoogMetadata metadata.MD
}
// NewClient creates a new cloud tasks client.
//
// Cloud Tasks allows developers to manage the execution of background
// work in their applications.
func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...)
if err != nil {
return nil, err
}
c := &Client{
conn: conn,
CallOptions: defaultCallOptions(),
client: taskspb.NewCloudTasksClient(conn),
}
c.setGoogleClientInfo()
return c, nil
}
// Connection returns the client's connection to the API service.
func (c *Client) Connection() *grpc.ClientConn {
return c.conn
}
// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *Client) Close() error {
return c.conn.Close()
}
// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *Client) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}
// ListQueues lists queues.
//
// Queues are returned in lexicographical order.
func (c *Client) ListQueues(ctx context.Context, req *taskspb.ListQueuesRequest, opts ...gax.CallOption) *QueueIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListQueues[0:len(c.CallOptions.ListQueues):len(c.CallOptions.ListQueues)], opts...)
it := &QueueIterator{}
it.InternalFetch = func(pageSize int, pageToken string) ([]*taskspb.Queue, string, error) {
var resp *taskspb.ListQueuesResponse
req.PageToken = pageToken
if pageSize > math.MaxInt32 {
req.PageSize = math.MaxInt32
} else {
req.PageSize = int32(pageSize)
}
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.ListQueues(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, "", err
}
return resp.Queues, resp.NextPageToken, nil
}
fetch := func(pageSize int, pageToken string) (string, error) {
items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
if err != nil {
return "", err
}
it.items = append(it.items, items...)
return nextPageToken, nil
}
it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
return it
}
// GetQueue gets a queue.
func (c *Client) GetQueue(ctx context.Context, req *taskspb.GetQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetQueue[0:len(c.CallOptions.GetQueue):len(c.CallOptions.GetQueue)], opts...)
var resp *taskspb.Queue
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.GetQueue(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// CreateQueue creates a queue.
//
// Queues created with this method allow tasks to live for a maximum of 31
// days. After a task is 31 days old, the task will be deleted regardless of whether
// it was dispatched or not.
//
// WARNING: Using this method may have unintended side effects if you are
// using an App Engine queue.yaml or queue.xml file to manage your queues.
// Read
// Overview of Queue Management and queue.yaml (at /cloud-tasks/docs/queue-yaml)
// before using this method.
func (c *Client) CreateQueue(ctx context.Context, req *taskspb.CreateQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateQueue[0:len(c.CallOptions.CreateQueue):len(c.CallOptions.CreateQueue)], opts...)
var resp *taskspb.Queue
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.CreateQueue(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// UpdateQueue updates a queue.
//
// This method creates the queue if it does not exist and updates
// the queue if it does exist.
//
// Queues created with this method allow tasks to live for a maximum of 31
// days. After a task is 31 days old, the task will be deleted regardless of whether
// it was dispatched or not.
//
// WARNING: Using this method may have unintended side effects if you are
// using an App Engine queue.yaml or queue.xml file to manage your queues.
// Read
// Overview of Queue Management and queue.yaml (at /cloud-tasks/docs/queue-yaml)
// before using this method.
func (c *Client) UpdateQueue(ctx context.Context, req *taskspb.UpdateQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.UpdateQueue[0:len(c.CallOptions.UpdateQueue):len(c.CallOptions.UpdateQueue)], opts...)
var resp *taskspb.Queue
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.UpdateQueue(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeleteQueue deletes a queue.
//
// This command will delete the queue even if it has tasks in it.
//
// Note: If you delete a queue, a queue with the same name can't be created
// for 7 days.
//
// WARNING: Using this method may have unintended side effects if you are
// using an App Engine queue.yaml or queue.xml file to manage your queues.
// Read
// Overview of Queue Management and queue.yaml (at /cloud-tasks/docs/queue-yaml)
// before using this method.
func (c *Client) DeleteQueue(ctx context.Context, req *taskspb.DeleteQueueRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteQueue[0:len(c.CallOptions.DeleteQueue):len(c.CallOptions.DeleteQueue)], opts...)
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
_, err = c.client.DeleteQueue(ctx, req, settings.GRPC...)
return err
}, opts...)
return err
}
// PurgeQueue purges a queue by deleting all of its tasks.
//
// All tasks created before this method is called are permanently deleted.
//
// Purge operations can take up to one minute to take effect. Tasks
// might be dispatched before the purge takes effect. A purge is irreversible.
func (c *Client) PurgeQueue(ctx context.Context, req *taskspb.PurgeQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.PurgeQueue[0:len(c.CallOptions.PurgeQueue):len(c.CallOptions.PurgeQueue)], opts...)
var resp *taskspb.Queue
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.PurgeQueue(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// PauseQueue pauses the queue.
//
// If a queue is paused then the system will stop dispatching tasks
// until the queue is resumed via
// [ResumeQueue][google.cloud.tasks.v2beta2.CloudTasks.ResumeQueue]. Tasks can still be added
// when the queue is paused. A queue is paused if its
// [state][google.cloud.tasks.v2beta2.Queue.state] is [PAUSED][google.cloud.tasks.v2beta2.Queue.State.PAUSED].
func (c *Client) PauseQueue(ctx context.Context, req *taskspb.PauseQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.PauseQueue[0:len(c.CallOptions.PauseQueue):len(c.CallOptions.PauseQueue)], opts...)
var resp *taskspb.Queue
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.PauseQueue(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// ResumeQueue resume a queue.
//
// This method resumes a queue after it has been
// [PAUSED][google.cloud.tasks.v2beta2.Queue.State.PAUSED] or
// [DISABLED][google.cloud.tasks.v2beta2.Queue.State.DISABLED]. The state of a queue is stored
// in the queue's [state][google.cloud.tasks.v2beta2.Queue.state]; after calling this method it
// will be set to [RUNNING][google.cloud.tasks.v2beta2.Queue.State.RUNNING].
//
// WARNING: Resuming many high-QPS queues at the same time can
// lead to target overloading. If you are resuming high-QPS
// queues, follow the 500/50/5 pattern described in
// Managing Cloud Tasks Scaling Risks (at /cloud-tasks/pdfs/managing-cloud-tasks-scaling-risks-2017-06-05.pdf).
func (c *Client) ResumeQueue(ctx context.Context, req *taskspb.ResumeQueueRequest, opts ...gax.CallOption) (*taskspb.Queue, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ResumeQueue[0:len(c.CallOptions.ResumeQueue):len(c.CallOptions.ResumeQueue)], opts...)
var resp *taskspb.Queue
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.ResumeQueue(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// GetIamPolicy gets the access control policy for a [Queue][google.cloud.tasks.v2beta2.Queue].
// Returns an empty policy if the resource exists and does not have a policy
// set.
//
// Authorization requires the following Google IAM (at /iam) permission on the
// specified resource parent:
//
// cloudtasks.queues.getIamPolicy
func (c *Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...)
var resp *iampb.Policy
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.GetIamPolicy(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// SetIamPolicy sets the access control policy for a [Queue][google.cloud.tasks.v2beta2.Queue]. Replaces any existing
// policy.
//
// Note: The Cloud Console does not check queue-level IAM permissions yet.
// Project-level permissions are required to use the Cloud Console.
//
// Authorization requires the following Google IAM (at /iam) permission on the
// specified resource parent:
//
// cloudtasks.queues.setIamPolicy
func (c *Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...)
var resp *iampb.Policy
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.SetIamPolicy(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// TestIamPermissions returns permissions that a caller has on a [Queue][google.cloud.tasks.v2beta2.Queue].
// If the resource does not exist, this will return an empty set of
// permissions, not a [NOT_FOUND][google.rpc.Code.NOT_FOUND] error.
//
// Note: This operation is designed to be used for building permission-aware
// UIs and command-line tools, not for authorization checking. This operation
// may "fail open" without warning.
func (c *Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...)
var resp *iampb.TestIamPermissionsResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.TestIamPermissions(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// ListTasks lists the tasks in a queue.
//
// By default, only the [BASIC][google.cloud.tasks.v2beta2.Task.View.BASIC] view is retrieved
// due to performance considerations;
// [response_view][google.cloud.tasks.v2beta2.ListTasksRequest.response_view] controls the
// subset of information which is returned.
func (c *Client) ListTasks(ctx context.Context, req *taskspb.ListTasksRequest, opts ...gax.CallOption) *TaskIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListTasks[0:len(c.CallOptions.ListTasks):len(c.CallOptions.ListTasks)], opts...)
it := &TaskIterator{}
it.InternalFetch = func(pageSize int, pageToken string) ([]*taskspb.Task, string, error) {
var resp *taskspb.ListTasksResponse
req.PageToken = pageToken
if pageSize > math.MaxInt32 {
req.PageSize = math.MaxInt32
} else {
req.PageSize = int32(pageSize)
}
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.ListTasks(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, "", err
}
return resp.Tasks, resp.NextPageToken, nil
}
fetch := func(pageSize int, pageToken string) (string, error) {
items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
if err != nil {
return "", err
}
it.items = append(it.items, items...)
return nextPageToken, nil
}
it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
return it
}
// GetTask gets a task.
func (c *Client) GetTask(ctx context.Context, req *taskspb.GetTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetTask[0:len(c.CallOptions.GetTask):len(c.CallOptions.GetTask)], opts...)
var resp *taskspb.Task
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.GetTask(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// CreateTask creates a task and adds it to a queue.
//
// To add multiple tasks at the same time, use
// HTTP batching (at /storage/docs/json_api/v1/how-tos/batch)
// or the batching documentation for your client library, for example
// https://developers.google.com/api-client-library/python/guide/batch.
//
// Tasks cannot be updated after creation; there is no UpdateTask command.
//
// For App Engine queues (at google.cloud.tasks.v2beta2.AppEngineHttpTarget),
// the maximum task size is 100KB.
//
// For pull queues (at google.cloud.tasks.v2beta2.PullTarget), this
// the maximum task size is 1MB.
func (c *Client) CreateTask(ctx context.Context, req *taskspb.CreateTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateTask[0:len(c.CallOptions.CreateTask):len(c.CallOptions.CreateTask)], opts...)
var resp *taskspb.Task
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.CreateTask(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeleteTask deletes a task.
//
// A task can be deleted if it is scheduled or dispatched. A task
// cannot be deleted if it has completed successfully or permanently
// failed.
func (c *Client) DeleteTask(ctx context.Context, req *taskspb.DeleteTaskRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteTask[0:len(c.CallOptions.DeleteTask):len(c.CallOptions.DeleteTask)], opts...)
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
_, err = c.client.DeleteTask(ctx, req, settings.GRPC...)
return err
}, opts...)
return err
}
// LeaseTasks leases tasks from a pull queue for
// [lease_duration][google.cloud.tasks.v2beta2.LeaseTasksRequest.lease_duration].
//
// This method is invoked by the worker to obtain a lease. The
// worker must acknowledge the task via
// [AcknowledgeTask][google.cloud.tasks.v2beta2.CloudTasks.AcknowledgeTask] after they have
// performed the work associated with the task.
//
// The [payload][google.cloud.tasks.v2beta2.PullMessage.payload] is intended to store data that
// the worker needs to perform the work associated with the task. To
// return the payloads in the [response][google.cloud.tasks.v2beta2.LeaseTasksResponse], set
// [response_view][google.cloud.tasks.v2beta2.LeaseTasksRequest.response_view] to
// [FULL][google.cloud.tasks.v2beta2.Task.View.FULL].
//
// A maximum of 10 qps of [LeaseTasks][google.cloud.tasks.v2beta2.CloudTasks.LeaseTasks]
// requests are allowed per
// queue. [RESOURCE_EXHAUSTED][google.rpc.Code.RESOURCE_EXHAUSTED]
// is returned when this limit is
// exceeded. [RESOURCE_EXHAUSTED][google.rpc.Code.RESOURCE_EXHAUSTED]
// is also returned when
// [max_tasks_dispatched_per_second][google.cloud.tasks.v2beta2.RateLimits.max_tasks_dispatched_per_second]
// is exceeded.
func (c *Client) LeaseTasks(ctx context.Context, req *taskspb.LeaseTasksRequest, opts ...gax.CallOption) (*taskspb.LeaseTasksResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.LeaseTasks[0:len(c.CallOptions.LeaseTasks):len(c.CallOptions.LeaseTasks)], opts...)
var resp *taskspb.LeaseTasksResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.LeaseTasks(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// AcknowledgeTask acknowledges a pull task.
//
// The worker, that is, the entity that
// [leased][google.cloud.tasks.v2beta2.CloudTasks.LeaseTasks] this task must call this method
// to indicate that the work associated with the task has finished.
//
// The worker must acknowledge a task within the
// [lease_duration][google.cloud.tasks.v2beta2.LeaseTasksRequest.lease_duration] or the lease
// will expire and the task will become available to be leased
// again. After the task is acknowledged, it will not be returned
// by a later [LeaseTasks][google.cloud.tasks.v2beta2.CloudTasks.LeaseTasks],
// [GetTask][google.cloud.tasks.v2beta2.CloudTasks.GetTask], or
// [ListTasks][google.cloud.tasks.v2beta2.CloudTasks.ListTasks].
//
// To acknowledge multiple tasks at the same time, use
// HTTP batching (at /storage/docs/json_api/v1/how-tos/batch)
// or the batching documentation for your client library, for example
// https://developers.google.com/api-client-library/python/guide/batch.
func (c *Client) AcknowledgeTask(ctx context.Context, req *taskspb.AcknowledgeTaskRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.AcknowledgeTask[0:len(c.CallOptions.AcknowledgeTask):len(c.CallOptions.AcknowledgeTask)], opts...)
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
_, err = c.client.AcknowledgeTask(ctx, req, settings.GRPC...)
return err
}, opts...)
return err
}
// RenewLease renew the current lease of a pull task.
//
// The worker can use this method to extend the lease by a new
// duration, starting from now. The new task lease will be
// returned in the task's [schedule_time][google.cloud.tasks.v2beta2.Task.schedule_time].
func (c *Client) RenewLease(ctx context.Context, req *taskspb.RenewLeaseRequest, opts ...gax.CallOption) (*taskspb.Task, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.RenewLease[0:len(c.CallOptions.RenewLease):len(c.CallOptions.RenewLease)], opts...)
var resp *taskspb.Task
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.RenewLease(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// CancelLease cancel a pull task's lease.
//
// The worker can use this method to cancel a task's lease by
// setting its [schedule_time][google.cloud.tasks.v2beta2.Task.schedule_time] to now. This will
// make the task available to be leased to the next caller of
// [LeaseTasks][google.cloud.tasks.v2beta2.CloudTasks.LeaseTasks].
func (c *Client) CancelLease(ctx context.Context, req *taskspb.CancelLeaseRequest, opts ...gax.CallOption) (*taskspb.Task, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CancelLease[0:len(c.CallOptions.CancelLease):len(c.CallOptions.CancelLease)], opts...)
var resp *taskspb.Task
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.CancelLease(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// RunTask forces a task to run now.
//
// When this method is called, Cloud Tasks will dispatch the task, even if
// the task is already running, the queue has reached its [RateLimits][google.cloud.tasks.v2beta2.RateLimits] or
// is [PAUSED][google.cloud.tasks.v2beta2.Queue.State.PAUSED].
//
// This command is meant to be used for manual debugging. For
// example, [RunTask][google.cloud.tasks.v2beta2.CloudTasks.RunTask] can be used to retry a failed
// task after a fix has been made or to manually force a task to be
// dispatched now.
//
// The dispatched task is returned. That is, the task that is returned
// contains the [status][google.cloud.tasks.v2beta2.Task.status] after the task is dispatched but
// before the task is received by its target.
//
// If Cloud Tasks receives a successful response from the task's
// target, then the task will be deleted; otherwise the task's
// [schedule_time][google.cloud.tasks.v2beta2.Task.schedule_time] will be reset to the time that
// [RunTask][google.cloud.tasks.v2beta2.CloudTasks.RunTask] was called plus the retry delay specified
// in the queue's [RetryConfig][google.cloud.tasks.v2beta2.RetryConfig].
//
// [RunTask][google.cloud.tasks.v2beta2.CloudTasks.RunTask] returns
// [NOT_FOUND][google.rpc.Code.NOT_FOUND] when it is called on a
// task that has already succeeded or permanently failed.
//
// [RunTask][google.cloud.tasks.v2beta2.CloudTasks.RunTask] cannot be called on a
// [pull task][google.cloud.tasks.v2beta2.PullMessage].
func (c *Client) RunTask(ctx context.Context, req *taskspb.RunTaskRequest, opts ...gax.CallOption) (*taskspb.Task, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.RunTask[0:len(c.CallOptions.RunTask):len(c.CallOptions.RunTask)], opts...)
var resp *taskspb.Task
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.RunTask(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// QueueIterator manages a stream of *taskspb.Queue.
type QueueIterator struct {
items []*taskspb.Queue
pageInfo *iterator.PageInfo
nextFunc func() error
// InternalFetch is for use by the Google Cloud Libraries only.
// It is not part of the stable interface of this package.
//
// InternalFetch returns results from a single call to the underlying RPC.
// The number of results is no greater than pageSize.
// If there are no more results, nextPageToken is empty and err is nil.
InternalFetch func(pageSize int, pageToken string) (results []*taskspb.Queue, nextPageToken string, err error)
}
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *QueueIterator) PageInfo() *iterator.PageInfo {
return it.pageInfo
}
// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *QueueIterator) Next() (*taskspb.Queue, error) {
var item *taskspb.Queue
if err := it.nextFunc(); err != nil {
return item, err
}
item = it.items[0]
it.items = it.items[1:]
return item, nil
}
func (it *QueueIterator) bufLen() int {
return len(it.items)
}
func (it *QueueIterator) takeBuf() interface{} {
b := it.items
it.items = nil
return b
}
// TaskIterator manages a stream of *taskspb.Task.
type TaskIterator struct {
items []*taskspb.Task
pageInfo *iterator.PageInfo
nextFunc func() error
// InternalFetch is for use by the Google Cloud Libraries only.
// It is not part of the stable interface of this package.
//
// InternalFetch returns results from a single call to the underlying RPC.
// The number of results is no greater than pageSize.
// If there are no more results, nextPageToken is empty and err is nil.
InternalFetch func(pageSize int, pageToken string) (results []*taskspb.Task, nextPageToken string, err error)
}
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *TaskIterator) PageInfo() *iterator.PageInfo {
return it.pageInfo
}
// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *TaskIterator) Next() (*taskspb.Task, error) {
var item *taskspb.Task
if err := it.nextFunc(); err != nil {
return item, err
}
item = it.items[0]
it.items = it.items[1:]
return item, nil
}
func (it *TaskIterator) bufLen() int {
return len(it.items)
}
func (it *TaskIterator) takeBuf() interface{} {
b := it.items
it.items = nil
return b
}

View File

@ -14,18 +14,19 @@
// AUTO-GENERATED CODE. DO NOT EDIT.
package dlp_test
package cloudtasks_test
import (
"cloud.google.com/go/privacy/dlp/apiv2beta2"
"cloud.google.com/go/cloudtasks/apiv2beta2"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2beta2"
taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2beta2"
iampb "google.golang.org/genproto/googleapis/iam/v1"
)
func ExampleNewClient() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
@ -33,197 +34,17 @@ func ExampleNewClient() {
_ = c
}
func ExampleClient_InspectContent() {
func ExampleClient_ListQueues() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.InspectContentRequest{
req := &taskspb.ListQueuesRequest{
// TODO: Fill request struct fields.
}
resp, err := c.InspectContent(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_RedactImage() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.RedactImageRequest{
// TODO: Fill request struct fields.
}
resp, err := c.RedactImage(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_DeidentifyContent() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.DeidentifyContentRequest{
// TODO: Fill request struct fields.
}
resp, err := c.DeidentifyContent(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_ReidentifyContent() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.ReidentifyContentRequest{
// TODO: Fill request struct fields.
}
resp, err := c.ReidentifyContent(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_InspectDataSource() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.InspectDataSourceRequest{
// TODO: Fill request struct fields.
}
resp, err := c.InspectDataSource(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_AnalyzeDataSourceRisk() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.AnalyzeDataSourceRiskRequest{
// TODO: Fill request struct fields.
}
resp, err := c.AnalyzeDataSourceRisk(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_ListInfoTypes() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.ListInfoTypesRequest{
// TODO: Fill request struct fields.
}
resp, err := c.ListInfoTypes(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_CreateInspectTemplate() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.CreateInspectTemplateRequest{
// TODO: Fill request struct fields.
}
resp, err := c.CreateInspectTemplate(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_UpdateInspectTemplate() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.UpdateInspectTemplateRequest{
// TODO: Fill request struct fields.
}
resp, err := c.UpdateInspectTemplate(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_GetInspectTemplate() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.GetInspectTemplateRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetInspectTemplate(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_ListInspectTemplates() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.ListInspectTemplatesRequest{
// TODO: Fill request struct fields.
}
it := c.ListInspectTemplates(ctx, req)
it := c.ListQueues(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
@ -237,33 +58,17 @@ func ExampleClient_ListInspectTemplates() {
}
}
func ExampleClient_DeleteInspectTemplate() {
func ExampleClient_GetQueue() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.DeleteInspectTemplateRequest{
req := &taskspb.GetQueueRequest{
// TODO: Fill request struct fields.
}
err = c.DeleteInspectTemplate(ctx, req)
if err != nil {
// TODO: Handle error.
}
}
func ExampleClient_CreateDeidentifyTemplate() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.CreateDeidentifyTemplateRequest{
// TODO: Fill request struct fields.
}
resp, err := c.CreateDeidentifyTemplate(ctx, req)
resp, err := c.GetQueue(ctx, req)
if err != nil {
// TODO: Handle error.
}
@ -271,17 +76,17 @@ func ExampleClient_CreateDeidentifyTemplate() {
_ = resp
}
func ExampleClient_UpdateDeidentifyTemplate() {
func ExampleClient_CreateQueue() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.UpdateDeidentifyTemplateRequest{
req := &taskspb.CreateQueueRequest{
// TODO: Fill request struct fields.
}
resp, err := c.UpdateDeidentifyTemplate(ctx, req)
resp, err := c.CreateQueue(ctx, req)
if err != nil {
// TODO: Handle error.
}
@ -289,17 +94,17 @@ func ExampleClient_UpdateDeidentifyTemplate() {
_ = resp
}
func ExampleClient_GetDeidentifyTemplate() {
func ExampleClient_UpdateQueue() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.GetDeidentifyTemplateRequest{
req := &taskspb.UpdateQueueRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetDeidentifyTemplate(ctx, req)
resp, err := c.UpdateQueue(ctx, req)
if err != nil {
// TODO: Handle error.
}
@ -307,17 +112,141 @@ func ExampleClient_GetDeidentifyTemplate() {
_ = resp
}
func ExampleClient_ListDeidentifyTemplates() {
func ExampleClient_DeleteQueue() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.ListDeidentifyTemplatesRequest{
req := &taskspb.DeleteQueueRequest{
// TODO: Fill request struct fields.
}
it := c.ListDeidentifyTemplates(ctx, req)
err = c.DeleteQueue(ctx, req)
if err != nil {
// TODO: Handle error.
}
}
func ExampleClient_PurgeQueue() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.PurgeQueueRequest{
// TODO: Fill request struct fields.
}
resp, err := c.PurgeQueue(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_PauseQueue() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.PauseQueueRequest{
// TODO: Fill request struct fields.
}
resp, err := c.PauseQueue(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_ResumeQueue() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.ResumeQueueRequest{
// TODO: Fill request struct fields.
}
resp, err := c.ResumeQueue(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_GetIamPolicy() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &iampb.GetIamPolicyRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetIamPolicy(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_SetIamPolicy() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &iampb.SetIamPolicyRequest{
// TODO: Fill request struct fields.
}
resp, err := c.SetIamPolicy(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_TestIamPermissions() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &iampb.TestIamPermissionsRequest{
// TODO: Fill request struct fields.
}
resp, err := c.TestIamPermissions(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_ListTasks() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.ListTasksRequest{
// TODO: Fill request struct fields.
}
it := c.ListTasks(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
@ -331,57 +260,17 @@ func ExampleClient_ListDeidentifyTemplates() {
}
}
func ExampleClient_DeleteDeidentifyTemplate() {
func ExampleClient_GetTask() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.DeleteDeidentifyTemplateRequest{
req := &taskspb.GetTaskRequest{
// TODO: Fill request struct fields.
}
err = c.DeleteDeidentifyTemplate(ctx, req)
if err != nil {
// TODO: Handle error.
}
}
func ExampleClient_ListDlpJobs() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.ListDlpJobsRequest{
// TODO: Fill request struct fields.
}
it := c.ListDlpJobs(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
}
func ExampleClient_GetDlpJob() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.GetDlpJobRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetDlpJob(ctx, req)
resp, err := c.GetTask(ctx, req)
if err != nil {
// TODO: Handle error.
}
@ -389,34 +278,124 @@ func ExampleClient_GetDlpJob() {
_ = resp
}
func ExampleClient_DeleteDlpJob() {
func ExampleClient_CreateTask() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.DeleteDlpJobRequest{
req := &taskspb.CreateTaskRequest{
// TODO: Fill request struct fields.
}
err = c.DeleteDlpJob(ctx, req)
resp, err := c.CreateTask(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_DeleteTask() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.DeleteTaskRequest{
// TODO: Fill request struct fields.
}
err = c.DeleteTask(ctx, req)
if err != nil {
// TODO: Handle error.
}
}
func ExampleClient_CancelDlpJob() {
func ExampleClient_LeaseTasks() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.CancelDlpJobRequest{
req := &taskspb.LeaseTasksRequest{
// TODO: Fill request struct fields.
}
err = c.CancelDlpJob(ctx, req)
resp, err := c.LeaseTasks(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_AcknowledgeTask() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.AcknowledgeTaskRequest{
// TODO: Fill request struct fields.
}
err = c.AcknowledgeTask(ctx, req)
if err != nil {
// TODO: Handle error.
}
}
func ExampleClient_RenewLease() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.RenewLeaseRequest{
// TODO: Fill request struct fields.
}
resp, err := c.RenewLease(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_CancelLease() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.CancelLeaseRequest{
// TODO: Fill request struct fields.
}
resp, err := c.CancelLease(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_RunTask() {
ctx := context.Background()
c, err := cloudtasks.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &taskspb.RunTaskRequest{
// TODO: Fill request struct fields.
}
resp, err := c.RunTask(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}

View File

@ -14,15 +14,15 @@
// AUTO-GENERATED CODE. DO NOT EDIT.
// Package dlp is an auto-generated package for the
// DLP API.
// Package cloudtasks is an auto-generated package for the
// Cloud Tasks API.
//
// NOTE: This package is in alpha. It is not stable, and is likely to change.
//
// The Google Data Loss Prevention API provides methods for detection of
// privacy-sensitive fragments in text, images, and Google Cloud Platform
// storage repositories.
package dlp // import "cloud.google.com/go/dlp/apiv2beta1"
// Manages the execution of large numbers of distributed requests. Cloud
// Tasks
// is in Alpha.
package cloudtasks // import "cloud.google.com/go/cloudtasks/apiv2beta2"
import (
"golang.org/x/net/context"

File diff suppressed because it is too large Load Diff

View File

@ -152,17 +152,19 @@ type NoOmit struct {
}
type OmitAll struct {
A string `datastore:",omitempty"`
B int `datastore:"Bb,omitempty"`
C bool `datastore:",omitempty,noindex"`
F []int `datastore:",omitempty"`
A string `datastore:",omitempty"`
B int `datastore:"Bb,omitempty"`
C bool `datastore:",omitempty,noindex"`
D time.Time `datastore:",omitempty"`
F []int `datastore:",omitempty"`
}
type Omit struct {
A string `datastore:",omitempty"`
B int `datastore:"Bb,omitempty"`
C bool `datastore:",omitempty,noindex"`
F []int `datastore:",omitempty"`
A string `datastore:",omitempty"`
B int `datastore:"Bb,omitempty"`
C bool `datastore:",omitempty,noindex"`
D time.Time `datastore:",omitempty"`
F []int `datastore:",omitempty"`
S `datastore:",omitempty"`
}

View File

@ -15,6 +15,9 @@
/*
Package datastore provides a client for Google Cloud Datastore.
See https://godoc.org/cloud.google.com/go for authentication, timeouts,
connection pooling and similar aspects of this package.
Basic Operations
@ -481,11 +484,5 @@ directed to the emulator instead of the production Datastore service.
To install and set up the emulator and its environment variables, see the documentation
at https://cloud.google.com/datastore/docs/tools/datastore-emulator.
Authentication
See examples of authorization and authentication at
https://godoc.org/cloud.google.com/go#pkg-examples.
*/
package datastore // import "cloud.google.com/go/datastore"

View File

@ -475,6 +475,7 @@ func TestNamespaceQuery(t *testing.T) {
var gs []Gopher
// Ignore errors for the rest of this test.
client.GetAll(ctx, NewQuery("gopher"), &gs)
if got, want := <-gotNamespace, ""; got != want {
t.Errorf("GetAll: got namespace %q, want %q", got, want)

View File

@ -438,6 +438,10 @@ func isEmptyValue(v reflect.Value) bool {
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
case reflect.Struct:
if t, ok := v.Interface().(time.Time); ok {
return t.IsZero()
}
}
return false
}

View File

@ -167,7 +167,7 @@ func (c *Client) RunInTransaction(ctx context.Context, f func(tx *Transaction) e
return nil, err
}
if err := f(tx); err != nil {
tx.Rollback()
_ = tx.Rollback()
return nil, err
}
if cmt, err := tx.Commit(); err != ErrConcurrentTransaction {

View File

@ -0,0 +1,599 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow
import (
"math"
"time"
"cloud.google.com/go/internal/version"
"cloud.google.com/go/longrunning"
lroauto "cloud.google.com/go/longrunning/autogen"
structpbpb "github.com/golang/protobuf/ptypes/struct"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/api/transport"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
longrunningpb "google.golang.org/genproto/googleapis/longrunning"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
)
// AgentsCallOptions contains the retry settings for each method of AgentsClient.
type AgentsCallOptions struct {
GetAgent []gax.CallOption
SearchAgents []gax.CallOption
TrainAgent []gax.CallOption
ExportAgent []gax.CallOption
ImportAgent []gax.CallOption
RestoreAgent []gax.CallOption
}
func defaultAgentsClientOptions() []option.ClientOption {
return []option.ClientOption{
option.WithEndpoint("dialogflow.googleapis.com:443"),
option.WithScopes(DefaultAuthScopes()...),
}
}
func defaultAgentsCallOptions() *AgentsCallOptions {
retry := map[[2]string][]gax.CallOption{
{"default", "idempotent"}: {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.DeadlineExceeded,
codes.Unavailable,
}, gax.Backoff{
Initial: 100 * time.Millisecond,
Max: 60000 * time.Millisecond,
Multiplier: 1.3,
})
}),
},
}
return &AgentsCallOptions{
GetAgent: retry[[2]string{"default", "idempotent"}],
SearchAgents: retry[[2]string{"default", "idempotent"}],
TrainAgent: retry[[2]string{"default", "idempotent"}],
ExportAgent: retry[[2]string{"default", "idempotent"}],
ImportAgent: retry[[2]string{"default", "non_idempotent"}],
RestoreAgent: retry[[2]string{"default", "idempotent"}],
}
}
// AgentsClient is a client for interacting with Dialogflow API.
type AgentsClient struct {
// The connection to the service.
conn *grpc.ClientConn
// The gRPC API client.
agentsClient dialogflowpb.AgentsClient
// LROClient is used internally to handle longrunning operations.
// It is exposed so that its CallOptions can be modified if required.
// Users should not Close this client.
LROClient *lroauto.OperationsClient
// The call options for this service.
CallOptions *AgentsCallOptions
// The x-goog-* metadata to be sent with each request.
xGoogMetadata metadata.MD
}
// NewAgentsClient creates a new agents client.
//
// Agents are best described as Natural Language Understanding (NLU) modules
// that transform user requests into actionable data. You can include agents
// in your app, product, or service to determine user intent and respond to the
// user in a natural way.
//
// After you create an agent, you can add [Intents][google.cloud.dialogflow.v2.Intents], [Contexts][google.cloud.dialogflow.v2.Contexts],
// [Entity Types][google.cloud.dialogflow.v2.EntityTypes], [Webhooks][google.cloud.dialogflow.v2.WebhookRequest], and so on to
// manage the flow of a conversation and match user input to predefined intents
// and actions.
//
// You can create an agent using both Dialogflow Standard Edition and
// Dialogflow Enterprise Edition. For details, see
// Dialogflow Editions (at /dialogflow-enterprise/docs/editions).
//
// You can save your agent for backup or versioning by exporting the agent by
// using the [ExportAgent][google.cloud.dialogflow.v2.Agents.ExportAgent] method. You can import a saved
// agent by using the [ImportAgent][google.cloud.dialogflow.v2.Agents.ImportAgent] method.
//
// Dialogflow provides several
// prebuilt agents (at https://dialogflow.com/docs/prebuilt-agents) for common
// conversation scenarios such as determining a date and time, converting
// currency, and so on.
//
// For more information about agents, see the
// Dialogflow documentation (at https://dialogflow.com/docs/agents).
func NewAgentsClient(ctx context.Context, opts ...option.ClientOption) (*AgentsClient, error) {
conn, err := transport.DialGRPC(ctx, append(defaultAgentsClientOptions(), opts...)...)
if err != nil {
return nil, err
}
c := &AgentsClient{
conn: conn,
CallOptions: defaultAgentsCallOptions(),
agentsClient: dialogflowpb.NewAgentsClient(conn),
}
c.setGoogleClientInfo()
c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn))
if err != nil {
// This error "should not happen", since we are just reusing old connection
// and never actually need to dial.
// If this does happen, we could leak conn. However, we cannot close conn:
// If the user invoked the function with option.WithGRPCConn,
// we would close a connection that's still in use.
// TODO(pongad): investigate error conditions.
return nil, err
}
return c, nil
}
// Connection returns the client's connection to the API service.
func (c *AgentsClient) Connection() *grpc.ClientConn {
return c.conn
}
// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *AgentsClient) Close() error {
return c.conn.Close()
}
// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *AgentsClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}
// GetAgent retrieves the specified agent.
func (c *AgentsClient) GetAgent(ctx context.Context, req *dialogflowpb.GetAgentRequest, opts ...gax.CallOption) (*dialogflowpb.Agent, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetAgent[0:len(c.CallOptions.GetAgent):len(c.CallOptions.GetAgent)], opts...)
var resp *dialogflowpb.Agent
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.agentsClient.GetAgent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// SearchAgents returns the list of agents.
//
// Since there is at most one conversational agent per project, this method is
// useful primarily for listing all agents across projects the caller has
// access to. One can achieve that with a wildcard project collection id "-".
// Refer to List
// Sub-Collections (at https://cloud.google.com/apis/design/design_patterns#list_sub-collections).
func (c *AgentsClient) SearchAgents(ctx context.Context, req *dialogflowpb.SearchAgentsRequest, opts ...gax.CallOption) *AgentIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.SearchAgents[0:len(c.CallOptions.SearchAgents):len(c.CallOptions.SearchAgents)], opts...)
it := &AgentIterator{}
it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.Agent, string, error) {
var resp *dialogflowpb.SearchAgentsResponse
req.PageToken = pageToken
if pageSize > math.MaxInt32 {
req.PageSize = math.MaxInt32
} else {
req.PageSize = int32(pageSize)
}
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.agentsClient.SearchAgents(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, "", err
}
return resp.Agents, resp.NextPageToken, nil
}
fetch := func(pageSize int, pageToken string) (string, error) {
items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
if err != nil {
return "", err
}
it.items = append(it.items, items...)
return nextPageToken, nil
}
it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
return it
}
// TrainAgent trains the specified agent.
//
// Operation <response: [google.protobuf.Empty][google.protobuf.Empty],
// metadata: [google.protobuf.Struct][google.protobuf.Struct]>
func (c *AgentsClient) TrainAgent(ctx context.Context, req *dialogflowpb.TrainAgentRequest, opts ...gax.CallOption) (*TrainAgentOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.TrainAgent[0:len(c.CallOptions.TrainAgent):len(c.CallOptions.TrainAgent)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.agentsClient.TrainAgent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &TrainAgentOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// ExportAgent exports the specified agent to a ZIP file.
//
// Operation <response: [ExportAgentResponse][google.cloud.dialogflow.v2.ExportAgentResponse],
// metadata: [google.protobuf.Struct][google.protobuf.Struct]>
func (c *AgentsClient) ExportAgent(ctx context.Context, req *dialogflowpb.ExportAgentRequest, opts ...gax.CallOption) (*ExportAgentOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ExportAgent[0:len(c.CallOptions.ExportAgent):len(c.CallOptions.ExportAgent)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.agentsClient.ExportAgent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &ExportAgentOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// ImportAgent imports the specified agent from a ZIP file.
//
// Uploads new intents and entity types without deleting the existing ones.
// Intents and entity types with the same name are replaced with the new
// versions from ImportAgentRequest.
//
// Operation <response: [google.protobuf.Empty][google.protobuf.Empty],
// metadata: [google.protobuf.Struct][google.protobuf.Struct]>
func (c *AgentsClient) ImportAgent(ctx context.Context, req *dialogflowpb.ImportAgentRequest, opts ...gax.CallOption) (*ImportAgentOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ImportAgent[0:len(c.CallOptions.ImportAgent):len(c.CallOptions.ImportAgent)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.agentsClient.ImportAgent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &ImportAgentOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// RestoreAgent restores the specified agent from a ZIP file.
//
// Replaces the current agent version with a new one. All the intents and
// entity types in the older version are deleted.
//
// Operation <response: [google.protobuf.Empty][google.protobuf.Empty],
// metadata: [google.protobuf.Struct][google.protobuf.Struct]>
func (c *AgentsClient) RestoreAgent(ctx context.Context, req *dialogflowpb.RestoreAgentRequest, opts ...gax.CallOption) (*RestoreAgentOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.RestoreAgent[0:len(c.CallOptions.RestoreAgent):len(c.CallOptions.RestoreAgent)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.agentsClient.RestoreAgent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &RestoreAgentOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// AgentIterator manages a stream of *dialogflowpb.Agent.
type AgentIterator struct {
items []*dialogflowpb.Agent
pageInfo *iterator.PageInfo
nextFunc func() error
// InternalFetch is for use by the Google Cloud Libraries only.
// It is not part of the stable interface of this package.
//
// InternalFetch returns results from a single call to the underlying RPC.
// The number of results is no greater than pageSize.
// If there are no more results, nextPageToken is empty and err is nil.
InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.Agent, nextPageToken string, err error)
}
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *AgentIterator) PageInfo() *iterator.PageInfo {
return it.pageInfo
}
// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *AgentIterator) Next() (*dialogflowpb.Agent, error) {
var item *dialogflowpb.Agent
if err := it.nextFunc(); err != nil {
return item, err
}
item = it.items[0]
it.items = it.items[1:]
return item, nil
}
func (it *AgentIterator) bufLen() int {
return len(it.items)
}
func (it *AgentIterator) takeBuf() interface{} {
b := it.items
it.items = nil
return b
}
// ExportAgentOperation manages a long-running operation from ExportAgent.
type ExportAgentOperation struct {
lro *longrunning.Operation
}
// ExportAgentOperation returns a new ExportAgentOperation from a given name.
// The name must be that of a previously created ExportAgentOperation, possibly from a different process.
func (c *AgentsClient) ExportAgentOperation(name string) *ExportAgentOperation {
return &ExportAgentOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *ExportAgentOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.ExportAgentResponse, error) {
var resp dialogflowpb.ExportAgentResponse
if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil {
return nil, err
}
return &resp, nil
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully,
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *ExportAgentOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.ExportAgentResponse, error) {
var resp dialogflowpb.ExportAgentResponse
if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
return nil, err
}
if !op.Done() {
return nil, nil
}
return &resp, nil
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *ExportAgentOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *ExportAgentOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *ExportAgentOperation) Name() string {
return op.lro.Name()
}
// ImportAgentOperation manages a long-running operation from ImportAgent.
type ImportAgentOperation struct {
lro *longrunning.Operation
}
// ImportAgentOperation returns a new ImportAgentOperation from a given name.
// The name must be that of a previously created ImportAgentOperation, possibly from a different process.
func (c *AgentsClient) ImportAgentOperation(name string) *ImportAgentOperation {
return &ImportAgentOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *ImportAgentOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...)
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully, op.Done will return true.
func (op *ImportAgentOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.Poll(ctx, nil, opts...)
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *ImportAgentOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *ImportAgentOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *ImportAgentOperation) Name() string {
return op.lro.Name()
}
// RestoreAgentOperation manages a long-running operation from RestoreAgent.
type RestoreAgentOperation struct {
lro *longrunning.Operation
}
// RestoreAgentOperation returns a new RestoreAgentOperation from a given name.
// The name must be that of a previously created RestoreAgentOperation, possibly from a different process.
func (c *AgentsClient) RestoreAgentOperation(name string) *RestoreAgentOperation {
return &RestoreAgentOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *RestoreAgentOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...)
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully, op.Done will return true.
func (op *RestoreAgentOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.Poll(ctx, nil, opts...)
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *RestoreAgentOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *RestoreAgentOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *RestoreAgentOperation) Name() string {
return op.lro.Name()
}
// TrainAgentOperation manages a long-running operation from TrainAgent.
type TrainAgentOperation struct {
lro *longrunning.Operation
}
// TrainAgentOperation returns a new TrainAgentOperation from a given name.
// The name must be that of a previously created TrainAgentOperation, possibly from a different process.
func (c *AgentsClient) TrainAgentOperation(name string) *TrainAgentOperation {
return &TrainAgentOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *TrainAgentOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...)
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully, op.Done will return true.
func (op *TrainAgentOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.Poll(ctx, nil, opts...)
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *TrainAgentOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *TrainAgentOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *TrainAgentOperation) Name() string {
return op.lro.Name()
}

View File

@ -0,0 +1,156 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow_test
import (
"cloud.google.com/go/dialogflow/apiv2"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
)
func ExampleNewAgentsClient() {
ctx := context.Background()
c, err := dialogflow.NewAgentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
// TODO: Use client.
_ = c
}
func ExampleAgentsClient_GetAgent() {
ctx := context.Background()
c, err := dialogflow.NewAgentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.GetAgentRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetAgent(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleAgentsClient_SearchAgents() {
ctx := context.Background()
c, err := dialogflow.NewAgentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.SearchAgentsRequest{
// TODO: Fill request struct fields.
}
it := c.SearchAgents(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
}
func ExampleAgentsClient_TrainAgent() {
ctx := context.Background()
c, err := dialogflow.NewAgentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.TrainAgentRequest{
// TODO: Fill request struct fields.
}
op, err := c.TrainAgent(ctx, req)
if err != nil {
// TODO: Handle error.
}
err = op.Wait(ctx)
// TODO: Handle error.
}
func ExampleAgentsClient_ExportAgent() {
ctx := context.Background()
c, err := dialogflow.NewAgentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.ExportAgentRequest{
// TODO: Fill request struct fields.
}
op, err := c.ExportAgent(ctx, req)
if err != nil {
// TODO: Handle error.
}
resp, err := op.Wait(ctx)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleAgentsClient_ImportAgent() {
ctx := context.Background()
c, err := dialogflow.NewAgentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.ImportAgentRequest{
// TODO: Fill request struct fields.
}
op, err := c.ImportAgent(ctx, req)
if err != nil {
// TODO: Handle error.
}
err = op.Wait(ctx)
// TODO: Handle error.
}
func ExampleAgentsClient_RestoreAgent() {
ctx := context.Background()
c, err := dialogflow.NewAgentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.RestoreAgentRequest{
// TODO: Fill request struct fields.
}
op, err := c.RestoreAgent(ctx, req)
if err != nil {
// TODO: Handle error.
}
err = op.Wait(ctx)
// TODO: Handle error.
}

View File

@ -0,0 +1,293 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow
import (
"math"
"time"
"cloud.google.com/go/internal/version"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/api/transport"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
)
// ContextsCallOptions contains the retry settings for each method of ContextsClient.
type ContextsCallOptions struct {
ListContexts []gax.CallOption
GetContext []gax.CallOption
CreateContext []gax.CallOption
UpdateContext []gax.CallOption
DeleteContext []gax.CallOption
DeleteAllContexts []gax.CallOption
}
func defaultContextsClientOptions() []option.ClientOption {
return []option.ClientOption{
option.WithEndpoint("dialogflow.googleapis.com:443"),
option.WithScopes(DefaultAuthScopes()...),
}
}
func defaultContextsCallOptions() *ContextsCallOptions {
retry := map[[2]string][]gax.CallOption{
{"default", "idempotent"}: {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.DeadlineExceeded,
codes.Unavailable,
}, gax.Backoff{
Initial: 100 * time.Millisecond,
Max: 60000 * time.Millisecond,
Multiplier: 1.3,
})
}),
},
}
return &ContextsCallOptions{
ListContexts: retry[[2]string{"default", "idempotent"}],
GetContext: retry[[2]string{"default", "idempotent"}],
CreateContext: retry[[2]string{"default", "non_idempotent"}],
UpdateContext: retry[[2]string{"default", "non_idempotent"}],
DeleteContext: retry[[2]string{"default", "idempotent"}],
DeleteAllContexts: retry[[2]string{"default", "idempotent"}],
}
}
// ContextsClient is a client for interacting with Dialogflow API.
type ContextsClient struct {
// The connection to the service.
conn *grpc.ClientConn
// The gRPC API client.
contextsClient dialogflowpb.ContextsClient
// The call options for this service.
CallOptions *ContextsCallOptions
// The x-goog-* metadata to be sent with each request.
xGoogMetadata metadata.MD
}
// NewContextsClient creates a new contexts client.
//
// A context represents additional information included with user input or with
// an intent returned by the Dialogflow API. Contexts are helpful for
// differentiating user input which may be vague or have a different meaning
// depending on additional details from your application such as user setting
// and preferences, previous user input, where the user is in your application,
// geographic location, and so on.
//
// You can include contexts as input parameters of a
// [DetectIntent][google.cloud.dialogflow.v2.Sessions.DetectIntent] (or
// [StreamingDetectIntent][google.cloud.dialogflow.v2.Sessions.StreamingDetectIntent]) request,
// or as output contexts included in the returned intent.
// Contexts expire when an intent is matched, after the number of DetectIntent
// requests specified by the lifespan_count parameter, or after 10 minutes
// if no intents are matched for a DetectIntent request.
//
// For more information about contexts, see the
// Dialogflow documentation (at https://dialogflow.com/docs/contexts).
func NewContextsClient(ctx context.Context, opts ...option.ClientOption) (*ContextsClient, error) {
conn, err := transport.DialGRPC(ctx, append(defaultContextsClientOptions(), opts...)...)
if err != nil {
return nil, err
}
c := &ContextsClient{
conn: conn,
CallOptions: defaultContextsCallOptions(),
contextsClient: dialogflowpb.NewContextsClient(conn),
}
c.setGoogleClientInfo()
return c, nil
}
// Connection returns the client's connection to the API service.
func (c *ContextsClient) Connection() *grpc.ClientConn {
return c.conn
}
// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *ContextsClient) Close() error {
return c.conn.Close()
}
// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *ContextsClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}
// ListContexts returns the list of all contexts in the specified session.
func (c *ContextsClient) ListContexts(ctx context.Context, req *dialogflowpb.ListContextsRequest, opts ...gax.CallOption) *ContextIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListContexts[0:len(c.CallOptions.ListContexts):len(c.CallOptions.ListContexts)], opts...)
it := &ContextIterator{}
it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.Context, string, error) {
var resp *dialogflowpb.ListContextsResponse
req.PageToken = pageToken
if pageSize > math.MaxInt32 {
req.PageSize = math.MaxInt32
} else {
req.PageSize = int32(pageSize)
}
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.contextsClient.ListContexts(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, "", err
}
return resp.Contexts, resp.NextPageToken, nil
}
fetch := func(pageSize int, pageToken string) (string, error) {
items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
if err != nil {
return "", err
}
it.items = append(it.items, items...)
return nextPageToken, nil
}
it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
return it
}
// GetContext retrieves the specified context.
func (c *ContextsClient) GetContext(ctx context.Context, req *dialogflowpb.GetContextRequest, opts ...gax.CallOption) (*dialogflowpb.Context, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetContext[0:len(c.CallOptions.GetContext):len(c.CallOptions.GetContext)], opts...)
var resp *dialogflowpb.Context
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.contextsClient.GetContext(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// CreateContext creates a context.
func (c *ContextsClient) CreateContext(ctx context.Context, req *dialogflowpb.CreateContextRequest, opts ...gax.CallOption) (*dialogflowpb.Context, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateContext[0:len(c.CallOptions.CreateContext):len(c.CallOptions.CreateContext)], opts...)
var resp *dialogflowpb.Context
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.contextsClient.CreateContext(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// UpdateContext updates the specified context.
func (c *ContextsClient) UpdateContext(ctx context.Context, req *dialogflowpb.UpdateContextRequest, opts ...gax.CallOption) (*dialogflowpb.Context, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.UpdateContext[0:len(c.CallOptions.UpdateContext):len(c.CallOptions.UpdateContext)], opts...)
var resp *dialogflowpb.Context
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.contextsClient.UpdateContext(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeleteContext deletes the specified context.
func (c *ContextsClient) DeleteContext(ctx context.Context, req *dialogflowpb.DeleteContextRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteContext[0:len(c.CallOptions.DeleteContext):len(c.CallOptions.DeleteContext)], opts...)
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
_, err = c.contextsClient.DeleteContext(ctx, req, settings.GRPC...)
return err
}, opts...)
return err
}
// DeleteAllContexts deletes all active contexts in the specified session.
func (c *ContextsClient) DeleteAllContexts(ctx context.Context, req *dialogflowpb.DeleteAllContextsRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteAllContexts[0:len(c.CallOptions.DeleteAllContexts):len(c.CallOptions.DeleteAllContexts)], opts...)
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
_, err = c.contextsClient.DeleteAllContexts(ctx, req, settings.GRPC...)
return err
}, opts...)
return err
}
// ContextIterator manages a stream of *dialogflowpb.Context.
type ContextIterator struct {
items []*dialogflowpb.Context
pageInfo *iterator.PageInfo
nextFunc func() error
// InternalFetch is for use by the Google Cloud Libraries only.
// It is not part of the stable interface of this package.
//
// InternalFetch returns results from a single call to the underlying RPC.
// The number of results is no greater than pageSize.
// If there are no more results, nextPageToken is empty and err is nil.
InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.Context, nextPageToken string, err error)
}
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *ContextIterator) PageInfo() *iterator.PageInfo {
return it.pageInfo
}
// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *ContextIterator) Next() (*dialogflowpb.Context, error) {
var item *dialogflowpb.Context
if err := it.nextFunc(); err != nil {
return item, err
}
item = it.items[0]
it.items = it.items[1:]
return item, nil
}
func (it *ContextIterator) bufLen() int {
return len(it.items)
}
func (it *ContextIterator) takeBuf() interface{} {
b := it.items
it.items = nil
return b
}

View File

@ -0,0 +1,144 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow_test
import (
"cloud.google.com/go/dialogflow/apiv2"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
)
func ExampleNewContextsClient() {
ctx := context.Background()
c, err := dialogflow.NewContextsClient(ctx)
if err != nil {
// TODO: Handle error.
}
// TODO: Use client.
_ = c
}
func ExampleContextsClient_ListContexts() {
ctx := context.Background()
c, err := dialogflow.NewContextsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.ListContextsRequest{
// TODO: Fill request struct fields.
}
it := c.ListContexts(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
}
func ExampleContextsClient_GetContext() {
ctx := context.Background()
c, err := dialogflow.NewContextsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.GetContextRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetContext(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleContextsClient_CreateContext() {
ctx := context.Background()
c, err := dialogflow.NewContextsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.CreateContextRequest{
// TODO: Fill request struct fields.
}
resp, err := c.CreateContext(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleContextsClient_UpdateContext() {
ctx := context.Background()
c, err := dialogflow.NewContextsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.UpdateContextRequest{
// TODO: Fill request struct fields.
}
resp, err := c.UpdateContext(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleContextsClient_DeleteContext() {
ctx := context.Background()
c, err := dialogflow.NewContextsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.DeleteContextRequest{
// TODO: Fill request struct fields.
}
err = c.DeleteContext(ctx, req)
if err != nil {
// TODO: Handle error.
}
}
func ExampleContextsClient_DeleteAllContexts() {
ctx := context.Background()
c, err := dialogflow.NewContextsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.DeleteAllContextsRequest{
// TODO: Fill request struct fields.
}
err = c.DeleteAllContexts(ctx, req)
if err != nil {
// TODO: Handle error.
}
}

View File

@ -14,15 +14,14 @@
// AUTO-GENERATED CODE. DO NOT EDIT.
// Package dlp is an auto-generated package for the
// DLP API.
// Package dialogflow is an auto-generated package for the
// Dialogflow API.
//
// NOTE: This package is in alpha. It is not stable, and is likely to change.
//
// The Google Data Loss Prevention API provides methods for detection of
// privacy-sensitive fragments in text, images, and Google Cloud Platform
// storage repositories.
package dlp // import "cloud.google.com/go/privacy/dlp/apiv2beta2"
// An end-to-end development suite for conversational interfaces (e.g.,
// chatbots, voice-powered apps and devices).
package dialogflow // import "cloud.google.com/go/dialogflow/apiv2"
import (
"golang.org/x/net/context"

View File

@ -0,0 +1,718 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow
import (
"math"
"time"
"cloud.google.com/go/internal/version"
"cloud.google.com/go/longrunning"
lroauto "cloud.google.com/go/longrunning/autogen"
structpbpb "github.com/golang/protobuf/ptypes/struct"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/api/transport"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
longrunningpb "google.golang.org/genproto/googleapis/longrunning"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
)
// EntityTypesCallOptions contains the retry settings for each method of EntityTypesClient.
type EntityTypesCallOptions struct {
ListEntityTypes []gax.CallOption
GetEntityType []gax.CallOption
CreateEntityType []gax.CallOption
UpdateEntityType []gax.CallOption
DeleteEntityType []gax.CallOption
BatchUpdateEntityTypes []gax.CallOption
BatchDeleteEntityTypes []gax.CallOption
BatchCreateEntities []gax.CallOption
BatchUpdateEntities []gax.CallOption
BatchDeleteEntities []gax.CallOption
}
func defaultEntityTypesClientOptions() []option.ClientOption {
return []option.ClientOption{
option.WithEndpoint("dialogflow.googleapis.com:443"),
option.WithScopes(DefaultAuthScopes()...),
}
}
func defaultEntityTypesCallOptions() *EntityTypesCallOptions {
retry := map[[2]string][]gax.CallOption{
{"default", "idempotent"}: {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.DeadlineExceeded,
codes.Unavailable,
}, gax.Backoff{
Initial: 100 * time.Millisecond,
Max: 60000 * time.Millisecond,
Multiplier: 1.3,
})
}),
},
}
return &EntityTypesCallOptions{
ListEntityTypes: retry[[2]string{"default", "idempotent"}],
GetEntityType: retry[[2]string{"default", "idempotent"}],
CreateEntityType: retry[[2]string{"default", "non_idempotent"}],
UpdateEntityType: retry[[2]string{"default", "non_idempotent"}],
DeleteEntityType: retry[[2]string{"default", "idempotent"}],
BatchUpdateEntityTypes: retry[[2]string{"default", "non_idempotent"}],
BatchDeleteEntityTypes: retry[[2]string{"default", "idempotent"}],
BatchCreateEntities: retry[[2]string{"default", "non_idempotent"}],
BatchUpdateEntities: retry[[2]string{"default", "non_idempotent"}],
BatchDeleteEntities: retry[[2]string{"default", "idempotent"}],
}
}
// EntityTypesClient is a client for interacting with Dialogflow API.
type EntityTypesClient struct {
// The connection to the service.
conn *grpc.ClientConn
// The gRPC API client.
entityTypesClient dialogflowpb.EntityTypesClient
// LROClient is used internally to handle longrunning operations.
// It is exposed so that its CallOptions can be modified if required.
// Users should not Close this client.
LROClient *lroauto.OperationsClient
// The call options for this service.
CallOptions *EntityTypesCallOptions
// The x-goog-* metadata to be sent with each request.
xGoogMetadata metadata.MD
}
// NewEntityTypesClient creates a new entity types client.
//
// Entities are extracted from user input and represent parameters that are
// meaningful to your application. For example, a date range, a proper name
// such as a geographic location or landmark, and so on. Entities represent
// actionable data for your application.
//
// When you define an entity, you can also include synonyms that all map to
// that entity. For example, "soft drink", "soda", "pop", and so on.
//
// There are three types of entities:
//
// * **System** - entities that are defined by the Dialogflow API for common
// data types such as date, time, currency, and so on. A system entity is
// represented by the `EntityType` type.
//
// * **Developer** - entities that are defined by you that represent
// actionable data that is meaningful to your application. For example,
// you could define a `pizza.sauce` entity for red or white pizza sauce,
// a `pizza.cheese` entity for the different types of cheese on a pizza,
// a `pizza.topping` entity for different toppings, and so on. A developer
// entity is represented by the `EntityType` type.
//
// * **User** - entities that are built for an individual user such as
// favorites, preferences, playlists, and so on. A user entity is
// represented by the [SessionEntityType][google.cloud.dialogflow.v2.SessionEntityType] type.
//
// For more information about entity types, see the
// [Dialogflow documentation](https://dialogflow.com/docs/entities).
func NewEntityTypesClient(ctx context.Context, opts ...option.ClientOption) (*EntityTypesClient, error) {
conn, err := transport.DialGRPC(ctx, append(defaultEntityTypesClientOptions(), opts...)...)
if err != nil {
return nil, err
}
c := &EntityTypesClient{
conn: conn,
CallOptions: defaultEntityTypesCallOptions(),
entityTypesClient: dialogflowpb.NewEntityTypesClient(conn),
}
c.setGoogleClientInfo()
c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn))
if err != nil {
// This error "should not happen", since we are just reusing old connection
// and never actually need to dial.
// If this does happen, we could leak conn. However, we cannot close conn:
// If the user invoked the function with option.WithGRPCConn,
// we would close a connection that's still in use.
// TODO(pongad): investigate error conditions.
return nil, err
}
return c, nil
}
// Connection returns the client's connection to the API service.
func (c *EntityTypesClient) Connection() *grpc.ClientConn {
return c.conn
}
// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *EntityTypesClient) Close() error {
return c.conn.Close()
}
// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *EntityTypesClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}
// ListEntityTypes returns the list of all entity types in the specified agent.
func (c *EntityTypesClient) ListEntityTypes(ctx context.Context, req *dialogflowpb.ListEntityTypesRequest, opts ...gax.CallOption) *EntityTypeIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListEntityTypes[0:len(c.CallOptions.ListEntityTypes):len(c.CallOptions.ListEntityTypes)], opts...)
it := &EntityTypeIterator{}
it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.EntityType, string, error) {
var resp *dialogflowpb.ListEntityTypesResponse
req.PageToken = pageToken
if pageSize > math.MaxInt32 {
req.PageSize = math.MaxInt32
} else {
req.PageSize = int32(pageSize)
}
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.ListEntityTypes(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, "", err
}
return resp.EntityTypes, resp.NextPageToken, nil
}
fetch := func(pageSize int, pageToken string) (string, error) {
items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
if err != nil {
return "", err
}
it.items = append(it.items, items...)
return nextPageToken, nil
}
it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
return it
}
// GetEntityType retrieves the specified entity type.
func (c *EntityTypesClient) GetEntityType(ctx context.Context, req *dialogflowpb.GetEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.EntityType, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetEntityType[0:len(c.CallOptions.GetEntityType):len(c.CallOptions.GetEntityType)], opts...)
var resp *dialogflowpb.EntityType
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.GetEntityType(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// CreateEntityType creates an entity type in the specified agent.
func (c *EntityTypesClient) CreateEntityType(ctx context.Context, req *dialogflowpb.CreateEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.EntityType, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateEntityType[0:len(c.CallOptions.CreateEntityType):len(c.CallOptions.CreateEntityType)], opts...)
var resp *dialogflowpb.EntityType
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.CreateEntityType(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// UpdateEntityType updates the specified entity type.
func (c *EntityTypesClient) UpdateEntityType(ctx context.Context, req *dialogflowpb.UpdateEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.EntityType, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.UpdateEntityType[0:len(c.CallOptions.UpdateEntityType):len(c.CallOptions.UpdateEntityType)], opts...)
var resp *dialogflowpb.EntityType
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.UpdateEntityType(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeleteEntityType deletes the specified entity type.
func (c *EntityTypesClient) DeleteEntityType(ctx context.Context, req *dialogflowpb.DeleteEntityTypeRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteEntityType[0:len(c.CallOptions.DeleteEntityType):len(c.CallOptions.DeleteEntityType)], opts...)
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
_, err = c.entityTypesClient.DeleteEntityType(ctx, req, settings.GRPC...)
return err
}, opts...)
return err
}
// BatchUpdateEntityTypes updates/Creates multiple entity types in the specified agent.
//
// Operation <response: [BatchUpdateEntityTypesResponse][google.cloud.dialogflow.v2.BatchUpdateEntityTypesResponse],
// metadata: [google.protobuf.Struct][google.protobuf.Struct]>
func (c *EntityTypesClient) BatchUpdateEntityTypes(ctx context.Context, req *dialogflowpb.BatchUpdateEntityTypesRequest, opts ...gax.CallOption) (*BatchUpdateEntityTypesOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.BatchUpdateEntityTypes[0:len(c.CallOptions.BatchUpdateEntityTypes):len(c.CallOptions.BatchUpdateEntityTypes)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.BatchUpdateEntityTypes(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &BatchUpdateEntityTypesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// BatchDeleteEntityTypes deletes entity types in the specified agent.
//
// Operation <response: [google.protobuf.Empty][google.protobuf.Empty],
// metadata: [google.protobuf.Struct][google.protobuf.Struct]>
func (c *EntityTypesClient) BatchDeleteEntityTypes(ctx context.Context, req *dialogflowpb.BatchDeleteEntityTypesRequest, opts ...gax.CallOption) (*BatchDeleteEntityTypesOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.BatchDeleteEntityTypes[0:len(c.CallOptions.BatchDeleteEntityTypes):len(c.CallOptions.BatchDeleteEntityTypes)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.BatchDeleteEntityTypes(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &BatchDeleteEntityTypesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// BatchCreateEntities creates multiple new entities in the specified entity type (extends the
// existing collection of entries).
//
// Operation <response: [google.protobuf.Empty][google.protobuf.Empty]>
func (c *EntityTypesClient) BatchCreateEntities(ctx context.Context, req *dialogflowpb.BatchCreateEntitiesRequest, opts ...gax.CallOption) (*BatchCreateEntitiesOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.BatchCreateEntities[0:len(c.CallOptions.BatchCreateEntities):len(c.CallOptions.BatchCreateEntities)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.BatchCreateEntities(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &BatchCreateEntitiesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// BatchUpdateEntities updates entities in the specified entity type (replaces the existing
// collection of entries).
//
// Operation <response: [google.protobuf.Empty][google.protobuf.Empty],
// metadata: [google.protobuf.Struct][google.protobuf.Struct]>
func (c *EntityTypesClient) BatchUpdateEntities(ctx context.Context, req *dialogflowpb.BatchUpdateEntitiesRequest, opts ...gax.CallOption) (*BatchUpdateEntitiesOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.BatchUpdateEntities[0:len(c.CallOptions.BatchUpdateEntities):len(c.CallOptions.BatchUpdateEntities)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.BatchUpdateEntities(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &BatchUpdateEntitiesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// BatchDeleteEntities deletes entities in the specified entity type.
//
// Operation <response: [google.protobuf.Empty][google.protobuf.Empty],
// metadata: [google.protobuf.Struct][google.protobuf.Struct]>
func (c *EntityTypesClient) BatchDeleteEntities(ctx context.Context, req *dialogflowpb.BatchDeleteEntitiesRequest, opts ...gax.CallOption) (*BatchDeleteEntitiesOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.BatchDeleteEntities[0:len(c.CallOptions.BatchDeleteEntities):len(c.CallOptions.BatchDeleteEntities)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.entityTypesClient.BatchDeleteEntities(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &BatchDeleteEntitiesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// EntityTypeIterator manages a stream of *dialogflowpb.EntityType.
type EntityTypeIterator struct {
items []*dialogflowpb.EntityType
pageInfo *iterator.PageInfo
nextFunc func() error
// InternalFetch is for use by the Google Cloud Libraries only.
// It is not part of the stable interface of this package.
//
// InternalFetch returns results from a single call to the underlying RPC.
// The number of results is no greater than pageSize.
// If there are no more results, nextPageToken is empty and err is nil.
InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.EntityType, nextPageToken string, err error)
}
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *EntityTypeIterator) PageInfo() *iterator.PageInfo {
return it.pageInfo
}
// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *EntityTypeIterator) Next() (*dialogflowpb.EntityType, error) {
var item *dialogflowpb.EntityType
if err := it.nextFunc(); err != nil {
return item, err
}
item = it.items[0]
it.items = it.items[1:]
return item, nil
}
func (it *EntityTypeIterator) bufLen() int {
return len(it.items)
}
func (it *EntityTypeIterator) takeBuf() interface{} {
b := it.items
it.items = nil
return b
}
// BatchCreateEntitiesOperation manages a long-running operation from BatchCreateEntities.
type BatchCreateEntitiesOperation struct {
lro *longrunning.Operation
}
// BatchCreateEntitiesOperation returns a new BatchCreateEntitiesOperation from a given name.
// The name must be that of a previously created BatchCreateEntitiesOperation, possibly from a different process.
func (c *EntityTypesClient) BatchCreateEntitiesOperation(name string) *BatchCreateEntitiesOperation {
return &BatchCreateEntitiesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *BatchCreateEntitiesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...)
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully, op.Done will return true.
func (op *BatchCreateEntitiesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.Poll(ctx, nil, opts...)
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *BatchCreateEntitiesOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *BatchCreateEntitiesOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *BatchCreateEntitiesOperation) Name() string {
return op.lro.Name()
}
// BatchDeleteEntitiesOperation manages a long-running operation from BatchDeleteEntities.
type BatchDeleteEntitiesOperation struct {
lro *longrunning.Operation
}
// BatchDeleteEntitiesOperation returns a new BatchDeleteEntitiesOperation from a given name.
// The name must be that of a previously created BatchDeleteEntitiesOperation, possibly from a different process.
func (c *EntityTypesClient) BatchDeleteEntitiesOperation(name string) *BatchDeleteEntitiesOperation {
return &BatchDeleteEntitiesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *BatchDeleteEntitiesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...)
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully, op.Done will return true.
func (op *BatchDeleteEntitiesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.Poll(ctx, nil, opts...)
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *BatchDeleteEntitiesOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *BatchDeleteEntitiesOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *BatchDeleteEntitiesOperation) Name() string {
return op.lro.Name()
}
// BatchDeleteEntityTypesOperation manages a long-running operation from BatchDeleteEntityTypes.
type BatchDeleteEntityTypesOperation struct {
lro *longrunning.Operation
}
// BatchDeleteEntityTypesOperation returns a new BatchDeleteEntityTypesOperation from a given name.
// The name must be that of a previously created BatchDeleteEntityTypesOperation, possibly from a different process.
func (c *EntityTypesClient) BatchDeleteEntityTypesOperation(name string) *BatchDeleteEntityTypesOperation {
return &BatchDeleteEntityTypesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *BatchDeleteEntityTypesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...)
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully, op.Done will return true.
func (op *BatchDeleteEntityTypesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.Poll(ctx, nil, opts...)
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *BatchDeleteEntityTypesOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *BatchDeleteEntityTypesOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *BatchDeleteEntityTypesOperation) Name() string {
return op.lro.Name()
}
// BatchUpdateEntitiesOperation manages a long-running operation from BatchUpdateEntities.
type BatchUpdateEntitiesOperation struct {
lro *longrunning.Operation
}
// BatchUpdateEntitiesOperation returns a new BatchUpdateEntitiesOperation from a given name.
// The name must be that of a previously created BatchUpdateEntitiesOperation, possibly from a different process.
func (c *EntityTypesClient) BatchUpdateEntitiesOperation(name string) *BatchUpdateEntitiesOperation {
return &BatchUpdateEntitiesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *BatchUpdateEntitiesOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...)
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully, op.Done will return true.
func (op *BatchUpdateEntitiesOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.Poll(ctx, nil, opts...)
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *BatchUpdateEntitiesOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *BatchUpdateEntitiesOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *BatchUpdateEntitiesOperation) Name() string {
return op.lro.Name()
}
// BatchUpdateEntityTypesOperation manages a long-running operation from BatchUpdateEntityTypes.
type BatchUpdateEntityTypesOperation struct {
lro *longrunning.Operation
}
// BatchUpdateEntityTypesOperation returns a new BatchUpdateEntityTypesOperation from a given name.
// The name must be that of a previously created BatchUpdateEntityTypesOperation, possibly from a different process.
func (c *EntityTypesClient) BatchUpdateEntityTypesOperation(name string) *BatchUpdateEntityTypesOperation {
return &BatchUpdateEntityTypesOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *BatchUpdateEntityTypesOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.BatchUpdateEntityTypesResponse, error) {
var resp dialogflowpb.BatchUpdateEntityTypesResponse
if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil {
return nil, err
}
return &resp, nil
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully,
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *BatchUpdateEntityTypesOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.BatchUpdateEntityTypesResponse, error) {
var resp dialogflowpb.BatchUpdateEntityTypesResponse
if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
return nil, err
}
if !op.Done() {
return nil, nil
}
return &resp, nil
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *BatchUpdateEntityTypesOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *BatchUpdateEntityTypesOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *BatchUpdateEntityTypesOperation) Name() string {
return op.lro.Name()
}

View File

@ -0,0 +1,227 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow_test
import (
"cloud.google.com/go/dialogflow/apiv2"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
)
func ExampleNewEntityTypesClient() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
// TODO: Use client.
_ = c
}
func ExampleEntityTypesClient_ListEntityTypes() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.ListEntityTypesRequest{
// TODO: Fill request struct fields.
}
it := c.ListEntityTypes(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
}
func ExampleEntityTypesClient_GetEntityType() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.GetEntityTypeRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetEntityType(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleEntityTypesClient_CreateEntityType() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.CreateEntityTypeRequest{
// TODO: Fill request struct fields.
}
resp, err := c.CreateEntityType(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleEntityTypesClient_UpdateEntityType() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.UpdateEntityTypeRequest{
// TODO: Fill request struct fields.
}
resp, err := c.UpdateEntityType(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleEntityTypesClient_DeleteEntityType() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.DeleteEntityTypeRequest{
// TODO: Fill request struct fields.
}
err = c.DeleteEntityType(ctx, req)
if err != nil {
// TODO: Handle error.
}
}
func ExampleEntityTypesClient_BatchUpdateEntityTypes() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.BatchUpdateEntityTypesRequest{
// TODO: Fill request struct fields.
}
op, err := c.BatchUpdateEntityTypes(ctx, req)
if err != nil {
// TODO: Handle error.
}
resp, err := op.Wait(ctx)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleEntityTypesClient_BatchDeleteEntityTypes() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.BatchDeleteEntityTypesRequest{
// TODO: Fill request struct fields.
}
op, err := c.BatchDeleteEntityTypes(ctx, req)
if err != nil {
// TODO: Handle error.
}
err = op.Wait(ctx)
// TODO: Handle error.
}
func ExampleEntityTypesClient_BatchCreateEntities() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.BatchCreateEntitiesRequest{
// TODO: Fill request struct fields.
}
op, err := c.BatchCreateEntities(ctx, req)
if err != nil {
// TODO: Handle error.
}
err = op.Wait(ctx)
// TODO: Handle error.
}
func ExampleEntityTypesClient_BatchUpdateEntities() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.BatchUpdateEntitiesRequest{
// TODO: Fill request struct fields.
}
op, err := c.BatchUpdateEntities(ctx, req)
if err != nil {
// TODO: Handle error.
}
err = op.Wait(ctx)
// TODO: Handle error.
}
func ExampleEntityTypesClient_BatchDeleteEntities() {
ctx := context.Background()
c, err := dialogflow.NewEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.BatchDeleteEntitiesRequest{
// TODO: Fill request struct fields.
}
op, err := c.BatchDeleteEntities(ctx, req)
if err != nil {
// TODO: Handle error.
}
err = op.Wait(ctx)
// TODO: Handle error.
}

View File

@ -0,0 +1,482 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow
import (
"math"
"time"
"cloud.google.com/go/internal/version"
"cloud.google.com/go/longrunning"
lroauto "cloud.google.com/go/longrunning/autogen"
structpbpb "github.com/golang/protobuf/ptypes/struct"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/api/transport"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
longrunningpb "google.golang.org/genproto/googleapis/longrunning"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
)
// IntentsCallOptions contains the retry settings for each method of IntentsClient.
type IntentsCallOptions struct {
ListIntents []gax.CallOption
GetIntent []gax.CallOption
CreateIntent []gax.CallOption
UpdateIntent []gax.CallOption
DeleteIntent []gax.CallOption
BatchUpdateIntents []gax.CallOption
BatchDeleteIntents []gax.CallOption
}
func defaultIntentsClientOptions() []option.ClientOption {
return []option.ClientOption{
option.WithEndpoint("dialogflow.googleapis.com:443"),
option.WithScopes(DefaultAuthScopes()...),
}
}
func defaultIntentsCallOptions() *IntentsCallOptions {
retry := map[[2]string][]gax.CallOption{
{"default", "idempotent"}: {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.DeadlineExceeded,
codes.Unavailable,
}, gax.Backoff{
Initial: 100 * time.Millisecond,
Max: 60000 * time.Millisecond,
Multiplier: 1.3,
})
}),
},
}
return &IntentsCallOptions{
ListIntents: retry[[2]string{"default", "idempotent"}],
GetIntent: retry[[2]string{"default", "idempotent"}],
CreateIntent: retry[[2]string{"default", "non_idempotent"}],
UpdateIntent: retry[[2]string{"default", "non_idempotent"}],
DeleteIntent: retry[[2]string{"default", "idempotent"}],
BatchUpdateIntents: retry[[2]string{"default", "non_idempotent"}],
BatchDeleteIntents: retry[[2]string{"default", "idempotent"}],
}
}
// IntentsClient is a client for interacting with Dialogflow API.
type IntentsClient struct {
// The connection to the service.
conn *grpc.ClientConn
// The gRPC API client.
intentsClient dialogflowpb.IntentsClient
// LROClient is used internally to handle longrunning operations.
// It is exposed so that its CallOptions can be modified if required.
// Users should not Close this client.
LROClient *lroauto.OperationsClient
// The call options for this service.
CallOptions *IntentsCallOptions
// The x-goog-* metadata to be sent with each request.
xGoogMetadata metadata.MD
}
// NewIntentsClient creates a new intents client.
//
// An intent represents a mapping between input from a user and an action to
// be taken by your application. When you pass user input to the
// [DetectIntent][google.cloud.dialogflow.v2.Sessions.DetectIntent] (or
// [StreamingDetectIntent][google.cloud.dialogflow.v2.Sessions.StreamingDetectIntent]) method, the
// Dialogflow API analyzes the input and searches
// for a matching intent. If no match is found, the Dialogflow API returns a
// fallback intent (`is_fallback` = true).
//
// You can provide additional information for the Dialogflow API to use to
// match user input to an intent by adding the following to your intent.
//
// * **Contexts** - provide additional context for intent analysis. For
// example, if an intent is related to an object in your application that
// plays music, you can provide a context to determine when to match the
// intent if the user input is “turn it off”. You can include a context
// that matches the intent when there is previous user input of
// "play music", and not when there is previous user input of
// "turn on the light".
//
// * **Events** - allow for matching an intent by using an event name
// instead of user input. Your application can provide an event name and
// related parameters to the Dialogflow API to match an intent. For
// example, when your application starts, you can send a welcome event
// with a user name parameter to the Dialogflow API to match an intent with
// a personalized welcome message for the user.
//
// * **Training phrases** - provide examples of user input to train the
// Dialogflow API agent to better match intents.
//
// For more information about intents, see the
// [Dialogflow documentation](https://dialogflow.com/docs/intents).
func NewIntentsClient(ctx context.Context, opts ...option.ClientOption) (*IntentsClient, error) {
conn, err := transport.DialGRPC(ctx, append(defaultIntentsClientOptions(), opts...)...)
if err != nil {
return nil, err
}
c := &IntentsClient{
conn: conn,
CallOptions: defaultIntentsCallOptions(),
intentsClient: dialogflowpb.NewIntentsClient(conn),
}
c.setGoogleClientInfo()
c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn))
if err != nil {
// This error "should not happen", since we are just reusing old connection
// and never actually need to dial.
// If this does happen, we could leak conn. However, we cannot close conn:
// If the user invoked the function with option.WithGRPCConn,
// we would close a connection that's still in use.
// TODO(pongad): investigate error conditions.
return nil, err
}
return c, nil
}
// Connection returns the client's connection to the API service.
func (c *IntentsClient) Connection() *grpc.ClientConn {
return c.conn
}
// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *IntentsClient) Close() error {
return c.conn.Close()
}
// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *IntentsClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}
// ListIntents returns the list of all intents in the specified agent.
func (c *IntentsClient) ListIntents(ctx context.Context, req *dialogflowpb.ListIntentsRequest, opts ...gax.CallOption) *IntentIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListIntents[0:len(c.CallOptions.ListIntents):len(c.CallOptions.ListIntents)], opts...)
it := &IntentIterator{}
it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.Intent, string, error) {
var resp *dialogflowpb.ListIntentsResponse
req.PageToken = pageToken
if pageSize > math.MaxInt32 {
req.PageSize = math.MaxInt32
} else {
req.PageSize = int32(pageSize)
}
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.intentsClient.ListIntents(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, "", err
}
return resp.Intents, resp.NextPageToken, nil
}
fetch := func(pageSize int, pageToken string) (string, error) {
items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
if err != nil {
return "", err
}
it.items = append(it.items, items...)
return nextPageToken, nil
}
it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
return it
}
// GetIntent retrieves the specified intent.
func (c *IntentsClient) GetIntent(ctx context.Context, req *dialogflowpb.GetIntentRequest, opts ...gax.CallOption) (*dialogflowpb.Intent, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetIntent[0:len(c.CallOptions.GetIntent):len(c.CallOptions.GetIntent)], opts...)
var resp *dialogflowpb.Intent
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.intentsClient.GetIntent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// CreateIntent creates an intent in the specified agent.
func (c *IntentsClient) CreateIntent(ctx context.Context, req *dialogflowpb.CreateIntentRequest, opts ...gax.CallOption) (*dialogflowpb.Intent, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateIntent[0:len(c.CallOptions.CreateIntent):len(c.CallOptions.CreateIntent)], opts...)
var resp *dialogflowpb.Intent
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.intentsClient.CreateIntent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// UpdateIntent updates the specified intent.
func (c *IntentsClient) UpdateIntent(ctx context.Context, req *dialogflowpb.UpdateIntentRequest, opts ...gax.CallOption) (*dialogflowpb.Intent, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.UpdateIntent[0:len(c.CallOptions.UpdateIntent):len(c.CallOptions.UpdateIntent)], opts...)
var resp *dialogflowpb.Intent
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.intentsClient.UpdateIntent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeleteIntent deletes the specified intent.
func (c *IntentsClient) DeleteIntent(ctx context.Context, req *dialogflowpb.DeleteIntentRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteIntent[0:len(c.CallOptions.DeleteIntent):len(c.CallOptions.DeleteIntent)], opts...)
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
_, err = c.intentsClient.DeleteIntent(ctx, req, settings.GRPC...)
return err
}, opts...)
return err
}
// BatchUpdateIntents updates/Creates multiple intents in the specified agent.
//
// Operation <response: [BatchUpdateIntentsResponse][google.cloud.dialogflow.v2.BatchUpdateIntentsResponse]>
func (c *IntentsClient) BatchUpdateIntents(ctx context.Context, req *dialogflowpb.BatchUpdateIntentsRequest, opts ...gax.CallOption) (*BatchUpdateIntentsOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.BatchUpdateIntents[0:len(c.CallOptions.BatchUpdateIntents):len(c.CallOptions.BatchUpdateIntents)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.intentsClient.BatchUpdateIntents(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &BatchUpdateIntentsOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// BatchDeleteIntents deletes intents in the specified agent.
//
// Operation <response: [google.protobuf.Empty][google.protobuf.Empty]>
func (c *IntentsClient) BatchDeleteIntents(ctx context.Context, req *dialogflowpb.BatchDeleteIntentsRequest, opts ...gax.CallOption) (*BatchDeleteIntentsOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.BatchDeleteIntents[0:len(c.CallOptions.BatchDeleteIntents):len(c.CallOptions.BatchDeleteIntents)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.intentsClient.BatchDeleteIntents(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &BatchDeleteIntentsOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// IntentIterator manages a stream of *dialogflowpb.Intent.
type IntentIterator struct {
items []*dialogflowpb.Intent
pageInfo *iterator.PageInfo
nextFunc func() error
// InternalFetch is for use by the Google Cloud Libraries only.
// It is not part of the stable interface of this package.
//
// InternalFetch returns results from a single call to the underlying RPC.
// The number of results is no greater than pageSize.
// If there are no more results, nextPageToken is empty and err is nil.
InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.Intent, nextPageToken string, err error)
}
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *IntentIterator) PageInfo() *iterator.PageInfo {
return it.pageInfo
}
// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *IntentIterator) Next() (*dialogflowpb.Intent, error) {
var item *dialogflowpb.Intent
if err := it.nextFunc(); err != nil {
return item, err
}
item = it.items[0]
it.items = it.items[1:]
return item, nil
}
func (it *IntentIterator) bufLen() int {
return len(it.items)
}
func (it *IntentIterator) takeBuf() interface{} {
b := it.items
it.items = nil
return b
}
// BatchDeleteIntentsOperation manages a long-running operation from BatchDeleteIntents.
type BatchDeleteIntentsOperation struct {
lro *longrunning.Operation
}
// BatchDeleteIntentsOperation returns a new BatchDeleteIntentsOperation from a given name.
// The name must be that of a previously created BatchDeleteIntentsOperation, possibly from a different process.
func (c *IntentsClient) BatchDeleteIntentsOperation(name string) *BatchDeleteIntentsOperation {
return &BatchDeleteIntentsOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *BatchDeleteIntentsOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.WaitWithInterval(ctx, nil, 5000*time.Millisecond, opts...)
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully, op.Done will return true.
func (op *BatchDeleteIntentsOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
return op.lro.Poll(ctx, nil, opts...)
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *BatchDeleteIntentsOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *BatchDeleteIntentsOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *BatchDeleteIntentsOperation) Name() string {
return op.lro.Name()
}
// BatchUpdateIntentsOperation manages a long-running operation from BatchUpdateIntents.
type BatchUpdateIntentsOperation struct {
lro *longrunning.Operation
}
// BatchUpdateIntentsOperation returns a new BatchUpdateIntentsOperation from a given name.
// The name must be that of a previously created BatchUpdateIntentsOperation, possibly from a different process.
func (c *IntentsClient) BatchUpdateIntentsOperation(name string) *BatchUpdateIntentsOperation {
return &BatchUpdateIntentsOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *BatchUpdateIntentsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.BatchUpdateIntentsResponse, error) {
var resp dialogflowpb.BatchUpdateIntentsResponse
if err := op.lro.WaitWithInterval(ctx, &resp, 5000*time.Millisecond, opts...); err != nil {
return nil, err
}
return &resp, nil
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully,
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *BatchUpdateIntentsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dialogflowpb.BatchUpdateIntentsResponse, error) {
var resp dialogflowpb.BatchUpdateIntentsResponse
if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
return nil, err
}
if !op.Done() {
return nil, nil
}
return &resp, nil
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *BatchUpdateIntentsOperation) Metadata() (*structpbpb.Struct, error) {
var meta structpbpb.Struct
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *BatchUpdateIntentsOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *BatchUpdateIntentsOperation) Name() string {
return op.lro.Name()
}

View File

@ -14,17 +14,18 @@
// AUTO-GENERATED CODE. DO NOT EDIT.
package dlp_test
package dialogflow_test
import (
"cloud.google.com/go/dlp/apiv2beta1"
"cloud.google.com/go/dialogflow/apiv2"
"golang.org/x/net/context"
dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2beta1"
"google.golang.org/api/iterator"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
)
func ExampleNewClient() {
func ExampleNewIntentsClient() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := dialogflow.NewIntentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
@ -32,17 +33,41 @@ func ExampleNewClient() {
_ = c
}
func ExampleClient_InspectContent() {
func ExampleIntentsClient_ListIntents() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := dialogflow.NewIntentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.InspectContentRequest{
req := &dialogflowpb.ListIntentsRequest{
// TODO: Fill request struct fields.
}
resp, err := c.InspectContent(ctx, req)
it := c.ListIntents(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
}
func ExampleIntentsClient_GetIntent() {
ctx := context.Background()
c, err := dialogflow.NewIntentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.GetIntentRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetIntent(ctx, req)
if err != nil {
// TODO: Handle error.
}
@ -50,17 +75,17 @@ func ExampleClient_InspectContent() {
_ = resp
}
func ExampleClient_RedactContent() {
func ExampleIntentsClient_CreateIntent() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := dialogflow.NewIntentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.RedactContentRequest{
req := &dialogflowpb.CreateIntentRequest{
// TODO: Fill request struct fields.
}
resp, err := c.RedactContent(ctx, req)
resp, err := c.CreateIntent(ctx, req)
if err != nil {
// TODO: Handle error.
}
@ -68,17 +93,17 @@ func ExampleClient_RedactContent() {
_ = resp
}
func ExampleClient_DeidentifyContent() {
func ExampleIntentsClient_UpdateIntent() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := dialogflow.NewIntentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.DeidentifyContentRequest{
req := &dialogflowpb.UpdateIntentRequest{
// TODO: Fill request struct fields.
}
resp, err := c.DeidentifyContent(ctx, req)
resp, err := c.UpdateIntent(ctx, req)
if err != nil {
// TODO: Handle error.
}
@ -86,17 +111,33 @@ func ExampleClient_DeidentifyContent() {
_ = resp
}
func ExampleClient_AnalyzeDataSourceRisk() {
func ExampleIntentsClient_DeleteIntent() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := dialogflow.NewIntentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.AnalyzeDataSourceRiskRequest{
req := &dialogflowpb.DeleteIntentRequest{
// TODO: Fill request struct fields.
}
op, err := c.AnalyzeDataSourceRisk(ctx, req)
err = c.DeleteIntent(ctx, req)
if err != nil {
// TODO: Handle error.
}
}
func ExampleIntentsClient_BatchUpdateIntents() {
ctx := context.Background()
c, err := dialogflow.NewIntentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.BatchUpdateIntentsRequest{
// TODO: Fill request struct fields.
}
op, err := c.BatchUpdateIntents(ctx, req)
if err != nil {
// TODO: Handle error.
}
@ -109,79 +150,21 @@ func ExampleClient_AnalyzeDataSourceRisk() {
_ = resp
}
func ExampleClient_CreateInspectOperation() {
func ExampleIntentsClient_BatchDeleteIntents() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
c, err := dialogflow.NewIntentsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.CreateInspectOperationRequest{
req := &dialogflowpb.BatchDeleteIntentsRequest{
// TODO: Fill request struct fields.
}
op, err := c.CreateInspectOperation(ctx, req)
op, err := c.BatchDeleteIntents(ctx, req)
if err != nil {
// TODO: Handle error.
}
resp, err := op.Wait(ctx)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_ListInspectFindings() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.ListInspectFindingsRequest{
// TODO: Fill request struct fields.
}
resp, err := c.ListInspectFindings(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_ListInfoTypes() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.ListInfoTypesRequest{
// TODO: Fill request struct fields.
}
resp, err := c.ListInfoTypes(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_ListRootCategories() {
ctx := context.Background()
c, err := dlp.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dlppb.ListRootCategoriesRequest{
// TODO: Fill request struct fields.
}
resp, err := c.ListRootCategories(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
err = op.Wait(ctx)
// TODO: Handle error.
}

3149
vendor/cloud.google.com/go/dialogflow/apiv2/mock_test.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,274 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow
import (
"math"
"time"
"cloud.google.com/go/internal/version"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/api/transport"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
)
// SessionEntityTypesCallOptions contains the retry settings for each method of SessionEntityTypesClient.
type SessionEntityTypesCallOptions struct {
ListSessionEntityTypes []gax.CallOption
GetSessionEntityType []gax.CallOption
CreateSessionEntityType []gax.CallOption
UpdateSessionEntityType []gax.CallOption
DeleteSessionEntityType []gax.CallOption
}
func defaultSessionEntityTypesClientOptions() []option.ClientOption {
return []option.ClientOption{
option.WithEndpoint("dialogflow.googleapis.com:443"),
option.WithScopes(DefaultAuthScopes()...),
}
}
func defaultSessionEntityTypesCallOptions() *SessionEntityTypesCallOptions {
retry := map[[2]string][]gax.CallOption{
{"default", "idempotent"}: {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.DeadlineExceeded,
codes.Unavailable,
}, gax.Backoff{
Initial: 100 * time.Millisecond,
Max: 60000 * time.Millisecond,
Multiplier: 1.3,
})
}),
},
}
return &SessionEntityTypesCallOptions{
ListSessionEntityTypes: retry[[2]string{"default", "idempotent"}],
GetSessionEntityType: retry[[2]string{"default", "idempotent"}],
CreateSessionEntityType: retry[[2]string{"default", "non_idempotent"}],
UpdateSessionEntityType: retry[[2]string{"default", "non_idempotent"}],
DeleteSessionEntityType: retry[[2]string{"default", "idempotent"}],
}
}
// SessionEntityTypesClient is a client for interacting with Dialogflow API.
type SessionEntityTypesClient struct {
// The connection to the service.
conn *grpc.ClientConn
// The gRPC API client.
sessionEntityTypesClient dialogflowpb.SessionEntityTypesClient
// The call options for this service.
CallOptions *SessionEntityTypesCallOptions
// The x-goog-* metadata to be sent with each request.
xGoogMetadata metadata.MD
}
// NewSessionEntityTypesClient creates a new session entity types client.
//
// Entities are extracted from user input and represent parameters that are
// meaningful to your application. For example, a date range, a proper name
// such as a geographic location or landmark, and so on. Entities represent
// actionable data for your application.
//
// Session entity types are referred to as **User** entity types and are
// entities that are built for an individual user such as
// favorites, preferences, playlists, and so on. You can redefine a session
// entity type at the session level.
//
// For more information about entity types, see the
// [Dialogflow documentation](https://dialogflow.com/docs/entities).
func NewSessionEntityTypesClient(ctx context.Context, opts ...option.ClientOption) (*SessionEntityTypesClient, error) {
conn, err := transport.DialGRPC(ctx, append(defaultSessionEntityTypesClientOptions(), opts...)...)
if err != nil {
return nil, err
}
c := &SessionEntityTypesClient{
conn: conn,
CallOptions: defaultSessionEntityTypesCallOptions(),
sessionEntityTypesClient: dialogflowpb.NewSessionEntityTypesClient(conn),
}
c.setGoogleClientInfo()
return c, nil
}
// Connection returns the client's connection to the API service.
func (c *SessionEntityTypesClient) Connection() *grpc.ClientConn {
return c.conn
}
// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *SessionEntityTypesClient) Close() error {
return c.conn.Close()
}
// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *SessionEntityTypesClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}
// ListSessionEntityTypes returns the list of all session entity types in the specified session.
func (c *SessionEntityTypesClient) ListSessionEntityTypes(ctx context.Context, req *dialogflowpb.ListSessionEntityTypesRequest, opts ...gax.CallOption) *SessionEntityTypeIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListSessionEntityTypes[0:len(c.CallOptions.ListSessionEntityTypes):len(c.CallOptions.ListSessionEntityTypes)], opts...)
it := &SessionEntityTypeIterator{}
it.InternalFetch = func(pageSize int, pageToken string) ([]*dialogflowpb.SessionEntityType, string, error) {
var resp *dialogflowpb.ListSessionEntityTypesResponse
req.PageToken = pageToken
if pageSize > math.MaxInt32 {
req.PageSize = math.MaxInt32
} else {
req.PageSize = int32(pageSize)
}
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.sessionEntityTypesClient.ListSessionEntityTypes(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, "", err
}
return resp.SessionEntityTypes, resp.NextPageToken, nil
}
fetch := func(pageSize int, pageToken string) (string, error) {
items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
if err != nil {
return "", err
}
it.items = append(it.items, items...)
return nextPageToken, nil
}
it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
return it
}
// GetSessionEntityType retrieves the specified session entity type.
func (c *SessionEntityTypesClient) GetSessionEntityType(ctx context.Context, req *dialogflowpb.GetSessionEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.SessionEntityType, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetSessionEntityType[0:len(c.CallOptions.GetSessionEntityType):len(c.CallOptions.GetSessionEntityType)], opts...)
var resp *dialogflowpb.SessionEntityType
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.sessionEntityTypesClient.GetSessionEntityType(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// CreateSessionEntityType creates a session entity type.
func (c *SessionEntityTypesClient) CreateSessionEntityType(ctx context.Context, req *dialogflowpb.CreateSessionEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.SessionEntityType, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateSessionEntityType[0:len(c.CallOptions.CreateSessionEntityType):len(c.CallOptions.CreateSessionEntityType)], opts...)
var resp *dialogflowpb.SessionEntityType
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.sessionEntityTypesClient.CreateSessionEntityType(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// UpdateSessionEntityType updates the specified session entity type.
func (c *SessionEntityTypesClient) UpdateSessionEntityType(ctx context.Context, req *dialogflowpb.UpdateSessionEntityTypeRequest, opts ...gax.CallOption) (*dialogflowpb.SessionEntityType, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.UpdateSessionEntityType[0:len(c.CallOptions.UpdateSessionEntityType):len(c.CallOptions.UpdateSessionEntityType)], opts...)
var resp *dialogflowpb.SessionEntityType
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.sessionEntityTypesClient.UpdateSessionEntityType(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeleteSessionEntityType deletes the specified session entity type.
func (c *SessionEntityTypesClient) DeleteSessionEntityType(ctx context.Context, req *dialogflowpb.DeleteSessionEntityTypeRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteSessionEntityType[0:len(c.CallOptions.DeleteSessionEntityType):len(c.CallOptions.DeleteSessionEntityType)], opts...)
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
_, err = c.sessionEntityTypesClient.DeleteSessionEntityType(ctx, req, settings.GRPC...)
return err
}, opts...)
return err
}
// SessionEntityTypeIterator manages a stream of *dialogflowpb.SessionEntityType.
type SessionEntityTypeIterator struct {
items []*dialogflowpb.SessionEntityType
pageInfo *iterator.PageInfo
nextFunc func() error
// InternalFetch is for use by the Google Cloud Libraries only.
// It is not part of the stable interface of this package.
//
// InternalFetch returns results from a single call to the underlying RPC.
// The number of results is no greater than pageSize.
// If there are no more results, nextPageToken is empty and err is nil.
InternalFetch func(pageSize int, pageToken string) (results []*dialogflowpb.SessionEntityType, nextPageToken string, err error)
}
// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *SessionEntityTypeIterator) PageInfo() *iterator.PageInfo {
return it.pageInfo
}
// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *SessionEntityTypeIterator) Next() (*dialogflowpb.SessionEntityType, error) {
var item *dialogflowpb.SessionEntityType
if err := it.nextFunc(); err != nil {
return item, err
}
item = it.items[0]
it.items = it.items[1:]
return item, nil
}
func (it *SessionEntityTypeIterator) bufLen() int {
return len(it.items)
}
func (it *SessionEntityTypeIterator) takeBuf() interface{} {
b := it.items
it.items = nil
return b
}

View File

@ -0,0 +1,128 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow_test
import (
"cloud.google.com/go/dialogflow/apiv2"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
)
func ExampleNewSessionEntityTypesClient() {
ctx := context.Background()
c, err := dialogflow.NewSessionEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
// TODO: Use client.
_ = c
}
func ExampleSessionEntityTypesClient_ListSessionEntityTypes() {
ctx := context.Background()
c, err := dialogflow.NewSessionEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.ListSessionEntityTypesRequest{
// TODO: Fill request struct fields.
}
it := c.ListSessionEntityTypes(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
}
func ExampleSessionEntityTypesClient_GetSessionEntityType() {
ctx := context.Background()
c, err := dialogflow.NewSessionEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.GetSessionEntityTypeRequest{
// TODO: Fill request struct fields.
}
resp, err := c.GetSessionEntityType(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleSessionEntityTypesClient_CreateSessionEntityType() {
ctx := context.Background()
c, err := dialogflow.NewSessionEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.CreateSessionEntityTypeRequest{
// TODO: Fill request struct fields.
}
resp, err := c.CreateSessionEntityType(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleSessionEntityTypesClient_UpdateSessionEntityType() {
ctx := context.Background()
c, err := dialogflow.NewSessionEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.UpdateSessionEntityTypeRequest{
// TODO: Fill request struct fields.
}
resp, err := c.UpdateSessionEntityType(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleSessionEntityTypesClient_DeleteSessionEntityType() {
ctx := context.Background()
c, err := dialogflow.NewSessionEntityTypesClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.DeleteSessionEntityTypeRequest{
// TODO: Fill request struct fields.
}
err = c.DeleteSessionEntityType(ctx, req)
if err != nil {
// TODO: Handle error.
}
}

View File

@ -0,0 +1,142 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow
import (
"cloud.google.com/go/internal/version"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/option"
"google.golang.org/api/transport"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)
// SessionsCallOptions contains the retry settings for each method of SessionsClient.
type SessionsCallOptions struct {
DetectIntent []gax.CallOption
StreamingDetectIntent []gax.CallOption
}
func defaultSessionsClientOptions() []option.ClientOption {
return []option.ClientOption{
option.WithEndpoint("dialogflow.googleapis.com:443"),
option.WithScopes(DefaultAuthScopes()...),
}
}
func defaultSessionsCallOptions() *SessionsCallOptions {
retry := map[[2]string][]gax.CallOption{}
return &SessionsCallOptions{
DetectIntent: retry[[2]string{"default", "non_idempotent"}],
StreamingDetectIntent: retry[[2]string{"default", "non_idempotent"}],
}
}
// SessionsClient is a client for interacting with Dialogflow API.
type SessionsClient struct {
// The connection to the service.
conn *grpc.ClientConn
// The gRPC API client.
sessionsClient dialogflowpb.SessionsClient
// The call options for this service.
CallOptions *SessionsCallOptions
// The x-goog-* metadata to be sent with each request.
xGoogMetadata metadata.MD
}
// NewSessionsClient creates a new sessions client.
//
// A session represents an interaction with a user. You retrieve user input
// and pass it to the [DetectIntent][google.cloud.dialogflow.v2.Sessions.DetectIntent] (or
// [StreamingDetectIntent][google.cloud.dialogflow.v2.Sessions.StreamingDetectIntent]) method to determine
// user intent and respond.
func NewSessionsClient(ctx context.Context, opts ...option.ClientOption) (*SessionsClient, error) {
conn, err := transport.DialGRPC(ctx, append(defaultSessionsClientOptions(), opts...)...)
if err != nil {
return nil, err
}
c := &SessionsClient{
conn: conn,
CallOptions: defaultSessionsCallOptions(),
sessionsClient: dialogflowpb.NewSessionsClient(conn),
}
c.setGoogleClientInfo()
return c, nil
}
// Connection returns the client's connection to the API service.
func (c *SessionsClient) Connection() *grpc.ClientConn {
return c.conn
}
// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *SessionsClient) Close() error {
return c.conn.Close()
}
// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *SessionsClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}
// DetectIntent processes a natural language query and returns structured, actionable data
// as a result. This method is not idempotent, because it may cause contexts
// and session entity types to be updated, which in turn might affect
// results of future queries.
func (c *SessionsClient) DetectIntent(ctx context.Context, req *dialogflowpb.DetectIntentRequest, opts ...gax.CallOption) (*dialogflowpb.DetectIntentResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DetectIntent[0:len(c.CallOptions.DetectIntent):len(c.CallOptions.DetectIntent)], opts...)
var resp *dialogflowpb.DetectIntentResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.sessionsClient.DetectIntent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// StreamingDetectIntent processes a natural language query in audio format in a streaming fashion
// and returns structured, actionable data as a result. This method is only
// available via the gRPC API (not REST).
func (c *SessionsClient) StreamingDetectIntent(ctx context.Context, opts ...gax.CallOption) (dialogflowpb.Sessions_StreamingDetectIntentClient, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.StreamingDetectIntent[0:len(c.CallOptions.StreamingDetectIntent):len(c.CallOptions.StreamingDetectIntent)], opts...)
var resp dialogflowpb.Sessions_StreamingDetectIntentClient
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.sessionsClient.StreamingDetectIntent(ctx, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}

View File

@ -0,0 +1,87 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dialogflow_test
import (
"io"
"cloud.google.com/go/dialogflow/apiv2"
"golang.org/x/net/context"
dialogflowpb "google.golang.org/genproto/googleapis/cloud/dialogflow/v2"
)
func ExampleNewSessionsClient() {
ctx := context.Background()
c, err := dialogflow.NewSessionsClient(ctx)
if err != nil {
// TODO: Handle error.
}
// TODO: Use client.
_ = c
}
func ExampleSessionsClient_DetectIntent() {
ctx := context.Background()
c, err := dialogflow.NewSessionsClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &dialogflowpb.DetectIntentRequest{
// TODO: Fill request struct fields.
}
resp, err := c.DetectIntent(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleSessionsClient_StreamingDetectIntent() {
ctx := context.Background()
c, err := dialogflow.NewSessionsClient(ctx)
if err != nil {
// TODO: Handle error.
}
stream, err := c.StreamingDetectIntent(ctx)
if err != nil {
// TODO: Handle error.
}
go func() {
reqs := []*dialogflowpb.StreamingDetectIntentRequest{
// TODO: Create requests.
}
for _, req := range reqs {
if err := stream.Send(req); err != nil {
// TODO: Handle error.
}
}
stream.CloseSend()
}()
for {
resp, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
// TODO: handle error.
}
// TODO: Use resp.
_ = resp
}
}

View File

@ -259,7 +259,7 @@ func (c *Client) ListInfoTypes(ctx context.Context, req *dlppb.ListInfoTypesRequ
return resp, nil
}
// CreateInspectTemplate creates an inspect template for re-using frequently used configuration
// CreateInspectTemplate creates an InspectTemplate for re-using frequently used configuration
// for inspecting content, images, and storage.
func (c *Client) CreateInspectTemplate(ctx context.Context, req *dlppb.CreateInspectTemplateRequest, opts ...gax.CallOption) (*dlppb.InspectTemplate, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
@ -276,7 +276,7 @@ func (c *Client) CreateInspectTemplate(ctx context.Context, req *dlppb.CreateIns
return resp, nil
}
// UpdateInspectTemplate updates the inspect template.
// UpdateInspectTemplate updates the InspectTemplate.
func (c *Client) UpdateInspectTemplate(ctx context.Context, req *dlppb.UpdateInspectTemplateRequest, opts ...gax.CallOption) (*dlppb.InspectTemplate, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.UpdateInspectTemplate[0:len(c.CallOptions.UpdateInspectTemplate):len(c.CallOptions.UpdateInspectTemplate)], opts...)
@ -292,7 +292,7 @@ func (c *Client) UpdateInspectTemplate(ctx context.Context, req *dlppb.UpdateIns
return resp, nil
}
// GetInspectTemplate gets an inspect template.
// GetInspectTemplate gets an InspectTemplate.
func (c *Client) GetInspectTemplate(ctx context.Context, req *dlppb.GetInspectTemplateRequest, opts ...gax.CallOption) (*dlppb.InspectTemplate, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetInspectTemplate[0:len(c.CallOptions.GetInspectTemplate):len(c.CallOptions.GetInspectTemplate)], opts...)
@ -308,7 +308,7 @@ func (c *Client) GetInspectTemplate(ctx context.Context, req *dlppb.GetInspectTe
return resp, nil
}
// ListInspectTemplates lists inspect templates.
// ListInspectTemplates lists InspectTemplates.
func (c *Client) ListInspectTemplates(ctx context.Context, req *dlppb.ListInspectTemplatesRequest, opts ...gax.CallOption) *InspectTemplateIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListInspectTemplates[0:len(c.CallOptions.ListInspectTemplates):len(c.CallOptions.ListInspectTemplates)], opts...)
@ -343,7 +343,7 @@ func (c *Client) ListInspectTemplates(ctx context.Context, req *dlppb.ListInspec
return it
}
// DeleteInspectTemplate deletes an inspect template.
// DeleteInspectTemplate deletes an InspectTemplate.
func (c *Client) DeleteInspectTemplate(ctx context.Context, req *dlppb.DeleteInspectTemplateRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteInspectTemplate[0:len(c.CallOptions.DeleteInspectTemplate):len(c.CallOptions.DeleteInspectTemplate)], opts...)
@ -355,8 +355,8 @@ func (c *Client) DeleteInspectTemplate(ctx context.Context, req *dlppb.DeleteIns
return err
}
// CreateDeidentifyTemplate creates a de-identify template for re-using frequently used configuration
// for Deidentifying content, images, and storage.
// CreateDeidentifyTemplate creates a DeidentifyTemplate for re-using frequently used configuration
// for de-identifying content, images, and storage.
func (c *Client) CreateDeidentifyTemplate(ctx context.Context, req *dlppb.CreateDeidentifyTemplateRequest, opts ...gax.CallOption) (*dlppb.DeidentifyTemplate, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateDeidentifyTemplate[0:len(c.CallOptions.CreateDeidentifyTemplate):len(c.CallOptions.CreateDeidentifyTemplate)], opts...)
@ -372,7 +372,7 @@ func (c *Client) CreateDeidentifyTemplate(ctx context.Context, req *dlppb.Create
return resp, nil
}
// UpdateDeidentifyTemplate updates the de-identify template.
// UpdateDeidentifyTemplate updates the DeidentifyTemplate.
func (c *Client) UpdateDeidentifyTemplate(ctx context.Context, req *dlppb.UpdateDeidentifyTemplateRequest, opts ...gax.CallOption) (*dlppb.DeidentifyTemplate, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.UpdateDeidentifyTemplate[0:len(c.CallOptions.UpdateDeidentifyTemplate):len(c.CallOptions.UpdateDeidentifyTemplate)], opts...)
@ -388,7 +388,7 @@ func (c *Client) UpdateDeidentifyTemplate(ctx context.Context, req *dlppb.Update
return resp, nil
}
// GetDeidentifyTemplate gets a de-identify template.
// GetDeidentifyTemplate gets a DeidentifyTemplate.
func (c *Client) GetDeidentifyTemplate(ctx context.Context, req *dlppb.GetDeidentifyTemplateRequest, opts ...gax.CallOption) (*dlppb.DeidentifyTemplate, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.GetDeidentifyTemplate[0:len(c.CallOptions.GetDeidentifyTemplate):len(c.CallOptions.GetDeidentifyTemplate)], opts...)
@ -404,7 +404,7 @@ func (c *Client) GetDeidentifyTemplate(ctx context.Context, req *dlppb.GetDeiden
return resp, nil
}
// ListDeidentifyTemplates lists de-identify templates.
// ListDeidentifyTemplates lists DeidentifyTemplates.
func (c *Client) ListDeidentifyTemplates(ctx context.Context, req *dlppb.ListDeidentifyTemplatesRequest, opts ...gax.CallOption) *DeidentifyTemplateIterator {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListDeidentifyTemplates[0:len(c.CallOptions.ListDeidentifyTemplates):len(c.CallOptions.ListDeidentifyTemplates)], opts...)
@ -439,7 +439,7 @@ func (c *Client) ListDeidentifyTemplates(ctx context.Context, req *dlppb.ListDei
return it
}
// DeleteDeidentifyTemplate deletes a de-identify template.
// DeleteDeidentifyTemplate deletes a DeidentifyTemplate.
func (c *Client) DeleteDeidentifyTemplate(ctx context.Context, req *dlppb.DeleteDeidentifyTemplateRequest, opts ...gax.CallOption) error {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeleteDeidentifyTemplate[0:len(c.CallOptions.DeleteDeidentifyTemplate):len(c.CallOptions.DeleteDeidentifyTemplate)], opts...)
@ -451,8 +451,8 @@ func (c *Client) DeleteDeidentifyTemplate(ctx context.Context, req *dlppb.Delete
return err
}
// CreateDlpJob creates a new job to inspect storage or calculate risk metrics How-to
// guide (at /dlp/docs/compute-risk-analysis).
// CreateDlpJob creates a new job to inspect storage or calculate risk metrics.
// How-to guide (at /dlp/docs/compute-risk-analysis).
func (c *Client) CreateDlpJob(ctx context.Context, req *dlppb.CreateDlpJobRequest, opts ...gax.CallOption) (*dlppb.DlpJob, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateDlpJob[0:len(c.CallOptions.CreateDlpJob):len(c.CallOptions.CreateDlpJob)], opts...)

View File

@ -19,8 +19,9 @@
//
// NOTE: This package is in alpha. It is not stable, and is likely to change.
//
// Provides methods for detection of privacy-sensitive fragments in text,
// images, and Google Cloud Platform storage repositories.
// Provides methods for detection, risk analysis, and de-identification of
// privacy-sensitive fragments in text, images, and Google Cloud Platform
// storage repositories.
package dlp // import "cloud.google.com/go/dlp/apiv2"
import (

View File

@ -1,429 +0,0 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dlp
import (
"time"
"cloud.google.com/go/internal/version"
"cloud.google.com/go/longrunning"
lroauto "cloud.google.com/go/longrunning/autogen"
gax "github.com/googleapis/gax-go"
"golang.org/x/net/context"
"google.golang.org/api/option"
"google.golang.org/api/transport"
longrunningpb "google.golang.org/genproto/googleapis/longrunning"
dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2beta1"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
)
// CallOptions contains the retry settings for each method of Client.
type CallOptions struct {
InspectContent []gax.CallOption
RedactContent []gax.CallOption
DeidentifyContent []gax.CallOption
AnalyzeDataSourceRisk []gax.CallOption
CreateInspectOperation []gax.CallOption
ListInspectFindings []gax.CallOption
ListInfoTypes []gax.CallOption
ListRootCategories []gax.CallOption
}
func defaultClientOptions() []option.ClientOption {
return []option.ClientOption{
option.WithEndpoint("dlp.googleapis.com:443"),
option.WithScopes(DefaultAuthScopes()...),
}
}
func defaultCallOptions() *CallOptions {
retry := map[[2]string][]gax.CallOption{
{"default", "idempotent"}: {
gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{
codes.DeadlineExceeded,
codes.Unavailable,
}, gax.Backoff{
Initial: 100 * time.Millisecond,
Max: 60000 * time.Millisecond,
Multiplier: 1.3,
})
}),
},
}
return &CallOptions{
InspectContent: retry[[2]string{"default", "non_idempotent"}],
RedactContent: retry[[2]string{"default", "non_idempotent"}],
DeidentifyContent: retry[[2]string{"default", "idempotent"}],
AnalyzeDataSourceRisk: retry[[2]string{"default", "idempotent"}],
CreateInspectOperation: retry[[2]string{"default", "non_idempotent"}],
ListInspectFindings: retry[[2]string{"default", "idempotent"}],
ListInfoTypes: retry[[2]string{"default", "idempotent"}],
ListRootCategories: retry[[2]string{"default", "idempotent"}],
}
}
// Client is a client for interacting with DLP API.
type Client struct {
// The connection to the service.
conn *grpc.ClientConn
// The gRPC API client.
client dlppb.DlpServiceClient
// LROClient is used internally to handle longrunning operations.
// It is exposed so that its CallOptions can be modified if required.
// Users should not Close this client.
LROClient *lroauto.OperationsClient
// The call options for this service.
CallOptions *CallOptions
// The x-goog-* metadata to be sent with each request.
xGoogMetadata metadata.MD
}
// NewClient creates a new dlp service client.
//
// The DLP API is a service that allows clients
// to detect the presence of Personally Identifiable Information (PII) and other
// privacy-sensitive data in user-supplied, unstructured data streams, like text
// blocks or images.
// The service also includes methods for sensitive data redaction and
// scheduling of data scans on Google Cloud Platform based data sets.
func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
conn, err := transport.DialGRPC(ctx, append(defaultClientOptions(), opts...)...)
if err != nil {
return nil, err
}
c := &Client{
conn: conn,
CallOptions: defaultCallOptions(),
client: dlppb.NewDlpServiceClient(conn),
}
c.setGoogleClientInfo()
c.LROClient, err = lroauto.NewOperationsClient(ctx, option.WithGRPCConn(conn))
if err != nil {
// This error "should not happen", since we are just reusing old connection
// and never actually need to dial.
// If this does happen, we could leak conn. However, we cannot close conn:
// If the user invoked the function with option.WithGRPCConn,
// we would close a connection that's still in use.
// TODO(pongad): investigate error conditions.
return nil, err
}
return c, nil
}
// Connection returns the client's connection to the API service.
func (c *Client) Connection() *grpc.ClientConn {
return c.conn
}
// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *Client) Close() error {
return c.conn.Close()
}
// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *Client) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}
// InspectContent finds potentially sensitive info in a list of strings.
// This method has limits on input size, processing time, and output size.
func (c *Client) InspectContent(ctx context.Context, req *dlppb.InspectContentRequest, opts ...gax.CallOption) (*dlppb.InspectContentResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.InspectContent[0:len(c.CallOptions.InspectContent):len(c.CallOptions.InspectContent)], opts...)
var resp *dlppb.InspectContentResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.InspectContent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// RedactContent redacts potentially sensitive info from a list of strings.
// This method has limits on input size, processing time, and output size.
func (c *Client) RedactContent(ctx context.Context, req *dlppb.RedactContentRequest, opts ...gax.CallOption) (*dlppb.RedactContentResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.RedactContent[0:len(c.CallOptions.RedactContent):len(c.CallOptions.RedactContent)], opts...)
var resp *dlppb.RedactContentResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.RedactContent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// DeidentifyContent de-identifies potentially sensitive info from a list of strings.
// This method has limits on input size and output size.
func (c *Client) DeidentifyContent(ctx context.Context, req *dlppb.DeidentifyContentRequest, opts ...gax.CallOption) (*dlppb.DeidentifyContentResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.DeidentifyContent[0:len(c.CallOptions.DeidentifyContent):len(c.CallOptions.DeidentifyContent)], opts...)
var resp *dlppb.DeidentifyContentResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.DeidentifyContent(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// AnalyzeDataSourceRisk schedules a job to compute risk analysis metrics over content in a Google
// Cloud Platform repository.
func (c *Client) AnalyzeDataSourceRisk(ctx context.Context, req *dlppb.AnalyzeDataSourceRiskRequest, opts ...gax.CallOption) (*AnalyzeDataSourceRiskOperation, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.AnalyzeDataSourceRisk[0:len(c.CallOptions.AnalyzeDataSourceRisk):len(c.CallOptions.AnalyzeDataSourceRisk)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.AnalyzeDataSourceRisk(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &AnalyzeDataSourceRiskOperation{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// CreateInspectOperation schedules a job scanning content in a Google Cloud Platform data
// repository.
func (c *Client) CreateInspectOperation(ctx context.Context, req *dlppb.CreateInspectOperationRequest, opts ...gax.CallOption) (*CreateInspectOperationHandle, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.CreateInspectOperation[0:len(c.CallOptions.CreateInspectOperation):len(c.CallOptions.CreateInspectOperation)], opts...)
var resp *longrunningpb.Operation
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.CreateInspectOperation(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return &CreateInspectOperationHandle{
lro: longrunning.InternalNewOperation(c.LROClient, resp),
}, nil
}
// ListInspectFindings returns list of results for given inspect operation result set id.
func (c *Client) ListInspectFindings(ctx context.Context, req *dlppb.ListInspectFindingsRequest, opts ...gax.CallOption) (*dlppb.ListInspectFindingsResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListInspectFindings[0:len(c.CallOptions.ListInspectFindings):len(c.CallOptions.ListInspectFindings)], opts...)
var resp *dlppb.ListInspectFindingsResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.ListInspectFindings(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// ListInfoTypes returns sensitive information types for given category.
func (c *Client) ListInfoTypes(ctx context.Context, req *dlppb.ListInfoTypesRequest, opts ...gax.CallOption) (*dlppb.ListInfoTypesResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListInfoTypes[0:len(c.CallOptions.ListInfoTypes):len(c.CallOptions.ListInfoTypes)], opts...)
var resp *dlppb.ListInfoTypesResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.ListInfoTypes(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// ListRootCategories returns the list of root categories of sensitive information.
func (c *Client) ListRootCategories(ctx context.Context, req *dlppb.ListRootCategoriesRequest, opts ...gax.CallOption) (*dlppb.ListRootCategoriesResponse, error) {
ctx = insertMetadata(ctx, c.xGoogMetadata)
opts = append(c.CallOptions.ListRootCategories[0:len(c.CallOptions.ListRootCategories):len(c.CallOptions.ListRootCategories)], opts...)
var resp *dlppb.ListRootCategoriesResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.ListRootCategories(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// AnalyzeDataSourceRiskOperation manages a long-running operation from AnalyzeDataSourceRisk.
type AnalyzeDataSourceRiskOperation struct {
lro *longrunning.Operation
}
// AnalyzeDataSourceRiskOperation returns a new AnalyzeDataSourceRiskOperation from a given name.
// The name must be that of a previously created AnalyzeDataSourceRiskOperation, possibly from a different process.
func (c *Client) AnalyzeDataSourceRiskOperation(name string) *AnalyzeDataSourceRiskOperation {
return &AnalyzeDataSourceRiskOperation{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *AnalyzeDataSourceRiskOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*dlppb.RiskAnalysisOperationResult, error) {
var resp dlppb.RiskAnalysisOperationResult
if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil {
return nil, err
}
return &resp, nil
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully,
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *AnalyzeDataSourceRiskOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*dlppb.RiskAnalysisOperationResult, error) {
var resp dlppb.RiskAnalysisOperationResult
if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
return nil, err
}
if !op.Done() {
return nil, nil
}
return &resp, nil
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *AnalyzeDataSourceRiskOperation) Metadata() (*dlppb.RiskAnalysisOperationMetadata, error) {
var meta dlppb.RiskAnalysisOperationMetadata
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *AnalyzeDataSourceRiskOperation) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *AnalyzeDataSourceRiskOperation) Name() string {
return op.lro.Name()
}
// CreateInspectOperationHandle manages a long-running operation from CreateInspectOperation.
type CreateInspectOperationHandle struct {
lro *longrunning.Operation
}
// CreateInspectOperationHandle returns a new CreateInspectOperationHandle from a given name.
// The name must be that of a previously created CreateInspectOperationHandle, possibly from a different process.
func (c *Client) CreateInspectOperationHandle(name string) *CreateInspectOperationHandle {
return &CreateInspectOperationHandle{
lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
}
}
// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *CreateInspectOperationHandle) Wait(ctx context.Context, opts ...gax.CallOption) (*dlppb.InspectOperationResult, error) {
var resp dlppb.InspectOperationResult
if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, opts...); err != nil {
return nil, err
}
return &resp, nil
}
// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully,
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *CreateInspectOperationHandle) Poll(ctx context.Context, opts ...gax.CallOption) (*dlppb.InspectOperationResult, error) {
var resp dlppb.InspectOperationResult
if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
return nil, err
}
if !op.Done() {
return nil, nil
}
return &resp, nil
}
// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *CreateInspectOperationHandle) Metadata() (*dlppb.InspectOperationMetadata, error) {
var meta dlppb.InspectOperationMetadata
if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
return nil, nil
} else if err != nil {
return nil, err
}
return &meta, nil
}
// Done reports whether the long-running operation has completed.
func (op *CreateInspectOperationHandle) Done() bool {
return op.lro.Done()
}
// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *CreateInspectOperationHandle) Name() string {
return op.lro.Name()
}

View File

@ -1,844 +0,0 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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.
// AUTO-GENERATED CODE. DO NOT EDIT.
package dlp
import (
longrunningpb "google.golang.org/genproto/googleapis/longrunning"
dlppb "google.golang.org/genproto/googleapis/privacy/dlp/v2beta1"
)
import (
"flag"
"fmt"
"io"
"log"
"net"
"os"
"strings"
"testing"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"golang.org/x/net/context"
"google.golang.org/api/option"
status "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
gstatus "google.golang.org/grpc/status"
)
var _ = io.EOF
var _ = ptypes.MarshalAny
var _ status.Status
type mockDlpServer struct {
// Embed for forward compatibility.
// Tests will keep working if more methods are added
// in the future.
dlppb.DlpServiceServer
reqs []proto.Message
// If set, all calls return this error.
err error
// responses to return if err == nil
resps []proto.Message
}
func (s *mockDlpServer) InspectContent(ctx context.Context, req *dlppb.InspectContentRequest) (*dlppb.InspectContentResponse, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*dlppb.InspectContentResponse), nil
}
func (s *mockDlpServer) RedactContent(ctx context.Context, req *dlppb.RedactContentRequest) (*dlppb.RedactContentResponse, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*dlppb.RedactContentResponse), nil
}
func (s *mockDlpServer) DeidentifyContent(ctx context.Context, req *dlppb.DeidentifyContentRequest) (*dlppb.DeidentifyContentResponse, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*dlppb.DeidentifyContentResponse), nil
}
func (s *mockDlpServer) CreateInspectOperation(ctx context.Context, req *dlppb.CreateInspectOperationRequest) (*longrunningpb.Operation, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*longrunningpb.Operation), nil
}
func (s *mockDlpServer) AnalyzeDataSourceRisk(ctx context.Context, req *dlppb.AnalyzeDataSourceRiskRequest) (*longrunningpb.Operation, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*longrunningpb.Operation), nil
}
func (s *mockDlpServer) ListInspectFindings(ctx context.Context, req *dlppb.ListInspectFindingsRequest) (*dlppb.ListInspectFindingsResponse, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*dlppb.ListInspectFindingsResponse), nil
}
func (s *mockDlpServer) ListInfoTypes(ctx context.Context, req *dlppb.ListInfoTypesRequest) (*dlppb.ListInfoTypesResponse, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*dlppb.ListInfoTypesResponse), nil
}
func (s *mockDlpServer) ListRootCategories(ctx context.Context, req *dlppb.ListRootCategoriesRequest) (*dlppb.ListRootCategoriesResponse, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
}
s.reqs = append(s.reqs, req)
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*dlppb.ListRootCategoriesResponse), nil
}
// clientOpt is the option tests should use to connect to the test server.
// It is initialized by TestMain.
var clientOpt option.ClientOption
var (
mockDlp mockDlpServer
)
func TestMain(m *testing.M) {
flag.Parse()
serv := grpc.NewServer()
dlppb.RegisterDlpServiceServer(serv, &mockDlp)
lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
log.Fatal(err)
}
go serv.Serve(lis)
conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
clientOpt = option.WithGRPCConn(conn)
os.Exit(m.Run())
}
func TestDlpServiceInspectContent(t *testing.T) {
var expectedResponse *dlppb.InspectContentResponse = &dlppb.InspectContentResponse{}
mockDlp.err = nil
mockDlp.reqs = nil
mockDlp.resps = append(mockDlp.resps[:0], expectedResponse)
var name string = "EMAIL_ADDRESS"
var infoTypesElement = &dlppb.InfoType{
Name: name,
}
var infoTypes = []*dlppb.InfoType{infoTypesElement}
var inspectConfig = &dlppb.InspectConfig{
InfoTypes: infoTypes,
}
var type_ string = "text/plain"
var value string = "My email is example@example.com."
var itemsElement = &dlppb.ContentItem{
Type: type_,
DataItem: &dlppb.ContentItem_Value{
Value: value,
},
}
var items = []*dlppb.ContentItem{itemsElement}
var request = &dlppb.InspectContentRequest{
InspectConfig: inspectConfig,
Items: items,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.InspectContent(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) {
t.Errorf("wrong request %q, want %q", got, want)
}
if want, got := expectedResponse, resp; !proto.Equal(want, got) {
t.Errorf("wrong response %q, want %q)", got, want)
}
}
func TestDlpServiceInspectContentError(t *testing.T) {
errCode := codes.PermissionDenied
mockDlp.err = gstatus.Error(errCode, "test error")
var name string = "EMAIL_ADDRESS"
var infoTypesElement = &dlppb.InfoType{
Name: name,
}
var infoTypes = []*dlppb.InfoType{infoTypesElement}
var inspectConfig = &dlppb.InspectConfig{
InfoTypes: infoTypes,
}
var type_ string = "text/plain"
var value string = "My email is example@example.com."
var itemsElement = &dlppb.ContentItem{
Type: type_,
DataItem: &dlppb.ContentItem_Value{
Value: value,
},
}
var items = []*dlppb.ContentItem{itemsElement}
var request = &dlppb.InspectContentRequest{
InspectConfig: inspectConfig,
Items: items,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.InspectContent(context.Background(), request)
if st, ok := gstatus.FromError(err); !ok {
t.Errorf("got error %v, expected grpc error", err)
} else if c := st.Code(); c != errCode {
t.Errorf("got error code %q, want %q", c, errCode)
}
_ = resp
}
func TestDlpServiceRedactContent(t *testing.T) {
var expectedResponse *dlppb.RedactContentResponse = &dlppb.RedactContentResponse{}
mockDlp.err = nil
mockDlp.reqs = nil
mockDlp.resps = append(mockDlp.resps[:0], expectedResponse)
var name string = "EMAIL_ADDRESS"
var infoTypesElement = &dlppb.InfoType{
Name: name,
}
var infoTypes = []*dlppb.InfoType{infoTypesElement}
var inspectConfig = &dlppb.InspectConfig{
InfoTypes: infoTypes,
}
var type_ string = "text/plain"
var value string = "My email is example@example.com."
var itemsElement = &dlppb.ContentItem{
Type: type_,
DataItem: &dlppb.ContentItem_Value{
Value: value,
},
}
var items = []*dlppb.ContentItem{itemsElement}
var name2 string = "EMAIL_ADDRESS"
var infoType = &dlppb.InfoType{
Name: name2,
}
var replaceWith string = "REDACTED"
var replaceConfigsElement = &dlppb.RedactContentRequest_ReplaceConfig{
InfoType: infoType,
ReplaceWith: replaceWith,
}
var replaceConfigs = []*dlppb.RedactContentRequest_ReplaceConfig{replaceConfigsElement}
var request = &dlppb.RedactContentRequest{
InspectConfig: inspectConfig,
Items: items,
ReplaceConfigs: replaceConfigs,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.RedactContent(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) {
t.Errorf("wrong request %q, want %q", got, want)
}
if want, got := expectedResponse, resp; !proto.Equal(want, got) {
t.Errorf("wrong response %q, want %q)", got, want)
}
}
func TestDlpServiceRedactContentError(t *testing.T) {
errCode := codes.PermissionDenied
mockDlp.err = gstatus.Error(errCode, "test error")
var name string = "EMAIL_ADDRESS"
var infoTypesElement = &dlppb.InfoType{
Name: name,
}
var infoTypes = []*dlppb.InfoType{infoTypesElement}
var inspectConfig = &dlppb.InspectConfig{
InfoTypes: infoTypes,
}
var type_ string = "text/plain"
var value string = "My email is example@example.com."
var itemsElement = &dlppb.ContentItem{
Type: type_,
DataItem: &dlppb.ContentItem_Value{
Value: value,
},
}
var items = []*dlppb.ContentItem{itemsElement}
var name2 string = "EMAIL_ADDRESS"
var infoType = &dlppb.InfoType{
Name: name2,
}
var replaceWith string = "REDACTED"
var replaceConfigsElement = &dlppb.RedactContentRequest_ReplaceConfig{
InfoType: infoType,
ReplaceWith: replaceWith,
}
var replaceConfigs = []*dlppb.RedactContentRequest_ReplaceConfig{replaceConfigsElement}
var request = &dlppb.RedactContentRequest{
InspectConfig: inspectConfig,
Items: items,
ReplaceConfigs: replaceConfigs,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.RedactContent(context.Background(), request)
if st, ok := gstatus.FromError(err); !ok {
t.Errorf("got error %v, expected grpc error", err)
} else if c := st.Code(); c != errCode {
t.Errorf("got error code %q, want %q", c, errCode)
}
_ = resp
}
func TestDlpServiceDeidentifyContent(t *testing.T) {
var expectedResponse *dlppb.DeidentifyContentResponse = &dlppb.DeidentifyContentResponse{}
mockDlp.err = nil
mockDlp.reqs = nil
mockDlp.resps = append(mockDlp.resps[:0], expectedResponse)
var deidentifyConfig *dlppb.DeidentifyConfig = &dlppb.DeidentifyConfig{}
var inspectConfig *dlppb.InspectConfig = &dlppb.InspectConfig{}
var items []*dlppb.ContentItem = nil
var request = &dlppb.DeidentifyContentRequest{
DeidentifyConfig: deidentifyConfig,
InspectConfig: inspectConfig,
Items: items,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.DeidentifyContent(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) {
t.Errorf("wrong request %q, want %q", got, want)
}
if want, got := expectedResponse, resp; !proto.Equal(want, got) {
t.Errorf("wrong response %q, want %q)", got, want)
}
}
func TestDlpServiceDeidentifyContentError(t *testing.T) {
errCode := codes.PermissionDenied
mockDlp.err = gstatus.Error(errCode, "test error")
var deidentifyConfig *dlppb.DeidentifyConfig = &dlppb.DeidentifyConfig{}
var inspectConfig *dlppb.InspectConfig = &dlppb.InspectConfig{}
var items []*dlppb.ContentItem = nil
var request = &dlppb.DeidentifyContentRequest{
DeidentifyConfig: deidentifyConfig,
InspectConfig: inspectConfig,
Items: items,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.DeidentifyContent(context.Background(), request)
if st, ok := gstatus.FromError(err); !ok {
t.Errorf("got error %v, expected grpc error", err)
} else if c := st.Code(); c != errCode {
t.Errorf("got error code %q, want %q", c, errCode)
}
_ = resp
}
func TestDlpServiceAnalyzeDataSourceRisk(t *testing.T) {
var expectedResponse *dlppb.RiskAnalysisOperationResult = &dlppb.RiskAnalysisOperationResult{}
mockDlp.err = nil
mockDlp.reqs = nil
any, err := ptypes.MarshalAny(expectedResponse)
if err != nil {
t.Fatal(err)
}
mockDlp.resps = append(mockDlp.resps[:0], &longrunningpb.Operation{
Name: "longrunning-test",
Done: true,
Result: &longrunningpb.Operation_Response{Response: any},
})
var privacyMetric *dlppb.PrivacyMetric = &dlppb.PrivacyMetric{}
var sourceTable *dlppb.BigQueryTable = &dlppb.BigQueryTable{}
var request = &dlppb.AnalyzeDataSourceRiskRequest{
PrivacyMetric: privacyMetric,
SourceTable: sourceTable,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
respLRO, err := c.AnalyzeDataSourceRisk(context.Background(), request)
if err != nil {
t.Fatal(err)
}
resp, err := respLRO.Wait(context.Background())
if err != nil {
t.Fatal(err)
}
if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) {
t.Errorf("wrong request %q, want %q", got, want)
}
if want, got := expectedResponse, resp; !proto.Equal(want, got) {
t.Errorf("wrong response %q, want %q)", got, want)
}
}
func TestDlpServiceAnalyzeDataSourceRiskError(t *testing.T) {
errCode := codes.PermissionDenied
mockDlp.err = nil
mockDlp.resps = append(mockDlp.resps[:0], &longrunningpb.Operation{
Name: "longrunning-test",
Done: true,
Result: &longrunningpb.Operation_Error{
Error: &status.Status{
Code: int32(errCode),
Message: "test error",
},
},
})
var privacyMetric *dlppb.PrivacyMetric = &dlppb.PrivacyMetric{}
var sourceTable *dlppb.BigQueryTable = &dlppb.BigQueryTable{}
var request = &dlppb.AnalyzeDataSourceRiskRequest{
PrivacyMetric: privacyMetric,
SourceTable: sourceTable,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
respLRO, err := c.AnalyzeDataSourceRisk(context.Background(), request)
if err != nil {
t.Fatal(err)
}
resp, err := respLRO.Wait(context.Background())
if st, ok := gstatus.FromError(err); !ok {
t.Errorf("got error %v, expected grpc error", err)
} else if c := st.Code(); c != errCode {
t.Errorf("got error code %q, want %q", c, errCode)
}
_ = resp
}
func TestDlpServiceCreateInspectOperation(t *testing.T) {
var name2 string = "name2-1052831874"
var expectedResponse = &dlppb.InspectOperationResult{
Name: name2,
}
mockDlp.err = nil
mockDlp.reqs = nil
any, err := ptypes.MarshalAny(expectedResponse)
if err != nil {
t.Fatal(err)
}
mockDlp.resps = append(mockDlp.resps[:0], &longrunningpb.Operation{
Name: "longrunning-test",
Done: true,
Result: &longrunningpb.Operation_Response{Response: any},
})
var name string = "EMAIL_ADDRESS"
var infoTypesElement = &dlppb.InfoType{
Name: name,
}
var infoTypes = []*dlppb.InfoType{infoTypesElement}
var inspectConfig = &dlppb.InspectConfig{
InfoTypes: infoTypes,
}
var url string = "gs://example_bucket/example_file.png"
var fileSet = &dlppb.CloudStorageOptions_FileSet{
Url: url,
}
var cloudStorageOptions = &dlppb.CloudStorageOptions{
FileSet: fileSet,
}
var storageConfig = &dlppb.StorageConfig{
Type: &dlppb.StorageConfig_CloudStorageOptions{
CloudStorageOptions: cloudStorageOptions,
},
}
var outputConfig *dlppb.OutputStorageConfig = &dlppb.OutputStorageConfig{}
var request = &dlppb.CreateInspectOperationRequest{
InspectConfig: inspectConfig,
StorageConfig: storageConfig,
OutputConfig: outputConfig,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
respLRO, err := c.CreateInspectOperation(context.Background(), request)
if err != nil {
t.Fatal(err)
}
resp, err := respLRO.Wait(context.Background())
if err != nil {
t.Fatal(err)
}
if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) {
t.Errorf("wrong request %q, want %q", got, want)
}
if want, got := expectedResponse, resp; !proto.Equal(want, got) {
t.Errorf("wrong response %q, want %q)", got, want)
}
}
func TestDlpServiceCreateInspectOperationError(t *testing.T) {
errCode := codes.PermissionDenied
mockDlp.err = nil
mockDlp.resps = append(mockDlp.resps[:0], &longrunningpb.Operation{
Name: "longrunning-test",
Done: true,
Result: &longrunningpb.Operation_Error{
Error: &status.Status{
Code: int32(errCode),
Message: "test error",
},
},
})
var name string = "EMAIL_ADDRESS"
var infoTypesElement = &dlppb.InfoType{
Name: name,
}
var infoTypes = []*dlppb.InfoType{infoTypesElement}
var inspectConfig = &dlppb.InspectConfig{
InfoTypes: infoTypes,
}
var url string = "gs://example_bucket/example_file.png"
var fileSet = &dlppb.CloudStorageOptions_FileSet{
Url: url,
}
var cloudStorageOptions = &dlppb.CloudStorageOptions{
FileSet: fileSet,
}
var storageConfig = &dlppb.StorageConfig{
Type: &dlppb.StorageConfig_CloudStorageOptions{
CloudStorageOptions: cloudStorageOptions,
},
}
var outputConfig *dlppb.OutputStorageConfig = &dlppb.OutputStorageConfig{}
var request = &dlppb.CreateInspectOperationRequest{
InspectConfig: inspectConfig,
StorageConfig: storageConfig,
OutputConfig: outputConfig,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
respLRO, err := c.CreateInspectOperation(context.Background(), request)
if err != nil {
t.Fatal(err)
}
resp, err := respLRO.Wait(context.Background())
if st, ok := gstatus.FromError(err); !ok {
t.Errorf("got error %v, expected grpc error", err)
} else if c := st.Code(); c != errCode {
t.Errorf("got error code %q, want %q", c, errCode)
}
_ = resp
}
func TestDlpServiceListInspectFindings(t *testing.T) {
var nextPageToken string = "nextPageToken-1530815211"
var expectedResponse = &dlppb.ListInspectFindingsResponse{
NextPageToken: nextPageToken,
}
mockDlp.err = nil
mockDlp.reqs = nil
mockDlp.resps = append(mockDlp.resps[:0], expectedResponse)
var formattedName string = fmt.Sprintf("inspect/results/%s", "[RESULT]")
var request = &dlppb.ListInspectFindingsRequest{
Name: formattedName,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.ListInspectFindings(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) {
t.Errorf("wrong request %q, want %q", got, want)
}
if want, got := expectedResponse, resp; !proto.Equal(want, got) {
t.Errorf("wrong response %q, want %q)", got, want)
}
}
func TestDlpServiceListInspectFindingsError(t *testing.T) {
errCode := codes.PermissionDenied
mockDlp.err = gstatus.Error(errCode, "test error")
var formattedName string = fmt.Sprintf("inspect/results/%s", "[RESULT]")
var request = &dlppb.ListInspectFindingsRequest{
Name: formattedName,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.ListInspectFindings(context.Background(), request)
if st, ok := gstatus.FromError(err); !ok {
t.Errorf("got error %v, expected grpc error", err)
} else if c := st.Code(); c != errCode {
t.Errorf("got error code %q, want %q", c, errCode)
}
_ = resp
}
func TestDlpServiceListInfoTypes(t *testing.T) {
var expectedResponse *dlppb.ListInfoTypesResponse = &dlppb.ListInfoTypesResponse{}
mockDlp.err = nil
mockDlp.reqs = nil
mockDlp.resps = append(mockDlp.resps[:0], expectedResponse)
var category string = "PII"
var languageCode string = "en"
var request = &dlppb.ListInfoTypesRequest{
Category: category,
LanguageCode: languageCode,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.ListInfoTypes(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) {
t.Errorf("wrong request %q, want %q", got, want)
}
if want, got := expectedResponse, resp; !proto.Equal(want, got) {
t.Errorf("wrong response %q, want %q)", got, want)
}
}
func TestDlpServiceListInfoTypesError(t *testing.T) {
errCode := codes.PermissionDenied
mockDlp.err = gstatus.Error(errCode, "test error")
var category string = "PII"
var languageCode string = "en"
var request = &dlppb.ListInfoTypesRequest{
Category: category,
LanguageCode: languageCode,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.ListInfoTypes(context.Background(), request)
if st, ok := gstatus.FromError(err); !ok {
t.Errorf("got error %v, expected grpc error", err)
} else if c := st.Code(); c != errCode {
t.Errorf("got error code %q, want %q", c, errCode)
}
_ = resp
}
func TestDlpServiceListRootCategories(t *testing.T) {
var expectedResponse *dlppb.ListRootCategoriesResponse = &dlppb.ListRootCategoriesResponse{}
mockDlp.err = nil
mockDlp.reqs = nil
mockDlp.resps = append(mockDlp.resps[:0], expectedResponse)
var languageCode string = "en"
var request = &dlppb.ListRootCategoriesRequest{
LanguageCode: languageCode,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.ListRootCategories(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if want, got := request, mockDlp.reqs[0]; !proto.Equal(want, got) {
t.Errorf("wrong request %q, want %q", got, want)
}
if want, got := expectedResponse, resp; !proto.Equal(want, got) {
t.Errorf("wrong response %q, want %q)", got, want)
}
}
func TestDlpServiceListRootCategoriesError(t *testing.T) {
errCode := codes.PermissionDenied
mockDlp.err = gstatus.Error(errCode, "test error")
var languageCode string = "en"
var request = &dlppb.ListRootCategoriesRequest{
LanguageCode: languageCode,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.ListRootCategories(context.Background(), request)
if st, ok := gstatus.FromError(err); !ok {
t.Errorf("got error %v, expected grpc error", err)
} else if c := st.Code(); c != errCode {
t.Errorf("got error code %q, want %q", c, errCode)
}
_ = resp
}

View File

@ -1,27 +0,0 @@
// Copyright 2018 Google LLC
//
// 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
//
// https://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 dlp
// ResultPath returns the path for the result resource.
//
// Deprecated: Use
// fmt.Sprintf("inspect/results/%s", result)
// instead.
func ResultPath(result string) string {
return "" +
"inspect/results/" +
result +
""
}

60
vendor/cloud.google.com/go/examples_test.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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 cloud_test
import (
"time"
"cloud.google.com/go/bigquery"
"golang.org/x/net/context"
)
// To set a timeout for an RPC, use context.WithTimeout.
func Example_timeout() {
ctx := context.Background()
// Do not set a timeout on the context passed to NewClient: dialing happens
// asynchronously, and the context is used to refresh credentials in the
// background.
client, err := bigquery.NewClient(ctx, "project-id")
if err != nil {
// TODO: handle error.
}
// Time out if it takes more than 10 seconds to create a dataset.
tctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel() // Always call cancel.
if err := client.Dataset("new-dataset").Create(tctx, nil); err != nil {
// TODO: handle error.
}
}
// To arrange for an RPC to be canceled, use context.WithCancel.
func Example_cancellation() {
ctx := context.Background()
// Do not cancel the context passed to NewClient: dialing happens asynchronously,
// and the context is used to refresh credentials in the background.
client, err := bigquery.NewClient(ctx, "project-id")
if err != nil {
// TODO: handle error.
}
cctx, cancel := context.WithCancel(ctx)
defer cancel() // Always call cancel.
// TODO: Make the cancel function available to whatever might want to cancel the
// call--perhaps a GUI button.
if err := client.Dataset("new-dataset").Create(cctx, nil); err != nil {
// TODO: handle error.
}
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// A runner for the cross-language tests.
// A runner for the conformance tests.
package firestore
@ -26,21 +26,29 @@ import (
"path/filepath"
"strings"
"testing"
"time"
pb "cloud.google.com/go/firestore/genproto"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
ts "github.com/golang/protobuf/ptypes/timestamp"
"github.com/google/go-cmp/cmp"
"golang.org/x/net/context"
"google.golang.org/api/iterator"
fspb "google.golang.org/genproto/googleapis/firestore/v1beta1"
)
func TestCrossLanguageTests(t *testing.T) {
const conformanceTestWatchTargetID = 1
func TestConformanceTests(t *testing.T) {
const dir = "testdata"
fis, err := ioutil.ReadDir(dir)
if err != nil {
t.Fatal(err)
}
wtid := watchTargetID
watchTargetID = conformanceTestWatchTargetID
defer func() { watchTargetID = wtid }()
n := 0
for _, fi := range fis {
if strings.HasSuffix(fi.Name(), ".textproto") {
@ -48,7 +56,7 @@ func TestCrossLanguageTests(t *testing.T) {
n++
}
}
t.Logf("ran %d cross-language tests", n)
t.Logf("ran %d conformance tests", n)
}
func runTestFromFile(t *testing.T, filename string) {
@ -168,11 +176,78 @@ func runTest(t *testing.T, msg string, test *pb.Test) {
}
}
case *pb.Test_Listen:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
iter := c.Collection("C").OrderBy("a", Asc).Snapshots(ctx)
var rs []interface{}
for _, r := range tt.Listen.Responses {
rs = append(rs, r)
}
srv.addRPC(&fspb.ListenRequest{
Database: "projects/projectID/databases/(default)",
TargetChange: &fspb.ListenRequest_AddTarget{iter.ws.target},
}, rs)
got, err := nSnapshots(iter, len(tt.Listen.Snapshots))
if err != nil {
t.Errorf("%s: %v", msg, err)
} else if diff := cmp.Diff(got, tt.Listen.Snapshots); diff != "" {
t.Errorf("%s:\n%s", msg, diff)
}
if tt.Listen.IsError {
_, err := iter.Next()
if err == nil {
t.Errorf("%s: got nil, want error", msg)
}
}
default:
t.Fatalf("unknown test type %T", tt)
}
}
func nSnapshots(iter *QuerySnapshotIterator, n int) ([]*pb.Snapshot, error) {
var snaps []*pb.Snapshot
for i := 0; i < n; i++ {
diter, err := iter.Next()
if err != nil {
return snaps, err
}
s := &pb.Snapshot{ReadTime: mustTimestampProto(iter.ReadTime)}
for {
doc, err := diter.Next()
if err == iterator.Done {
break
}
if err != nil {
return snaps, err
}
s.Docs = append(s.Docs, doc.proto)
}
for _, c := range iter.Changes {
var k pb.DocChange_Kind
switch c.Kind {
case DocumentAdded:
k = pb.DocChange_ADDED
case DocumentRemoved:
k = pb.DocChange_REMOVED
case DocumentModified:
k = pb.DocChange_MODIFIED
default:
panic("bad kind")
}
s.Changes = append(s.Changes, &pb.DocChange{
Kind: k,
Doc: c.Doc.proto,
OldIndex: int32(c.OldIndex),
NewIndex: int32(c.NewIndex),
})
}
snaps = append(snaps, s)
}
return snaps, nil
}
func docRefFromPath(p string, c *Client) *DocumentRef {
return &DocumentRef{
Path: p,

View File

@ -21,6 +21,9 @@ database.
See https://cloud.google.com/firestore/docs for an introduction
to Cloud Firestore and additional help on using the Firestore API.
See https://godoc.org/cloud.google.com/go for authentication, timeouts,
connection pooling and similar aspects of this package.
Note: you can't use both Cloud Firestore and Cloud Datastore in the same
project.
@ -209,10 +212,5 @@ read and write methods of the Transaction passed to it.
if err != nil {
// TODO: Handle error.
}
Authentication
See examples of authorization and authentication at
https://godoc.org/cloud.google.com/go#pkg-examples.
*/
package firestore

View File

@ -96,9 +96,11 @@ func (d *DocumentRef) Get(ctx context.Context) (*DocumentSnapshot, error) {
// is the underlying type of a Integer.
// - float32 and float64 convert to Double.
// - []byte converts to Bytes.
// - time.Time converts to Timestamp.
// - latlng.LatLng converts to GeoPoint. latlng is the package
// "google.golang.org/genproto/googleapis/type/latlng".
// - time.Time and *ts.Timestamp convert to Timestamp. ts is the package
// "github.com/golang/protobuf/ptypes/timestamp".
// - *latlng.LatLng converts to GeoPoint. latlng is the package
// "google.golang.org/genproto/googleapis/type/latlng". You should always use
// a pointer to a LatLng.
// - Slices convert to Array.
// - Maps and structs convert to Map.
// - nils of any type convert to Null.
@ -182,6 +184,10 @@ func (d *DocumentRef) newSetWrites(data interface{}, opts []SetOption) ([]*pb.Wr
if v.Kind() != reflect.Map {
return nil, errors.New("firestore: MergeAll can only be specified with map data")
}
if v.Len() == 0 {
// Special case: MergeAll with an empty map.
return d.newUpdateWithTransform(&pb.Document{Name: d.Path}, []FieldPath{}, nil, nil, true), nil
}
fpvsFromData(v, nil, &fpvs)
} else {
// Set with merge paths. Collect only the values at the given paths.
@ -218,6 +224,10 @@ func fpvsFromData(v reflect.Value, prefix FieldPath, fpvs *[]fpv) {
// removePathsIf creates a new slice of FieldPaths that contains
// exactly those elements of fps for which pred returns false.
func removePathsIf(fps []FieldPath, pred func(FieldPath) bool) []FieldPath {
// Return fps if it's empty to preserve the distinction betweeen nil and zero-length.
if len(fps) == 0 {
return fps
}
var result []FieldPath
for _, fp := range fps {
if !pred(fp) {
@ -344,7 +354,7 @@ func (d *DocumentRef) newUpdateWithTransform(doc *pb.Document, updatePaths []Fie
if updateOnEmpty || len(doc.Fields) > 0 ||
len(updatePaths) > 0 || (pc != nil && len(serverTimestampPaths) == 0) {
var mask *pb.DocumentMask
if len(updatePaths) > 0 {
if updatePaths != nil {
sfps := toServiceFieldPaths(updatePaths)
sort.Strings(sfps) // TODO(jba): make tests pass without this
mask = &pb.DocumentMask{FieldPaths: sfps}

View File

@ -89,7 +89,7 @@ func TestDocGet(t *testing.T) {
}
func TestDocSet(t *testing.T) {
// Most tests for Set are in the cross-language tests.
// Most tests for Set are in the conformance tests.
ctx := context.Background()
c, srv := newMock(t)
@ -134,7 +134,7 @@ func TestDocSet(t *testing.T) {
func TestDocCreate(t *testing.T) {
// Verify creation with structs. In particular, make sure zero values
// are handled well.
// Other tests for Create are handled by the cross-language tests.
// Other tests for Create are handled by the conformance tests.
ctx := context.Background()
c, srv := newMock(t)
@ -199,7 +199,7 @@ var (
testFields = map[string]*pb.Value{"a": intval(1)}
)
// Update is tested by the cross-language tests.
// Update is tested by the conformance tests.
func TestFPVsFromData(t *testing.T) {
type S struct{ X int }

View File

@ -110,7 +110,7 @@ func (d *DocumentSnapshot) DataTo(p interface{}) error {
if !d.Exists() {
return status.Errorf(codes.NotFound, "document %s does not exist", d.Ref.Path)
}
return setFromProtoValue(p, &pb.Value{&pb.Value_MapValue{&pb.MapValue{d.proto.Fields}}}, d.c)
return setFromProtoValue(p, &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: d.proto.Fields}}}, d.c)
}
// DataAt returns the data value denoted by path.

View File

@ -161,7 +161,7 @@ func setAtPath(m map[string]*pb.Value, fp FieldPath, val *pb.Value) {
} else {
v, ok := m[fp[0]]
if !ok {
v = &pb.Value{&pb.Value_MapValue{&pb.MapValue{map[string]*pb.Value{}}}}
v = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: map[string]*pb.Value{}}}}
m[fp[0]] = v
}
// The type assertion below cannot fail, because setAtPath is only called

View File

@ -33,7 +33,7 @@ import (
var (
tm = time.Date(2016, 12, 25, 0, 0, 0, 123456789, time.UTC)
ll = &latlng.LatLng{Latitude: 20, Longitude: 30}
ptm = &ts.Timestamp{12345, 67890}
ptm = &ts.Timestamp{Seconds: 12345, Nanos: 67890}
)
func TestCreateFromProtoValue(t *testing.T) {
@ -52,7 +52,7 @@ func TestCreateFromProtoValue(t *testing.T) {
want: []byte{1, 2},
},
{
in: &pb.Value{&pb.Value_GeoPointValue{ll}},
in: &pb.Value{ValueType: &pb.Value_GeoPointValue{ll}},
want: ll,
},
{
@ -200,7 +200,7 @@ func TestSetFromProtoValueNoJSON(t *testing.T) {
}{
{&bs, bytesval(bytes), bytes},
{&tmi, tsval(tm), tm},
{&tmp, &pb.Value{&pb.Value_TimestampValue{ptm}}, ptm},
{&tmp, &pb.Value{ValueType: &pb.Value_TimestampValue{ptm}}, ptm},
{&lli, geoval(ll), ll},
} {
if err := setFromProtoValue(test.in, test.val, &Client{}); err != nil {
@ -247,7 +247,7 @@ func TestSetFromProtoValueErrors(t *testing.T) {
{new(int16), floatval(math.MaxFloat32)}, // doesn't fit
{new(uint16), floatval(math.MaxFloat32)}, // doesn't fit
{new(float32),
&pb.Value{&pb.Value_IntegerValue{math.MaxInt64}}}, // overflow
&pb.Value{ValueType: &pb.Value_IntegerValue{math.MaxInt64}}}, // overflow
} {
err := setFromProtoValue(test.in, test.val, c)
if err == nil {

View File

@ -26,15 +26,20 @@ It has these top-level messages:
Cursor
DocSnapshot
FieldPath
ListenTest
Snapshot
DocChange
*/
package tests
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_firestore_v1beta14 "google.golang.org/genproto/googleapis/firestore/v1beta1"
import google_firestore_v1beta1 "google.golang.org/genproto/googleapis/firestore/v1beta1"
import google_firestore_v1beta11 "google.golang.org/genproto/googleapis/firestore/v1beta1"
import google_firestore_v1beta14 "google.golang.org/genproto/googleapis/firestore/v1beta1"
import google_firestore_v1beta12 "google.golang.org/genproto/googleapis/firestore/v1beta1"
import google_protobuf1 "github.com/golang/protobuf/ptypes/timestamp"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@ -47,6 +52,33 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type DocChange_Kind int32
const (
DocChange_KIND_UNSPECIFIED DocChange_Kind = 0
DocChange_ADDED DocChange_Kind = 1
DocChange_REMOVED DocChange_Kind = 2
DocChange_MODIFIED DocChange_Kind = 3
)
var DocChange_Kind_name = map[int32]string{
0: "KIND_UNSPECIFIED",
1: "ADDED",
2: "REMOVED",
3: "MODIFIED",
}
var DocChange_Kind_value = map[string]int32{
"KIND_UNSPECIFIED": 0,
"ADDED": 1,
"REMOVED": 2,
"MODIFIED": 3,
}
func (x DocChange_Kind) String() string {
return proto.EnumName(DocChange_Kind_name, int32(x))
}
func (DocChange_Kind) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{19, 0} }
// A collection of tests.
type TestSuite struct {
Tests []*Test `protobuf:"bytes,1,rep,name=tests" json:"tests,omitempty"`
@ -75,6 +107,7 @@ type Test struct {
// *Test_UpdatePaths
// *Test_Delete
// *Test_Query
// *Test_Listen
Test isTest_Test `protobuf_oneof:"test"`
}
@ -108,6 +141,9 @@ type Test_Delete struct {
type Test_Query struct {
Query *QueryTest `protobuf:"bytes,8,opt,name=query,oneof"`
}
type Test_Listen struct {
Listen *ListenTest `protobuf:"bytes,9,opt,name=listen,oneof"`
}
func (*Test_Get) isTest_Test() {}
func (*Test_Create) isTest_Test() {}
@ -116,6 +152,7 @@ func (*Test_Update) isTest_Test() {}
func (*Test_UpdatePaths) isTest_Test() {}
func (*Test_Delete) isTest_Test() {}
func (*Test_Query) isTest_Test() {}
func (*Test_Listen) isTest_Test() {}
func (m *Test) GetTest() isTest_Test {
if m != nil {
@ -180,6 +217,13 @@ func (m *Test) GetQuery() *QueryTest {
return nil
}
func (m *Test) GetListen() *ListenTest {
if x, ok := m.GetTest().(*Test_Listen); ok {
return x.Listen
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*Test) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _Test_OneofMarshaler, _Test_OneofUnmarshaler, _Test_OneofSizer, []interface{}{
@ -190,6 +234,7 @@ func (*Test) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, f
(*Test_UpdatePaths)(nil),
(*Test_Delete)(nil),
(*Test_Query)(nil),
(*Test_Listen)(nil),
}
}
@ -232,6 +277,11 @@ func _Test_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
if err := b.EncodeMessage(x.Query); err != nil {
return err
}
case *Test_Listen:
b.EncodeVarint(9<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Listen); err != nil {
return err
}
case nil:
default:
return fmt.Errorf("Test.Test has unexpected type %T", x)
@ -298,6 +348,14 @@ func _Test_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (
err := b.DecodeMessage(msg)
m.Test = &Test_Query{msg}
return true, err
case 9: // test.listen
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(ListenTest)
err := b.DecodeMessage(msg)
m.Test = &Test_Listen{msg}
return true, err
default:
return false, nil
}
@ -342,6 +400,11 @@ func _Test_OneofSizer(msg proto.Message) (n int) {
n += proto.SizeVarint(8<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *Test_Listen:
s := proto.Size(x.Listen)
n += proto.SizeVarint(9<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
@ -1153,6 +1216,121 @@ func (m *FieldPath) GetField() []string {
return nil
}
// A test of the Listen streaming RPC (a.k.a. FireStore watch).
// If the sequence of responses is provided to the implementation,
// it should produce the sequence of snapshots.
// If is_error is true, an error should occur after the snapshots.
//
// The tests assume that the query is
// Collection("projects/projectID/databases/(default)/documents/C").OrderBy("a", Ascending)
//
// The watch target ID used in these tests is 1. Test interpreters
// should either change their client's ID for testing,
// or change the ID in the tests before running them.
type ListenTest struct {
Responses []*google_firestore_v1beta14.ListenResponse `protobuf:"bytes,1,rep,name=responses" json:"responses,omitempty"`
Snapshots []*Snapshot `protobuf:"bytes,2,rep,name=snapshots" json:"snapshots,omitempty"`
IsError bool `protobuf:"varint,3,opt,name=is_error,json=isError" json:"is_error,omitempty"`
}
func (m *ListenTest) Reset() { *m = ListenTest{} }
func (m *ListenTest) String() string { return proto.CompactTextString(m) }
func (*ListenTest) ProtoMessage() {}
func (*ListenTest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
func (m *ListenTest) GetResponses() []*google_firestore_v1beta14.ListenResponse {
if m != nil {
return m.Responses
}
return nil
}
func (m *ListenTest) GetSnapshots() []*Snapshot {
if m != nil {
return m.Snapshots
}
return nil
}
func (m *ListenTest) GetIsError() bool {
if m != nil {
return m.IsError
}
return false
}
type Snapshot struct {
Docs []*google_firestore_v1beta11.Document `protobuf:"bytes,1,rep,name=docs" json:"docs,omitempty"`
Changes []*DocChange `protobuf:"bytes,2,rep,name=changes" json:"changes,omitempty"`
ReadTime *google_protobuf1.Timestamp `protobuf:"bytes,3,opt,name=read_time,json=readTime" json:"read_time,omitempty"`
}
func (m *Snapshot) Reset() { *m = Snapshot{} }
func (m *Snapshot) String() string { return proto.CompactTextString(m) }
func (*Snapshot) ProtoMessage() {}
func (*Snapshot) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
func (m *Snapshot) GetDocs() []*google_firestore_v1beta11.Document {
if m != nil {
return m.Docs
}
return nil
}
func (m *Snapshot) GetChanges() []*DocChange {
if m != nil {
return m.Changes
}
return nil
}
func (m *Snapshot) GetReadTime() *google_protobuf1.Timestamp {
if m != nil {
return m.ReadTime
}
return nil
}
type DocChange struct {
Kind DocChange_Kind `protobuf:"varint,1,opt,name=kind,enum=tests.DocChange_Kind" json:"kind,omitempty"`
Doc *google_firestore_v1beta11.Document `protobuf:"bytes,2,opt,name=doc" json:"doc,omitempty"`
OldIndex int32 `protobuf:"varint,3,opt,name=old_index,json=oldIndex" json:"old_index,omitempty"`
NewIndex int32 `protobuf:"varint,4,opt,name=new_index,json=newIndex" json:"new_index,omitempty"`
}
func (m *DocChange) Reset() { *m = DocChange{} }
func (m *DocChange) String() string { return proto.CompactTextString(m) }
func (*DocChange) ProtoMessage() {}
func (*DocChange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
func (m *DocChange) GetKind() DocChange_Kind {
if m != nil {
return m.Kind
}
return DocChange_KIND_UNSPECIFIED
}
func (m *DocChange) GetDoc() *google_firestore_v1beta11.Document {
if m != nil {
return m.Doc
}
return nil
}
func (m *DocChange) GetOldIndex() int32 {
if m != nil {
return m.OldIndex
}
return 0
}
func (m *DocChange) GetNewIndex() int32 {
if m != nil {
return m.NewIndex
}
return 0
}
func init() {
proto.RegisterType((*TestSuite)(nil), "tests.TestSuite")
proto.RegisterType((*Test)(nil), "tests.Test")
@ -1171,73 +1349,95 @@ func init() {
proto.RegisterType((*Cursor)(nil), "tests.Cursor")
proto.RegisterType((*DocSnapshot)(nil), "tests.DocSnapshot")
proto.RegisterType((*FieldPath)(nil), "tests.FieldPath")
proto.RegisterType((*ListenTest)(nil), "tests.ListenTest")
proto.RegisterType((*Snapshot)(nil), "tests.Snapshot")
proto.RegisterType((*DocChange)(nil), "tests.DocChange")
proto.RegisterEnum("tests.DocChange_Kind", DocChange_Kind_name, DocChange_Kind_value)
}
func init() { proto.RegisterFile("test.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 994 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xc4, 0x56, 0x5f, 0x6f, 0xdc, 0x44,
0x10, 0xaf, 0x7d, 0x67, 0x9f, 0x3d, 0x0e, 0xa5, 0xac, 0x50, 0x65, 0x0a, 0x88, 0xab, 0x15, 0x92,
0x83, 0xa2, 0x2b, 0x09, 0xe2, 0x09, 0x09, 0x94, 0x4b, 0x48, 0x2a, 0xa4, 0xaa, 0xc1, 0x57, 0xe0,
0x05, 0xe9, 0x70, 0xec, 0x71, 0x62, 0xe4, 0xf3, 0x5e, 0x77, 0xd7, 0x45, 0xfd, 0x48, 0x20, 0xf1,
0xc0, 0x37, 0xe1, 0x91, 0x4f, 0xc0, 0x37, 0x80, 0x67, 0xb4, 0x7f, 0x7c, 0xb6, 0xd3, 0x5c, 0xc9,
0x43, 0x29, 0x6f, 0xbb, 0x33, 0xbf, 0x99, 0x9d, 0xf9, 0xcd, 0xec, 0xec, 0x02, 0x08, 0xe4, 0x62,
0xba, 0x62, 0x54, 0x50, 0xe2, 0xc8, 0x35, 0xbf, 0x33, 0x39, 0xa7, 0xf4, 0xbc, 0xc4, 0xfb, 0x79,
0xc1, 0x90, 0x0b, 0xca, 0xf0, 0xfe, 0xd3, 0xbd, 0x33, 0x14, 0xc9, 0x5e, 0x2b, 0xd1, 0x06, 0x77,
0xde, 0xdf, 0x88, 0x4c, 0xe9, 0x72, 0x49, 0x2b, 0x03, 0xdb, 0xde, 0x08, 0x7b, 0x52, 0x23, 0x7b,
0xa6, 0x51, 0xd1, 0x14, 0xfc, 0xc7, 0xc8, 0xc5, 0xbc, 0x2e, 0x04, 0x92, 0xbb, 0xa0, 0x83, 0x09,
0xad, 0xf1, 0x60, 0x12, 0xec, 0x07, 0x53, 0xb5, 0x9b, 0x4a, 0x40, 0xac, 0x35, 0xd1, 0x9f, 0x36,
0x0c, 0xe5, 0x9e, 0x8c, 0x21, 0xc8, 0x90, 0xa7, 0xac, 0x58, 0x89, 0x82, 0x56, 0xa1, 0x35, 0xb6,
0x26, 0x7e, 0xdc, 0x15, 0x91, 0x08, 0x06, 0xe7, 0x28, 0x42, 0x7b, 0x6c, 0x4d, 0x82, 0xfd, 0x9b,
0xc6, 0xd7, 0x09, 0x0a, 0x69, 0xfe, 0xe0, 0x46, 0x2c, 0x95, 0xe4, 0x1e, 0xb8, 0x29, 0xc3, 0x44,
0x60, 0x38, 0x50, 0xb0, 0x37, 0x0c, 0xec, 0x50, 0x09, 0x0d, 0xd2, 0x40, 0xa4, 0x43, 0x8e, 0x22,
0x1c, 0xf6, 0x1c, 0xce, 0x5b, 0x87, 0x5c, 0x3b, 0xac, 0x57, 0x99, 0x74, 0xe8, 0xf4, 0x1c, 0x7e,
0xa3, 0x84, 0x8d, 0x43, 0x0d, 0x21, 0x9f, 0xc1, 0x96, 0x5e, 0x2d, 0x56, 0x89, 0xb8, 0xe0, 0xa1,
0xab, 0x4c, 0x6e, 0xf7, 0x4c, 0x4e, 0xa5, 0xc6, 0xd8, 0x05, 0x75, 0x2b, 0x92, 0x27, 0x65, 0x58,
0xa2, 0xc0, 0x70, 0xd4, 0x3b, 0xe9, 0x48, 0x09, 0x9b, 0x93, 0x34, 0x84, 0x4c, 0xc0, 0x51, 0xac,
0x87, 0x9e, 0xc2, 0xde, 0x32, 0xd8, 0xaf, 0xa5, 0xcc, 0x40, 0x35, 0x60, 0xe6, 0xc2, 0x50, 0xea,
0x22, 0x0e, 0x23, 0xc3, 0x15, 0x19, 0xc3, 0x56, 0x46, 0xd3, 0x05, 0xc3, 0x5c, 0xc5, 0x69, 0xb8,
0x86, 0x8c, 0xa6, 0x31, 0xe6, 0x32, 0x18, 0x72, 0x0c, 0x23, 0x86, 0x4f, 0x6a, 0xe4, 0x0d, 0xdd,
0x1f, 0x4d, 0x75, 0xf5, 0xa7, 0x6d, 0xf3, 0x98, 0xea, 0xcb, 0x0a, 0x1c, 0xd1, 0xb4, 0x5e, 0x62,
0x25, 0x62, 0x6d, 0x13, 0x37, 0xc6, 0xd1, 0xcf, 0x16, 0x40, 0x4b, 0xfd, 0x35, 0x0e, 0x7e, 0x1b,
0xfc, 0x1f, 0x39, 0xad, 0x16, 0x59, 0x22, 0x12, 0x75, 0xb4, 0x1f, 0x7b, 0x52, 0x70, 0x94, 0x88,
0x84, 0x1c, 0xb4, 0x51, 0xe9, 0xea, 0xee, 0x6e, 0x8e, 0xea, 0x90, 0x2e, 0x97, 0xc5, 0x73, 0x01,
0x91, 0xb7, 0xc0, 0x2b, 0xf8, 0x02, 0x19, 0xa3, 0x4c, 0xd5, 0xdd, 0x8b, 0x47, 0x05, 0xff, 0x52,
0x6e, 0xa3, 0xdf, 0x2d, 0x18, 0xcd, 0xaf, 0xcd, 0xd0, 0x04, 0x5c, 0xaa, 0x3b, 0xd5, 0xee, 0x55,
0x60, 0x8e, 0xe2, 0x91, 0x92, 0xc7, 0x46, 0xdf, 0x4f, 0x69, 0xb0, 0x39, 0xa5, 0xe1, 0x4b, 0x48,
0xc9, 0xe9, 0xa7, 0xf4, 0x97, 0x05, 0xd0, 0x36, 0xea, 0x35, 0xb2, 0xfa, 0x0a, 0xb6, 0x56, 0x0c,
0x53, 0x5a, 0x65, 0x45, 0x27, 0xb7, 0x9d, 0xcd, 0x31, 0x9d, 0x76, 0xd0, 0x71, 0xcf, 0xf6, 0xff,
0xcc, 0xfb, 0x37, 0x1b, 0x5e, 0xbf, 0x74, 0xdb, 0x5e, 0x71, 0xf2, 0x7b, 0x10, 0xe4, 0x05, 0x96,
0x99, 0x19, 0x04, 0x03, 0x35, 0xff, 0x9a, 0x1e, 0x39, 0x96, 0x1a, 0x79, 0x64, 0x0c, 0x79, 0xb3,
0xe4, 0xe4, 0x3d, 0x08, 0x14, 0x5f, 0x4f, 0x93, 0xb2, 0x46, 0x1e, 0x0e, 0xc7, 0x03, 0x19, 0x9f,
0x14, 0x7d, 0xab, 0x24, 0x5d, 0xce, 0x9c, 0x97, 0xc0, 0x99, 0xdb, 0xe7, 0xec, 0x0f, 0x0b, 0xa0,
0x1d, 0x35, 0xaf, 0x98, 0xae, 0xff, 0xf6, 0x66, 0x9f, 0x80, 0xbf, 0xbe, 0x96, 0xe4, 0x16, 0x0c,
0x92, 0xb2, 0x54, 0xf9, 0x78, 0xb1, 0x5c, 0xca, 0xab, 0xac, 0xca, 0xc0, 0x43, 0x7b, 0x43, 0x99,
0x8c, 0x3e, 0xfa, 0xd5, 0x02, 0x7f, 0x3d, 0x62, 0x65, 0x83, 0xa7, 0xb4, 0x2c, 0xbb, 0xfc, 0x78,
0x52, 0xa0, 0xd8, 0xd9, 0x85, 0x51, 0x5a, 0x26, 0x35, 0xc7, 0xc6, 0xeb, 0x6b, 0xcd, 0x4b, 0xa4,
0xa4, 0x71, 0xa3, 0x25, 0x5f, 0x34, 0x93, 0x5c, 0x27, 0xfe, 0xc1, 0xe6, 0xc4, 0xe7, 0x82, 0xd5,
0xa9, 0xa8, 0x19, 0x66, 0x2a, 0x06, 0x33, 0xe0, 0x5f, 0x94, 0xf8, 0xdf, 0x36, 0xb8, 0xfa, 0x3c,
0xb2, 0x0b, 0x2e, 0xc7, 0x12, 0x53, 0xa1, 0x22, 0x6d, 0xc3, 0x99, 0x2b, 0xa1, 0x7c, 0x59, 0xb4,
0x9a, 0x6c, 0x83, 0xf3, 0xd3, 0x05, 0x32, 0x34, 0xf5, 0xdc, 0x32, 0xb8, 0xef, 0xa4, 0x4c, 0xbe,
0x2a, 0x4a, 0x49, 0xee, 0x81, 0x47, 0x59, 0x86, 0x6c, 0x71, 0xd6, 0x04, 0xde, 0xbc, 0x9f, 0x8f,
0xa4, 0x78, 0xf6, 0xec, 0xc1, 0x8d, 0x78, 0x44, 0xf5, 0x92, 0x84, 0xe0, 0xd2, 0x3c, 0x6f, 0x9e,
0x5a, 0x47, 0x1e, 0xa6, 0xf7, 0xe4, 0x36, 0x38, 0x65, 0xb1, 0x2c, 0x74, 0x43, 0x4b, 0x85, 0xde,
0x92, 0x0f, 0xc1, 0xe3, 0x22, 0x61, 0x62, 0x91, 0x08, 0xf3, 0x88, 0xae, 0xe9, 0xab, 0x19, 0xa7,
0x4c, 0x7a, 0x57, 0x80, 0x03, 0x41, 0x3e, 0x86, 0xc0, 0x60, 0x73, 0x81, 0xcc, 0x3c, 0x9e, 0xcf,
0xc1, 0x41, 0xc3, 0x25, 0x84, 0xec, 0x80, 0x8b, 0x55, 0x26, 0x7d, 0x7b, 0x57, 0x83, 0x1d, 0xac,
0xb2, 0x03, 0x41, 0xa6, 0x00, 0x12, 0x77, 0x86, 0x39, 0x65, 0x18, 0xfa, 0x57, 0x63, 0x7d, 0xac,
0xb2, 0x99, 0x42, 0xcc, 0x3c, 0x70, 0x75, 0x55, 0xa3, 0x7d, 0x70, 0x35, 0xb1, 0x9d, 0xe6, 0xb2,
0xfe, 0xa5, 0xb9, 0xbe, 0x07, 0x47, 0x91, 0x4c, 0xb6, 0x61, 0xb8, 0x6e, 0xa9, 0xab, 0x0c, 0x94,
0x96, 0xdc, 0x04, 0x9b, 0xae, 0xcc, 0x13, 0x69, 0xd3, 0x15, 0x79, 0x17, 0xa0, 0x1d, 0x1f, 0x66,
0xde, 0xfa, 0xeb, 0xe9, 0x11, 0x3d, 0x84, 0x91, 0xa9, 0xcc, 0x35, 0xfd, 0xbf, 0x03, 0x7e, 0x56,
0x30, 0x4c, 0xd7, 0x77, 0xdb, 0x8f, 0x5b, 0x41, 0xf4, 0x03, 0xb8, 0x9a, 0x01, 0xf2, 0xa9, 0x1e,
0x14, 0xbc, 0x4a, 0x56, 0xfc, 0x82, 0x36, 0xed, 0x45, 0x9a, 0xcf, 0x0b, 0x4d, 0xe7, 0x46, 0x13,
0x07, 0x59, 0xbb, 0xb9, 0x3c, 0xed, 0xec, 0xcb, 0xd3, 0x2e, 0xfa, 0x1c, 0x82, 0x8e, 0x31, 0x21,
0x9d, 0xa0, 0x7d, 0x13, 0xe2, 0x8b, 0x3e, 0x0b, 0xd1, 0x5d, 0xf0, 0xd7, 0x29, 0x91, 0x37, 0xc1,
0x51, 0x2c, 0xab, 0x22, 0xf8, 0xb1, 0xde, 0xcc, 0x1e, 0xc2, 0x4e, 0x4a, 0x97, 0xcd, 0x85, 0x4b,
0x4b, 0x5a, 0x67, 0x9d, 0x6b, 0x97, 0xd2, 0x2a, 0xa7, 0x6c, 0x99, 0x54, 0x29, 0xfe, 0x62, 0x47,
0x27, 0x1a, 0x74, 0xa8, 0x40, 0xc7, 0x6b, 0xd0, 0x63, 0x95, 0xe5, 0xa9, 0xfc, 0xfa, 0x9e, 0xb9,
0xea, 0x07, 0xfc, 0xc9, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x96, 0x46, 0xb3, 0x8d, 0x0b,
0x00, 0x00,
// 1292 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xc4, 0x57, 0x4d, 0x73, 0xdb, 0xc4,
0x1b, 0xaf, 0x6c, 0x4b, 0x96, 0x1e, 0xe7, 0xdf, 0xe6, 0xbf, 0x53, 0x3a, 0x26, 0xc0, 0x34, 0xd5,
0x94, 0xc6, 0x6d, 0xc1, 0xa1, 0xe1, 0xed, 0xc0, 0x0c, 0x4c, 0x12, 0x3b, 0x6d, 0x28, 0x6d, 0x82,
0xdc, 0x96, 0x4b, 0x66, 0x8c, 0xa2, 0x5d, 0x27, 0x02, 0x59, 0xeb, 0xee, 0xae, 0xfa, 0xf2, 0x39,
0xb8, 0x73, 0x65, 0x60, 0x86, 0x03, 0x5f, 0x83, 0x13, 0x47, 0x3e, 0x03, 0x77, 0x38, 0x33, 0xfb,
0x26, 0x59, 0x69, 0x5d, 0x72, 0x28, 0xe5, 0xb6, 0xfb, 0x3c, 0xbf, 0xe7, 0xfd, 0x65, 0x25, 0x00,
0x41, 0xb8, 0xe8, 0xcf, 0x18, 0x15, 0x14, 0xb9, 0xf2, 0xcc, 0x57, 0xde, 0x3e, 0xa2, 0xf4, 0x28,
0x23, 0xeb, 0x93, 0x94, 0x11, 0x2e, 0x28, 0x23, 0xeb, 0x8f, 0x6e, 0x1c, 0x12, 0x11, 0xdf, 0x58,
0x4f, 0xe8, 0x74, 0x4a, 0x73, 0x8d, 0x5e, 0x59, 0x5b, 0x08, 0xc3, 0x34, 0x29, 0xa6, 0x24, 0x37,
0x6a, 0x57, 0x7a, 0x0b, 0x81, 0x25, 0xc5, 0x20, 0x2f, 0x2f, 0x44, 0x3e, 0x2c, 0x08, 0x7b, 0x6a,
0x50, 0x17, 0x0d, 0x4a, 0xdd, 0x0e, 0x8b, 0xc9, 0xba, 0x48, 0xa7, 0x84, 0x8b, 0x78, 0x3a, 0xd3,
0x80, 0xb0, 0x0f, 0xc1, 0x3d, 0xc2, 0xc5, 0xa8, 0x48, 0x05, 0x41, 0x97, 0x40, 0x87, 0xd5, 0x75,
0x56, 0x9b, 0xbd, 0xce, 0x46, 0xa7, 0xaf, 0x6e, 0x7d, 0x09, 0x88, 0x34, 0x27, 0xfc, 0xae, 0x09,
0x2d, 0x79, 0x47, 0xab, 0xd0, 0xc1, 0x84, 0x27, 0x2c, 0x9d, 0x89, 0x94, 0xe6, 0x5d, 0x67, 0xd5,
0xe9, 0x05, 0xd1, 0x3c, 0x09, 0x85, 0xd0, 0x3c, 0x22, 0xa2, 0xdb, 0x58, 0x75, 0x7a, 0x9d, 0x8d,
0xb3, 0x46, 0xd7, 0x4d, 0x22, 0xa4, 0xf8, 0xad, 0x33, 0x91, 0x64, 0xa2, 0xeb, 0xe0, 0x25, 0x8c,
0xc4, 0x82, 0x74, 0x9b, 0x0a, 0xf6, 0x7f, 0x03, 0xdb, 0x56, 0x44, 0x83, 0x34, 0x10, 0xa9, 0x90,
0x13, 0xd1, 0x6d, 0xd5, 0x14, 0x8e, 0x2a, 0x85, 0x5c, 0x2b, 0x2c, 0x66, 0x58, 0x2a, 0x74, 0x6b,
0x0a, 0xef, 0x2b, 0xa2, 0x55, 0xa8, 0x21, 0xe8, 0x13, 0x58, 0xd2, 0xa7, 0xf1, 0x2c, 0x16, 0xc7,
0xbc, 0xeb, 0x29, 0x91, 0x0b, 0x35, 0x91, 0x7d, 0xc9, 0x31, 0x72, 0x9d, 0xa2, 0x22, 0x49, 0x4b,
0x98, 0x64, 0x44, 0x90, 0x6e, 0xbb, 0x66, 0x69, 0xa0, 0x88, 0xd6, 0x92, 0x86, 0xa0, 0x1e, 0xb8,
0xaa, 0x2c, 0x5d, 0x5f, 0x61, 0x97, 0x0d, 0xf6, 0x4b, 0x49, 0x33, 0x50, 0x0d, 0x90, 0x6a, 0xb3,
0x94, 0x0b, 0x92, 0x77, 0x83, 0x9a, 0xda, 0x2f, 0x14, 0xd1, 0xaa, 0xd5, 0x90, 0x2d, 0x0f, 0x5a,
0x92, 0x1b, 0x72, 0x68, 0x9b, 0xc4, 0xa2, 0x55, 0x58, 0xc2, 0x34, 0x19, 0x33, 0x32, 0x51, 0x41,
0x99, 0xc2, 0x00, 0xa6, 0x49, 0x44, 0x26, 0xd2, 0x73, 0xb4, 0x03, 0x6d, 0x46, 0x1e, 0x16, 0x84,
0xdb, 0xda, 0xbc, 0xd3, 0xd7, 0x5d, 0xd2, 0xaf, 0x7a, 0xcc, 0xf4, 0x92, 0x2c, 0xd7, 0xc0, 0x74,
0x68, 0xa4, 0x65, 0x22, 0x2b, 0x1c, 0xfe, 0xe8, 0x00, 0x54, 0x75, 0x3a, 0x85, 0xe1, 0x37, 0x20,
0xf8, 0x86, 0xd3, 0x7c, 0x8c, 0x63, 0x11, 0x2b, 0xd3, 0x41, 0xe4, 0x4b, 0xc2, 0x20, 0x16, 0x31,
0xda, 0xac, 0xbc, 0xd2, 0xad, 0xb0, 0xb6, 0xd8, 0xab, 0x6d, 0x3a, 0x9d, 0xa6, 0xcf, 0x38, 0x84,
0x5e, 0x07, 0x3f, 0xe5, 0x63, 0xc2, 0x18, 0x65, 0xaa, 0x49, 0xfc, 0xa8, 0x9d, 0xf2, 0xa1, 0xbc,
0x86, 0xbf, 0x39, 0xd0, 0x1e, 0x9d, 0x3a, 0x43, 0x3d, 0xf0, 0xa8, 0x6e, 0xeb, 0x46, 0xad, 0x5c,
0x23, 0x22, 0xf6, 0x14, 0x3d, 0x32, 0xfc, 0x7a, 0x48, 0xcd, 0xc5, 0x21, 0xb5, 0x5e, 0x42, 0x48,
0x6e, 0x3d, 0xa4, 0x3f, 0x1d, 0x80, 0xaa, 0xab, 0x4f, 0x11, 0xd5, 0xe7, 0xb0, 0x34, 0x63, 0x24,
0xa1, 0x39, 0x4e, 0xe7, 0x62, 0xbb, 0xb2, 0xd8, 0xa7, 0xfd, 0x39, 0x74, 0x54, 0x93, 0xfd, 0x2f,
0xe3, 0xfe, 0xa5, 0x01, 0xe7, 0x4e, 0x8c, 0xe6, 0x2b, 0x0e, 0xfe, 0x06, 0x74, 0x26, 0x29, 0xc9,
0xb0, 0xd9, 0x1a, 0x4d, 0xb5, 0x2c, 0x6d, 0x8f, 0xec, 0x48, 0x8e, 0x34, 0x19, 0xc1, 0xc4, 0x1e,
0x39, 0xba, 0x08, 0x1d, 0x95, 0xaf, 0x47, 0x71, 0x56, 0x10, 0xde, 0x6d, 0xad, 0x36, 0xa5, 0x7f,
0x92, 0xf4, 0x40, 0x51, 0xe6, 0x73, 0xe6, 0xbe, 0x84, 0x9c, 0x79, 0xf5, 0x9c, 0xfd, 0xee, 0x00,
0x54, 0x7b, 0xe9, 0x15, 0xa7, 0xeb, 0xdf, 0x9d, 0xec, 0x9b, 0x10, 0x94, 0x63, 0x89, 0x96, 0xa1,
0x19, 0x67, 0x99, 0x8a, 0xc7, 0x8f, 0xe4, 0x51, 0x8e, 0xb2, 0x2a, 0x03, 0xef, 0x36, 0x16, 0x94,
0xc9, 0xf0, 0xc3, 0x9f, 0x1d, 0x08, 0xca, 0x7d, 0x2c, 0x1b, 0x3c, 0xa1, 0x59, 0x36, 0x9f, 0x1f,
0x5f, 0x12, 0x54, 0x76, 0xd6, 0xa0, 0x9d, 0x64, 0x71, 0xc1, 0x89, 0xd5, 0xfa, 0x3f, 0xfb, 0x6c,
0x29, 0x6a, 0x64, 0xb9, 0xe8, 0x33, 0xbb, 0xf6, 0x75, 0xe0, 0x57, 0x17, 0x07, 0x3e, 0x12, 0xac,
0x48, 0x44, 0xc1, 0x08, 0x56, 0x3e, 0xd8, 0xd7, 0xe0, 0x05, 0x81, 0xff, 0xd5, 0x00, 0x4f, 0xdb,
0x43, 0x6b, 0xe0, 0x71, 0x92, 0x91, 0x44, 0x28, 0x4f, 0x2b, 0x77, 0x46, 0x8a, 0x28, 0xdf, 0x0b,
0xcd, 0x46, 0x97, 0xc1, 0x7d, 0x7c, 0x4c, 0x18, 0x31, 0xf5, 0x5c, 0x32, 0xb8, 0xaf, 0x24, 0x4d,
0x3e, 0x41, 0x8a, 0x89, 0xae, 0x83, 0x4f, 0x19, 0x26, 0x6c, 0x7c, 0x68, 0x1d, 0xb7, 0x8f, 0xed,
0x9e, 0x24, 0x6f, 0x3d, 0xbd, 0x75, 0x26, 0x6a, 0x53, 0x7d, 0x44, 0x5d, 0xf0, 0xe8, 0x64, 0x62,
0xdf, 0x65, 0x57, 0x1a, 0xd3, 0x77, 0x74, 0x01, 0xdc, 0x2c, 0x9d, 0xa6, 0xba, 0xa1, 0x25, 0x43,
0x5f, 0xd1, 0x35, 0xf0, 0xb9, 0x88, 0x99, 0x18, 0xc7, 0xc2, 0xbc, 0xb8, 0x65, 0xfa, 0x0a, 0xc6,
0x29, 0x93, 0xda, 0x15, 0x60, 0x53, 0xa0, 0xf7, 0xa0, 0x63, 0xb0, 0x13, 0x41, 0x98, 0x79, 0x69,
0x9f, 0x81, 0x83, 0x86, 0x4b, 0x08, 0xba, 0x02, 0x1e, 0xc9, 0xb1, 0xd4, 0xed, 0x3f, 0x1f, 0xec,
0x92, 0x1c, 0x6f, 0x0a, 0xd4, 0x07, 0x90, 0xb8, 0x43, 0x32, 0xa1, 0x8c, 0x98, 0xb7, 0xf6, 0x19,
0x6c, 0x40, 0x72, 0xbc, 0xa5, 0x10, 0x5b, 0x3e, 0x78, 0xba, 0xaa, 0xe1, 0x06, 0x78, 0x3a, 0xb1,
0x73, 0xcd, 0xe5, 0xfc, 0x43, 0x73, 0x1d, 0x80, 0xab, 0x92, 0x8c, 0x2e, 0x43, 0xab, 0x6c, 0xa9,
0xe7, 0x09, 0x28, 0x2e, 0x3a, 0x0b, 0x0d, 0x3a, 0x33, 0x4f, 0x64, 0x83, 0xce, 0xd0, 0x5b, 0x00,
0xd5, 0xfa, 0x30, 0xfb, 0x36, 0x28, 0xb7, 0x47, 0x78, 0x07, 0xda, 0xa6, 0x32, 0xa7, 0xd4, 0xff,
0x26, 0x04, 0x38, 0x65, 0x24, 0x29, 0x67, 0x3b, 0x88, 0x2a, 0x42, 0xf8, 0x35, 0x78, 0x3a, 0x03,
0xe8, 0x43, 0xbd, 0x28, 0x78, 0x1e, 0xcf, 0xf8, 0x31, 0xb5, 0xed, 0x85, 0xec, 0x97, 0x0e, 0x4d,
0x46, 0x86, 0x13, 0x75, 0x70, 0x75, 0x39, 0xb9, 0xed, 0x1a, 0x27, 0xb7, 0x5d, 0xf8, 0x29, 0x74,
0xe6, 0x84, 0x11, 0x9a, 0x73, 0x3a, 0x30, 0x2e, 0xbe, 0xe8, 0x63, 0x21, 0xbc, 0x04, 0x41, 0x19,
0x12, 0x3a, 0x0f, 0xae, 0xca, 0xb2, 0x2a, 0x42, 0x10, 0xe9, 0x4b, 0xf8, 0xbd, 0x03, 0x50, 0x7d,
0x33, 0xa1, 0x1d, 0x08, 0x18, 0xe1, 0x33, 0x9a, 0xcb, 0xa1, 0xd5, 0xd5, 0xea, 0x2d, 0x9e, 0x46,
0x2d, 0x18, 0x19, 0x81, 0xa8, 0x12, 0x45, 0xef, 0x42, 0x60, 0xb3, 0x61, 0x87, 0xff, 0x9c, 0x9d,
0x36, 0x9b, 0x8b, 0x0a, 0x51, 0x9b, 0xdf, 0x66, 0x7d, 0x7e, 0x7f, 0x70, 0xc0, 0x2f, 0x33, 0xf0,
0x11, 0xb4, 0x30, 0x4d, 0xac, 0x67, 0xe1, 0x62, 0xcf, 0xca, 0xaf, 0x31, 0x85, 0x47, 0xd7, 0xa0,
0x9d, 0x1c, 0xc7, 0xf9, 0x11, 0x39, 0xb9, 0xdf, 0x06, 0x34, 0xd9, 0x56, 0x8c, 0xc8, 0x02, 0xd0,
0xc7, 0x32, 0x05, 0x31, 0x1e, 0xcb, 0x5f, 0x00, 0x33, 0xd7, 0x2b, 0xd6, 0x90, 0xfd, 0x3f, 0xe8,
0xdf, 0xb3, 0xff, 0x07, 0x91, 0x2f, 0xc1, 0xf2, 0x1a, 0xfe, 0xe1, 0x40, 0x50, 0xea, 0x43, 0x57,
0xa1, 0xf5, 0x6d, 0x9a, 0x63, 0x55, 0xac, 0xb3, 0x1b, 0xaf, 0x9d, 0xb4, 0xd7, 0xbf, 0x9d, 0xe6,
0x38, 0x52, 0x10, 0xf4, 0x01, 0x34, 0x31, 0x4d, 0xcc, 0xb2, 0x39, 0x4d, 0x50, 0x12, 0x2e, 0x2b,
0x4f, 0x33, 0x3c, 0x4e, 0x73, 0x4c, 0x9e, 0x28, 0x3f, 0xdd, 0xc8, 0xa7, 0x19, 0xde, 0x95, 0x77,
0xc9, 0xcc, 0xc9, 0x63, 0xc3, 0x6c, 0x69, 0x66, 0x4e, 0x1e, 0x2b, 0x66, 0xb8, 0x05, 0x2d, 0x69,
0x1d, 0x9d, 0x87, 0xe5, 0xdb, 0xbb, 0x77, 0x07, 0xe3, 0xfb, 0x77, 0x47, 0xfb, 0xc3, 0xed, 0xdd,
0x9d, 0xdd, 0xe1, 0x60, 0xf9, 0x0c, 0x0a, 0xc0, 0xdd, 0x1c, 0x0c, 0x86, 0x83, 0x65, 0x07, 0x75,
0xa0, 0x1d, 0x0d, 0xef, 0xec, 0x3d, 0x18, 0x0e, 0x96, 0x1b, 0x68, 0x09, 0xfc, 0x3b, 0x7b, 0x03,
0x8d, 0x6a, 0x6e, 0x3d, 0x81, 0x2b, 0x09, 0x9d, 0x5a, 0x5f, 0x93, 0x8c, 0x16, 0x78, 0xce, 0xe3,
0x84, 0xe6, 0x13, 0xca, 0xa6, 0x71, 0x9e, 0x90, 0x9f, 0x1a, 0xe1, 0x4d, 0x0d, 0xda, 0x56, 0xa0,
0x9d, 0x12, 0x74, 0x4f, 0x65, 0x64, 0x5f, 0xa6, 0xf4, 0xd7, 0x46, 0x4f, 0x83, 0x0e, 0x14, 0xe8,
0xa0, 0x04, 0x1d, 0x28, 0xd0, 0xc1, 0x76, 0xa5, 0xef, 0xd0, 0x53, 0x45, 0x78, 0xff, 0xef, 0x00,
0x00, 0x00, 0xff, 0xff, 0xc2, 0x7a, 0x63, 0xd5, 0x67, 0x0e, 0x00, 0x00,
}

View File

@ -29,6 +29,7 @@ import (
"cloud.google.com/go/internal/pretty"
"cloud.google.com/go/internal/testutil"
"cloud.google.com/go/internal/uid"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
@ -55,7 +56,7 @@ const (
var (
iClient *Client
iColl *CollectionRef
collectionIDs = testutil.NewUIDSpace("go-integration-test")
collectionIDs = uid.NewSpace("go-integration-test", nil)
)
func initIntegrationTest() {
@ -389,6 +390,18 @@ func TestIntegration_Set(t *testing.T) {
if !wr3.UpdateTime.Before(wr4.UpdateTime) {
t.Errorf("update time did not increase: old=%s, new=%s", wr3.UpdateTime, wr4.UpdateTime)
}
// Writing an empty doc with MergeAll should create the doc.
doc2 := coll.NewDoc()
want = map[string]interface{}{}
_, err = doc2.Set(ctx, want, MergeAll)
if err != nil {
t.Fatal(err)
}
ds = h.mustGet(doc2)
if got := ds.Data(); !testEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
}
}
func TestIntegration_Delete(t *testing.T) {

View File

@ -36,11 +36,11 @@ func TestProcessPreconditionsForVerify(t *testing.T) {
},
{
in: []Precondition{Exists},
want: &pb.Precondition{&pb.Precondition_Exists{true}},
want: &pb.Precondition{ConditionType: &pb.Precondition_Exists{true}},
},
{
in: []Precondition{LastUpdateTime(aTime)},
want: &pb.Precondition{&pb.Precondition_UpdateTime{aTimestamp}},
want: &pb.Precondition{ConditionType: &pb.Precondition_UpdateTime{aTimestamp}},
},
{
in: []Precondition{Exists, LastUpdateTime(aTime)},
@ -79,11 +79,11 @@ func TestProcessPreconditionsForDelete(t *testing.T) {
},
{
in: []Precondition{Exists},
want: &pb.Precondition{&pb.Precondition_Exists{true}},
want: &pb.Precondition{ConditionType: &pb.Precondition_Exists{true}},
},
{
in: []Precondition{LastUpdateTime(aTime)},
want: &pb.Precondition{&pb.Precondition_UpdateTime{aTimestamp}},
want: &pb.Precondition{ConditionType: &pb.Precondition_UpdateTime{aTimestamp}},
},
{
in: []Precondition{Exists, LastUpdateTime(aTime)},
@ -114,11 +114,11 @@ func TestProcessPreconditionsForUpdate(t *testing.T) {
}{
{
in: nil,
want: &pb.Precondition{&pb.Precondition_Exists{true}},
want: &pb.Precondition{ConditionType: &pb.Precondition_Exists{true}},
},
{
in: []Precondition{},
want: &pb.Precondition{&pb.Precondition_Exists{true}},
want: &pb.Precondition{ConditionType: &pb.Precondition_Exists{true}},
},
{
@ -127,7 +127,7 @@ func TestProcessPreconditionsForUpdate(t *testing.T) {
},
{
in: []Precondition{LastUpdateTime(aTime)},
want: &pb.Precondition{&pb.Precondition_UpdateTime{aTimestamp}},
want: &pb.Precondition{ConditionType: &pb.Precondition_UpdateTime{aTimestamp}},
},
{
in: []Precondition{Exists, LastUpdateTime(aTime)},

View File

@ -160,7 +160,7 @@ func (q Query) Offset(n int) Query {
// Limit returns a new Query that specifies the maximum number of results to return.
// It must not be negative.
func (q Query) Limit(n int) Query {
q.limit = &wrappers.Int32Value{trunc32(n)}
q.limit = &wrappers.Int32Value{Value: trunc32(n)}
return q
}
@ -363,7 +363,7 @@ func (q *Query) fieldValuesToCursorValues(fieldValues []interface{}) ([]*pb.Valu
if !ok {
return nil, fmt.Errorf("firestore: expected doc ID for DocumentID field, got %T", fval)
}
vals[i] = &pb.Value{&pb.Value_ReferenceValue{q.collectionPath() + "/" + docID}}
vals[i] = &pb.Value{ValueType: &pb.Value_ReferenceValue{q.collectionPath() + "/" + docID}}
} else {
var sawTransform bool
vals[i], sawTransform, err = toProtoValue(reflect.ValueOf(fval))
@ -387,7 +387,7 @@ func (q *Query) docSnapshotToCursorValues(ds *DocumentSnapshot, orders []order)
if dp != qp {
return nil, fmt.Errorf("firestore: document snapshot for %s passed to query on %s", dp, qp)
}
vals[i] = &pb.Value{&pb.Value_ReferenceValue{ds.Ref.Path}}
vals[i] = &pb.Value{ValueType: &pb.Value_ReferenceValue{ds.Ref.Path}}
} else {
val, err := valueAtPath(ord.fieldPath, ds.proto.Fields)
if err != nil {
@ -534,7 +534,7 @@ func (r order) toProto() (*pb.StructuredQuery_Order, error) {
}
func fref(fp FieldPath) *pb.StructuredQuery_FieldReference {
return &pb.StructuredQuery_FieldReference{fp.toServiceFieldPath()}
return &pb.StructuredQuery_FieldReference{FieldPath: fp.toServiceFieldPath()}
}
func trunc32(i int) int32 {

View File

@ -153,7 +153,7 @@ func TestQueryToProto(t *testing.T) {
in: q.Where("a", ">", 5).Where("b", "<", "foo"),
want: &pb.StructuredQuery{
Where: &pb.StructuredQuery_Filter{
&pb.StructuredQuery_Filter_CompositeFilter{
FilterType: &pb.StructuredQuery_Filter_CompositeFilter{
&pb.StructuredQuery_CompositeFilter{
Op: pb.StructuredQuery_CompositeFilter_AND,
Filters: []*pb.StructuredQuery_Filter{
@ -174,9 +174,9 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy("b", Asc).OrderBy("a", Desc).OrderByPath([]string{"~"}, Asc),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("b"), pb.StructuredQuery_ASCENDING},
{fref1("a"), pb.StructuredQuery_DESCENDING},
{fref1("~"), pb.StructuredQuery_ASCENDING},
{Field: fref1("b"), Direction: pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_DESCENDING},
{Field: fref1("~"), Direction: pb.StructuredQuery_ASCENDING},
},
},
},
@ -185,7 +185,7 @@ func TestQueryToProto(t *testing.T) {
in: q.Offset(2).Limit(3),
want: &pb.StructuredQuery{
Offset: 2,
Limit: &wrappers.Int32Value{3},
Limit: &wrappers.Int32Value{Value: 3},
},
},
{
@ -193,7 +193,7 @@ func TestQueryToProto(t *testing.T) {
in: q.Offset(2).Limit(3).Limit(4).Offset(5), // last wins
want: &pb.StructuredQuery{
Offset: 5,
Limit: &wrappers.Int32Value{4},
Limit: &wrappers.Int32Value{Value: 4},
},
},
{
@ -201,7 +201,7 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy("a", Asc).StartAt(7).EndBefore(9),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7)},
@ -218,7 +218,7 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy("a", Asc).StartAt(7).EndAt(9),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7)},
@ -235,7 +235,7 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy("a", Asc).StartAfter(7).EndAt(9),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7)},
@ -252,7 +252,7 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy(DocumentID, Asc).StartAfter("foo").EndBefore("bar"),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("__name__"), pb.StructuredQuery_ASCENDING},
{Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{refval(coll.parentPath + "/documents/C/foo")},
@ -269,8 +269,8 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy("a", Asc).OrderBy("b", Desc).StartAfter(7, 8).EndAt(9, 10),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_ASCENDING},
{fref1("b"), pb.StructuredQuery_DESCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING},
{Field: fref1("b"), Direction: pb.StructuredQuery_DESCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7), intval(8)},
@ -290,7 +290,7 @@ func TestQueryToProto(t *testing.T) {
EndAt(3).EndBefore(4),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(2)},
@ -309,7 +309,7 @@ func TestQueryToProto(t *testing.T) {
in: q.StartAt(docsnap),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("__name__"), pb.StructuredQuery_ASCENDING},
{Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{refval(coll.parentPath + "/documents/C/D")},
@ -322,8 +322,8 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy("a", Asc).StartAt(docsnap),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_ASCENDING},
{fref1("__name__"), pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING},
{Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7), refval(coll.parentPath + "/documents/C/D")},
@ -337,8 +337,8 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy("a", Desc).StartAt(docsnap),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_DESCENDING},
{fref1("__name__"), pb.StructuredQuery_DESCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_DESCENDING},
{Field: fref1("__name__"), Direction: pb.StructuredQuery_DESCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7), refval(coll.parentPath + "/documents/C/D")},
@ -351,9 +351,9 @@ func TestQueryToProto(t *testing.T) {
in: q.OrderBy("a", Desc).OrderBy("b", Asc).StartAt(docsnap),
want: &pb.StructuredQuery{
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_DESCENDING},
{fref1("b"), pb.StructuredQuery_ASCENDING},
{fref1("__name__"), pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_DESCENDING},
{Field: fref1("b"), Direction: pb.StructuredQuery_ASCENDING},
{Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7), intval(8), refval(coll.parentPath + "/documents/C/D")},
@ -367,7 +367,7 @@ func TestQueryToProto(t *testing.T) {
want: &pb.StructuredQuery{
Where: filtr([]string{"a"}, "==", 3),
OrderBy: []*pb.StructuredQuery_Order{
{fref1("__name__"), pb.StructuredQuery_ASCENDING},
{Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{refval(coll.parentPath + "/documents/C/D")},
@ -381,8 +381,8 @@ func TestQueryToProto(t *testing.T) {
want: &pb.StructuredQuery{
Where: filtr([]string{"a"}, "<", 3),
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_ASCENDING},
{fref1("__name__"), pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING},
{Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7), refval(coll.parentPath + "/documents/C/D")},
@ -395,7 +395,7 @@ func TestQueryToProto(t *testing.T) {
in: q.Where("b", "==", 1).Where("a", "<", 3).StartAt(docsnap),
want: &pb.StructuredQuery{
Where: &pb.StructuredQuery_Filter{
&pb.StructuredQuery_Filter_CompositeFilter{
FilterType: &pb.StructuredQuery_Filter_CompositeFilter{
&pb.StructuredQuery_CompositeFilter{
Op: pb.StructuredQuery_CompositeFilter_AND,
Filters: []*pb.StructuredQuery_Filter{
@ -406,8 +406,8 @@ func TestQueryToProto(t *testing.T) {
},
},
OrderBy: []*pb.StructuredQuery_Order{
{fref1("a"), pb.StructuredQuery_ASCENDING},
{fref1("__name__"), pb.StructuredQuery_ASCENDING},
{Field: fref1("a"), Direction: pb.StructuredQuery_ASCENDING},
{Field: fref1("__name__"), Direction: pb.StructuredQuery_ASCENDING},
},
StartAt: &pb.Cursor{
Values: []*pb.Value{intval(7), refval(coll.parentPath + "/documents/C/D")},

View File

@ -1 +1 @@
SHA1(/usr/local/google/home/jba/go/src/github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/testdata/test-suite.binproto)= 1502b0250a2ecd854b80509e3e456e46ade89ea7
SHA1(/usr/local/google/home/jba/go/src/github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/testdata/test-suite.binproto)= 6c622d8affaf1ea2ebeb063f9898f5d942343cb7

View File

@ -0,0 +1,246 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# Various changes to a single document.
description: "listen: add a doc, modify it, delete it, then add it again"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
target_ids: 1
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
responses: <
document_delete: <
document: "projects/projectID/databases/(default)/documents/C/d1"
>
>
responses: <
target_change: <
read_time: <
seconds: 3
>
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
target_ids: 1
>
>
responses: <
target_change: <
read_time: <
seconds: 4
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
read_time: <
seconds: 1
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
changes: <
kind: MODIFIED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
>
read_time: <
seconds: 2
>
>
snapshots: <
changes: <
kind: REMOVED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
new_index: -1
>
read_time: <
seconds: 3
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
old_index: -1
>
read_time: <
seconds: 4
>
>
>

View File

@ -0,0 +1,79 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# Snapshot with a single document.
description: "listen: add a doc"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
read_time: <
seconds: 2
>
>
>

View File

@ -0,0 +1,190 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# A snapshot with three documents. The documents are sorted first by the "a"
# field, then by their path. The changes are ordered the same way.
description: "listen: add three documents"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 2
>
read_time: <
seconds: 2
>
>
>

View File

@ -0,0 +1,115 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# The DocumentRemove response behaves exactly like DocumentDelete.
description: "listen: DocumentRemove behaves like DocumentDelete"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
responses: <
document_remove: <
document: "projects/projectID/databases/(default)/documents/C/d1"
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
read_time: <
seconds: 1
>
>
snapshots: <
changes: <
kind: REMOVED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
new_index: -1
>
read_time: <
seconds: 2
>
>
>

View File

@ -0,0 +1,25 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# There are no changes, so the snapshot should be empty.
description: "listen: no changes; empty snapshot"
listen: <
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
snapshots: <
read_time: <
seconds: 1
>
>
>

View File

@ -0,0 +1,247 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# A Filter response whose count matches the size of the current state (docs in
# last snapshot + docs added - docs deleted) is a no-op.
description: "listen: Filter response with same size is a no-op"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_delete: <
document: "projects/projectID/databases/(default)/documents/C/d1"
>
>
responses: <
filter: <
count: 2
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 1
>
read_time: <
seconds: 1
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: REMOVED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: 1
new_index: -1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 1
>
read_time: <
seconds: 2
>
>
>

View File

@ -0,0 +1,524 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# Changes should be ordered with deletes first, then additions, then mods, each in
# query order. Old indices refer to the immediately previous state, not the
# previous snapshot
description: "listen: multiple documents, added, deleted and updated"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d4"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d5"
fields: <
key: "a"
value: <
integer_value: 4
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_delete: <
document: "projects/projectID/databases/(default)/documents/C/d3"
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: -1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
target_ids: 1
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d6"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_delete: <
document: "projects/projectID/databases/(default)/documents/C/d2"
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d4"
fields: <
key: "a"
value: <
integer_value: -2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
target_ids: 1
>
>
responses: <
target_change: <
read_time: <
seconds: 4
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d4"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d4"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 2
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 3
>
read_time: <
seconds: 2
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d4"
fields: <
key: "a"
value: <
integer_value: -2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: -1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d6"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d5"
fields: <
key: "a"
value: <
integer_value: 4
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: REMOVED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
new_index: -1
>
changes: <
kind: REMOVED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
new_index: -1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d6"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 2
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d5"
fields: <
key: "a"
value: <
integer_value: 4
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 3
>
changes: <
kind: MODIFIED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d4"
fields: <
key: "a"
value: <
integer_value: -2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
>
changes: <
kind: MODIFIED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: -1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
old_index: 1
new_index: 1
>
read_time: <
seconds: 4
>
>
>

View File

@ -0,0 +1,141 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# If the watch state is not marked CURRENT, no snapshot is issued.
description: "listen: no snapshot if we don't see CURRENT"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
old_index: -1
new_index: 1
>
read_time: <
seconds: 2
>
>
>

View File

@ -0,0 +1,143 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# Document updates are recognized by a change in the update time, not the data.
# This shouldn't actually happen. It is just a test of the update logic.
description: "listen: add a doc, then change it but without changing its update time"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
responses: <
document_delete: <
document: "projects/projectID/databases/(default)/documents/C/d1"
>
>
responses: <
target_change: <
read_time: <
seconds: 3
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
read_time: <
seconds: 1
>
>
snapshots: <
changes: <
kind: REMOVED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
new_index: -1
>
read_time: <
seconds: 3
>
>
>

View File

@ -0,0 +1,131 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# A DocumentChange with the watch target ID in the removed_target_ids field is the
# same as deleting a document.
description: "listen: DocumentChange with removed_target_id is like a delete."
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
removed_target_ids: 1
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
read_time: <
seconds: 1
>
>
snapshots: <
changes: <
kind: REMOVED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
new_index: -1
>
read_time: <
seconds: 2
>
>
>

View File

@ -0,0 +1,258 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# A RESET message turns off the CURRENT state, and marks all documents as deleted.
# If a document appeared on the stream but was never part of a snapshot ("d3" in
# this test), a reset will make it disappear completely.
description: "listen: RESET turns off CURRENT"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d3"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: RESET
>
>
responses: <
target_change: <
read_time: <
seconds: 2
>
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
target_ids: 1
>
>
responses: <
target_change: <
read_time: <
seconds: 3
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 1
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 2
>
>
old_index: -1
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
new_index: 1
>
read_time: <
seconds: 1
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
changes: <
kind: REMOVED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 2
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: 1
new_index: -1
>
changes: <
kind: MODIFIED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d2"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 3
>
>
>
read_time: <
seconds: 3
>
>
>

View File

@ -0,0 +1,88 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# A TargetChange_ADD response must have the same watch target ID.
description: "listen: TargetChange_ADD is a no-op if it has the same target ID"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
target_change_type: ADD
target_ids: 1
read_time: <
seconds: 2
>
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
snapshots: <
docs: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
changes: <
kind: ADDED
doc: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
old_index: -1
>
read_time: <
seconds: 1
>
>
>

View File

@ -0,0 +1,50 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# A TargetChange_ADD response must have the same watch target ID.
description: "listen: TargetChange_ADD is an error if it has a different target ID"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
target_change_type: ADD
target_ids: 2
read_time: <
seconds: 2
>
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
is_error: true
>

View File

@ -0,0 +1,46 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# A TargetChange_REMOVE response should never be sent.
description: "listen: TargetChange_REMOVE should not appear"
listen: <
responses: <
document_change: <
document: <
name: "projects/projectID/databases/(default)/documents/C/d1"
fields: <
key: "a"
value: <
integer_value: 3
>
>
create_time: <
seconds: 1
>
update_time: <
seconds: 1
>
>
target_ids: 1
>
>
responses: <
target_change: <
target_change_type: CURRENT
>
>
responses: <
target_change: <
target_change_type: REMOVE
>
>
responses: <
target_change: <
read_time: <
seconds: 1
>
>
>
is_error: true
>

View File

@ -1,15 +1,23 @@
# DO NOT MODIFY. This file was generated by
# github.com/GoogleCloudPlatform/google-cloud-common/testing/firestore/cmd/generate-firestore-tests/generate-firestore-tests.go.
# It makes no sense to specify MergeAll and provide no data, so we disallow it on
# the client.
# This is a valid call that can be used to ensure a document exists.
description: "set: MergeAll cannot be specified with empty data."
description: "set: MergeAll can be specified with empty data."
set: <
doc_ref_path: "projects/projectID/databases/(default)/documents/C/d"
option: <
all: true
>
json_data: "{}"
is_error: true
request: <
database: "projects/projectID/databases/(default)"
writes: <
update: <
name: "projects/projectID/databases/(default)/documents/C/d"
>
update_mask: <
>
>
>
>

View File

@ -27,7 +27,7 @@ import (
"google.golang.org/genproto/googleapis/type/latlng"
)
var nullValue = &pb.Value{&pb.Value_NullValue{}}
var nullValue = &pb.Value{ValueType: &pb.Value_NullValue{}}
var (
typeOfByteSlice = reflect.TypeOf([]byte{})
@ -59,31 +59,31 @@ func toProtoValue(v reflect.Value) (pbv *pb.Value, sawServerTimestamp bool, err
}
switch x := vi.(type) {
case []byte:
return &pb.Value{&pb.Value_BytesValue{x}}, false, nil
return &pb.Value{ValueType: &pb.Value_BytesValue{x}}, false, nil
case time.Time:
ts, err := ptypes.TimestampProto(x)
if err != nil {
return nil, false, err
}
return &pb.Value{&pb.Value_TimestampValue{ts}}, false, nil
return &pb.Value{ValueType: &pb.Value_TimestampValue{ts}}, false, nil
case *ts.Timestamp:
if x == nil {
// gRPC doesn't like nil oneofs. Use NullValue.
return nullValue, false, nil
}
return &pb.Value{&pb.Value_TimestampValue{x}}, false, nil
return &pb.Value{ValueType: &pb.Value_TimestampValue{x}}, false, nil
case *latlng.LatLng:
if x == nil {
// gRPC doesn't like nil oneofs. Use NullValue.
return nullValue, false, nil
}
return &pb.Value{&pb.Value_GeoPointValue{x}}, false, nil
return &pb.Value{ValueType: &pb.Value_GeoPointValue{x}}, false, nil
case *DocumentRef:
if x == nil {
// gRPC doesn't like nil oneofs. Use NullValue.
return nullValue, false, nil
}
return &pb.Value{&pb.Value_ReferenceValue{x.Path}}, false, nil
return &pb.Value{ValueType: &pb.Value_ReferenceValue{x.Path}}, false, nil
// Do not add bool, string, int, etc. to this switch; leave them in the
// reflect-based switch below. Moving them here would drop support for
// types whose underlying types are those primitives.
@ -92,15 +92,15 @@ func toProtoValue(v reflect.Value) (pbv *pb.Value, sawServerTimestamp bool, err
}
switch v.Kind() {
case reflect.Bool:
return &pb.Value{&pb.Value_BooleanValue{v.Bool()}}, false, nil
return &pb.Value{ValueType: &pb.Value_BooleanValue{v.Bool()}}, false, nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return &pb.Value{&pb.Value_IntegerValue{v.Int()}}, false, nil
return &pb.Value{ValueType: &pb.Value_IntegerValue{v.Int()}}, false, nil
case reflect.Uint8, reflect.Uint16, reflect.Uint32:
return &pb.Value{&pb.Value_IntegerValue{int64(v.Uint())}}, false, nil
return &pb.Value{ValueType: &pb.Value_IntegerValue{int64(v.Uint())}}, false, nil
case reflect.Float32, reflect.Float64:
return &pb.Value{&pb.Value_DoubleValue{v.Float()}}, false, nil
return &pb.Value{ValueType: &pb.Value_DoubleValue{v.Float()}}, false, nil
case reflect.String:
return &pb.Value{&pb.Value_StringValue{v.String()}}, false, nil
return &pb.Value{ValueType: &pb.Value_StringValue{v.String()}}, false, nil
case reflect.Slice:
return sliceToProtoValue(v)
case reflect.Map:
@ -139,7 +139,7 @@ func sliceToProtoValue(v reflect.Value) (*pb.Value, bool, error) {
}
vals[i] = val
}
return &pb.Value{&pb.Value_ArrayValue{&pb.ArrayValue{vals}}}, false, nil
return &pb.Value{ValueType: &pb.Value_ArrayValue{&pb.ArrayValue{Values: vals}}}, false, nil
}
func mapToProtoValue(v reflect.Value) (*pb.Value, bool, error) {
@ -175,7 +175,7 @@ func mapToProtoValue(v reflect.Value) (*pb.Value, bool, error) {
// The entire map consisted of ServerTimestamp values.
pv = nil
} else {
pv = &pb.Value{&pb.Value_MapValue{&pb.MapValue{m}}}
pv = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}}
}
return pv, sawServerTimestamp, nil
}
@ -215,7 +215,7 @@ func structToProtoValue(v reflect.Value) (*pb.Value, bool, error) {
// The entire struct consisted of ServerTimestamp or omitempty values.
pv = nil
} else {
pv = &pb.Value{&pb.Value_MapValue{&pb.MapValue{m}}}
pv = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}}
}
return pv, sawServerTimestamp, nil
}

View File

@ -64,10 +64,10 @@ var (
"I": intval(1),
"U": intval(2),
"F": floatval(3),
"S": &pb.Value{&pb.Value_StringValue{"four"}},
"S": &pb.Value{ValueType: &pb.Value_StringValue{"four"}},
"Y": bytesval([]byte{5}),
"T": tsval(tm),
"Ts": &pb.Value{&pb.Value_TimestampValue{ptm}},
"Ts": &pb.Value{ValueType: &pb.Value_TimestampValue{ptm}},
"G": geoval(ll),
"L": arrayval(intval(6)),
"M": mapval(map[string]*pb.Value{"a": intval(7)}),
@ -95,7 +95,7 @@ func TestToProtoValue(t *testing.T) {
{"str", strval("str")},
{[]byte{1, 2}, bytesval([]byte{1, 2})},
{tm, tsval(tm)},
{ptm, &pb.Value{&pb.Value_TimestampValue{ptm}}},
{ptm, &pb.Value{ValueType: &pb.Value_TimestampValue{ptm}}},
{ll, geoval(ll)},
{[]int{1, 2}, arrayval(intval(1), intval(2))},
{&[]int{1, 2}, arrayval(intval(1), intval(2))},
@ -254,7 +254,7 @@ func TestToProtoValueEmbedded(t *testing.T) {
want := mapval(map[string]*pb.Value{
"Time": tsval(tm),
"LatLng": geoval(ll),
"Timestamp": &pb.Value{&pb.Value_TimestampValue{ptm}},
"Timestamp": &pb.Value{ValueType: &pb.Value_TimestampValue{ptm}},
})
if !testEqual(got, want) {
t.Errorf("got %+v, want %+v", got, want)

View File

@ -92,8 +92,7 @@ func TestRunTransaction(t *testing.T) {
if err != nil {
return err
}
tx.Update(docref, []Update{{Path: "count", Value: count.(int64) + 1}})
return nil
return tx.Update(docref, []Update{{Path: "count", Value: count.(int64) + 1}})
})
if err != nil {
t.Fatal(err)
@ -137,7 +136,7 @@ func TestRunTransaction(t *testing.T) {
Database: db,
Options: &pb.TransactionOptions{
Mode: &pb.TransactionOptions_ReadWrite_{
&pb.TransactionOptions_ReadWrite{tid},
&pb.TransactionOptions_ReadWrite{RetryTransaction: tid},
},
},
},
@ -226,7 +225,9 @@ func TestTransactionErrors(t *testing.T) {
srv.addRPC(beginReq, beginRes)
srv.addRPC(rollbackReq, &empty.Empty{})
err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error {
tx.Delete(c.Doc("C/a"))
if err := tx.Delete(c.Doc("C/a")); err != nil {
return err
}
if _, err := tx.Get(c.Doc("C/a")); err != nil {
return err
}
@ -241,7 +242,9 @@ func TestTransactionErrors(t *testing.T) {
srv.addRPC(beginReq, beginRes)
srv.addRPC(rollbackReq, &empty.Empty{})
err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error {
tx.Delete(c.Doc("C/a"))
if err := tx.Delete(c.Doc("C/a")); err != nil {
return err
}
it := tx.Documents(c.Collection("C").Select("x"))
defer it.Stop()
if _, err := it.Next(); err != iterator.Done {
@ -258,8 +261,12 @@ func TestTransactionErrors(t *testing.T) {
srv.addRPC(beginReq, beginRes)
srv.addRPC(rollbackReq, &empty.Empty{})
err = c.RunTransaction(ctx, func(_ context.Context, tx *Transaction) error {
tx.Delete(c.Doc("C/a"))
tx.Get(c.Doc("C/a"))
if err := tx.Delete(c.Doc("C/a")); err != nil {
return err
}
if _, err := tx.Get(c.Doc("C/a")); err != nil {
return err
}
return nil
})
if err != errReadAfterWrite {
@ -294,7 +301,7 @@ func TestTransactionErrors(t *testing.T) {
Database: db,
Options: &pb.TransactionOptions{
Mode: &pb.TransactionOptions_ReadWrite_{
&pb.TransactionOptions_ReadWrite{tid},
&pb.TransactionOptions_ReadWrite{RetryTransaction: tid},
},
},
},

View File

@ -103,23 +103,23 @@ func intval(i int) *pb.Value {
}
func int64val(i int64) *pb.Value {
return &pb.Value{&pb.Value_IntegerValue{i}}
return &pb.Value{ValueType: &pb.Value_IntegerValue{i}}
}
func boolval(b bool) *pb.Value {
return &pb.Value{&pb.Value_BooleanValue{b}}
return &pb.Value{ValueType: &pb.Value_BooleanValue{b}}
}
func floatval(f float64) *pb.Value {
return &pb.Value{&pb.Value_DoubleValue{f}}
return &pb.Value{ValueType: &pb.Value_DoubleValue{f}}
}
func strval(s string) *pb.Value {
return &pb.Value{&pb.Value_StringValue{s}}
return &pb.Value{ValueType: &pb.Value_StringValue{s}}
}
func bytesval(b []byte) *pb.Value {
return &pb.Value{&pb.Value_BytesValue{b}}
return &pb.Value{ValueType: &pb.Value_BytesValue{b}}
}
func tsval(t time.Time) *pb.Value {
@ -127,24 +127,24 @@ func tsval(t time.Time) *pb.Value {
if err != nil {
panic(fmt.Sprintf("bad time %s in test: %v", t, err))
}
return &pb.Value{&pb.Value_TimestampValue{ts}}
return &pb.Value{ValueType: &pb.Value_TimestampValue{ts}}
}
func geoval(ll *latlng.LatLng) *pb.Value {
return &pb.Value{&pb.Value_GeoPointValue{ll}}
return &pb.Value{ValueType: &pb.Value_GeoPointValue{ll}}
}
func arrayval(s ...*pb.Value) *pb.Value {
if s == nil {
s = []*pb.Value{}
}
return &pb.Value{&pb.Value_ArrayValue{&pb.ArrayValue{s}}}
return &pb.Value{ValueType: &pb.Value_ArrayValue{&pb.ArrayValue{Values: s}}}
}
func mapval(m map[string]*pb.Value) *pb.Value {
return &pb.Value{&pb.Value_MapValue{&pb.MapValue{m}}}
return &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}}
}
func refval(path string) *pb.Value {
return &pb.Value{&pb.Value_ReferenceValue{path}}
return &pb.Value{ValueType: &pb.Value_ReferenceValue{path}}
}

View File

@ -62,7 +62,8 @@ type DocumentChange struct {
// https://github.com/googleapis/nodejs-firestore/blob/master/src/watch.js.
// The sole target ID for all streams from this client.
const watchTargetID int32 = 'g' + 'o'
// Variable for testing.
var watchTargetID int32 = 'g' + 'o'
var defaultBackoff = gax.Backoff{
// Values from https://github.com/googleapis/nodejs-firestore/blob/master/src/backoff.js.
@ -98,7 +99,7 @@ func newWatchStreamForDocument(ctx context.Context, dr *DocumentRef) *watchStrea
compare := func(_, _ *DocumentSnapshot) (int, error) { return 0, nil }
return newWatchStream(ctx, dr.Parent.c, compare, &pb.Target{
TargetType: &pb.Target_Documents{
Documents: &pb.Target_DocumentsTarget{[]string{dr.Path}},
Documents: &pb.Target_DocumentsTarget{Documents: []string{dr.Path}},
},
TargetId: watchTargetID,
})

View File

@ -173,108 +173,6 @@ func mapDocs(m map[string]*DocumentSnapshot, less func(a, b *DocumentSnapshot) b
return ds
}
func TestWatchStream(t *testing.T) {
// Preliminary, very basic tests. Will expand and turn into cross-language tests
// later.
ctx := context.Background()
c, srv := newMock(t)
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
baseTime := time.Now()
readTime := baseTime.Add(5 * time.Second)
readTimestamp := mustTimestampProto(readTime)
doc := func(path string, value int, tm time.Time) *DocumentSnapshot {
ref := c.Doc(path)
ts := mustTimestampProto(tm)
return &DocumentSnapshot{
Ref: ref,
proto: &pb.Document{
Name: ref.Path,
Fields: map[string]*pb.Value{"foo": intval(value)},
CreateTime: ts,
UpdateTime: ts,
},
CreateTime: tm,
UpdateTime: tm,
ReadTime: readTime,
}
}
change := func(ds *DocumentSnapshot) *pb.ListenResponse {
return &pb.ListenResponse{ResponseType: &pb.ListenResponse_DocumentChange{&pb.DocumentChange{
Document: ds.proto,
TargetIds: []int32{watchTargetID},
}}}
}
del := func(ds *DocumentSnapshot) *pb.ListenResponse {
return &pb.ListenResponse{ResponseType: &pb.ListenResponse_DocumentDelete{&pb.DocumentDelete{
Document: ds.Ref.Path,
}}}
}
q := Query{c: c, collectionID: "x"}
current := &pb.ListenResponse{ResponseType: &pb.ListenResponse_TargetChange{&pb.TargetChange{
TargetChangeType: pb.TargetChange_CURRENT,
}}}
noChange := &pb.ListenResponse{ResponseType: &pb.ListenResponse_TargetChange{&pb.TargetChange{
TargetChangeType: pb.TargetChange_NO_CHANGE,
ReadTime: readTimestamp,
}}}
doc1 := doc("C/d1", 1, baseTime)
doc1a := doc("C/d1", 2, baseTime.Add(time.Second))
doc2 := doc("C/d2", 3, baseTime)
for _, test := range []struct {
desc string
responses []interface{}
want []*DocumentSnapshot
}{
{
"no changes: empty btree",
[]interface{}{current, noChange},
nil,
},
{
"add a doc",
[]interface{}{change(doc1), current, noChange},
[]*DocumentSnapshot{doc1},
},
{
"add a doc, then remove it",
[]interface{}{change(doc1), del(doc1), current, noChange},
[]*DocumentSnapshot(nil),
},
{
"add a doc, then add another one",
[]interface{}{change(doc1), change(doc2), current, noChange},
[]*DocumentSnapshot{doc1, doc2},
},
{
"add a doc, then change it",
[]interface{}{change(doc1), change(doc1a), current, noChange},
[]*DocumentSnapshot{doc1a},
},
} {
ws, err := newWatchStreamForQuery(ctx, q)
if err != nil {
t.Fatal(err)
}
request := &pb.ListenRequest{
Database: "projects/projectID/databases/(default)",
TargetChange: &pb.ListenRequest_AddTarget{ws.target},
}
srv.addRPC(request, test.responses)
tree, _, _, err := ws.nextSnapshot()
if err != nil {
t.Fatalf("%s: %v", test.desc, err)
}
got := treeDocs(tree)
if diff := testDiff(got, test.want); diff != "" {
t.Errorf("%s: %s", test.desc, diff)
}
}
}
func TestWatchCancel(t *testing.T) {
// Canceling the context of a watch should result in a codes.Canceled error from the next
// call to the iterator's Next method.

View File

@ -62,7 +62,7 @@ func TestWriteBatch(t *testing.T) {
Fields: map[string]*pb.Value{"*": intval(3)},
},
},
UpdateMask: &pb.DocumentMask{[]string{"`*`"}},
UpdateMask: &pb.DocumentMask{FieldPaths: []string{"`*`"}},
CurrentDocument: &pb.Precondition{
ConditionType: &pb.Precondition_Exists{true},
},

View File

@ -0,0 +1,128 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
// httpr is a proxy that can record or replay HTTP requests.
// Start httpr with either the -record or -replay flags, providing a filename.
// Terminate the process with an interrupt (kill -2) to write the log file when recording.
// To get the CA certificate of the proxy, issue a GET to http://localhost:CP/authority.cer, where
// CP is the control port.
// +build go1.8
package main
import (
"encoding/base64"
"flag"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"os/signal"
"cloud.google.com/go/httpreplay/internal/proxy"
"github.com/google/martian/martianhttp"
)
var (
port = flag.Int("port", 8080, "port of the proxy")
controlPort = flag.Int("control-port", 8181, "port for controlling the proxy")
record = flag.String("record", "", "record traffic and save to filename")
replay = flag.String("replay", "", "read filename and replay traffic")
debugHeaders = flag.Bool("debug-headers", false, "log header mismatches")
)
func main() {
flag.Parse()
if *record == "" && *replay == "" {
log.Fatal("provide either -record or -replay")
}
if *record != "" && *replay != "" {
log.Fatal("provide only one of -record and -replay")
}
log.Printf("httpr: starting proxy on port %d and control on port %d", *port, *controlPort)
var pr *proxy.Proxy
var err error
if *record != "" {
pr, err = proxy.ForRecording(*record, *port)
} else {
pr, err = proxy.ForReplaying(*replay, *port)
}
if err != nil {
log.Fatal(err)
}
proxy.DebugHeaders = *debugHeaders
// Expose handlers on the control port.
mux := http.NewServeMux()
mux.Handle("/authority.cer", martianhttp.NewAuthorityHandler(pr.CACert))
mux.HandleFunc("/initial", handleInitial(pr))
lControl, err := net.Listen("tcp", fmt.Sprintf(":%d", *controlPort))
if err != nil {
log.Fatal(err)
}
go http.Serve(lControl, mux)
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, os.Interrupt)
<-sigc
log.Println("httpr: shutting down")
if err := pr.Close(); err != nil {
log.Fatal(err)
}
}
func handleInitial(pr *proxy.Proxy) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case "GET":
if pr.Initial != nil {
switch x := pr.Initial.(type) {
case []byte:
w.Write(x)
case string:
// If it's base64, then it's most likely from the JSON in the saved file
// (json.Marshal encodes []byte as a base64 string). Decode it.
if bytes, err := base64.StdEncoding.DecodeString(x); err == nil {
w.Write(bytes)
} else {
// If it's not base64, write the string out directly.
w.Write([]byte(x))
}
default:
// We don't know what it is, so just print it.
fmt.Fprint(w, x)
}
}
case "POST":
bytes, err := ioutil.ReadAll(req.Body)
req.Body.Close()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "reading body: %v", err)
}
pr.Initial = bytes
default:
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "use GET to retrieve initial or POST to set it")
}
}
}

View File

@ -0,0 +1,230 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
// +build go1.8
package main_test
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"os/exec"
"strings"
"testing"
"time"
"cloud.google.com/go/internal/testutil"
"cloud.google.com/go/storage"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"google.golang.org/api/option"
)
const initial = "initial state"
func TestIntegration_HTTPR(t *testing.T) {
if testing.Short() {
t.Skip("Integration tests skipped in short mode")
}
if testutil.ProjID() == "" {
t.Fatal("set GCLOUD_TESTS_GOLANG_PROJECT_ID and GCLOUD_TESTS_GOLANG_KEY")
}
// Get a unique temporary filename.
f, err := ioutil.TempFile("", "httpreplay")
if err != nil {
t.Fatal(err)
}
replayFilename := f.Name()
if err := f.Close(); err != nil {
t.Fatal(err)
}
defer os.Remove(replayFilename)
if err := exec.Command("go", "build").Run(); err != nil {
t.Fatalf("running 'go build': %v", err)
}
defer os.Remove("./httpr")
want := runRecord(t, replayFilename)
got := runReplay(t, replayFilename)
if got != want {
t.Fatalf("got %q, want %q", got, want)
}
}
func runRecord(t *testing.T, filename string) string {
cmd, tr, cport, err := start("-record", filename)
if err != nil {
t.Fatal(err)
}
defer stop(t, cmd)
ctx := context.Background()
hc := &http.Client{
Transport: &oauth2.Transport{
Base: tr,
Source: testutil.TokenSource(ctx, storage.ScopeFullControl),
},
}
res, err := http.Post(
fmt.Sprintf("http://localhost:%s/initial", cport),
"text/plain",
strings.NewReader(initial))
if err != nil {
t.Fatal(err)
}
if res.StatusCode != 200 {
t.Fatalf("from POST: %s", res.Status)
}
info, err := getBucketInfo(ctx, hc)
if err != nil {
t.Fatal(err)
}
return info
}
func runReplay(t *testing.T, filename string) string {
cmd, tr, cport, err := start("-replay", filename)
if err != nil {
t.Fatal(err)
}
defer stop(t, cmd)
hc := &http.Client{Transport: tr}
res, err := http.Get(fmt.Sprintf("http://localhost:%s/initial", cport))
if err != nil {
t.Fatal(err)
}
if res.StatusCode != 200 {
t.Fatalf("from GET: %s", res.Status)
}
bytes, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
t.Fatal(err)
}
if got, want := string(bytes), initial; got != want {
t.Errorf("initial: got %q, want %q", got, want)
}
info, err := getBucketInfo(context.Background(), hc)
if err != nil {
t.Fatal(err)
}
return info
}
// Start the proxy binary and wait for it to come up.
// Return a transport that talks to the proxy, as well as the control port.
// modeFlag must be either "-record" or "-replay".
func start(modeFlag, filename string) (*exec.Cmd, *http.Transport, string, error) {
pport, err := pickPort()
if err != nil {
return nil, nil, "", err
}
cport, err := pickPort()
if err != nil {
return nil, nil, "", err
}
cmd := exec.Command("./httpr", "-port", pport, "-control-port", cport, modeFlag, filename, "-debug-headers")
if err := cmd.Start(); err != nil {
return nil, nil, "", err
}
// Wait for the server to come up.
serverUp := false
for i := 0; i < 10; i++ {
if conn, err := net.Dial("tcp", "localhost:"+cport); err == nil {
conn.Close()
serverUp = true
break
}
time.Sleep(time.Second)
}
if !serverUp {
return nil, nil, "", errors.New("server never came up")
}
tr, err := proxyTransport(pport, cport)
if err != nil {
return nil, nil, "", err
}
return cmd, tr, cport, nil
}
func stop(t *testing.T, cmd *exec.Cmd) {
if err := cmd.Process.Signal(os.Interrupt); err != nil {
t.Fatal(err)
}
}
// pickPort picks an unused port.
func pickPort() (string, error) {
l, err := net.Listen("tcp", ":0")
if err != nil {
return "", err
}
addr := l.Addr().String()
_, port, err := net.SplitHostPort(addr)
if err != nil {
return "", err
}
l.Close()
return port, nil
}
func proxyTransport(pport, cport string) (*http.Transport, error) {
caCert, err := getBody(fmt.Sprintf("http://localhost:%s/authority.cer", cport))
if err != nil {
return nil, err
}
caCertPool := x509.NewCertPool()
if !caCertPool.AppendCertsFromPEM([]byte(caCert)) {
return nil, errors.New("bad CA Cert")
}
return &http.Transport{
Proxy: http.ProxyURL(&url.URL{Host: "localhost:" + pport}),
TLSClientConfig: &tls.Config{RootCAs: caCertPool},
}, nil
}
func getBucketInfo(ctx context.Context, hc *http.Client) (string, error) {
client, err := storage.NewClient(ctx, option.WithHTTPClient(hc))
if err != nil {
return "", err
}
defer client.Close()
b := client.Bucket(testutil.ProjID())
attrs, err := b.Attrs(ctx)
if err != nil {
return "", err
}
return fmt.Sprintf("name:%s reqpays:%v location:%s sclass:%s",
attrs.Name, attrs.RequesterPays, attrs.Location, attrs.StorageClass), nil
}
func getBody(url string) ([]byte, error) {
res, err := http.Get(url)
if err != nil {
return nil, err
}
if res.StatusCode != 200 {
return nil, fmt.Errorf("response: %s", res.Status)
}
defer res.Body.Close()
return ioutil.ReadAll(res.Body)
}

148
vendor/cloud.google.com/go/httpreplay/httpreplay.go generated vendored Normal file
View File

@ -0,0 +1,148 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
// +build go1.8
// Package httpreplay provides an API for recording and replaying traffic
// from HTTP-based Google API clients.
//
// To record:
// 1. Call NewRecorder to get a Recorder.
// 2. Use its Client method to obtain an HTTP client to use when making API calls.
// 3. Close the Recorder when you're done. That will save the
// log of interactions to the file you provided to NewRecorder.
//
// To replay:
// 1. Call NewReplayer with the same filename you used to record to get a Replayer.
// 2. Call its Client method and use the client to make the same API calls.
// You will get back the recorded responses.
// 3. Close the Replayer when you're done.
//
// This package is EXPERIMENTAL and is subject to change or removal without notice.
// It requires Go version 1.8 or higher.
package httpreplay
// TODO(jba): add examples.
import (
"fmt"
"net/http"
"cloud.google.com/go/httpreplay/internal/proxy"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"google.golang.org/api/option"
htransport "google.golang.org/api/transport/http"
)
// A Recorder records HTTP interactions.
type Recorder struct {
filename string
proxy *proxy.Proxy
}
// NewRecorder creates a recorder that writes to filename. The file will
// also store initial state that can be retrieved to configure replay. The "initial"
// argument must work with json.Marshal.
//
// You must call Close on the Recorder to ensure that all data is written.
func NewRecorder(filename string, initial interface{}) (*Recorder, error) {
p, err := proxy.ForRecording(filename, 0)
if err != nil {
return nil, err
}
p.Initial = initial
return &Recorder{proxy: p}, nil
}
// Client returns an http.Client to be used for recording. Provide authentication options
// like option.WithTokenSource as you normally would, or omit them to use Application Default
// Credentials.
func (r *Recorder) Client(ctx context.Context, opts ...option.ClientOption) (*http.Client, error) {
hc, _, err := htransport.NewClient(ctx, opts...)
if err != nil {
return nil, err
}
// The http.Client returned by htransport.NewClient contains an
// http.RoundTripper. We want to somehow plug in a Transport that calls the proxy
// (returned by r.proxy.Transport).
//
// htransport.NewClient constructs its RoundTripper via the decorator pattern, by
// nesting several implementations of RoundTripper inside each other, ending with
// http.DefaultTransport. For example, one of the decorators is oauth2.Transport,
// which inserts an Authorization header and then calls the next RoundTripper in
// the sequence (stored in a field called Base).
//
// The problem is that we need to insert the proxy Transport at the end of this
// sequence, where http.DefaultTransport currently lives. But we can't traverse
// that sequence of RoundTrippers in general, because we don't know their types.
//
// For now, we only handle the special (but common) case where the first
// RoundTripper in the sequence is an oauth2.Transport. We can replace its Base
// field with the proxy transport. This causes us to lose the other RoundTrippers
// in the sequence, but those aren't essential for testing.
//
// A better solution would be to add option.WithBaseTransport, which would allow
// us to replace the http.DefaultTransport at the end of the sequence with the
// transport of our choice.
otrans, ok := hc.Transport.(*oauth2.Transport)
if !ok {
return nil, fmt.Errorf("can't handle Transport of type %T", hc.Transport)
}
otrans.Base = r.proxy.Transport()
return hc, nil
}
// Close closes the Recorder and saves the log file.
func (r *Recorder) Close() error {
return r.proxy.Close()
}
// A Replayer replays previously recorded HTTP interactions.
type Replayer struct {
proxy *proxy.Proxy
}
// NewReplayer creates a replayer that reads from filename.
func NewReplayer(filename string) (*Replayer, error) {
p, err := proxy.ForReplaying(filename, 0)
if err != nil {
return nil, err
}
return &Replayer{proxy: p}, nil
}
// Client returns an HTTP client for replaying. The client does not need to be
// configured with credentials for authenticating to a server, since it never
// contacts a real backend.
func (r *Replayer) Client(ctx context.Context) (*http.Client, error) {
return &http.Client{Transport: r.proxy.Transport()}, nil
}
// Initial returns the initial state saved by the Recorder.
func (r *Replayer) Initial() interface{} {
return r.proxy.Initial
}
// Close closes the replayer.
func (r *Replayer) Close() error {
return r.proxy.Close()
}
// DebugHeaders helps to determine whether a header should be ignored.
// When true, if requests have the same method, URL and body but differ
// in a header, the first mismatched header is logged.
func DebugHeaders() {
proxy.DebugHeaders = true
}

View File

@ -0,0 +1,123 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
// +build go1.8
package httpreplay_test
import (
"bytes"
"io/ioutil"
"net/http"
"os"
"testing"
"cloud.google.com/go/httpreplay"
"cloud.google.com/go/internal/testutil"
"cloud.google.com/go/storage"
"golang.org/x/net/context"
"google.golang.org/api/option"
)
func TestIntegration_RecordAndReplay(t *testing.T) {
if testing.Short() {
t.Skip("Integration tests skipped in short mode")
}
f, err := ioutil.TempFile("", "httpreplay")
if err != nil {
t.Fatal(err)
}
replayFilename := f.Name()
if err := f.Close(); err != nil {
t.Fatal(err)
}
defer os.Remove(replayFilename)
projectID := testutil.ProjID()
if projectID == "" {
t.Skip("Need project ID. See CONTRIBUTING.md for details.")
}
ctx := context.Background()
// Record.
rec, err := httpreplay.NewRecorder(replayFilename, nil)
if err != nil {
t.Fatal(err)
}
hc, err := rec.Client(ctx, option.WithTokenSource(
testutil.TokenSource(ctx, storage.ScopeFullControl)))
if err != nil {
t.Fatal(err)
}
wanta, wantc := run(t, hc)
if err := rec.Close(); err != nil {
t.Fatalf("rec.Close: %v", err)
}
// Replay.
rep, err := httpreplay.NewReplayer(replayFilename)
if err != nil {
t.Fatal(err)
}
defer rep.Close()
hc, err = rep.Client(ctx)
if err != nil {
t.Fatal(err)
}
gota, gotc := run(t, hc)
if diff := testutil.Diff(gota, wanta); diff != "" {
t.Error(diff)
}
if !bytes.Equal(gotc, wantc) {
t.Errorf("got %q, want %q", gotc, wantc)
}
if got, want := rep.Initial(), "initial state"; got != want {
t.Errorf("initial: got %v, want %q", got, want)
}
}
// TODO(jba): test errors
func run(t *testing.T, hc *http.Client) (*storage.BucketAttrs, []byte) {
ctx := context.Background()
client, err := storage.NewClient(ctx, option.WithHTTPClient(hc))
if err != nil {
t.Fatal(err)
}
defer client.Close()
b := client.Bucket(testutil.ProjID())
attrs, err := b.Attrs(ctx)
if err != nil {
t.Fatal(err)
}
obj := b.Object("replay-test")
w := obj.NewWriter(ctx)
if _, err := w.Write([]byte("hello")); err != nil {
t.Fatal(err)
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
r, err := obj.NewReader(ctx)
if err != nil {
t.Fatal(err)
}
defer r.Close()
contents, err := ioutil.ReadAll(r)
if err != nil {
t.Fatal(err)
}
return attrs, contents
}

View File

@ -0,0 +1,215 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
// +build go1.8
// The proxy package provides a record/replay HTTP proxy. It is designed to support
// both an in-memory API (cloud.google.com/go/httpreplay) and a standalone server
// (cloud.google.com/go/httpreplay/cmd/httpr).
package proxy
// See github.com/google/martian/cmd/proxy/main.go for the origin of much of this.
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"strings"
"time"
"github.com/google/martian"
"github.com/google/martian/fifo"
"github.com/google/martian/har"
"github.com/google/martian/httpspec"
"github.com/google/martian/martianlog"
"github.com/google/martian/mitm"
)
// A Proxy is an HTTP proxy that supports recording or replaying requests.
type Proxy struct {
// The certificate that the proxy uses to participate in TLS.
CACert *x509.Certificate
// The URL of the proxy.
URL *url.URL
// Initial state of the client. Must be serializable with json.Marshal.
Initial interface{}
mproxy *martian.Proxy
filename string // for log
logger *har.Logger // for recording only
}
// ForRecording returns a Proxy configured to record.
func ForRecording(filename string, port int) (*Proxy, error) {
p, err := newProxy(filename)
if err != nil {
return nil, err
}
// Configure the transport for the proxy's outgoing traffic.
p.mproxy.SetRoundTripper(&http.Transport{
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: time.Second,
})
// Construct a group that performs the standard proxy stack of request/response
// modifications.
stack, _ := httpspec.NewStack("httpr") // second arg is an internal group that we don't need
p.mproxy.SetRequestModifier(stack)
p.mproxy.SetResponseModifier(stack)
// Make a group for logging requests and responses.
logGroup := fifo.NewGroup()
skipAuth := skipLoggingByHost("accounts.google.com")
logGroup.AddRequestModifier(skipAuth)
logGroup.AddResponseModifier(skipAuth)
p.logger = har.NewLogger()
logGroup.AddRequestModifier(martian.RequestModifierFunc(
func(req *http.Request) error { return withRedactedHeaders(req, p.logger) }))
logGroup.AddResponseModifier(p.logger)
stack.AddRequestModifier(logGroup)
stack.AddResponseModifier(logGroup)
// Ordinary debug logging.
logger := martianlog.NewLogger()
logger.SetDecode(true)
stack.AddRequestModifier(logger)
stack.AddResponseModifier(logger)
if err := p.start(port); err != nil {
return nil, err
}
return p, nil
}
func newProxy(filename string) (*Proxy, error) {
mproxy := martian.NewProxy()
// Set up a man-in-the-middle configuration with a CA certificate so the proxy can
// participate in TLS.
x509c, priv, err := mitm.NewAuthority("cloud.google.com/go/httpreplay", "HTTPReplay Authority", time.Hour)
if err != nil {
return nil, err
}
mc, err := mitm.NewConfig(x509c, priv)
if err != nil {
return nil, err
}
mc.SetValidity(time.Hour)
mc.SetOrganization("cloud.google.com/go/httpreplay")
mc.SkipTLSVerify(false)
if err != nil {
return nil, err
}
mproxy.SetMITM(mc)
return &Proxy{
mproxy: mproxy,
CACert: x509c,
filename: filename,
}, nil
}
func (p *Proxy) start(port int) error {
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
return err
}
p.URL = &url.URL{Scheme: "http", Host: l.Addr().String()}
go p.mproxy.Serve(l)
return nil
}
// Transport returns an http.Transport for clients who want to talk to the proxy.
func (p *Proxy) Transport() *http.Transport {
caCertPool := x509.NewCertPool()
caCertPool.AddCert(p.CACert)
return &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: caCertPool},
Proxy: func(*http.Request) (*url.URL, error) { return p.URL, nil },
}
}
// Close closes the proxy. If the proxy is recording, it also writes the log.
func (p *Proxy) Close() error {
p.mproxy.Close()
if p.logger != nil {
return p.writeLog()
}
return nil
}
type httprFile struct {
Initial interface{}
HAR *har.HAR
}
func (p *Proxy) writeLog() error {
f := httprFile{
Initial: p.Initial,
HAR: p.logger.ExportAndReset(),
}
bytes, err := json.Marshal(f)
if err != nil {
return err
}
return ioutil.WriteFile(p.filename, bytes, 0600) // only accessible by owner
}
// Headers that may contain sensitive data (auth tokens, keys).
var sensitiveHeaders = []string{
"Authorization",
"X-Goog-Encryption-Key", // used by Cloud Storage for customer-supplied encryption
"X-Goog-Copy-Source-Encryption-Key", // ditto
}
// withRedactedHeaders removes sensitive header contents before calling mod.
func withRedactedHeaders(req *http.Request, mod martian.RequestModifier) error {
// We have to change the headers, then log, then restore them.
replaced := map[string]string{}
for _, h := range sensitiveHeaders {
if v := req.Header.Get(h); v != "" {
replaced[h] = v
req.Header.Set(h, "REDACTED")
}
}
err := mod.ModifyRequest(req)
for h, v := range replaced {
req.Header.Set(h, v)
}
return err
}
// skipLoggingByHost disables logging for traffic to a particular host.
type skipLoggingByHost string
func (s skipLoggingByHost) ModifyRequest(req *http.Request) error {
if strings.HasPrefix(req.Host, string(s)) {
martian.NewContext(req).SkipLogging()
}
return nil
}
func (s skipLoggingByHost) ModifyResponse(res *http.Response) error {
return s.ModifyRequest(res.Request)
}

Some files were not shown because too many files have changed in this diff Show More