2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-22 21:05:10 +00:00

Merge pull request #1301 from restic/update-blazer

Update vendored dependencies
This commit is contained in:
Alexander Neumann 2017-10-01 10:33:54 +02:00
commit f4120c9d45
1044 changed files with 203022 additions and 97709 deletions

26
Gopkg.lock generated
View File

@ -10,14 +10,14 @@
[[projects]] [[projects]]
name = "cloud.google.com/go" name = "cloud.google.com/go"
packages = ["compute/metadata"] packages = ["compute/metadata"]
revision = "5a9e19d4e1e41a734154e44a2132b358afb49a03" revision = "f6de2c509ed9d2af648c3c147207eaaf97149aed"
version = "v0.13.0" version = "v0.14.0"
[[projects]] [[projects]]
name = "github.com/Azure/azure-sdk-for-go" name = "github.com/Azure/azure-sdk-for-go"
packages = ["storage"] packages = ["storage"]
revision = "df4dd90d076ebbf6e87d08d3f00bfac8ff4bde1a" revision = "2592daf71ab6b95dcfc7f7437ecc1afb9ddb7360"
version = "v10.3.1-beta" version = "v11.0.0-beta"
[[projects]] [[projects]]
name = "github.com/Azure/go-autorest" name = "github.com/Azure/go-autorest"
@ -76,8 +76,8 @@
[[projects]] [[projects]]
name = "github.com/kurin/blazer" name = "github.com/kurin/blazer"
packages = ["b2","base","internal/b2types","internal/blog"] packages = ["b2","base","internal/b2types","internal/blog"]
revision = "1a870c3ee8b83e17d762307c6eae8f390ac3f4a0" revision = "cad56a04490fe20c43548d70a5a9af2be53ff14e"
version = "v0.1.1" version = "v0.2.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -149,7 +149,7 @@
branch = "master" branch = "master"
name = "github.com/spf13/cobra" name = "github.com/spf13/cobra"
packages = [".","doc"] packages = [".","doc"]
revision = "b78744579491c1ceeaaa3b40205e56b0591b93a3" revision = "e5f66de850af3302fbe378c8acded2b0fa55472c"
[[projects]] [[projects]]
name = "github.com/spf13/pflag" name = "github.com/spf13/pflag"
@ -161,31 +161,31 @@
branch = "master" branch = "master"
name = "golang.org/x/crypto" name = "golang.org/x/crypto"
packages = ["curve25519","ed25519","ed25519/internal/edwards25519","pbkdf2","poly1305","scrypt","ssh","ssh/terminal"] packages = ["curve25519","ed25519","ed25519/internal/edwards25519","pbkdf2","poly1305","scrypt","ssh","ssh/terminal"]
revision = "7d9177d70076375b9a59c8fde23d52d9c4a7ecd5" revision = "9419663f5a44be8b34ca85f08abc5fe1be11f8a3"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/net" name = "golang.org/x/net"
packages = ["context","context/ctxhttp"] packages = ["context","context/ctxhttp"]
revision = "b60f3a92103dfd93dfcb900ec77c6d0643510868" revision = "0a9397675ba34b2845f758fe3cd68828369c6517"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/oauth2" name = "golang.org/x/oauth2"
packages = [".","google","internal","jws","jwt"] packages = [".","google","internal","jws","jwt"]
revision = "13449ad91cb26cb47661c1b080790392170385fd" revision = "bb50c06baba3d0c76f9d125c0719093e315b5b44"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/sys" name = "golang.org/x/sys"
packages = ["unix","windows"] packages = ["unix","windows"]
revision = "b6e1ae21643682ce023deb8d152024597b0e9bb4" revision = "314a259e304ff91bd6985da2a7149bbf91237993"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "google.golang.org/api" name = "google.golang.org/api"
packages = ["gensupport","googleapi","googleapi/internal/uritemplates","storage/v1"] packages = ["gensupport","googleapi","googleapi/internal/uritemplates","storage/v1"]
revision = "586095a6e4078caf0dc0b64f8545fa8679442013" revision = "906273f42cdebd65de3a53f30dd9e23de1b55ba9"
[[projects]] [[projects]]
name = "google.golang.org/appengine" name = "google.golang.org/appengine"
@ -202,6 +202,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "53e4779dc4c7de2cd8b195f13c215c24da5efc5e33acf584615b5c43bfefd2db" inputs-digest = "2dcd9dd39ea4ddc31d36a6ed04dec261ab34484e350fba08a44f8cc5366d4d3f"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -29,10 +29,6 @@
name = "github.com/elithrar/simple-scrypt" name = "github.com/elithrar/simple-scrypt"
branch = "master" branch = "master"
[[constraint]]
name = "github.com/kurin/blazer"
version = "0.1.0"
[[constraint]] [[constraint]]
name = "github.com/minio/minio-go" name = "github.com/minio/minio-go"
version = "3.0.0" version = "3.0.0"

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

@ -33,6 +33,32 @@ make backwards-incompatible changes.
## News ## News
_September 28, 2017_
*v0.14.0*
- bigquery BREAKING CHANGES:
- Standard SQL is the default for queries and views.
- `Table.Create` takes `TableMetadata` as a second argument, instead of
options.
- `Dataset.Create` takes `DatasetMetadata` as a second argument.
- `DatasetMetadata` field `ID` renamed to `FullID`
- `TableMetadata` field `ID` renamed to `FullID`
- Other bigquery changes:
- The client will append a random suffix to a provided job ID if you set
`AddJobIDSuffix` to true in a job config.
- Listing jobs is supported.
- Better retry logic.
- vision, language, speech: clients are now stable
- monitoring: client is now beta
- profiler:
- Rename InstanceName to Instance, ZoneName to Zone
- Auto-detect service name and version on AppEngine.
_September 8, 2017_ _September 8, 2017_
*v0.13.0* *v0.13.0*
@ -124,11 +150,11 @@ Google API | Status | Package
[Bigtable][cloud-bigtable] | beta | [`cloud.google.com/go/bigtable`][cloud-bigtable-ref] [Bigtable][cloud-bigtable] | beta | [`cloud.google.com/go/bigtable`][cloud-bigtable-ref]
[BigQuery][cloud-bigquery] | beta | [`cloud.google.com/go/bigquery`][cloud-bigquery-ref] [BigQuery][cloud-bigquery] | beta | [`cloud.google.com/go/bigquery`][cloud-bigquery-ref]
[Logging][cloud-logging] | stable | [`cloud.google.com/go/logging`][cloud-logging-ref] [Logging][cloud-logging] | stable | [`cloud.google.com/go/logging`][cloud-logging-ref]
[Monitoring][cloud-monitoring] | alpha | [`cloud.google.com/go/monitoring/apiv3`][cloud-monitoring-ref] [Monitoring][cloud-monitoring] | beta | [`cloud.google.com/go/monitoring/apiv3`][cloud-monitoring-ref]
[Pub/Sub][cloud-pubsub] | beta | [`cloud.google.com/go/pubsub`][cloud-pubsub-ref] [Pub/Sub][cloud-pubsub] | beta | [`cloud.google.com/go/pubsub`][cloud-pubsub-ref]
[Vision][cloud-vision] | beta | [`cloud.google.com/go/vision/apiv1`][cloud-vision-ref] [Vision][cloud-vision] | stable | [`cloud.google.com/go/vision/apiv1`][cloud-vision-ref]
[Language][cloud-language] | beta | [`cloud.google.com/go/language/apiv1`][cloud-language-ref] [Language][cloud-language] | stable | [`cloud.google.com/go/language/apiv1`][cloud-language-ref]
[Speech][cloud-speech] | beta | [`cloud.google.com/go/speech/apiv1`][cloud-speech-ref] [Speech][cloud-speech] | stable | [`cloud.google.com/go/speech/apiv1`][cloud-speech-ref]
[Spanner][cloud-spanner] | beta | [`cloud.google.com/go/spanner`][cloud-spanner-ref] [Spanner][cloud-spanner] | beta | [`cloud.google.com/go/spanner`][cloud-spanner-ref]
[Translation][cloud-translation] | stable | [`cloud.google.com/go/translate`][cloud-translation-ref] [Translation][cloud-translation] | stable | [`cloud.google.com/go/translate`][cloud-translation-ref]
[Trace][cloud-trace] | alpha | [`cloud.google.com/go/trace`][cloud-trace-ref] [Trace][cloud-trace] | alpha | [`cloud.google.com/go/trace`][cloud-trace-ref]

View File

@ -21,9 +21,12 @@ import (
// CopyConfig holds the configuration for a copy job. // CopyConfig holds the configuration for a copy job.
type CopyConfig struct { type CopyConfig struct {
// JobID is the ID to use for the copy job. If unset, a job ID will be automatically created. // JobID is the ID to use for the job. If empty, a random job ID will be generated.
JobID string JobID string
// If AddJobIDSuffix is true, then a random string will be appended to JobID.
AddJobIDSuffix bool
// Srcs are the tables from which data will be copied. // Srcs are the tables from which data will be copied.
Srcs []*Table Srcs []*Table
@ -68,7 +71,9 @@ func (c *Copier) Run(ctx context.Context) (*Job, error) {
for _, t := range c.Srcs { for _, t := range c.Srcs {
conf.SourceTables = append(conf.SourceTables, t.tableRefProto()) conf.SourceTables = append(conf.SourceTables, t.tableRefProto())
} }
job := &bq.Job{Configuration: &bq.JobConfiguration{Copy: conf}} job := &bq.Job{
setJobRef(job, c.JobID, c.c.projectID) JobReference: createJobRef(c.JobID, c.AddJobIDSuffix, c.c.projectID),
Configuration: &bq.JobConfiguration{Copy: conf},
}
return c.c.insertJob(ctx, &insertJobConf{job: job}) return c.c.insertJob(ctx, &insertJobConf{job: job})
} }

View File

@ -17,16 +17,13 @@ package bigquery
import ( import (
"testing" "testing"
"cloud.google.com/go/internal/testutil"
"github.com/google/go-cmp/cmp/cmpopts"
"golang.org/x/net/context" "golang.org/x/net/context"
bq "google.golang.org/api/bigquery/v2" bq "google.golang.org/api/bigquery/v2"
) )
func defaultCopyJob() *bq.Job { func defaultCopyJob() *bq.Job {
return &bq.Job{ return &bq.Job{
JobReference: &bq.JobReference{ProjectId: "client-project-id"}, JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"},
Configuration: &bq.JobConfiguration{ Configuration: &bq.JobConfiguration{
Copy: &bq.JobConfigurationTableCopy{ Copy: &bq.JobConfigurationTableCopy{
DestinationTable: &bq.TableReference{ DestinationTable: &bq.TableReference{
@ -47,6 +44,7 @@ func defaultCopyJob() *bq.Job {
} }
func TestCopy(t *testing.T) { func TestCopy(t *testing.T) {
defer fixRandomJobID("RANDOM")()
testCases := []struct { testCases := []struct {
dst *Table dst *Table
srcs []*Table srcs []*Table
@ -132,18 +130,3 @@ func TestCopy(t *testing.T) {
checkJob(t, i, s.Job, tc.want) checkJob(t, i, s.Job, tc.want)
} }
} }
func checkJob(t *testing.T, i int, got, want *bq.Job) {
if got.JobReference == nil {
t.Errorf("#%d: empty job reference", i)
return
}
if got.JobReference.JobId == "" {
t.Errorf("#%d: empty job ID", i)
return
}
d := testutil.Diff(got, want, cmpopts.IgnoreFields(bq.JobReference{}, "JobId"))
if d != "" {
t.Errorf("#%d: (got=-, want=+) %s", i, d)
}
}

View File

@ -1,122 +0,0 @@
// Copyright 2015 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 bigquery
import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"cloud.google.com/go/internal/testutil"
"golang.org/x/net/context"
bq "google.golang.org/api/bigquery/v2"
)
type createTableRecorder struct {
conf *createTableConf
service
}
func (rec *createTableRecorder) createTable(ctx context.Context, conf *createTableConf) error {
rec.conf = conf
return nil
}
func TestCreateTableOptions(t *testing.T) {
s := &createTableRecorder{}
c := &Client{
projectID: "p",
service: s,
}
ds := c.Dataset("d")
table := ds.Table("t")
exp := time.Now()
q := "query"
if err := table.Create(context.Background(), TableExpiration(exp), ViewQuery(q), UseStandardSQL()); err != nil {
t.Fatalf("err calling Table.Create: %v", err)
}
want := createTableConf{
projectID: "p",
datasetID: "d",
tableID: "t",
expiration: exp,
viewQuery: q,
useStandardSQL: true,
}
equal := func(x, y createTableConf) bool {
return testutil.Equal(x, y, cmp.AllowUnexported(createTableConf{}))
}
if !equal(*s.conf, want) {
t.Errorf("createTableConf: got:\n%v\nwant:\n%v", *s.conf, want)
}
sc := Schema{fieldSchema("desc", "name", "STRING", false, true)}
if err := table.Create(context.Background(), TableExpiration(exp), sc); err != nil {
t.Fatalf("err calling Table.Create: %v", err)
}
want = createTableConf{
projectID: "p",
datasetID: "d",
tableID: "t",
expiration: exp,
// No need for an elaborate schema, that is tested in schema_test.go.
schema: &bq.TableSchema{
Fields: []*bq.TableFieldSchema{
bqTableFieldSchema("desc", "name", "STRING", "REQUIRED"),
},
},
}
if !equal(*s.conf, want) {
t.Errorf("createTableConf: got:\n%v\nwant:\n%v", *s.conf, want)
}
partitionCases := []struct {
timePartitioning TimePartitioning
expectedExpiration time.Duration
}{
{TimePartitioning{}, time.Duration(0)},
{TimePartitioning{time.Second}, time.Second},
}
for _, c := range partitionCases {
if err := table.Create(context.Background(), c.timePartitioning); err != nil {
t.Fatalf("err calling Table.Create: %v", err)
}
want = createTableConf{
projectID: "p",
datasetID: "d",
tableID: "t",
timePartitioning: &TimePartitioning{c.expectedExpiration},
}
if !equal(*s.conf, want) {
t.Errorf("createTableConf: got:\n%v\nwant:\n%v", *s.conf, want)
}
}
}
func TestCreateTableOptionsLegacySQL(t *testing.T) {
c := &Client{
projectID: "p",
service: &bigqueryService{},
}
ds := c.Dataset("d")
table := ds.Table("t")
if err := table.Create(context.Background(), UseStandardSQL(), UseLegacySQL()); err == nil {
t.Fatal("no error using both standard and legacy SQL options")
}
}

View File

@ -30,22 +30,28 @@ type Dataset struct {
c *Client c *Client
} }
// DatasetMetadata contains information about a BigQuery dataset.
type DatasetMetadata struct { type DatasetMetadata struct {
CreationTime time.Time // These fields can be set when creating a dataset.
LastModifiedTime time.Time // When the dataset or any of its tables were modified. Name string // The user-friendly name for this dataset.
DefaultTableExpiration time.Duration // The default expiration time for new tables. Description string // The user-friendly description of this dataset.
Description string // The user-friendly description of this dataset.
Name string // The user-friendly name for this dataset.
ID string
Location string // The geo location of the dataset. Location string // The geo location of the dataset.
DefaultTableExpiration time.Duration // The default expiration time for new tables.
Labels map[string]string // User-provided labels. Labels map[string]string // User-provided labels.
// These fields are read-only.
CreationTime time.Time
LastModifiedTime time.Time // When the dataset or any of its tables were modified.
FullID string // The full dataset ID in the form projectID:datasetID.
// ETag is the ETag obtained when reading metadata. Pass it to Dataset.Update to // ETag is the ETag obtained when reading metadata. Pass it to Dataset.Update to
// ensure that the metadata hasn't changed since it was read. // ensure that the metadata hasn't changed since it was read.
ETag string ETag string
// TODO(jba): access rules // TODO(jba): access rules
} }
// DatasetMetadataToUpdate is used when updating a dataset's metadata.
// Only non-nil fields will be updated.
type DatasetMetadataToUpdate struct { type DatasetMetadataToUpdate struct {
Description optional.String // The user-friendly description of this table. Description optional.String // The user-friendly description of this table.
Name optional.String // The user-friendly name for this dataset. Name optional.String // The user-friendly name for this dataset.
@ -89,10 +95,10 @@ func (c *Client) DatasetInProject(projectID, datasetID string) *Dataset {
} }
} }
// Create creates a dataset in the BigQuery service. An error will be returned // Create creates a dataset in the BigQuery service. An error will be returned if the
// if the dataset already exists. // dataset already exists. Pass in a DatasetMetadata value to configure the dataset.
func (d *Dataset) Create(ctx context.Context) error { func (d *Dataset) Create(ctx context.Context, md *DatasetMetadata) error {
return d.c.service.insertDataset(ctx, d.DatasetID, d.ProjectID) return d.c.service.insertDataset(ctx, d.DatasetID, d.ProjectID, md)
} }
// Delete deletes the dataset. // Delete deletes the dataset.

View File

@ -17,6 +17,7 @@ package bigquery_test
import ( import (
"fmt" "fmt"
"os" "os"
"time"
"cloud.google.com/go/bigquery" "cloud.google.com/go/bigquery"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -233,7 +234,8 @@ func ExampleDataset_Create() {
if err != nil { if err != nil {
// TODO: Handle error. // TODO: Handle error.
} }
if err := client.Dataset("my_dataset").Create(ctx); err != nil { ds := client.Dataset("my_dataset")
if err := ds.Create(ctx, &bigquery.DatasetMetadata{Location: "EU"}); err != nil {
// TODO: Handle error. // TODO: Handle error.
} }
} }
@ -389,13 +391,13 @@ func ExampleTable_Create() {
// TODO: Handle error. // TODO: Handle error.
} }
t := client.Dataset("my_dataset").Table("new-table") t := client.Dataset("my_dataset").Table("new-table")
if err := t.Create(ctx); err != nil { if err := t.Create(ctx, nil); err != nil {
// TODO: Handle error. // TODO: Handle error.
} }
} }
// If you know your table's schema initially, pass a Schema to Create. // Initialize a new table by passing TableMetadata to Table.Create.
func ExampleTable_Create_schema() { func ExampleTable_Create_initialize() {
ctx := context.Background() ctx := context.Background()
// Infer table schema from a Go type. // Infer table schema from a Go type.
schema, err := bigquery.InferSchema(Item{}) schema, err := bigquery.InferSchema(Item{})
@ -407,7 +409,12 @@ func ExampleTable_Create_schema() {
// TODO: Handle error. // TODO: Handle error.
} }
t := client.Dataset("my_dataset").Table("new-table") t := client.Dataset("my_dataset").Table("new-table")
if err := t.Create(ctx, schema); err != nil { if err := t.Create(ctx,
&bigquery.TableMetadata{
Name: "My New Table",
Schema: schema,
ExpirationTime: time.Now().Add(24 * time.Hour),
}); err != nil {
// TODO: Handle error. // TODO: Handle error.
} }
} }

View File

@ -21,9 +21,12 @@ import (
// ExtractConfig holds the configuration for an extract job. // ExtractConfig holds the configuration for an extract job.
type ExtractConfig struct { type ExtractConfig struct {
// JobID is the ID to use for the extract job. If empty, a job ID will be automatically created. // JobID is the ID to use for the job. If empty, a random job ID will be generated.
JobID string JobID string
// If AddJobIDSuffix is true, then a random string will be appended to JobID.
AddJobIDSuffix bool
// Src is the table from which data will be extracted. // Src is the table from which data will be extracted.
Src *Table Src *Table
@ -55,22 +58,23 @@ func (t *Table) ExtractorTo(dst *GCSReference) *Extractor {
// Run initiates an extract job. // Run initiates an extract job.
func (e *Extractor) Run(ctx context.Context) (*Job, error) { func (e *Extractor) Run(ctx context.Context) (*Job, error) {
conf := &bq.JobConfigurationExtract{} var printHeader *bool
job := &bq.Job{Configuration: &bq.JobConfiguration{Extract: conf}}
setJobRef(job, e.JobID, e.c.projectID)
conf.DestinationUris = append([]string{}, e.Dst.uris...)
conf.Compression = string(e.Dst.Compression)
conf.DestinationFormat = string(e.Dst.DestinationFormat)
conf.FieldDelimiter = e.Dst.FieldDelimiter
conf.SourceTable = e.Src.tableRefProto()
if e.DisableHeader { if e.DisableHeader {
f := false f := false
conf.PrintHeader = &f printHeader = &f
}
job := &bq.Job{
JobReference: createJobRef(e.JobID, e.AddJobIDSuffix, e.c.projectID),
Configuration: &bq.JobConfiguration{
Extract: &bq.JobConfigurationExtract{
DestinationUris: append([]string{}, e.Dst.uris...),
Compression: string(e.Dst.Compression),
DestinationFormat: string(e.Dst.DestinationFormat),
FieldDelimiter: e.Dst.FieldDelimiter,
SourceTable: e.Src.tableRefProto(),
PrintHeader: printHeader,
},
},
} }
return e.c.insertJob(ctx, &insertJobConf{job: job}) return e.c.insertJob(ctx, &insertJobConf{job: job})
} }

View File

@ -24,7 +24,7 @@ import (
func defaultExtractJob() *bq.Job { func defaultExtractJob() *bq.Job {
return &bq.Job{ return &bq.Job{
JobReference: &bq.JobReference{ProjectId: "client-project-id"}, JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"},
Configuration: &bq.JobConfiguration{ Configuration: &bq.JobConfiguration{
Extract: &bq.JobConfigurationExtract{ Extract: &bq.JobConfigurationExtract{
SourceTable: &bq.TableReference{ SourceTable: &bq.TableReference{
@ -39,6 +39,7 @@ func defaultExtractJob() *bq.Job {
} }
func TestExtract(t *testing.T) { func TestExtract(t *testing.T) {
defer fixRandomJobID("RANDOM")()
s := &testService{} s := &testService{}
c := &Client{ c := &Client{
service: s, service: s,

View File

@ -49,6 +49,7 @@ var (
}}, }},
} }
testTableExpiration time.Time testTableExpiration time.Time
datasetIDs = testutil.NewUIDSpace("dataset")
) )
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
@ -82,13 +83,13 @@ func initIntegrationTest() {
log.Fatalf("NewClient: %v", err) log.Fatalf("NewClient: %v", err)
} }
dataset = client.Dataset("bigquery_integration_test") dataset = client.Dataset("bigquery_integration_test")
if err := dataset.Create(ctx); err != nil && !hasStatusCode(err, http.StatusConflict) { // AlreadyExists is 409 if err := dataset.Create(ctx, nil); err != nil && !hasStatusCode(err, http.StatusConflict) { // AlreadyExists is 409
log.Fatalf("creating dataset: %v", err) log.Fatalf("creating dataset: %v", err)
} }
testTableExpiration = time.Now().Add(10 * time.Minute).Round(time.Second) testTableExpiration = time.Now().Add(10 * time.Minute).Round(time.Second)
} }
func TestIntegration_Create(t *testing.T) { func TestIntegration_TableCreate(t *testing.T) {
// Check that creating a record field with an empty schema is an error. // Check that creating a record field with an empty schema is an error.
if client == nil { if client == nil {
t.Skip("Integration tests skipped") t.Skip("Integration tests skipped")
@ -97,7 +98,10 @@ func TestIntegration_Create(t *testing.T) {
schema := Schema{ schema := Schema{
{Name: "rec", Type: RecordFieldType, Schema: Schema{}}, {Name: "rec", Type: RecordFieldType, Schema: Schema{}},
} }
err := table.Create(context.Background(), schema, TableExpiration(time.Now().Add(5*time.Minute))) err := table.Create(context.Background(), &TableMetadata{
Schema: schema,
ExpirationTime: time.Now().Add(5 * time.Minute),
})
if err == nil { if err == nil {
t.Fatal("want error, got nil") t.Fatal("want error, got nil")
} }
@ -106,7 +110,7 @@ func TestIntegration_Create(t *testing.T) {
} }
} }
func TestIntegration_CreateView(t *testing.T) { func TestIntegration_TableCreateView(t *testing.T) {
if client == nil { if client == nil {
t.Skip("Integration tests skipped") t.Skip("Integration tests skipped")
} }
@ -116,8 +120,12 @@ func TestIntegration_CreateView(t *testing.T) {
// Test that standard SQL views work. // Test that standard SQL views work.
view := dataset.Table("t_view_standardsql") view := dataset.Table("t_view_standardsql")
query := ViewQuery(fmt.Sprintf("SELECT APPROX_COUNT_DISTINCT(name) FROM `%s.%s.%s`", dataset.ProjectID, dataset.DatasetID, table.TableID)) query := fmt.Sprintf("SELECT APPROX_COUNT_DISTINCT(name) FROM `%s.%s.%s`",
err := view.Create(context.Background(), UseStandardSQL(), query) dataset.ProjectID, dataset.DatasetID, table.TableID)
err := view.Create(context.Background(), &TableMetadata{
ViewQuery: query,
UseStandardSQL: true,
})
if err != nil { if err != nil {
t.Fatalf("table.create: Did not expect an error, got: %v", err) t.Fatalf("table.create: Did not expect an error, got: %v", err)
} }
@ -137,8 +145,8 @@ func TestIntegration_TableMetadata(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// TODO(jba): check md more thorougly. // TODO(jba): check md more thorougly.
if got, want := md.ID, fmt.Sprintf("%s:%s.%s", dataset.ProjectID, dataset.DatasetID, table.TableID); got != want { if got, want := md.FullID, fmt.Sprintf("%s:%s.%s", dataset.ProjectID, dataset.DatasetID, table.TableID); got != want {
t.Errorf("metadata.ID: got %q, want %q", got, want) t.Errorf("metadata.FullID: got %q, want %q", got, want)
} }
if got, want := md.Type, RegularTable; got != want { if got, want := md.Type, RegularTable; got != want {
t.Errorf("metadata.Type: got %v, want %v", got, want) t.Errorf("metadata.Type: got %v, want %v", got, want)
@ -162,7 +170,11 @@ func TestIntegration_TableMetadata(t *testing.T) {
} }
for i, c := range partitionCases { for i, c := range partitionCases {
table := dataset.Table(fmt.Sprintf("t_metadata_partition_%v", i)) table := dataset.Table(fmt.Sprintf("t_metadata_partition_%v", i))
err = table.Create(context.Background(), schema, c.timePartitioning, TableExpiration(time.Now().Add(5*time.Minute))) err = table.Create(context.Background(), &TableMetadata{
Schema: schema,
TimePartitioning: &c.timePartitioning,
ExpirationTime: time.Now().Add(5 * time.Minute),
})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -180,6 +192,33 @@ func TestIntegration_TableMetadata(t *testing.T) {
} }
} }
func TestIntegration_DatasetCreate(t *testing.T) {
if client == nil {
t.Skip("Integration tests skipped")
}
ctx := context.Background()
uid := strings.Replace(datasetIDs.New(), "-", "_", -1)
ds := client.Dataset(uid)
wmd := &DatasetMetadata{Name: "name", Location: "EU"}
err := ds.Create(ctx, wmd)
if err != nil {
t.Fatal(err)
}
gmd, err := ds.Metadata(ctx)
if err != nil {
t.Fatal(err)
}
if got, want := gmd.Name, wmd.Name; got != want {
t.Errorf("name: got %q, want %q", got, want)
}
if got, want := gmd.Location, wmd.Location; got != want {
t.Errorf("location: got %q, want %q", got, want)
}
if err := ds.Delete(ctx); err != nil {
t.Fatalf("deleting dataset %s: %v", ds, err)
}
}
func TestIntegration_DatasetMetadata(t *testing.T) { func TestIntegration_DatasetMetadata(t *testing.T) {
if client == nil { if client == nil {
t.Skip("Integration tests skipped") t.Skip("Integration tests skipped")
@ -189,8 +228,8 @@ func TestIntegration_DatasetMetadata(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if got, want := md.ID, fmt.Sprintf("%s:%s", dataset.ProjectID, dataset.DatasetID); got != want { if got, want := md.FullID, fmt.Sprintf("%s:%s", dataset.ProjectID, dataset.DatasetID); got != want {
t.Errorf("ID: got %q, want %q", got, want) t.Errorf("FullID: got %q, want %q", got, want)
} }
jan2016 := time.Date(2016, 1, 1, 0, 0, 0, 0, time.UTC) jan2016 := time.Date(2016, 1, 1, 0, 0, 0, 0, time.UTC)
if md.CreationTime.Before(jan2016) { if md.CreationTime.Before(jan2016) {
@ -213,7 +252,7 @@ func TestIntegration_DatasetDelete(t *testing.T) {
} }
ctx := context.Background() ctx := context.Background()
ds := client.Dataset("delete_test") ds := client.Dataset("delete_test")
if err := ds.Create(ctx); err != nil && !hasStatusCode(err, http.StatusConflict) { // AlreadyExists is 409 if err := ds.Create(ctx, nil); err != nil && !hasStatusCode(err, http.StatusConflict) { // AlreadyExists is 409
t.Fatalf("creating dataset %s: %v", ds, err) t.Fatalf("creating dataset %s: %v", ds, err)
} }
if err := ds.Delete(ctx); err != nil { if err := ds.Delete(ctx); err != nil {
@ -276,8 +315,7 @@ func TestIntegration_DatasetUpdateDefaultExpiration(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Set the default expiration time. // Set the default expiration time.
md, err = dataset.Update(ctx, md, err = dataset.Update(ctx, DatasetMetadataToUpdate{DefaultTableExpiration: time.Hour}, "")
DatasetMetadataToUpdate{DefaultTableExpiration: time.Hour}, "")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -293,8 +331,7 @@ func TestIntegration_DatasetUpdateDefaultExpiration(t *testing.T) {
t.Fatalf("got %s, want 1h", md.DefaultTableExpiration) t.Fatalf("got %s, want 1h", md.DefaultTableExpiration)
} }
// Setting it to 0 deletes it (which looks like a 0 duration). // Setting it to 0 deletes it (which looks like a 0 duration).
md, err = dataset.Update(ctx, md, err = dataset.Update(ctx, DatasetMetadataToUpdate{DefaultTableExpiration: time.Duration(0)}, "")
DatasetMetadataToUpdate{DefaultTableExpiration: time.Duration(0)}, "")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -746,15 +783,7 @@ func TestIntegration_TableUpdate(t *testing.T) {
schema3[0], schema3[1], schema3[2], schema3[0], schema3[1], schema3[2],
{Name: "rec2", Type: RecordFieldType, Schema: Schema{}}}}, {Name: "rec2", Type: RecordFieldType, Schema: Schema{}}}},
} { } {
for { _, err = table.Update(ctx, TableMetadataToUpdate{Schema: Schema(test.fields)}, "")
_, err = table.Update(ctx, TableMetadataToUpdate{Schema: Schema(test.fields)}, "")
if !hasStatusCode(err, 403) {
break
}
// We've hit the rate limit for updates. Wait a bit and retry.
t.Logf("%s: retrying after getting %v", test.desc, err)
time.Sleep(4 * time.Second)
}
if err == nil { if err == nil {
t.Errorf("%s: want error, got nil", test.desc) t.Errorf("%s: want error, got nil", test.desc)
} else if !hasStatusCode(err, 400) { } else if !hasStatusCode(err, 400) {
@ -818,7 +847,9 @@ func TestIntegration_DML(t *testing.T) {
q.UseStandardSQL = true // necessary for DML q.UseStandardSQL = true // necessary for DML
job, err := q.Run(ctx) job, err := q.Run(ctx)
if err != nil { if err != nil {
fmt.Printf("q.Run: %v\n", err) if e, ok := err.(*googleapi.Error); ok && e.Code < 500 {
return true, err // fail on 4xx
}
return false, err return false, err
} }
if err := wait(ctx, job); err != nil { if err := wait(ctx, job); err != nil {
@ -961,6 +992,7 @@ func TestIntegration_LegacyQuery(t *testing.T) {
} }
for _, c := range testCases { for _, c := range testCases {
q := client.Query(c.query) q := client.Query(c.query)
q.UseLegacySQL = true
it, err := q.Read(ctx) it, err := q.Read(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -1070,11 +1102,11 @@ var useLegacySqlTests = []struct {
}{ }{
{t: legacyName, std: false, legacy: true, err: false}, {t: legacyName, std: false, legacy: true, err: false},
{t: legacyName, std: true, legacy: false, err: true}, {t: legacyName, std: true, legacy: false, err: true},
{t: legacyName, std: false, legacy: false, err: false}, // legacy SQL is default {t: legacyName, std: false, legacy: false, err: true}, // standard SQL is default
{t: legacyName, std: true, legacy: true, err: true}, {t: legacyName, std: true, legacy: true, err: true},
{t: stdName, std: false, legacy: true, err: true}, {t: stdName, std: false, legacy: true, err: true},
{t: stdName, std: true, legacy: false, err: false}, {t: stdName, std: true, legacy: false, err: false},
{t: stdName, std: false, legacy: false, err: true}, // legacy SQL is default {t: stdName, std: false, legacy: false, err: false}, // standard SQL is default
{t: stdName, std: true, legacy: true, err: true}, {t: stdName, std: true, legacy: true, err: true},
} }
@ -1099,7 +1131,7 @@ func TestIntegration_QueryUseLegacySQL(t *testing.T) {
} }
func TestIntegration_TableUseLegacySQL(t *testing.T) { func TestIntegration_TableUseLegacySQL(t *testing.T) {
// Test the UseLegacySQL and UseStandardSQL options for CreateTable. // Test UseLegacySQL and UseStandardSQL for Table.Create.
if client == nil { if client == nil {
t.Skip("Integration tests skipped") t.Skip("Integration tests skipped")
} }
@ -1108,15 +1140,12 @@ func TestIntegration_TableUseLegacySQL(t *testing.T) {
defer table.Delete(ctx) defer table.Delete(ctx)
for i, test := range useLegacySqlTests { for i, test := range useLegacySqlTests {
view := dataset.Table(fmt.Sprintf("t_view_%d", i)) view := dataset.Table(fmt.Sprintf("t_view_%d", i))
vq := ViewQuery(fmt.Sprintf("SELECT word from %s", test.t)) tm := &TableMetadata{
opts := []CreateTableOption{vq} ViewQuery: fmt.Sprintf("SELECT word from %s", test.t),
if test.std { UseStandardSQL: test.std,
opts = append(opts, UseStandardSQL()) UseLegacySQL: test.legacy,
} }
if test.legacy { err := view.Create(ctx, tm)
opts = append(opts, UseLegacySQL())
}
err := view.Create(ctx, opts...)
gotErr := err != nil gotErr := err != nil
if gotErr && !test.err { if gotErr && !test.err {
t.Errorf("%+v:\nunexpected error: %v", test, err) t.Errorf("%+v:\nunexpected error: %v", test, err)
@ -1127,11 +1156,46 @@ func TestIntegration_TableUseLegacySQL(t *testing.T) {
} }
} }
func TestIntegration_ListJobs(t *testing.T) {
// It's difficult to test the list of jobs, because we can't easily
// control what's in it. Also, there are many jobs in the test project,
// and it takes considerable time to list them all.
if client == nil {
t.Skip("Integration tests skipped")
}
ctx := context.Background()
// About all we can do is list a few jobs.
const max = 20
var jis []JobInfo
it := client.Jobs(ctx)
for {
ji, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
t.Fatal(err)
}
jis = append(jis, ji)
if len(jis) >= max {
break
}
}
// We expect that there is at least one job in the last few months.
if len(jis) == 0 {
t.Fatal("did not get any jobs")
}
}
// Creates a new, temporary table with a unique name and the given schema. // Creates a new, temporary table with a unique name and the given schema.
func newTable(t *testing.T, s Schema) *Table { func newTable(t *testing.T, s Schema) *Table {
name := fmt.Sprintf("t%d", time.Now().UnixNano()) name := fmt.Sprintf("t%d", time.Now().UnixNano())
table := dataset.Table(name) table := dataset.Table(name)
err := table.Create(context.Background(), s, TableExpiration(testTableExpiration)) err := table.Create(context.Background(), &TableMetadata{
Schema: s,
ExpirationTime: testTableExpiration,
})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -16,6 +16,7 @@ package bigquery
import ( import (
"errors" "errors"
"fmt"
"math/rand" "math/rand"
"os" "os"
"sync" "sync"
@ -25,6 +26,7 @@ import (
gax "github.com/googleapis/gax-go" gax "github.com/googleapis/gax-go"
"golang.org/x/net/context" "golang.org/x/net/context"
bq "google.golang.org/api/bigquery/v2" bq "google.golang.org/api/bigquery/v2"
"google.golang.org/api/iterator"
) )
// A Job represents an operation which has been submitted to BigQuery for processing. // A Job represents an operation which has been submitted to BigQuery for processing.
@ -58,7 +60,8 @@ func (j *Job) ID() string {
type State int type State int
const ( const (
Pending State = iota StateUnspecified State = iota // used only as a default in JobIterator
Pending
Running Running
Done Done
) )
@ -77,16 +80,17 @@ type JobStatus struct {
Statistics *JobStatistics Statistics *JobStatistics
} }
// setJobRef initializes job's JobReference if given a non-empty jobID. // createJobRef creates a JobReference.
// projectID must be non-empty. // projectID must be non-empty.
func setJobRef(job *bq.Job, jobID, projectID string) { func createJobRef(jobID string, addJobIDSuffix bool, projectID string) *bq.JobReference {
if jobID == "" { if jobID == "" {
// Generate an ID on the client so that insertJob can be idempotent. jobID = randomJobIDFn()
jobID = randomJobID() } else if addJobIDSuffix {
jobID += "-" + randomJobIDFn()
} }
// We don't check whether projectID is empty; the server will return an // We don't check whether projectID is empty; the server will return an
// error when it encounters the resulting JobReference. // error when it encounters the resulting JobReference.
job.JobReference = &bq.JobReference{ return &bq.JobReference{
JobId: jobID, JobId: jobID,
ProjectId: projectID, ProjectId: projectID,
} }
@ -99,8 +103,11 @@ var (
rng = rand.New(rand.NewSource(time.Now().UnixNano() ^ int64(os.Getpid()))) rng = rand.New(rand.NewSource(time.Now().UnixNano() ^ int64(os.Getpid())))
) )
// For testing.
var randomJobIDFn = randomJobID
func randomJobID() string { func randomJobID() string {
// As of August 2017, the BigQuery service uses 27 alphanumeric characters. // As of August 2017, the BigQuery service uses 27 alphanumeric characters for suffixes.
var b [27]byte var b [27]byte
rngMu.Lock() rngMu.Lock()
for i := 0; i < len(b); i++ { for i := 0; i < len(b); i++ {
@ -121,20 +128,25 @@ func (s *JobStatus) Err() error {
return s.err return s.err
} }
// Fill in the client field of Tables in the statistics.
func (s *JobStatus) setClient(c *Client) {
if s.Statistics == nil {
return
}
if qs, ok := s.Statistics.Details.(*QueryStatistics); ok {
for _, t := range qs.ReferencedTables {
t.c = c
}
}
}
// Status returns the current status of the job. It fails if the Status could not be determined. // Status returns the current status of the job. It fails if the Status could not be determined.
func (j *Job) Status(ctx context.Context) (*JobStatus, error) { func (j *Job) Status(ctx context.Context) (*JobStatus, error) {
js, err := j.c.service.jobStatus(ctx, j.projectID, j.jobID) js, err := j.c.service.jobStatus(ctx, j.projectID, j.jobID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Fill in the client field of Tables in the statistics. js.setClient(j.c)
if js.Statistics != nil {
if qs, ok := js.Statistics.Details.(*QueryStatistics); ok {
for _, t := range qs.ReferencedTables {
t.c = j.c
}
}
}
return js, nil return js, nil
} }
@ -346,3 +358,73 @@ type ExplainQueryStep struct {
func (*ExtractStatistics) implementsStatistics() {} func (*ExtractStatistics) implementsStatistics() {}
func (*LoadStatistics) implementsStatistics() {} func (*LoadStatistics) implementsStatistics() {}
func (*QueryStatistics) implementsStatistics() {} func (*QueryStatistics) implementsStatistics() {}
// Jobs lists jobs within a project.
func (c *Client) Jobs(ctx context.Context) *JobIterator {
it := &JobIterator{
ctx: ctx,
c: c,
ProjectID: c.projectID,
}
it.pageInfo, it.nextFunc = iterator.NewPageInfo(
it.fetch,
func() int { return len(it.items) },
func() interface{} { b := it.items; it.items = nil; return b })
return it
}
// A JobInfo consists of a Job and a JobStatus.
type JobInfo struct {
Job *Job
Status *JobStatus
}
// JobIterator iterates over jobs in a project.
type JobIterator struct {
ProjectID string // Project ID of the jobs to list. Default is the client's project.
AllUsers bool // Whether to list jobs owned by all users in the project, or just the current caller.
State State // List only jobs in the given state. Defaults to all states.
ctx context.Context
c *Client
pageInfo *iterator.PageInfo
nextFunc func() error
items []JobInfo
}
func (it *JobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }
func (it *JobIterator) Next() (JobInfo, error) {
if err := it.nextFunc(); err != nil {
return JobInfo{}, err
}
item := it.items[0]
it.items = it.items[1:]
return item, nil
}
func (it *JobIterator) fetch(pageSize int, pageToken string) (string, error) {
var st string
switch it.State {
case StateUnspecified:
st = ""
case Pending:
st = "pending"
case Running:
st = "running"
case Done:
st = "done"
default:
return "", fmt.Errorf("bigquery: invalid value for JobIterator.State: %d", it.State)
}
jobInfos, nextPageToken, err := it.c.service.listJobs(it.ctx, it.ProjectID, pageSize, pageToken, it.AllUsers, st)
if err != nil {
return "", err
}
for _, ji := range jobInfos {
ji.Job.c = it.c
ji.Status.setClient(it.c)
it.items = append(it.items, ji)
}
return nextPageToken, nil
}

95
vendor/cloud.google.com/go/bigquery/job_test.go generated vendored Normal file
View File

@ -0,0 +1,95 @@
// Copyright 2017 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 bigquery
import (
"testing"
"cloud.google.com/go/internal/testutil"
"golang.org/x/net/context"
bq "google.golang.org/api/bigquery/v2"
)
func TestCreateJobRef(t *testing.T) {
defer fixRandomJobID("RANDOM")()
for _, test := range []struct {
jobID string
addJobIDSuffix bool
want string
}{
{
jobID: "foo",
addJobIDSuffix: false,
want: "foo",
},
{
jobID: "",
addJobIDSuffix: false,
want: "RANDOM",
},
{
jobID: "",
addJobIDSuffix: true, // irrelevant
want: "RANDOM",
},
{
jobID: "foo",
addJobIDSuffix: true,
want: "foo-RANDOM",
},
} {
jr := createJobRef(test.jobID, test.addJobIDSuffix, "projectID")
got := jr.JobId
if got != test.want {
t.Errorf("%q, %t: got %q, want %q", test.jobID, test.addJobIDSuffix, got, test.want)
}
}
}
func fixRandomJobID(s string) func() {
prev := randomJobIDFn
randomJobIDFn = func() string { return s }
return func() { randomJobIDFn = prev }
}
func checkJob(t *testing.T, i int, got, want *bq.Job) {
if got.JobReference == nil {
t.Errorf("#%d: empty job reference", i)
return
}
if got.JobReference.JobId == "" {
t.Errorf("#%d: empty job ID", i)
return
}
d := testutil.Diff(got, want)
if d != "" {
t.Errorf("#%d: (got=-, want=+) %s", i, d)
}
}
type testService struct {
*bq.Job
service
}
func (s *testService) insertJob(ctx context.Context, projectID string, conf *insertJobConf) (*Job, error) {
s.Job = conf.job
return &Job{}, nil
}
func (s *testService) jobStatus(ctx context.Context, projectID, jobID string) (*JobStatus, error) {
return &JobStatus{State: Done}, nil
}

View File

@ -21,9 +21,12 @@ import (
// LoadConfig holds the configuration for a load job. // LoadConfig holds the configuration for a load job.
type LoadConfig struct { type LoadConfig struct {
// JobID is the ID to use for the load job. If unset, a job ID will be automatically created. // JobID is the ID to use for the job. If empty, a random job ID will be generated.
JobID string JobID string
// If AddJobIDSuffix is true, then a random string will be appended to JobID.
AddJobIDSuffix bool
// Src is the source from which data will be loaded. // Src is the source from which data will be loaded.
Src LoadSource Src LoadSource
@ -71,6 +74,7 @@ func (t *Table) LoaderFrom(src LoadSource) *Loader {
// Run initiates a load job. // Run initiates a load job.
func (l *Loader) Run(ctx context.Context) (*Job, error) { func (l *Loader) Run(ctx context.Context) (*Job, error) {
job := &bq.Job{ job := &bq.Job{
JobReference: createJobRef(l.JobID, l.AddJobIDSuffix, l.c.projectID),
Configuration: &bq.JobConfiguration{ Configuration: &bq.JobConfiguration{
Load: &bq.JobConfigurationLoad{ Load: &bq.JobConfigurationLoad{
CreateDisposition: string(l.CreateDisposition), CreateDisposition: string(l.CreateDisposition),
@ -80,9 +84,6 @@ func (l *Loader) Run(ctx context.Context) (*Job, error) {
} }
conf := &insertJobConf{job: job} conf := &insertJobConf{job: job}
l.Src.populateInsertJobConfForLoad(conf) l.Src.populateInsertJobConfForLoad(conf)
setJobRef(job, l.JobID, l.c.projectID)
job.Configuration.Load.DestinationTable = l.Dst.tableRefProto() job.Configuration.Load.DestinationTable = l.Dst.tableRefProto()
return l.c.insertJob(ctx, conf) return l.c.insertJob(ctx, conf)
} }

View File

@ -25,7 +25,7 @@ import (
func defaultLoadJob() *bq.Job { func defaultLoadJob() *bq.Job {
return &bq.Job{ return &bq.Job{
JobReference: &bq.JobReference{ProjectId: "client-project-id"}, JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"},
Configuration: &bq.JobConfiguration{ Configuration: &bq.JobConfiguration{
Load: &bq.JobConfigurationLoad{ Load: &bq.JobConfigurationLoad{
DestinationTable: &bq.TableReference{ DestinationTable: &bq.TableReference{
@ -67,6 +67,7 @@ func bqNestedFieldSchema() *bq.TableFieldSchema {
} }
func TestLoad(t *testing.T) { func TestLoad(t *testing.T) {
defer fixRandomJobID("RANDOM")()
c := &Client{projectID: "client-project-id"} c := &Client{projectID: "client-project-id"}
testCases := []struct { testCases := []struct {

View File

@ -23,10 +23,12 @@ import (
// QueryConfig holds the configuration for a query job. // QueryConfig holds the configuration for a query job.
type QueryConfig struct { type QueryConfig struct {
// JobID is the ID to use for the query job. If this field is empty, a job ID // JobID is the ID to use for the job. If empty, a random job ID will be generated.
// will be automatically created.
JobID string JobID string
// If AddJobIDSuffix is true, then a random string will be appended to JobID.
AddJobIDSuffix bool
// Dst is the table into which the results of the query will be written. // Dst is the table into which the results of the query will be written.
// If this field is nil, a temporary table will be created. // If this field is nil, a temporary table will be created.
Dst *Table Dst *Table
@ -87,8 +89,7 @@ type QueryConfig struct {
// used. // used.
MaxBytesBilled int64 MaxBytesBilled int64
// UseStandardSQL causes the query to use standard SQL. // UseStandardSQL causes the query to use standard SQL. The default.
// The default is false (using legacy SQL).
UseStandardSQL bool UseStandardSQL bool
// UseLegacySQL causes the query to use legacy SQL. // UseLegacySQL causes the query to use legacy SQL.
@ -128,12 +129,11 @@ func (c *Client) Query(q string) *Query {
// Run initiates a query job. // Run initiates a query job.
func (q *Query) Run(ctx context.Context) (*Job, error) { func (q *Query) Run(ctx context.Context) (*Job, error) {
job := &bq.Job{ job := &bq.Job{
JobReference: createJobRef(q.JobID, q.AddJobIDSuffix, q.client.projectID),
Configuration: &bq.JobConfiguration{ Configuration: &bq.JobConfiguration{
Query: &bq.JobConfigurationQuery{}, Query: &bq.JobConfigurationQuery{},
}, },
} }
setJobRef(job, q.JobID, q.client.projectID)
if err := q.QueryConfig.populateJobQueryConfig(job.Configuration.Query); err != nil { if err := q.QueryConfig.populateJobQueryConfig(job.Configuration.Query); err != nil {
return nil, err return nil, err
} }
@ -188,12 +188,11 @@ func (q *QueryConfig) populateJobQueryConfig(conf *bq.JobConfigurationQuery) err
if len(q.Parameters) > 0 && q.UseLegacySQL { if len(q.Parameters) > 0 && q.UseLegacySQL {
return errors.New("bigquery: cannot provide both Parameters (implying standard SQL) and UseLegacySQL") return errors.New("bigquery: cannot provide both Parameters (implying standard SQL) and UseLegacySQL")
} }
if q.UseStandardSQL || len(q.Parameters) > 0 {
conf.UseLegacySql = false
conf.ForceSendFields = append(conf.ForceSendFields, "UseLegacySql")
}
if q.UseLegacySQL { if q.UseLegacySQL {
conf.UseLegacySql = true conf.UseLegacySql = true
} else {
conf.UseLegacySql = false
conf.ForceSendFields = append(conf.ForceSendFields, "UseLegacySql")
} }
if q.Dst != nil && !q.Dst.implicitTable() { if q.Dst != nil && !q.Dst.implicitTable() {
conf.DestinationTable = q.Dst.tableRefProto() conf.DestinationTable = q.Dst.tableRefProto()

View File

@ -15,7 +15,6 @@
package bigquery package bigquery
import ( import (
"fmt"
"testing" "testing"
"cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/testutil"
@ -27,7 +26,7 @@ import (
func defaultQueryJob() *bq.Job { func defaultQueryJob() *bq.Job {
return &bq.Job{ return &bq.Job{
JobReference: &bq.JobReference{ProjectId: "client-project-id"}, JobReference: &bq.JobReference{JobId: "RANDOM", ProjectId: "client-project-id"},
Configuration: &bq.JobConfiguration{ Configuration: &bq.JobConfiguration{
Query: &bq.JobConfigurationQuery{ Query: &bq.JobConfigurationQuery{
DestinationTable: &bq.TableReference{ DestinationTable: &bq.TableReference{
@ -40,12 +39,15 @@ func defaultQueryJob() *bq.Job {
ProjectId: "def-project-id", ProjectId: "def-project-id",
DatasetId: "def-dataset-id", DatasetId: "def-dataset-id",
}, },
UseLegacySql: false,
ForceSendFields: []string{"UseLegacySql"},
}, },
}, },
} }
} }
func TestQuery(t *testing.T) { func TestQuery(t *testing.T) {
defer fixRandomJobID("RANDOM")()
c := &Client{ c := &Client{
projectID: "client-project-id", projectID: "client-project-id",
} }
@ -70,6 +72,20 @@ func TestQuery(t *testing.T) {
return j return j
}(), }(),
}, },
{
dst: c.Dataset("dataset-id").Table("table-id"),
src: &QueryConfig{
Q: "query string",
JobID: "jobID",
AddJobIDSuffix: true,
},
want: func() *bq.Job {
j := defaultQueryJob()
j.Configuration.Query.DefaultDataset = nil
j.JobReference.JobId = "jobID-RANDOM"
return j
}(),
},
{ {
dst: &Table{}, dst: &Table{},
src: defaultQuery, src: defaultQuery,
@ -246,10 +262,20 @@ func TestQuery(t *testing.T) {
DefaultDatasetID: "def-dataset-id", DefaultDatasetID: "def-dataset-id",
UseStandardSQL: true, UseStandardSQL: true,
}, },
want: defaultQueryJob(),
},
{
dst: c.Dataset("dataset-id").Table("table-id"),
src: &QueryConfig{
Q: "query string",
DefaultProjectID: "def-project-id",
DefaultDatasetID: "def-dataset-id",
UseLegacySQL: true,
},
want: func() *bq.Job { want: func() *bq.Job {
j := defaultQueryJob() j := defaultQueryJob()
j.Configuration.Query.UseLegacySql = false j.Configuration.Query.UseLegacySql = true
j.Configuration.Query.ForceSendFields = []string{"UseLegacySql"} j.Configuration.Query.ForceSendFields = nil
return j return j
}(), }(),
}, },
@ -290,6 +316,8 @@ func TestConfiguringQuery(t *testing.T) {
ProjectId: "def-project-id", ProjectId: "def-project-id",
DatasetId: "def-dataset-id", DatasetId: "def-dataset-id",
}, },
UseLegacySql: false,
ForceSendFields: []string{"UseLegacySql"},
}, },
}, },
JobReference: &bq.JobReference{ JobReference: &bq.JobReference{
@ -301,8 +329,8 @@ func TestConfiguringQuery(t *testing.T) {
if _, err := query.Run(context.Background()); err != nil { if _, err := query.Run(context.Background()); err != nil {
t.Fatalf("err calling Query.Run: %v", err) t.Fatalf("err calling Query.Run: %v", err)
} }
if !testutil.Equal(s.Job, want) { if diff := testutil.Diff(s.Job, want); diff != "" {
t.Errorf("querying: got:\n%v\nwant:\n%v", s.Job, want) t.Errorf("querying: -got +want:\n%s", diff)
} }
} }
@ -324,7 +352,5 @@ func TestQueryLegacySQL(t *testing.T) {
_, err = q.Run(context.Background()) _, err = q.Run(context.Background())
if err == nil { if err == nil {
t.Error("Parameters and UseLegacySQL: got nil, want error") t.Error("Parameters and UseLegacySQL: got nil, want error")
} else {
fmt.Println(err)
} }
} }

View File

@ -77,11 +77,6 @@ func (s Schema) asTableSchema() *bq.TableSchema {
return &bq.TableSchema{Fields: fields} return &bq.TableSchema{Fields: fields}
} }
// customizeCreateTable allows a Schema to be used directly as an option to CreateTable.
func (s Schema) customizeCreateTable(conf *createTableConf) {
conf.schema = s.asTableSchema()
}
func convertTableFieldSchema(tfs *bq.TableFieldSchema) *FieldSchema { func convertTableFieldSchema(tfs *bq.TableFieldSchema) *FieldSchema {
fs := &FieldSchema{ fs := &FieldSchema{
Description: tfs.Description, Description: tfs.Description,

View File

@ -41,9 +41,10 @@ type service interface {
getJob(ctx context.Context, projectId, jobID string) (*Job, error) getJob(ctx context.Context, projectId, jobID string) (*Job, error)
jobCancel(ctx context.Context, projectId, jobID string) error jobCancel(ctx context.Context, projectId, jobID string) error
jobStatus(ctx context.Context, projectId, jobID string) (*JobStatus, error) jobStatus(ctx context.Context, projectId, jobID string) (*JobStatus, error)
listJobs(ctx context.Context, projectId string, maxResults int, pageToken string, all bool, state string) ([]JobInfo, string, error)
// Tables // Tables
createTable(ctx context.Context, conf *createTableConf) error createTable(ctx context.Context, projectID, datasetID, tableID string, tm *TableMetadata) error
getTableMetadata(ctx context.Context, projectID, datasetID, tableID string) (*TableMetadata, error) getTableMetadata(ctx context.Context, projectID, datasetID, tableID string) (*TableMetadata, error)
deleteTable(ctx context.Context, projectID, datasetID, tableID string) error deleteTable(ctx context.Context, projectID, datasetID, tableID string) error
@ -56,7 +57,7 @@ type service interface {
insertRows(ctx context.Context, projectID, datasetID, tableID string, rows []*insertionRow, conf *insertRowsConf) error insertRows(ctx context.Context, projectID, datasetID, tableID string, rows []*insertionRow, conf *insertRowsConf) error
// Datasets // Datasets
insertDataset(ctx context.Context, datasetID, projectID string) error insertDataset(ctx context.Context, datasetID, projectID string, dm *DatasetMetadata) error
deleteDataset(ctx context.Context, datasetID, projectID string) error deleteDataset(ctx context.Context, datasetID, projectID string) error
getDatasetMetadata(ctx context.Context, projectID, datasetID string) (*DatasetMetadata, error) getDatasetMetadata(ctx context.Context, projectID, datasetID string) (*DatasetMetadata, error)
patchDataset(ctx context.Context, projectID, datasetID string, dm *DatasetMetadataToUpdate, etag string) (*DatasetMetadata, error) patchDataset(ctx context.Context, projectID, datasetID string, dm *DatasetMetadataToUpdate, etag string) (*DatasetMetadata, error)
@ -313,22 +314,11 @@ func (s *bigqueryService) insertRows(ctx context.Context, projectID, datasetID,
} }
func (s *bigqueryService) getJob(ctx context.Context, projectID, jobID string) (*Job, error) { func (s *bigqueryService) getJob(ctx context.Context, projectID, jobID string) (*Job, error) {
job, err := s.getJobInternal(ctx, projectID, jobID, "configuration") bqjob, err := s.getJobInternal(ctx, projectID, jobID, "configuration", "jobReference")
if err != nil { if err != nil {
return nil, err return nil, err
} }
var isQuery bool return jobFromProtos(bqjob.JobReference, bqjob.Configuration), nil
var dest *bq.TableReference
if job.Configuration.Query != nil {
isQuery = true
dest = job.Configuration.Query.DestinationTable
}
return &Job{
projectID: projectID,
jobID: jobID,
isQuery: isQuery,
destinationTable: dest,
}, nil
} }
func (s *bigqueryService) jobStatus(ctx context.Context, projectID, jobID string) (*JobStatus, error) { func (s *bigqueryService) jobStatus(ctx context.Context, projectID, jobID string) (*JobStatus, error) {
@ -346,9 +336,10 @@ func (s *bigqueryService) jobStatus(ctx context.Context, projectID, jobID string
func (s *bigqueryService) getJobInternal(ctx context.Context, projectID, jobID string, fields ...googleapi.Field) (*bq.Job, error) { func (s *bigqueryService) getJobInternal(ctx context.Context, projectID, jobID string, fields ...googleapi.Field) (*bq.Job, error) {
var job *bq.Job var job *bq.Job
call := s.s.Jobs.Get(projectID, jobID). call := s.s.Jobs.Get(projectID, jobID).Context(ctx)
Fields(fields...). if len(fields) > 0 {
Context(ctx) call = call.Fields(fields...)
}
setClientHeader(call.Header()) setClientHeader(call.Header())
err := runWithRetry(ctx, func() (err error) { err := runWithRetry(ctx, func() (err error) {
job, err = call.Do() job, err = call.Do()
@ -376,6 +367,21 @@ func (s *bigqueryService) jobCancel(ctx context.Context, projectID, jobID string
}) })
} }
func jobFromProtos(jr *bq.JobReference, config *bq.JobConfiguration) *Job {
var isQuery bool
var dest *bq.TableReference
if config.Query != nil {
isQuery = true
dest = config.Query.DestinationTable
}
return &Job{
projectID: jr.ProjectId,
jobID: jr.JobId,
isQuery: isQuery,
destinationTable: dest,
}
}
var stateMap = map[string]State{"PENDING": Pending, "RUNNING": Running, "DONE": Done} var stateMap = map[string]State{"PENDING": Pending, "RUNNING": Running, "DONE": Done}
func jobStatusFromProto(status *bq.JobStatus) (*JobStatus, error) { func jobStatusFromProto(status *bq.JobStatus) (*JobStatus, error) {
@ -496,63 +502,88 @@ func (s *bigqueryService) listTables(ctx context.Context, projectID, datasetID s
return tables, res.NextPageToken, nil return tables, res.NextPageToken, nil
} }
type createTableConf struct {
projectID, datasetID, tableID string
expiration time.Time
viewQuery string
schema *bq.TableSchema
useStandardSQL bool
useLegacySQL bool
timePartitioning *TimePartitioning
}
// createTable creates a table in the BigQuery service. // createTable creates a table in the BigQuery service.
// expiration is an optional time after which the table will be deleted and its storage reclaimed. // If tm.ViewQuery is non-empty, the created table will be of type VIEW.
// If viewQuery is non-empty, the created table will be of type VIEW.
// Note: expiration can only be set during table creation. // Note: expiration can only be set during table creation.
// Note: after table creation, a view can be modified only if its table was initially created with a view. // Note: after table creation, a view can be modified only if its table was initially created with a view.
func (s *bigqueryService) createTable(ctx context.Context, conf *createTableConf) error { func (s *bigqueryService) createTable(ctx context.Context, projectID, datasetID, tableID string, tm *TableMetadata) error {
if conf.useStandardSQL && conf.useLegacySQL { table, err := bqTableFromMetadata(tm)
return errors.New("bigquery: cannot provide both UseStandardSQL and UseLegacySQL") if err != nil {
return err
} }
table := &bq.Table{ table.TableReference = &bq.TableReference{
// TODO(jba): retry? Is this always idempotent? ProjectId: projectID,
TableReference: &bq.TableReference{ DatasetId: datasetID,
ProjectId: conf.projectID, TableId: tableID,
DatasetId: conf.datasetID,
TableId: conf.tableID,
},
} }
if !conf.expiration.IsZero() { req := s.s.Tables.Insert(projectID, datasetID, table).Context(ctx)
table.ExpirationTime = conf.expiration.UnixNano() / 1e6 setClientHeader(req.Header())
_, err = req.Do()
return err
}
func bqTableFromMetadata(tm *TableMetadata) (*bq.Table, error) {
t := &bq.Table{}
if tm == nil {
return t, nil
} }
// TODO(jba): make it impossible to provide both a view query and a schema. if tm.Schema != nil && tm.ViewQuery != "" {
if conf.viewQuery != "" { return nil, errors.New("bigquery: provide Schema or ViewQuery, not both")
table.View = &bq.ViewDefinition{ }
Query: conf.viewQuery, t.FriendlyName = tm.Name
t.Description = tm.Description
if tm.Schema != nil {
t.Schema = tm.Schema.asTableSchema()
}
if tm.ViewQuery != "" {
if tm.UseStandardSQL && tm.UseLegacySQL {
return nil, errors.New("bigquery: cannot provide both UseStandardSQL and UseLegacySQL")
} }
if conf.useStandardSQL { t.View = &bq.ViewDefinition{Query: tm.ViewQuery}
table.View.UseLegacySql = false if tm.UseLegacySQL {
table.View.ForceSendFields = append(table.View.ForceSendFields, "UseLegacySql") t.View.UseLegacySql = true
} } else {
if conf.useLegacySQL { t.View.UseLegacySql = false
table.View.UseLegacySql = true t.View.ForceSendFields = append(t.View.ForceSendFields, "UseLegacySql")
} }
} else if tm.UseLegacySQL || tm.UseStandardSQL {
return nil, errors.New("bigquery: UseLegacy/StandardSQL requires ViewQuery")
} }
if conf.schema != nil { if tm.TimePartitioning != nil {
table.Schema = conf.schema t.TimePartitioning = &bq.TimePartitioning{
}
if conf.timePartitioning != nil {
table.TimePartitioning = &bq.TimePartitioning{
Type: "DAY", Type: "DAY",
ExpirationMs: int64(conf.timePartitioning.Expiration.Seconds() * 1000), ExpirationMs: int64(tm.TimePartitioning.Expiration / time.Millisecond),
} }
} }
if !tm.ExpirationTime.IsZero() {
t.ExpirationTime = tm.ExpirationTime.UnixNano() / 1e6
}
req := s.s.Tables.Insert(conf.projectID, conf.datasetID, table).Context(ctx) if tm.FullID != "" {
setClientHeader(req.Header()) return nil, errors.New("cannot set FullID on create")
_, err := req.Do() }
return err if tm.Type != "" {
return nil, errors.New("cannot set Type on create")
}
if !tm.CreationTime.IsZero() {
return nil, errors.New("cannot set CreationTime on create")
}
if !tm.LastModifiedTime.IsZero() {
return nil, errors.New("cannot set LastModifiedTime on create")
}
if tm.NumBytes != 0 {
return nil, errors.New("cannot set NumBytes on create")
}
if tm.NumRows != 0 {
return nil, errors.New("cannot set NumRows on create")
}
if tm.StreamingBuffer != nil {
return nil, errors.New("cannot set StreamingBuffer on create")
}
if tm.ETag != "" {
return nil, errors.New("cannot set ETag on create")
}
return t, nil
} }
func (s *bigqueryService) getTableMetadata(ctx context.Context, projectID, datasetID, tableID string) (*TableMetadata, error) { func (s *bigqueryService) getTableMetadata(ctx context.Context, projectID, datasetID, tableID string) (*TableMetadata, error) {
@ -580,7 +611,7 @@ func bqTableToMetadata(t *bq.Table) *TableMetadata {
Description: t.Description, Description: t.Description,
Name: t.FriendlyName, Name: t.FriendlyName,
Type: TableType(t.Type), Type: TableType(t.Type),
ID: t.Id, FullID: t.Id,
NumBytes: t.NumBytes, NumBytes: t.NumBytes,
NumRows: t.NumRows, NumRows: t.NumRows,
ExpirationTime: unixMillisToTime(t.ExpirationTime), ExpirationTime: unixMillisToTime(t.ExpirationTime),
@ -592,7 +623,8 @@ func bqTableToMetadata(t *bq.Table) *TableMetadata {
md.Schema = convertTableSchema(t.Schema) md.Schema = convertTableSchema(t.Schema)
} }
if t.View != nil { if t.View != nil {
md.View = t.View.Query md.ViewQuery = t.View.Query
md.UseLegacySQL = t.View.UseLegacySql
} }
if t.TimePartitioning != nil { if t.TimePartitioning != nil {
md.TimePartitioning = &TimePartitioning{ md.TimePartitioning = &TimePartitioning{
@ -617,7 +649,7 @@ func bqDatasetToMetadata(d *bq.Dataset) *DatasetMetadata {
DefaultTableExpiration: time.Duration(d.DefaultTableExpirationMs) * time.Millisecond, DefaultTableExpiration: time.Duration(d.DefaultTableExpirationMs) * time.Millisecond,
Description: d.Description, Description: d.Description,
Name: d.FriendlyName, Name: d.FriendlyName,
ID: d.Id, FullID: d.Id,
Location: d.Location, Location: d.Location,
Labels: d.Labels, Labels: d.Labels,
ETag: d.Etag, ETag: d.Etag,
@ -678,39 +710,72 @@ func (s *bigqueryService) patchTable(ctx context.Context, projectID, datasetID,
if etag != "" { if etag != "" {
call.Header().Set("If-Match", etag) call.Header().Set("If-Match", etag)
} }
table, err := call.Do() var table *bq.Table
if err != nil { if err := runWithRetry(ctx, func() (err error) {
table, err = call.Do()
return err
}); err != nil {
return nil, err return nil, err
} }
return bqTableToMetadata(table), nil return bqTableToMetadata(table), nil
} }
func (s *bigqueryService) insertDataset(ctx context.Context, datasetID, projectID string) error { func (s *bigqueryService) insertDataset(ctx context.Context, datasetID, projectID string, dm *DatasetMetadata) error {
// TODO(jba): retry? // TODO(jba): retry?
ds := &bq.Dataset{ ds, err := bqDatasetFromMetadata(dm)
DatasetReference: &bq.DatasetReference{DatasetId: datasetID}, if err != nil {
return err
} }
ds.DatasetReference = &bq.DatasetReference{DatasetId: datasetID}
req := s.s.Datasets.Insert(projectID, ds).Context(ctx) req := s.s.Datasets.Insert(projectID, ds).Context(ctx)
setClientHeader(req.Header()) setClientHeader(req.Header())
_, err := req.Do() _, err = req.Do()
return err return err
} }
func (s *bigqueryService) patchDataset(ctx context.Context, projectID, datasetID string, dm *DatasetMetadataToUpdate, etag string) (*DatasetMetadata, error) { func (s *bigqueryService) patchDataset(ctx context.Context, projectID, datasetID string, dm *DatasetMetadataToUpdate, etag string) (*DatasetMetadata, error) {
ds := bqDatasetFromMetadata(dm) ds := bqDatasetFromUpdateMetadata(dm)
call := s.s.Datasets.Patch(projectID, datasetID, ds).Context(ctx) call := s.s.Datasets.Patch(projectID, datasetID, ds).Context(ctx)
setClientHeader(call.Header()) setClientHeader(call.Header())
if etag != "" { if etag != "" {
call.Header().Set("If-Match", etag) call.Header().Set("If-Match", etag)
} }
ds2, err := call.Do() var ds2 *bq.Dataset
if err != nil { if err := runWithRetry(ctx, func() (err error) {
ds2, err = call.Do()
return err
}); err != nil {
return nil, err return nil, err
} }
return bqDatasetToMetadata(ds2), nil return bqDatasetToMetadata(ds2), nil
} }
func bqDatasetFromMetadata(dm *DatasetMetadataToUpdate) *bq.Dataset { func bqDatasetFromMetadata(dm *DatasetMetadata) (*bq.Dataset, error) {
ds := &bq.Dataset{}
if dm == nil {
return ds, nil
}
ds.FriendlyName = dm.Name
ds.Description = dm.Description
ds.Location = dm.Location
ds.DefaultTableExpirationMs = int64(dm.DefaultTableExpiration / time.Millisecond)
ds.Labels = dm.Labels
if !dm.CreationTime.IsZero() {
return nil, errors.New("bigquery: Dataset.CreationTime is not writable")
}
if !dm.LastModifiedTime.IsZero() {
return nil, errors.New("bigquery: Dataset.LastModifiedTime is not writable")
}
if dm.FullID != "" {
return nil, errors.New("bigquery: Dataset.FullID is not writable")
}
if dm.ETag != "" {
return nil, errors.New("bigquery: Dataset.ETag is not writable")
}
return ds, nil
}
func bqDatasetFromUpdateMetadata(dm *DatasetMetadataToUpdate) *bq.Dataset {
ds := &bq.Dataset{} ds := &bq.Dataset{}
forceSend := func(field string) { forceSend := func(field string) {
ds.ForceSendFields = append(ds.ForceSendFields, field) ds.ForceSendFields = append(ds.ForceSendFields, field)
@ -730,7 +795,7 @@ func bqDatasetFromMetadata(dm *DatasetMetadataToUpdate) *bq.Dataset {
// Send a null to delete the field. // Send a null to delete the field.
ds.NullFields = append(ds.NullFields, "DefaultTableExpirationMs") ds.NullFields = append(ds.NullFields, "DefaultTableExpirationMs")
} else { } else {
ds.DefaultTableExpirationMs = int64(dur.Seconds() * 1000) ds.DefaultTableExpirationMs = int64(dur / time.Millisecond)
} }
} }
if dm.setLabels != nil || dm.deleteLabels != nil { if dm.setLabels != nil || dm.deleteLabels != nil {
@ -801,13 +866,54 @@ func (s *bigqueryService) convertListedDataset(d *bq.DatasetListDatasets) *Datas
} }
} }
func (s *bigqueryService) listJobs(ctx context.Context, projectID string, maxResults int, pageToken string, all bool, state string) ([]JobInfo, string, error) {
req := s.s.Jobs.List(projectID).
Context(ctx).
PageToken(pageToken).
Projection("full").
AllUsers(all)
if state != "" {
req.StateFilter(state)
}
setClientHeader(req.Header())
if maxResults > 0 {
req.MaxResults(int64(maxResults))
}
res, err := req.Do()
if err != nil {
return nil, "", err
}
var jobInfos []JobInfo
for _, j := range res.Jobs {
ji, err := s.convertListedJob(j)
if err != nil {
return nil, "", err
}
jobInfos = append(jobInfos, ji)
}
return jobInfos, res.NextPageToken, nil
}
func (s *bigqueryService) convertListedJob(j *bq.JobListJobs) (JobInfo, error) {
st, err := jobStatusFromProto(j.Status)
if err != nil {
return JobInfo{}, err
}
st.Statistics = jobStatisticsFromProto(j.Statistics)
return JobInfo{
Job: jobFromProtos(j.JobReference, j.Configuration),
Status: st,
}, nil
}
// runWithRetry calls the function until it returns nil or a non-retryable error, or // runWithRetry calls the function until it returns nil or a non-retryable error, or
// the context is done. // the context is done.
// See the similar function in ../storage/invoke.go. The main difference is the // See the similar function in ../storage/invoke.go. The main difference is the
// reason for retrying. // reason for retrying.
func runWithRetry(ctx context.Context, call func() error) error { func runWithRetry(ctx context.Context, call func() error) error {
// These parameters match the suggestions in https://cloud.google.com/bigquery/sla.
backoff := gax.Backoff{ backoff := gax.Backoff{
Initial: 2 * time.Second, Initial: 1 * time.Second,
Max: 32 * time.Second, Max: 32 * time.Second,
Multiplier: 2, Multiplier: 2,
} }
@ -820,7 +926,7 @@ func runWithRetry(ctx context.Context, call func() error) error {
}) })
} }
// Use the criteria in https://cloud.google.com/bigquery/troubleshooting-errors. // This is the correct definition of retryable according to the BigQuery team.
func retryableError(err error) bool { func retryableError(err error) bool {
e, ok := err.(*googleapi.Error) e, ok := err.(*googleapi.Error)
if !ok { if !ok {
@ -830,5 +936,5 @@ func retryableError(err error) bool {
if len(e.Errors) > 0 { if len(e.Errors) > 0 {
reason = e.Errors[0].Reason reason = e.Errors[0].Reason
} }
return reason == "backendError" && (e.Code == 500 || e.Code == 503) return reason == "backendError" || reason == "rateLimitExceeded"
} }

View File

@ -59,15 +59,15 @@ func TestBQTableToMetadata(t *testing.T) {
&TableMetadata{ &TableMetadata{
Description: "desc", Description: "desc",
Name: "fname", Name: "fname",
View: "view-query", ViewQuery: "view-query",
ID: "id", FullID: "id",
Type: ExternalTable, Type: ExternalTable,
ExpirationTime: aTime.Truncate(time.Millisecond), ExpirationTime: aTime.Truncate(time.Millisecond),
CreationTime: aTime.Truncate(time.Millisecond), CreationTime: aTime.Truncate(time.Millisecond),
LastModifiedTime: aTime.Truncate(time.Millisecond), LastModifiedTime: aTime.Truncate(time.Millisecond),
NumBytes: 123, NumBytes: 123,
NumRows: 7, NumRows: 7,
TimePartitioning: &TimePartitioning{Expiration: time.Duration(7890) * time.Millisecond}, TimePartitioning: &TimePartitioning{Expiration: 7890 * time.Millisecond},
StreamingBuffer: &StreamingBuffer{ StreamingBuffer: &StreamingBuffer{
EstimatedBytes: 11, EstimatedBytes: 11,
EstimatedRows: 3, EstimatedRows: 3,
@ -78,13 +78,156 @@ func TestBQTableToMetadata(t *testing.T) {
}, },
} { } {
got := bqTableToMetadata(test.in) got := bqTableToMetadata(test.in)
if !testutil.Equal(got, test.want) { if diff := testutil.Diff(got, test.want); diff != "" {
t.Errorf("%v:\ngot %+v\nwant %+v", test.in, got, test.want) t.Errorf("%+v:\n, -got, +want:\n%s", test.in, diff)
}
}
}
func TestBQTableFromMetadata(t *testing.T) {
aTime := time.Date(2017, 1, 26, 0, 0, 0, 0, time.Local)
aTimeMillis := aTime.UnixNano() / 1e6
sc := Schema{fieldSchema("desc", "name", "STRING", false, true)}
for _, test := range []struct {
in *TableMetadata
want *bq.Table
}{
{nil, &bq.Table{}},
{&TableMetadata{}, &bq.Table{}},
{
&TableMetadata{
Name: "n",
Description: "d",
Schema: sc,
ExpirationTime: aTime,
},
&bq.Table{
FriendlyName: "n",
Description: "d",
Schema: &bq.TableSchema{
Fields: []*bq.TableFieldSchema{
bqTableFieldSchema("desc", "name", "STRING", "REQUIRED"),
},
},
ExpirationTime: aTimeMillis,
},
},
{
&TableMetadata{ViewQuery: "q"},
&bq.Table{
View: &bq.ViewDefinition{
Query: "q",
UseLegacySql: false,
ForceSendFields: []string{"UseLegacySql"},
},
},
},
{
&TableMetadata{
ViewQuery: "q",
UseLegacySQL: true,
TimePartitioning: &TimePartitioning{},
},
&bq.Table{
View: &bq.ViewDefinition{
Query: "q",
UseLegacySql: true,
},
TimePartitioning: &bq.TimePartitioning{
Type: "DAY",
ExpirationMs: 0,
},
},
},
{
&TableMetadata{
ViewQuery: "q",
UseStandardSQL: true,
TimePartitioning: &TimePartitioning{time.Second},
},
&bq.Table{
View: &bq.ViewDefinition{
Query: "q",
UseLegacySql: false,
ForceSendFields: []string{"UseLegacySql"},
},
TimePartitioning: &bq.TimePartitioning{
Type: "DAY",
ExpirationMs: 1000,
},
},
},
} {
got, err := bqTableFromMetadata(test.in)
if err != nil {
t.Fatalf("%+v: %v", test.in, err)
}
if diff := testutil.Diff(got, test.want); diff != "" {
t.Errorf("%+v:\n-got, +want:\n%s", test.in, diff)
}
}
// Errors
for _, in := range []*TableMetadata{
{Schema: sc, ViewQuery: "q"}, // can't have both schema and query
{UseLegacySQL: true}, // UseLegacySQL without query
{UseStandardSQL: true}, // UseStandardSQL without query
// read-only fields
{FullID: "x"},
{Type: "x"},
{CreationTime: aTime},
{LastModifiedTime: aTime},
{NumBytes: 1},
{NumRows: 1},
{StreamingBuffer: &StreamingBuffer{}},
{ETag: "x"},
} {
_, err := bqTableFromMetadata(in)
if err == nil {
t.Errorf("%+v: got nil, want error", in)
} }
} }
} }
func TestBQDatasetFromMetadata(t *testing.T) { func TestBQDatasetFromMetadata(t *testing.T) {
for _, test := range []struct {
in *DatasetMetadata
want *bq.Dataset
}{
{nil, &bq.Dataset{}},
{&DatasetMetadata{Name: "name"}, &bq.Dataset{FriendlyName: "name"}},
{&DatasetMetadata{
Name: "name",
Description: "desc",
DefaultTableExpiration: time.Hour,
Location: "EU",
Labels: map[string]string{"x": "y"},
}, &bq.Dataset{
FriendlyName: "name",
Description: "desc",
DefaultTableExpirationMs: 60 * 60 * 1000,
Location: "EU",
Labels: map[string]string{"x": "y"},
}},
} {
got, err := bqDatasetFromMetadata(test.in)
if err != nil {
t.Fatal(err)
}
if !testutil.Equal(got, test.want) {
t.Errorf("%v:\ngot %+v\nwant %+v", test.in, got, test.want)
}
}
// Check that non-writeable fields are unset.
_, err := bqDatasetFromMetadata(&DatasetMetadata{FullID: "x"})
if err == nil {
t.Error("got nil, want error")
}
}
func TestBQDatasetFromUpdateMetadata(t *testing.T) {
dm := DatasetMetadataToUpdate{ dm := DatasetMetadataToUpdate{
Description: "desc", Description: "desc",
Name: "name", Name: "name",
@ -93,7 +236,7 @@ func TestBQDatasetFromMetadata(t *testing.T) {
dm.SetLabel("label", "value") dm.SetLabel("label", "value")
dm.DeleteLabel("del") dm.DeleteLabel("del")
got := bqDatasetFromMetadata(&dm) got := bqDatasetFromUpdateMetadata(&dm)
want := &bq.Dataset{ want := &bq.Dataset{
Description: "desc", Description: "desc",
FriendlyName: "name", FriendlyName: "name",

View File

@ -39,18 +39,39 @@ type Table struct {
// TableMetadata contains information about a BigQuery table. // TableMetadata contains information about a BigQuery table.
type TableMetadata struct { type TableMetadata struct {
Description string // The user-friendly description of this table. // The following fields can be set when creating a table.
Name string // The user-friendly name for this table.
Schema Schema
View string
ID string // An opaque ID uniquely identifying the table. // The user-friendly name for the table.
Type TableType Name string
// The user-friendly description of the table.
Description string
// The table schema. If provided on create, ViewQuery must be empty.
Schema Schema
// The query to use for a view. If provided on create, Schema must be nil.
ViewQuery string
// Use Legacy SQL for the view query.
// At most one of UseLegacySQL and UseStandardSQL can be true.
UseLegacySQL bool
// Use Legacy SQL for the view query. The default.
// At most one of UseLegacySQL and UseStandardSQL can be true.
UseStandardSQL bool
// If non-nil, the table is partitioned by time.
TimePartitioning *TimePartitioning
// The time when this table expires. If not set, the table will persist // The time when this table expires. If not set, the table will persist
// indefinitely. Expired tables will be deleted and their storage reclaimed. // indefinitely. Expired tables will be deleted and their storage reclaimed.
ExpirationTime time.Time ExpirationTime time.Time
// All the fields below are read-only.
FullID string // An opaque ID uniquely identifying the table.
Type TableType
CreationTime time.Time CreationTime time.Time
LastModifiedTime time.Time LastModifiedTime time.Time
@ -62,9 +83,6 @@ type TableMetadata struct {
// This does not include data that is being buffered during a streaming insert. // This does not include data that is being buffered during a streaming insert.
NumRows uint64 NumRows uint64
// The time-based partitioning settings for this table.
TimePartitioning *TimePartitioning
// Contains information regarding this table's streaming buffer, if one is // Contains information regarding this table's streaming buffer, if one is
// present. This field will be nil if the table is not being streamed to or if // present. This field will be nil if the table is not being streamed to or if
// there is no data in the streaming buffer. // there is no data in the streaming buffer.
@ -115,6 +133,14 @@ const (
ExternalTable TableType = "EXTERNAL" ExternalTable TableType = "EXTERNAL"
) )
// TimePartitioning describes the time-based date partitioning on a table.
// For more information see: https://cloud.google.com/bigquery/docs/creating-partitioned-tables.
type TimePartitioning struct {
// The amount of time to keep the storage for a partition.
// If the duration is empty (0), the data in the partitions do not expire.
Expiration time.Duration
}
// StreamingBuffer holds information about the streaming buffer. // StreamingBuffer holds information about the streaming buffer.
type StreamingBuffer struct { type StreamingBuffer struct {
// A lower-bound estimate of the number of bytes currently in the streaming // A lower-bound estimate of the number of bytes currently in the streaming
@ -148,18 +174,9 @@ func (t *Table) implicitTable() bool {
} }
// Create creates a table in the BigQuery service. // Create creates a table in the BigQuery service.
// To create a table with a schema, pass in a Schema to Create; // Pass in a TableMetadata value to configure the dataset.
// Schema is a valid CreateTableOption. func (t *Table) Create(ctx context.Context, tm *TableMetadata) error {
func (t *Table) Create(ctx context.Context, options ...CreateTableOption) error { return t.c.service.createTable(ctx, t.ProjectID, t.DatasetID, t.TableID, tm)
conf := &createTableConf{
projectID: t.ProjectID,
datasetID: t.DatasetID,
tableID: t.TableID,
}
for _, o := range options {
o.customizeCreateTable(conf)
}
return t.c.service.createTable(ctx, conf)
} }
// Metadata fetches the metadata for the table. // Metadata fetches the metadata for the table.
@ -172,63 +189,6 @@ func (t *Table) Delete(ctx context.Context) error {
return t.c.service.deleteTable(ctx, t.ProjectID, t.DatasetID, t.TableID) return t.c.service.deleteTable(ctx, t.ProjectID, t.DatasetID, t.TableID)
} }
// A CreateTableOption is an optional argument to CreateTable.
type CreateTableOption interface {
customizeCreateTable(*createTableConf)
}
type tableExpiration time.Time
// TableExpiration returns a CreateTableOption that will cause the created table to be deleted after the expiration time.
func TableExpiration(exp time.Time) CreateTableOption { return tableExpiration(exp) }
func (opt tableExpiration) customizeCreateTable(conf *createTableConf) {
conf.expiration = time.Time(opt)
}
type viewQuery string
// ViewQuery returns a CreateTableOption that causes the created table to be a virtual table defined by the supplied query.
// For more information see: https://cloud.google.com/bigquery/querying-data#views
func ViewQuery(query string) CreateTableOption { return viewQuery(query) }
func (opt viewQuery) customizeCreateTable(conf *createTableConf) {
conf.viewQuery = string(opt)
}
type useStandardSQL struct{}
// UseStandardSQL returns a CreateTableOption to set the table to use standard SQL.
// The default setting is false (using legacy SQL).
func UseStandardSQL() CreateTableOption { return useStandardSQL{} }
func (opt useStandardSQL) customizeCreateTable(conf *createTableConf) {
conf.useStandardSQL = true
}
type useLegacySQL struct{}
// UseLegacySQL returns a CreateTableOption to set the table to use legacy SQL.
// This is currently the default.
func UseLegacySQL() CreateTableOption { return useLegacySQL{} }
func (opt useLegacySQL) customizeCreateTable(conf *createTableConf) {
conf.useLegacySQL = true
}
// TimePartitioning is a CreateTableOption that can be used to set time-based
// date partitioning on a table.
// For more information see: https://cloud.google.com/bigquery/docs/creating-partitioned-tables
type TimePartitioning struct {
// (Optional) The amount of time to keep the storage for a partition.
// If the duration is empty (0), the data in the partitions do not expire.
Expiration time.Duration
}
func (opt TimePartitioning) customizeCreateTable(conf *createTableConf) {
conf.timePartitioning = &opt
}
// Read fetches the contents of the table. // Read fetches the contents of the table.
func (t *Table) Read(ctx context.Context) *RowIterator { func (t *Table) Read(ctx context.Context) *RowIterator {
return newRowIterator(ctx, t.c.service, &readTableConf{ return newRowIterator(ctx, t.c.service, &readTableConf{

View File

@ -14,11 +14,6 @@
package bigquery package bigquery
import (
"golang.org/x/net/context"
bq "google.golang.org/api/bigquery/v2"
)
func defaultGCS() *GCSReference { func defaultGCS() *GCSReference {
return &GCSReference{ return &GCSReference{
uris: []string{"uri"}, uris: []string{"uri"},
@ -30,18 +25,3 @@ var defaultQuery = &QueryConfig{
DefaultProjectID: "def-project-id", DefaultProjectID: "def-project-id",
DefaultDatasetID: "def-dataset-id", DefaultDatasetID: "def-dataset-id",
} }
type testService struct {
*bq.Job
service
}
func (s *testService) insertJob(ctx context.Context, projectID string, conf *insertJobConf) (*Job, error) {
s.Job = conf.job
return &Job{}, nil
}
func (s *testService) jobStatus(ctx context.Context, projectID, jobID string) (*JobStatus, error) {
return &JobStatus{State: Done}, nil
}

View File

@ -26,7 +26,7 @@ import (
// Repo is the current version of the client libraries in this // Repo is the current version of the client libraries in this
// repo. It should be a date in YYYYMMDD format. // repo. It should be a date in YYYYMMDD format.
const Repo = "20170621" const Repo = "20170928"
// Go returns the Go runtime version. The returned string // Go returns the Go runtime version. The returned string
// has no whitespace. // has no whitespace.

View File

@ -14,7 +14,7 @@
// AUTO-GENERATED CODE. DO NOT EDIT. // AUTO-GENERATED CODE. DO NOT EDIT.
// Package language is an experimental, auto-generated package for the // Package language is an auto-generated package for the
// Google Cloud Natural Language API. // Google Cloud Natural Language API.
// //
// Google Cloud Natural Language API provides natural language understanding // Google Cloud Natural Language API provides natural language understanding

View File

@ -31,10 +31,11 @@ import (
// CallOptions contains the retry settings for each method of Client. // CallOptions contains the retry settings for each method of Client.
type CallOptions struct { type CallOptions struct {
AnalyzeSentiment []gax.CallOption AnalyzeSentiment []gax.CallOption
AnalyzeEntities []gax.CallOption AnalyzeEntities []gax.CallOption
AnalyzeSyntax []gax.CallOption AnalyzeEntitySentiment []gax.CallOption
AnnotateText []gax.CallOption AnalyzeSyntax []gax.CallOption
AnnotateText []gax.CallOption
} }
func defaultClientOptions() []option.ClientOption { func defaultClientOptions() []option.ClientOption {
@ -60,10 +61,11 @@ func defaultCallOptions() *CallOptions {
}, },
} }
return &CallOptions{ return &CallOptions{
AnalyzeSentiment: retry[[2]string{"default", "idempotent"}], AnalyzeSentiment: retry[[2]string{"default", "idempotent"}],
AnalyzeEntities: retry[[2]string{"default", "idempotent"}], AnalyzeEntities: retry[[2]string{"default", "idempotent"}],
AnalyzeSyntax: retry[[2]string{"default", "idempotent"}], AnalyzeEntitySentiment: retry[[2]string{"default", "idempotent"}],
AnnotateText: retry[[2]string{"default", "idempotent"}], AnalyzeSyntax: retry[[2]string{"default", "idempotent"}],
AnnotateText: retry[[2]string{"default", "idempotent"}],
} }
} }
@ -155,6 +157,23 @@ func (c *Client) AnalyzeEntities(ctx context.Context, req *languagepb.AnalyzeEnt
return resp, nil return resp, nil
} }
// AnalyzeEntitySentiment finds entities, similar to [AnalyzeEntities][google.cloud.language.v1.LanguageService.AnalyzeEntities] in the text and analyzes
// sentiment associated with each entity and its mentions.
func (c *Client) AnalyzeEntitySentiment(ctx context.Context, req *languagepb.AnalyzeEntitySentimentRequest, opts ...gax.CallOption) (*languagepb.AnalyzeEntitySentimentResponse, error) {
ctx = insertXGoog(ctx, c.xGoogHeader)
opts = append(c.CallOptions.AnalyzeEntitySentiment[0:len(c.CallOptions.AnalyzeEntitySentiment):len(c.CallOptions.AnalyzeEntitySentiment)], opts...)
var resp *languagepb.AnalyzeEntitySentimentResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.AnalyzeEntitySentiment(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// AnalyzeSyntax analyzes the syntax of the text and provides sentence boundaries and // AnalyzeSyntax analyzes the syntax of the text and provides sentence boundaries and
// tokenization along with part of speech tags, dependency trees, and other // tokenization along with part of speech tags, dependency trees, and other
// properties. // properties.

View File

@ -68,6 +68,24 @@ func ExampleClient_AnalyzeEntities() {
_ = resp _ = resp
} }
func ExampleClient_AnalyzeEntitySentiment() {
ctx := context.Background()
c, err := language.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &languagepb.AnalyzeEntitySentimentRequest{
// TODO: Fill request struct fields.
}
resp, err := c.AnalyzeEntitySentiment(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_AnalyzeSyntax() { func ExampleClient_AnalyzeSyntax() {
ctx := context.Background() ctx := context.Background()
c, err := language.NewClient(ctx) c, err := language.NewClient(ctx)

View File

@ -84,6 +84,18 @@ func (s *mockLanguageServer) AnalyzeEntities(ctx context.Context, req *languagep
return s.resps[0].(*languagepb.AnalyzeEntitiesResponse), nil return s.resps[0].(*languagepb.AnalyzeEntitiesResponse), nil
} }
func (s *mockLanguageServer) AnalyzeEntitySentiment(ctx context.Context, req *languagepb.AnalyzeEntitySentimentRequest) (*languagepb.AnalyzeEntitySentimentResponse, 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].(*languagepb.AnalyzeEntitySentimentResponse), nil
}
func (s *mockLanguageServer) AnalyzeSyntax(ctx context.Context, req *languagepb.AnalyzeSyntaxRequest) (*languagepb.AnalyzeSyntaxResponse, error) { func (s *mockLanguageServer) AnalyzeSyntax(ctx context.Context, req *languagepb.AnalyzeSyntaxRequest) (*languagepb.AnalyzeSyntaxResponse, error) {
md, _ := metadata.FromIncomingContext(ctx) md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
@ -255,6 +267,65 @@ func TestLanguageServiceAnalyzeEntitiesError(t *testing.T) {
} }
_ = resp _ = resp
} }
func TestLanguageServiceAnalyzeEntitySentiment(t *testing.T) {
var language string = "language-1613589672"
var expectedResponse = &languagepb.AnalyzeEntitySentimentResponse{
Language: language,
}
mockLanguage.err = nil
mockLanguage.reqs = nil
mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse)
var document *languagepb.Document = &languagepb.Document{}
var request = &languagepb.AnalyzeEntitySentimentRequest{
Document: document,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.AnalyzeEntitySentiment(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if want, got := request, mockLanguage.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 TestLanguageServiceAnalyzeEntitySentimentError(t *testing.T) {
errCode := codes.PermissionDenied
mockLanguage.err = gstatus.Error(errCode, "test error")
var document *languagepb.Document = &languagepb.Document{}
var request = &languagepb.AnalyzeEntitySentimentRequest{
Document: document,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.AnalyzeEntitySentiment(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 TestLanguageServiceAnalyzeSyntax(t *testing.T) { func TestLanguageServiceAnalyzeSyntax(t *testing.T) {
var language string = "language-1613589672" var language string = "language-1613589672"
var expectedResponse = &languagepb.AnalyzeSyntaxResponse{ var expectedResponse = &languagepb.AnalyzeSyntaxResponse{

View File

@ -35,6 +35,7 @@ type CallOptions struct {
AnalyzeEntities []gax.CallOption AnalyzeEntities []gax.CallOption
AnalyzeEntitySentiment []gax.CallOption AnalyzeEntitySentiment []gax.CallOption
AnalyzeSyntax []gax.CallOption AnalyzeSyntax []gax.CallOption
ClassifyText []gax.CallOption
AnnotateText []gax.CallOption AnnotateText []gax.CallOption
} }
@ -65,6 +66,7 @@ func defaultCallOptions() *CallOptions {
AnalyzeEntities: retry[[2]string{"default", "idempotent"}], AnalyzeEntities: retry[[2]string{"default", "idempotent"}],
AnalyzeEntitySentiment: retry[[2]string{"default", "idempotent"}], AnalyzeEntitySentiment: retry[[2]string{"default", "idempotent"}],
AnalyzeSyntax: retry[[2]string{"default", "idempotent"}], AnalyzeSyntax: retry[[2]string{"default", "idempotent"}],
ClassifyText: retry[[2]string{"default", "idempotent"}],
AnnotateText: retry[[2]string{"default", "idempotent"}], AnnotateText: retry[[2]string{"default", "idempotent"}],
} }
} }
@ -192,8 +194,24 @@ func (c *Client) AnalyzeSyntax(ctx context.Context, req *languagepb.AnalyzeSynta
return resp, nil return resp, nil
} }
// AnnotateText a convenience method that provides all syntax, sentiment, and entity // ClassifyText classifies a document into categories.
// features in one call. func (c *Client) ClassifyText(ctx context.Context, req *languagepb.ClassifyTextRequest, opts ...gax.CallOption) (*languagepb.ClassifyTextResponse, error) {
ctx = insertXGoog(ctx, c.xGoogHeader)
opts = append(c.CallOptions.ClassifyText[0:len(c.CallOptions.ClassifyText):len(c.CallOptions.ClassifyText)], opts...)
var resp *languagepb.ClassifyTextResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.client.ClassifyText(ctx, req, settings.GRPC...)
return err
}, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
// AnnotateText a convenience method that provides all syntax, sentiment, entity, and
// classification features in one call.
func (c *Client) AnnotateText(ctx context.Context, req *languagepb.AnnotateTextRequest, opts ...gax.CallOption) (*languagepb.AnnotateTextResponse, error) { func (c *Client) AnnotateText(ctx context.Context, req *languagepb.AnnotateTextRequest, opts ...gax.CallOption) (*languagepb.AnnotateTextResponse, error) {
ctx = insertXGoog(ctx, c.xGoogHeader) ctx = insertXGoog(ctx, c.xGoogHeader)
opts = append(c.CallOptions.AnnotateText[0:len(c.CallOptions.AnnotateText):len(c.CallOptions.AnnotateText)], opts...) opts = append(c.CallOptions.AnnotateText[0:len(c.CallOptions.AnnotateText):len(c.CallOptions.AnnotateText)], opts...)

View File

@ -104,6 +104,24 @@ func ExampleClient_AnalyzeSyntax() {
_ = resp _ = resp
} }
func ExampleClient_ClassifyText() {
ctx := context.Background()
c, err := language.NewClient(ctx)
if err != nil {
// TODO: Handle error.
}
req := &languagepb.ClassifyTextRequest{
// TODO: Fill request struct fields.
}
resp, err := c.ClassifyText(ctx, req)
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
func ExampleClient_AnnotateText() { func ExampleClient_AnnotateText() {
ctx := context.Background() ctx := context.Background()
c, err := language.NewClient(ctx) c, err := language.NewClient(ctx)

View File

@ -108,6 +108,18 @@ func (s *mockLanguageServer) AnalyzeSyntax(ctx context.Context, req *languagepb.
return s.resps[0].(*languagepb.AnalyzeSyntaxResponse), nil return s.resps[0].(*languagepb.AnalyzeSyntaxResponse), nil
} }
func (s *mockLanguageServer) ClassifyText(ctx context.Context, req *languagepb.ClassifyTextRequest) (*languagepb.ClassifyTextResponse, 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].(*languagepb.ClassifyTextResponse), nil
}
func (s *mockLanguageServer) AnnotateText(ctx context.Context, req *languagepb.AnnotateTextRequest) (*languagepb.AnnotateTextResponse, error) { func (s *mockLanguageServer) AnnotateText(ctx context.Context, req *languagepb.AnnotateTextRequest) (*languagepb.AnnotateTextResponse, error) {
md, _ := metadata.FromIncomingContext(ctx) md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") { if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
@ -385,6 +397,62 @@ func TestLanguageServiceAnalyzeSyntaxError(t *testing.T) {
} }
_ = resp _ = resp
} }
func TestLanguageServiceClassifyText(t *testing.T) {
var expectedResponse *languagepb.ClassifyTextResponse = &languagepb.ClassifyTextResponse{}
mockLanguage.err = nil
mockLanguage.reqs = nil
mockLanguage.resps = append(mockLanguage.resps[:0], expectedResponse)
var document *languagepb.Document = &languagepb.Document{}
var request = &languagepb.ClassifyTextRequest{
Document: document,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.ClassifyText(context.Background(), request)
if err != nil {
t.Fatal(err)
}
if want, got := request, mockLanguage.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 TestLanguageServiceClassifyTextError(t *testing.T) {
errCode := codes.PermissionDenied
mockLanguage.err = gstatus.Error(errCode, "test error")
var document *languagepb.Document = &languagepb.Document{}
var request = &languagepb.ClassifyTextRequest{
Document: document,
}
c, err := NewClient(context.Background(), clientOpt)
if err != nil {
t.Fatal(err)
}
resp, err := c.ClassifyText(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 TestLanguageServiceAnnotateText(t *testing.T) { func TestLanguageServiceAnnotateText(t *testing.T) {
var language string = "language-1613589672" var language string = "language-1613589672"
var expectedResponse = &languagepb.AnnotateTextResponse{ var expectedResponse = &languagepb.AnnotateTextResponse{

View File

@ -36,7 +36,9 @@ package profiler
import ( import (
"bytes" "bytes"
"errors" "errors"
"fmt"
"log" "log"
"os"
"runtime/pprof" "runtime/pprof"
"sync" "sync"
"time" "time"
@ -60,8 +62,7 @@ import (
var ( var (
config Config config Config
startOnce sync.Once startOnce sync.Once
// getProjectID, getInstanceName, getZone, startCPUProfile, stopCPUProfile, // The functions below are stubbed to be overrideable for testing.
// writeHeapProfile and sleep are overrideable for testing.
getProjectID = gcemd.ProjectID getProjectID = gcemd.ProjectID
getInstanceName = gcemd.InstanceName getInstanceName = gcemd.InstanceName
getZone = gcemd.Zone getZone = gcemd.Zone
@ -69,6 +70,8 @@ var (
stopCPUProfile = pprof.StopCPUProfile stopCPUProfile = pprof.StopCPUProfile
writeHeapProfile = pprof.WriteHeapProfile writeHeapProfile = pprof.WriteHeapProfile
sleep = gax.Sleep sleep = gax.Sleep
dialGRPC = gtransport.Dial
onGCE = gcemd.OnGCE
) )
const ( const (
@ -116,20 +119,6 @@ type Config struct {
// or anywhere else outside of Google Cloud Platform. // or anywhere else outside of Google Cloud Platform.
ProjectID string ProjectID string
// InstanceName is the name of the VM instance to use instead of
// the one read from the VM metadata server.
//
// Set this if you are running the agent in your local environment
// or anywhere else outside of Google Cloud Platform.
InstanceName string
// ZoneName is the name of the zone to use instead of
// the one read from the VM metadata server.
//
// Set this if you are running the agent in your local environment
// or anywhere else outside of Google Cloud Platform.
ZoneName string
// APIAddr is the HTTP endpoint to use to connect to the profiler // APIAddr is the HTTP endpoint to use to connect to the profiler
// agent API. Defaults to the production environment, overridable // agent API. Defaults to the production environment, overridable
// for testing. // for testing.
@ -137,6 +126,9 @@ type Config struct {
// Target is deprecated, use Service instead. // Target is deprecated, use Service instead.
Target string Target string
instance string
zone string
} }
// startError represents the error occured during the // startError represents the error occured during the
@ -168,22 +160,14 @@ func start(cfg Config, options ...option.ClientOption) error {
} }
opts = append(opts, options...) opts = append(opts, options...)
conn, err := gtransport.Dial(ctx, opts...) conn, err := dialGRPC(ctx, opts...)
if err != nil { if err != nil {
debugLog("failed to dial GRPC: %v", err) debugLog("failed to dial GRPC: %v", err)
return err return err
} }
d, err := initializeDeployment() a := initializeAgent(pb.NewProfilerServiceClient(conn))
if err != nil { go pollProfilerService(withXGoogHeader(ctx), a)
debugLog("failed to initialize deployment: %v", err)
return err
}
l := initializeProfileLabels()
a, ctx := initializeResources(ctx, conn, d, l)
go pollProfilerService(ctx, a)
return nil return nil
} }
@ -196,7 +180,7 @@ func debugLog(format string, e ...interface{}) {
// agent polls Cloud Profiler server for instructions on behalf of // agent polls Cloud Profiler server for instructions on behalf of
// a task, and collects and uploads profiles as requested. // a task, and collects and uploads profiles as requested.
type agent struct { type agent struct {
client *client client pb.ProfilerServiceClient
deployment *pb.Deployment deployment *pb.Deployment
profileLabels map[string]string profileLabels map[string]string
} }
@ -254,7 +238,7 @@ func (a *agent) createProfile(ctx context.Context) *pb.Profile {
gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error var err error
p, err = a.client.client.CreateProfile(ctx, &req, grpc.Trailer(&md)) p, err = a.client.CreateProfile(ctx, &req, grpc.Trailer(&md))
return err return err
}, gax.WithRetry(func() gax.Retryer { }, gax.WithRetry(func() gax.Retryer {
return &retryer{ return &retryer{
@ -313,107 +297,91 @@ func (a *agent) profileAndUpload(ctx context.Context, p *pb.Profile) {
// Upload profile, discard profile in case of error. // Upload profile, discard profile in case of error.
debugLog("start uploading profile") debugLog("start uploading profile")
if _, err := a.client.client.UpdateProfile(ctx, &req); err != nil { if _, err := a.client.UpdateProfile(ctx, &req); err != nil {
debugLog("failed to upload profile: %v", err) debugLog("failed to upload profile: %v", err)
} }
} }
// client is a client for interacting with Cloud Profiler API. // withXGoogHeader sets the name and version of the application in
type client struct {
// gRPC API client.
client pb.ProfilerServiceClient
// Metadata for google API to be sent with each request.
xGoogHeader []string
}
// setXGoogHeader sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for // the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients. // use by Google-written clients.
func (c *client) setXGoogHeader(keyval ...string) { func withXGoogHeader(ctx context.Context, keyval ...string) context.Context {
kv := append([]string{"gl-go", version.Go(), "gccl", version.Repo}, keyval...) kv := append([]string{"gl-go", version.Go(), "gccl", version.Repo}, keyval...)
kv = append(kv, "gax", gax.Version, "grpc", grpc.Version) kv = append(kv, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogHeader = []string{gax.XGoogHeader(kv...)}
}
func (c *client) insertMetadata(ctx context.Context) context.Context {
md, _ := grpcmd.FromOutgoingContext(ctx) md, _ := grpcmd.FromOutgoingContext(ctx)
md = md.Copy() md = md.Copy()
md[xGoogAPIMetadata] = c.xGoogHeader md[xGoogAPIMetadata] = []string{gax.XGoogHeader(kv...)}
return grpcmd.NewOutgoingContext(ctx, md) return grpcmd.NewOutgoingContext(ctx, md)
} }
func initializeDeployment() (*pb.Deployment, error) { func initializeAgent(c pb.ProfilerServiceClient) *agent {
var err error labels := map[string]string{}
if config.zone != "" {
projectID := config.ProjectID labels[zoneNameLabel] = config.zone
if projectID == "" {
projectID, err = getProjectID()
if err != nil {
return nil, err
}
}
zone := config.ZoneName
if zone == "" {
zone, err = getZone()
if err != nil {
return nil, err
}
}
labels := map[string]string{
zoneNameLabel: zone,
} }
if config.ServiceVersion != "" { if config.ServiceVersion != "" {
labels[versionLabel] = config.ServiceVersion labels[versionLabel] = config.ServiceVersion
} }
d := &pb.Deployment{
return &pb.Deployment{ ProjectId: config.ProjectID,
ProjectId: projectID,
Target: config.Target, Target: config.Target,
Labels: labels, Labels: labels,
}, nil
}
func initializeProfileLabels() map[string]string {
instance := config.InstanceName
if instance == "" {
var err error
if instance, err = getInstanceName(); err != nil {
instance = "unknown"
debugLog("failed to get instance name: %v", err)
}
} }
return map[string]string{instanceLabel: instance} profileLabels := map[string]string{}
}
func initializeResources(ctx context.Context, conn *grpc.ClientConn, d *pb.Deployment, l map[string]string) (*agent, context.Context) { if config.instance != "" {
c := &client{ profileLabels[instanceLabel] = config.instance
client: pb.NewProfilerServiceClient(conn),
} }
c.setXGoogHeader()
ctx = c.insertMetadata(ctx)
return &agent{ return &agent{
client: c, client: c,
deployment: d, deployment: d,
profileLabels: l, profileLabels: profileLabels,
}, ctx }
} }
func initializeConfig(cfg Config) error { func initializeConfig(cfg Config) error {
config = cfg config = cfg
if config.Service != "" { switch {
case config.Service != "":
config.Target = config.Service config.Target = config.Service
case config.Target == "":
config.Target = os.Getenv("GAE_SERVICE")
} }
if config.Target == "" { if config.Target == "" {
return errors.New("service name must be specified in the configuration") return errors.New("service name must be specified in the configuration")
} }
if config.ServiceVersion == "" {
config.ServiceVersion = os.Getenv("GAE_VERSION")
}
if onGCE() {
var err error
if config.ProjectID == "" {
if config.ProjectID, err = getProjectID(); err != nil {
return fmt.Errorf("failed to get the project ID from Compute Engine: %v", err)
}
}
if config.zone, err = getZone(); err != nil {
return fmt.Errorf("failed to get zone from Compute Engine: %v", err)
}
if config.instance, err = getInstanceName(); err != nil {
return fmt.Errorf("failed to get instance from Compute Engine: %v", err)
}
} else {
if config.ProjectID == "" {
return fmt.Errorf("project ID must be specified in the configuration if running outside of GCP")
}
}
if config.APIAddr == "" { if config.APIAddr == "" {
config.APIAddr = apiAddress config.APIAddr = apiAddress
} }

View File

@ -15,21 +15,27 @@
package profiler package profiler
import ( import (
"bytes"
"compress/gzip"
"errors" "errors"
"fmt"
"io" "io"
"runtime/pprof" "log"
"math/rand"
"os"
"strings" "strings"
"testing" "testing"
"time" "time"
gcemd "cloud.google.com/go/compute/metadata"
"cloud.google.com/go/internal/testutil" "cloud.google.com/go/internal/testutil"
"cloud.google.com/go/profiler/mocks" "cloud.google.com/go/profiler/mocks"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
"github.com/google/pprof/profile"
gax "github.com/googleapis/gax-go" gax "github.com/googleapis/gax-go"
"golang.org/x/net/context" "golang.org/x/net/context"
gtransport "google.golang.org/api/transport/grpc"
pb "google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2" pb "google.golang.org/genproto/googleapis/devtools/cloudprofiler/v2"
edpb "google.golang.org/genproto/googleapis/rpc/errdetails" edpb "google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
@ -38,18 +44,21 @@ import (
) )
const ( const (
testProjectID = "test-project-ID" testProjectID = "test-project-ID"
testInstanceName = "test-instance-name" testInstance = "test-instance"
testZoneName = "test-zone-name" testZone = "test-zone"
testTarget = "test-target" testTarget = "test-target"
testService = "test-service" testService = "test-service"
testServiceVersion = "test-service-version" testSvcVersion = "test-service-version"
testProfileDuration = time.Second * 10
testServerTimeout = time.Second * 15
wantFunctionName = "profilee"
) )
func createTestDeployment() *pb.Deployment { func createTestDeployment() *pb.Deployment {
labels := map[string]string{ labels := map[string]string{
zoneNameLabel: testZoneName, zoneNameLabel: testZone,
versionLabel: testServiceVersion, versionLabel: testSvcVersion,
} }
return &pb.Deployment{ return &pb.Deployment{
ProjectId: testProjectID, ProjectId: testProjectID,
@ -59,11 +68,10 @@ func createTestDeployment() *pb.Deployment {
} }
func createTestAgent(psc pb.ProfilerServiceClient) *agent { func createTestAgent(psc pb.ProfilerServiceClient) *agent {
c := &client{client: psc}
return &agent{ return &agent{
client: c, client: psc,
deployment: createTestDeployment(), deployment: createTestDeployment(),
profileLabels: map[string]string{instanceLabel: testInstanceName}, profileLabels: map[string]string{instanceLabel: testInstance},
} }
} }
@ -98,11 +106,9 @@ func TestCreateProfile(t *testing.T) {
} }
func TestProfileAndUpload(t *testing.T) { func TestProfileAndUpload(t *testing.T) {
oldStartCPUProfile, oldStopCPUProfile, oldWriteHeapProfile, oldSleep := startCPUProfile, stopCPUProfile, writeHeapProfile, sleep
defer func() { defer func() {
startCPUProfile = pprof.StartCPUProfile startCPUProfile, stopCPUProfile, writeHeapProfile, sleep = oldStartCPUProfile, oldStopCPUProfile, oldWriteHeapProfile, oldSleep
stopCPUProfile = pprof.StopCPUProfile
writeHeapProfile = pprof.WriteHeapProfile
sleep = gax.Sleep
}() }()
ctx := context.Background() ctx := context.Background()
@ -306,118 +312,396 @@ func TestRetry(t *testing.T) {
} }
} }
func TestInitializeResources(t *testing.T) { func TestWithXGoogHeader(t *testing.T) {
d := createTestDeployment() ctx := withXGoogHeader(context.Background())
l := map[string]string{instanceLabel: testInstanceName}
ctx := context.Background()
a, ctx := initializeResources(ctx, nil, d, l)
if xg := a.client.xGoogHeader; len(xg) == 0 {
t.Errorf("initializeResources() sets empty xGoogHeader")
} else {
if !strings.Contains(xg[0], "gl-go/") {
t.Errorf("initializeResources() sets wrong xGoogHeader, got: %v, want gl-go key", xg[0])
}
if !strings.Contains(xg[0], "gccl/") {
t.Errorf("initializeResources() sets wrong xGoogHeader, got: %v, want gccl key", xg[0])
}
if !strings.Contains(xg[0], "gax/") {
t.Errorf("initializeResources() sets wrong xGoogHeader, got: %v, want gax key", xg[0])
}
if !strings.Contains(xg[0], "grpc/") {
t.Errorf("initializeResources() sets wrong xGoogHeader, got: %v, want grpc key", xg[0])
}
}
md, _ := grpcmd.FromOutgoingContext(ctx) md, _ := grpcmd.FromOutgoingContext(ctx)
if !testutil.Equal(md[xGoogAPIMetadata], a.client.xGoogHeader) { if xg := md[xGoogAPIMetadata]; len(xg) == 0 {
t.Errorf("md[%v] = %v, want equal xGoogHeader = %v", xGoogAPIMetadata, md[xGoogAPIMetadata], a.client.xGoogHeader) t.Errorf("withXGoogHeader() sets empty xGoogHeader")
} else {
if !strings.Contains(xg[0], "gl-go/") {
t.Errorf("withXGoogHeader() got: %v, want gl-go key", xg[0])
}
if !strings.Contains(xg[0], "gccl/") {
t.Errorf("withXGoogHeader() got: %v, want gccl key", xg[0])
}
if !strings.Contains(xg[0], "gax/") {
t.Errorf("withXGoogHeader() got: %v, want gax key", xg[0])
}
if !strings.Contains(xg[0], "grpc/") {
t.Errorf("withXGoogHeader() got: %v, want grpc key", xg[0])
}
} }
} }
func TestInitializeDeployment(t *testing.T) { func TestInitializeAgent(t *testing.T) {
defer func() {
getProjectID = gcemd.ProjectID
getZone = gcemd.Zone
config = Config{}
}()
getProjectID = func() (string, error) {
return testProjectID, nil
}
getZone = func() (string, error) {
return testZoneName, nil
}
cfg := Config{Service: testService, ServiceVersion: testServiceVersion}
initializeConfig(cfg)
d, err := initializeDeployment()
if err != nil {
t.Errorf("initializeDeployment() got error: %v, want no error", err)
}
if want := createTestDeployment(); !testutil.Equal(d, want) {
t.Errorf("initializeDeployment() got: %v, want %v", d, want)
}
}
func TestInitializeConfig(t *testing.T) {
oldConfig := config oldConfig := config
defer func() { defer func() {
config = oldConfig config = oldConfig
}() }()
for _, tt := range []struct {
config Config
wantDeploymentLabels map[string]string
wantProfileLabels map[string]string
}{
{
config: Config{ServiceVersion: testSvcVersion, zone: testZone},
wantDeploymentLabels: map[string]string{zoneNameLabel: testZone, versionLabel: testSvcVersion},
wantProfileLabels: map[string]string{},
},
{
config: Config{zone: testZone},
wantDeploymentLabels: map[string]string{zoneNameLabel: testZone},
wantProfileLabels: map[string]string{},
},
{
config: Config{ServiceVersion: testSvcVersion},
wantDeploymentLabels: map[string]string{versionLabel: testSvcVersion},
wantProfileLabels: map[string]string{},
},
{
config: Config{instance: testInstance},
wantDeploymentLabels: map[string]string{},
wantProfileLabels: map[string]string{instanceLabel: testInstance},
},
} {
config = tt.config
config.ProjectID = testProjectID
config.Target = testTarget
a := initializeAgent(nil)
wantDeployment := &pb.Deployment{
ProjectId: testProjectID,
Target: testTarget,
Labels: tt.wantDeploymentLabels,
}
if !testutil.Equal(a.deployment, wantDeployment) {
t.Errorf("initializeResources() got deployment: %v, want %v", a.deployment, wantDeployment)
}
if !testutil.Equal(a.profileLabels, tt.wantProfileLabels) {
t.Errorf("initializeResources() got profile labels: %v, want %v", a.profileLabels, tt.wantProfileLabels)
}
}
}
func TestInitializeConfig(t *testing.T) {
oldConfig, oldService, oldVersion, oldGetProjectID, oldGetInstanceName, oldGetZone, oldOnGCE := config, os.Getenv("GAE_SERVICE"), os.Getenv("GAE_VERSION"), getProjectID, getInstanceName, getZone, onGCE
defer func() {
config, getProjectID, getInstanceName, getZone, onGCE = oldConfig, oldGetProjectID, oldGetInstanceName, oldGetZone, oldOnGCE
if err := os.Setenv("GAE_SERVICE", oldService); err != nil {
t.Fatal(err)
}
if err := os.Setenv("GAE_VERSION", oldVersion); err != nil {
t.Fatal(err)
}
}()
testGAEService := "test-gae-service"
testGAEVersion := "test-gae-version"
testGCEProjectID := "test-gce-project-id"
for _, tt := range []struct { for _, tt := range []struct {
config Config config Config
wantTarget string wantConfig Config
wantErrorString string wantErrorString string
onGAE bool
onGCE bool
}{ }{
{ {
Config{Service: testService}, Config{Service: testService},
testService, Config{Target: testService, ProjectID: testGCEProjectID, zone: testZone, instance: testInstance},
"", "",
false,
true,
}, },
{ {
Config{Target: testTarget}, Config{Target: testTarget},
testTarget, Config{Target: testTarget, ProjectID: testGCEProjectID, zone: testZone, instance: testInstance},
"", "",
false,
true,
}, },
{ {
Config{}, Config{},
"", Config{},
"service name must be specified in the configuration", "service name must be specified in the configuration",
false,
true,
},
{
Config{Service: testService},
Config{Target: testService, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, zone: testZone, instance: testInstance},
"",
true,
true,
},
{
Config{Target: testTarget},
Config{Target: testTarget, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, zone: testZone, instance: testInstance},
"",
true,
true,
},
{
Config{},
Config{Target: testGAEService, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, zone: testZone, instance: testInstance},
"",
true,
true,
},
{
Config{Service: testService, ServiceVersion: testSvcVersion},
Config{Target: testService, ServiceVersion: testSvcVersion, ProjectID: testGCEProjectID, zone: testZone, instance: testInstance},
"",
false,
true,
},
{
Config{Service: testService, ServiceVersion: testSvcVersion},
Config{Target: testService, ServiceVersion: testSvcVersion, ProjectID: testGCEProjectID, zone: testZone, instance: testInstance},
"",
true,
true,
},
{
Config{Service: testService, ProjectID: testProjectID},
Config{Target: testService, ProjectID: testProjectID, zone: testZone, instance: testInstance},
"",
false,
true,
},
{
Config{Service: testService},
Config{Target: testService},
"project ID must be specified in the configuration if running outside of GCP",
false,
false,
}, },
} { } {
envService, envVersion := "", ""
if tt.onGAE {
envService, envVersion = testGAEService, testGAEVersion
}
if err := os.Setenv("GAE_SERVICE", envService); err != nil {
t.Fatal(err)
}
if err := os.Setenv("GAE_VERSION", envVersion); err != nil {
t.Fatal(err)
}
if tt.onGCE {
onGCE = func() bool { return true }
getProjectID = func() (string, error) { return testGCEProjectID, nil }
getZone = func() (string, error) { return testZone, nil }
getInstanceName = func() (string, error) { return testInstance, nil }
} else {
onGCE = func() bool { return false }
getProjectID = func() (string, error) { return "", fmt.Errorf("test get project id error") }
getZone = func() (string, error) { return "", fmt.Errorf("test get zone error") }
getInstanceName = func() (string, error) { return "", fmt.Errorf("test get instance error") }
}
errorString := "" errorString := ""
if err := initializeConfig(tt.config); err != nil { if err := initializeConfig(tt.config); err != nil {
errorString = err.Error() errorString = err.Error()
} }
if errorString != tt.wantErrorString { if !strings.Contains(errorString, tt.wantErrorString) {
t.Errorf("initializeConfig(%v) got error: %v, want %v", tt.config, errorString, tt.wantErrorString) t.Errorf("initializeConfig(%v) got error: %v, want contain %v", tt.config, errorString, tt.wantErrorString)
} }
if config.Target != tt.wantTarget { if tt.wantErrorString == "" {
t.Errorf("initializeConfig(%v) got target: %v, want %v", tt.config, config.Target, tt.wantTarget) tt.wantConfig.APIAddr = apiAddress
}
tt.wantConfig.Service = tt.config.Service
if config != tt.wantConfig {
t.Errorf("initializeConfig(%v) got: %v, want %v", tt.config, config, tt.wantConfig)
}
}
for _, tt := range []struct {
wantErrorString string
getProjectIDError bool
getZoneError bool
getInstanceError bool
}{
{
wantErrorString: "failed to get the project ID from Compute Engine:",
getProjectIDError: true,
},
{
wantErrorString: "failed to get zone from Compute Engine:",
getZoneError: true,
},
{
wantErrorString: "failed to get instance from Compute Engine:",
getInstanceError: true,
},
} {
onGCE = func() bool { return true }
if tt.getProjectIDError {
getProjectID = func() (string, error) { return "", fmt.Errorf("test get project ID error") }
} else {
getProjectID = func() (string, error) { return testGCEProjectID, nil }
}
if tt.getZoneError {
getZone = func() (string, error) { return "", fmt.Errorf("test get zone error") }
} else {
getZone = func() (string, error) { return testZone, nil }
}
if tt.getInstanceError {
getInstanceName = func() (string, error) { return "", fmt.Errorf("test get instance error") }
} else {
getInstanceName = func() (string, error) { return testInstance, nil }
}
errorString := ""
if err := initializeConfig(Config{Service: testService}); err != nil {
errorString = err.Error()
}
if !strings.Contains(errorString, tt.wantErrorString) {
t.Errorf("initializeConfig() got error: %v, want contain %v", errorString, tt.wantErrorString)
} }
} }
} }
func TestInitializeProfileLabels(t *testing.T) { type fakeProfilerServer struct {
pb.ProfilerServiceServer
count int
gotCPUProfile []byte
gotHeapProfile []byte
done chan bool
}
func (fs *fakeProfilerServer) CreateProfile(ctx context.Context, in *pb.CreateProfileRequest) (*pb.Profile, error) {
fs.count++
switch fs.count {
case 1:
return &pb.Profile{Name: "testCPU", ProfileType: pb.ProfileType_CPU, Duration: ptypes.DurationProto(testProfileDuration)}, nil
case 2:
return &pb.Profile{Name: "testHeap", ProfileType: pb.ProfileType_HEAP}, nil
default:
select {}
}
}
func (fs *fakeProfilerServer) UpdateProfile(ctx context.Context, in *pb.UpdateProfileRequest) (*pb.Profile, error) {
switch in.Profile.ProfileType {
case pb.ProfileType_CPU:
fs.gotCPUProfile = in.Profile.ProfileBytes
case pb.ProfileType_HEAP:
fs.gotHeapProfile = in.Profile.ProfileBytes
fs.done <- true
}
return in.Profile, nil
}
func profileeLoop(quit chan bool) {
for {
select {
case <-quit:
return
default:
profileeWork()
}
}
}
func profileeWork() {
data := make([]byte, 1024*1024)
rand.Read(data)
var b bytes.Buffer
gz := gzip.NewWriter(&b)
if _, err := gz.Write(data); err != nil {
log.Printf("failed to write to gzip stream", err)
return
}
if err := gz.Flush(); err != nil {
log.Printf("failed to flush to gzip stream", err)
return
}
if err := gz.Close(); err != nil {
log.Printf("failed to close gzip stream", err)
}
}
func checkSymbolization(p *profile.Profile) error {
for _, l := range p.Location {
if len(l.Line) > 0 && l.Line[0].Function != nil && strings.Contains(l.Line[0].Function.Name, wantFunctionName) {
return nil
}
}
return fmt.Errorf("want function name %v not found in profile", wantFunctionName)
}
func validateProfile(rawData []byte) error {
p, err := profile.ParseData(rawData)
if err != nil {
return fmt.Errorf("ParseData failed: %v", err)
}
if len(p.Sample) == 0 {
return fmt.Errorf("profile contains zero samples: %v", p)
}
if len(p.Location) == 0 {
return fmt.Errorf("profile contains zero locations: %v", p)
}
if len(p.Function) == 0 {
return fmt.Errorf("profile contains zero functions: %v", p)
}
if err := checkSymbolization(p); err != nil {
return fmt.Errorf("checkSymbolization failed: %v for %v", err, p)
}
return nil
}
func TestAgentWithServer(t *testing.T) {
oldDialGRPC, oldConfig := dialGRPC, config
defer func() { defer func() {
getInstanceName = gcemd.InstanceName dialGRPC, config = oldDialGRPC, oldConfig
}() }()
getInstanceName = func() (string, error) { srv, err := testutil.NewServer()
return testInstanceName, nil if err != nil {
t.Fatalf("testutil.NewServer(): %v", err)
}
fakeServer := &fakeProfilerServer{done: make(chan bool)}
pb.RegisterProfilerServiceServer(srv.Gsrv, fakeServer)
srv.Start()
dialGRPC = gtransport.DialInsecure
if err := Start(Config{
Target: testTarget,
ProjectID: testProjectID,
APIAddr: srv.Addr,
instance: testInstance,
zone: testZone,
}); err != nil {
t.Fatalf("Start(): %v", err)
} }
l := initializeProfileLabels() quitProfilee := make(chan bool)
want := map[string]string{instanceLabel: testInstanceName} go profileeLoop(quitProfilee)
if !testutil.Equal(l, want) {
t.Errorf("initializeProfileLabels() got: %v, want %v", l, want) select {
case <-fakeServer.done:
case <-time.After(testServerTimeout):
t.Errorf("got timeout after %v, want fake server done", testServerTimeout)
}
quitProfilee <- true
if err := validateProfile(fakeServer.gotCPUProfile); err != nil {
t.Errorf("validateProfile(gotCPUProfile): %v", err)
}
if err := validateProfile(fakeServer.gotHeapProfile); err != nil {
t.Errorf("validateProfile(gotHeapProfile): %v", err)
} }
} }

View File

@ -18,10 +18,12 @@ import (
"fmt" "fmt"
"os" "os"
"runtime" "runtime"
"time"
"google.golang.org/api/iterator" "google.golang.org/api/iterator"
"google.golang.org/api/option" "google.golang.org/api/option"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -66,6 +68,10 @@ func NewClient(ctx context.Context, projectID string, opts ...option.ClientOptio
// TODO(grpc/grpc-go#1388) using connection pool without WithBlock // TODO(grpc/grpc-go#1388) using connection pool without WithBlock
// can cause RPCs to fail randomly. We can delete this after the issue is fixed. // can cause RPCs to fail randomly. We can delete this after the issue is fixed.
option.WithGRPCDialOption(grpc.WithBlock()), option.WithGRPCDialOption(grpc.WithBlock()),
option.WithGRPCDialOption(grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 5 * time.Minute,
})),
} }
} }
o = append(o, opts...) o = append(o, opts...)

View File

@ -126,7 +126,7 @@ type Mutation struct {
// op is the operation type of the mutation. // op is the operation type of the mutation.
// See documentation for spanner.op for more details. // See documentation for spanner.op for more details.
op op op op
// Table is the name of the taget table to be modified. // Table is the name of the target table to be modified.
table string table string
// keySet is a set of primary keys that names the rows // keySet is a set of primary keys that names the rows
// in a delete operation. // in a delete operation.

View File

@ -948,8 +948,12 @@ func (hc *healthChecker) worker(i int) {
ws := getNextForTx() ws := getNextForTx()
if ws != nil { if ws != nil {
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel() err := ws.prepareForWrite(contextWithOutgoingMetadata(ctx, hc.pool.md))
ws.prepareForWrite(contextWithOutgoingMetadata(ctx, hc.pool.md)) cancel()
if err != nil {
// TODO(dixiao): handle error properly
log.Errorf("prepareForWrite failed: %v", err)
}
hc.pool.recycle(ws) hc.pool.recycle(ws)
hc.pool.mu.Lock() hc.pool.mu.Lock()
hc.pool.prepareReqs-- hc.pool.prepareReqs--

View File

@ -14,7 +14,7 @@
// AUTO-GENERATED CODE. DO NOT EDIT. // AUTO-GENERATED CODE. DO NOT EDIT.
// Package speech is an experimental, auto-generated package for the // Package speech is an auto-generated package for the
// Google Cloud Speech API. // Google Cloud Speech API.
// //
// Google Cloud Speech API. // Google Cloud Speech API.

View File

@ -197,8 +197,10 @@ func (b *BucketHandle) newPatchCall(uattrs *BucketAttrsToUpdate) (*raw.BucketsPa
} }
// BucketAttrs represents the metadata for a Google Cloud Storage bucket. // BucketAttrs represents the metadata for a Google Cloud Storage bucket.
// Read-only fields are ignored by BucketHandle.Create.
type BucketAttrs struct { type BucketAttrs struct {
// Name is the name of the bucket. // Name is the name of the bucket.
// This field is read-only.
Name string Name string
// ACL is the list of access control rules on the bucket. // ACL is the list of access control rules on the bucket.
@ -212,6 +214,7 @@ type BucketAttrs struct {
Location string Location string
// MetaGeneration is the metadata generation of the bucket. // MetaGeneration is the metadata generation of the bucket.
// This field is read-only.
MetaGeneration int64 MetaGeneration int64
// StorageClass is the default storage class of the bucket. This defines // StorageClass is the default storage class of the bucket. This defines
@ -224,10 +227,10 @@ type BucketAttrs struct {
StorageClass string StorageClass string
// Created is the creation time of the bucket. // Created is the creation time of the bucket.
// This field is read-only.
Created time.Time Created time.Time
// VersioningEnabled reports whether this bucket has versioning enabled. // VersioningEnabled reports whether this bucket has versioning enabled.
// This field is read-only.
VersioningEnabled bool VersioningEnabled bool
// Labels are the bucket's labels. // Labels are the bucket's labels.

View File

@ -110,7 +110,10 @@ func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error
// //
// Close need not be called at program exit. // Close need not be called at program exit.
func (c *Client) Close() error { func (c *Client) Close() error {
// Set fields to nil so that subsequent uses
// will panic.
c.hc = nil c.hc = nil
c.raw = nil
return nil return nil
} }
@ -346,11 +349,17 @@ func (o *ObjectHandle) Update(ctx context.Context, uattrs ObjectAttrsToUpdate) (
var forceSendFields, nullFields []string var forceSendFields, nullFields []string
if uattrs.ContentType != nil { if uattrs.ContentType != nil {
attrs.ContentType = optional.ToString(uattrs.ContentType) attrs.ContentType = optional.ToString(uattrs.ContentType)
forceSendFields = append(forceSendFields, "ContentType") // For ContentType, sending the empty string is a no-op.
// Instead we send a null.
if attrs.ContentType == "" {
nullFields = append(nullFields, "ContentType")
} else {
forceSendFields = append(forceSendFields, "ContentType")
}
} }
if uattrs.ContentLanguage != nil { if uattrs.ContentLanguage != nil {
attrs.ContentLanguage = optional.ToString(uattrs.ContentLanguage) attrs.ContentLanguage = optional.ToString(uattrs.ContentLanguage)
// For ContentLanguage It's an error to send the empty string. // For ContentLanguage it's an error to send the empty string.
// Instead we send a null. // Instead we send a null.
if attrs.ContentLanguage == "" { if attrs.ContentLanguage == "" {
nullFields = append(nullFields, "ContentLanguage") nullFields = append(nullFields, "ContentLanguage")

View File

@ -87,7 +87,7 @@ func (w *Writer) open() error {
w.opened = true w.opened = true
if w.ChunkSize < 0 { if w.ChunkSize < 0 {
return errors.New("storage: Writer.ChunkSize must non-negative") return errors.New("storage: Writer.ChunkSize must be non-negative")
} }
mediaOpts := []googleapi.MediaOption{ mediaOpts := []googleapi.MediaOption{
googleapi.ChunkSize(w.ChunkSize), googleapi.ChunkSize(w.ChunkSize),
@ -125,14 +125,21 @@ func (w *Writer) open() error {
call.UserProject(w.o.userProject) call.UserProject(w.o.userProject)
} }
setClientHeader(call.Header()) setClientHeader(call.Header())
// We will only retry here if the initial POST, which obtains a URI for // If the chunk size is zero, then no chunking is done on the Reader,
// the resumable upload, fails with a retryable error. The upload itself // which means we cannot retry: the first call will read the data, and if
// has its own retry logic. // it fails, there is no way to re-read.
err = runWithRetry(w.ctx, func() error { if w.ChunkSize == 0 {
var err2 error resp, err = call.Do()
resp, err2 = call.Do() } else {
return err2 // We will only retry here if the initial POST, which obtains a URI for
}) // the resumable upload, fails with a retryable error. The upload itself
// has its own retry logic.
err = runWithRetry(w.ctx, func() error {
var err2 error
resp, err2 = call.Do()
return err2
})
}
} }
if err != nil { if err != nil {
w.err = err w.err = err

View File

@ -33,6 +33,7 @@ import (
type fakeTransport struct { type fakeTransport struct {
gotReq *http.Request gotReq *http.Request
gotBody []byte
results []transportResult results []transportResult
} }
@ -47,6 +48,14 @@ func (t *fakeTransport) addResult(res *http.Response, err error) {
func (t *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) { func (t *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) {
t.gotReq = req t.gotReq = req
t.gotBody = nil
if req.Body != nil {
bytes, err := ioutil.ReadAll(req.Body)
if err != nil {
return nil, err
}
t.gotBody = bytes
}
if len(t.results) == 0 { if len(t.results) == 0 {
return nil, fmt.Errorf("error handling request") return nil, fmt.Errorf("error handling request")
} }
@ -58,6 +67,7 @@ func (t *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) {
func TestErrorOnObjectsInsertCall(t *testing.T) { func TestErrorOnObjectsInsertCall(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background() ctx := context.Background()
const contents = "hello world"
doWrite := func(hc *http.Client) *Writer { doWrite := func(hc *http.Client) *Writer {
client, err := NewClient(ctx, option.WithHTTPClient(hc)) client, err := NewClient(ctx, option.WithHTTPClient(hc))
@ -69,7 +79,7 @@ func TestErrorOnObjectsInsertCall(t *testing.T) {
// We can't check that the Write fails, since it depends on the write to the // We can't check that the Write fails, since it depends on the write to the
// underling fakeTransport failing which is racy. // underling fakeTransport failing which is racy.
wc.Write([]byte("hello world")) wc.Write([]byte(contents))
return wc return wc
} }
@ -94,6 +104,10 @@ func TestErrorOnObjectsInsertCall(t *testing.T) {
if err := wc.Close(); err != nil { if err := wc.Close(); err != nil {
t.Errorf("got %v, want nil", err) t.Errorf("got %v, want nil", err)
} }
got := string(ft.gotBody)
if !strings.Contains(got, contents) {
t.Errorf("got body %q, which does not contain %q", got, contents)
}
} }
func TestEncryption(t *testing.T) { func TestEncryption(t *testing.T) {

View File

@ -29,10 +29,16 @@ const grpcMetadataKey = "grpc-trace-bin"
// GRPCClientInterceptor returns a grpc.UnaryClientInterceptor that traces all outgoing requests from a gRPC client. // GRPCClientInterceptor returns a grpc.UnaryClientInterceptor that traces all outgoing requests from a gRPC client.
// The calling context should already have a *trace.Span; a child span will be // The calling context should already have a *trace.Span; a child span will be
// created for the outgoing gRPC call. If the calling context doesn't have a span, // created for the outgoing gRPC call. If the calling context doesn't have a span,
// the call will not be traced. // the call will not be traced. If the client is nil, then the interceptor just
// passes through the request.
// //
// The functionality in gRPC that this feature relies on is currently experimental. // The functionality in gRPC that this feature relies on is currently experimental.
func (c *Client) GRPCClientInterceptor() grpc.UnaryClientInterceptor { func (c *Client) GRPCClientInterceptor() grpc.UnaryClientInterceptor {
if c == nil {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
return invoker(ctx, method, req, reply, cc, opts...)
}
}
return grpc.UnaryClientInterceptor(c.grpcUnaryInterceptor) return grpc.UnaryClientInterceptor(c.grpcUnaryInterceptor)
} }
@ -75,8 +81,15 @@ func (c *Client) grpcUnaryInterceptor(ctx context.Context, method string, req, r
// //
// span := trace.FromContext(ctx) // span := trace.FromContext(ctx)
// //
// If the client is nil, then the interceptor just invokes the handler.
//
// The functionality in gRPC that this feature relies on is currently experimental. // The functionality in gRPC that this feature relies on is currently experimental.
func (c *Client) GRPCServerInterceptor() grpc.UnaryServerInterceptor { func (c *Client) GRPCServerInterceptor() grpc.UnaryServerInterceptor {
if c == nil {
return func(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
return handler(ctx, req)
}
}
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
md, _ := metadata.FromIncomingContext(ctx) md, _ := metadata.FromIncomingContext(ctx)
var traceHeader string var traceHeader string

View File

@ -69,6 +69,9 @@ func (t Transport) base() http.RoundTripper {
// //
// The span will be auto finished by the handler. // The span will be auto finished by the handler.
func (c *Client) HTTPHandler(h http.Handler) http.Handler { func (c *Client) HTTPHandler(h http.Handler) http.Handler {
if c == nil {
return h
}
return &handler{traceClient: c, handler: h} return &handler{traceClient: c, handler: h}
} }
@ -101,5 +104,4 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set(httpHeader, spanHeader(traceID, parentSpanID, span.trace.localOptions)) w.Header().Set(httpHeader, spanHeader(traceID, parentSpanID, span.trace.localOptions))
} }
h.handler.ServeHTTP(w, r) h.handler.ServeHTTP(w, r)
} }

View File

@ -254,7 +254,8 @@ func nextTraceID() string {
return fmt.Sprintf("%016x%016x", id1, id2) return fmt.Sprintf("%016x%016x", id1, id2)
} }
// Client is a client for uploading traces to the Google Stackdriver Trace server. // Client is a client for uploading traces to the Google Stackdriver Trace service.
// A nil Client will no-op for all of its methods.
type Client struct { type Client struct {
service *api.Service service *api.Service
projectID string projectID string
@ -310,13 +311,13 @@ func (c *Client) SetSamplingPolicy(p SamplingPolicy) {
} }
} }
// SpanFromHeader returns a new trace span, based on a provided request header // SpanFromHeader returns a new trace span based on a provided request header
// value. See https://cloud.google.com/trace/docs/faq. // value or nil iff the client is nil.
//
// It returns nil iff the client is nil.
// //
// The trace information and identifiers will be read from the header value. // The trace information and identifiers will be read from the header value.
// Otherwise, a new trace ID is made and the parent span ID is zero. // Otherwise, a new trace ID is made and the parent span ID is zero.
// For the exact format of the header value, see
// https://cloud.google.com/trace/docs/support#how_do_i_force_a_request_to_be_traced
// //
// The name of the new span is provided as an argument. // The name of the new span is provided as an argument.
// //
@ -352,9 +353,8 @@ func (c *Client) SpanFromHeader(name string, header string) *Span {
return span return span
} }
// SpanFromRequest returns a new trace span for an HTTP request. // SpanFromRequest returns a new trace span for an HTTP request or nil
// // iff the client is nil.
// It returns nil iff the client is nil.
// //
// If the incoming HTTP request contains a trace context header, the trace ID, // If the incoming HTTP request contains a trace context header, the trace ID,
// parent span ID, and tracing options will be read from that header. // parent span ID, and tracing options will be read from that header.
@ -390,7 +390,8 @@ func (c *Client) SpanFromRequest(r *http.Request) *Span {
return span return span
} }
// NewSpan returns a new trace span with the given name. // NewSpan returns a new trace span with the given name or nil iff the
// client is nil.
// //
// A new trace and span ID is generated to trace the span. // A new trace and span ID is generated to trace the span.
// Returned span need to be finished by calling Finish or FinishWait. // Returned span need to be finished by calling Finish or FinishWait.

View File

@ -1,689 +0,0 @@
// Copyright 2016 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 vision
import (
"image"
"golang.org/x/text/language"
pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
// Annotations contains all the annotations performed by the API on a single image.
// A nil field indicates either that the corresponding feature was not requested,
// or that annotation failed for that feature.
type Annotations struct {
// Faces holds the results of face detection.
Faces []*FaceAnnotation
// Landmarks holds the results of landmark detection.
Landmarks []*EntityAnnotation
// Logos holds the results of logo detection.
Logos []*EntityAnnotation
// Labels holds the results of label detection.
Labels []*EntityAnnotation
// Texts holds the results of text detection.
Texts []*EntityAnnotation
// FullText holds the results of full text (OCR) detection.
FullText *TextAnnotation
// SafeSearch holds the results of safe-search detection.
SafeSearch *SafeSearchAnnotation
// ImageProps contains properties of the annotated image.
ImageProps *ImageProps
// Web contains web annotations for the image.
Web *WebDetection
// CropHints contains crop hints for the image.
CropHints []*CropHint
// If non-nil, then one or more of the attempted annotations failed.
// Non-nil annotations are guaranteed to be correct, even if Error is
// non-nil.
Error error
}
func annotationsFromProto(res *pb.AnnotateImageResponse) *Annotations {
as := &Annotations{}
for _, a := range res.FaceAnnotations {
as.Faces = append(as.Faces, faceAnnotationFromProto(a))
}
for _, a := range res.LandmarkAnnotations {
as.Landmarks = append(as.Landmarks, entityAnnotationFromProto(a))
}
for _, a := range res.LogoAnnotations {
as.Logos = append(as.Logos, entityAnnotationFromProto(a))
}
for _, a := range res.LabelAnnotations {
as.Labels = append(as.Labels, entityAnnotationFromProto(a))
}
for _, a := range res.TextAnnotations {
as.Texts = append(as.Texts, entityAnnotationFromProto(a))
}
as.FullText = textAnnotationFromProto(res.FullTextAnnotation)
as.SafeSearch = safeSearchAnnotationFromProto(res.SafeSearchAnnotation)
as.ImageProps = imagePropertiesFromProto(res.ImagePropertiesAnnotation)
as.Web = webDetectionFromProto(res.WebDetection)
as.CropHints = cropHintsFromProto(res.CropHintsAnnotation)
if res.Error != nil {
// res.Error is a google.rpc.Status. Convert to a Go error. Use a gRPC
// error because it preserves the code as a separate field.
// TODO(jba): preserve the details field.
as.Error = grpc.Errorf(codes.Code(res.Error.Code), "%s", res.Error.Message)
}
return as
}
// A FaceAnnotation describes the results of face detection on an image.
type FaceAnnotation struct {
// BoundingPoly is the bounding polygon around the face. The coordinates of
// the bounding box are in the original image's scale, as returned in
// ImageParams. The bounding box is computed to "frame" the face in
// accordance with human expectations. It is based on the landmarker
// results. Note that one or more x and/or y coordinates may not be
// generated in the BoundingPoly (the polygon will be unbounded) if only a
// partial face appears in the image to be annotated.
BoundingPoly []image.Point
// FDBoundingPoly is tighter than BoundingPoly, and
// encloses only the skin part of the face. Typically, it is used to
// eliminate the face from any image analysis that detects the "amount of
// skin" visible in an image. It is not based on the landmarker results, only
// on the initial face detection, hence the fd (face detection) prefix.
FDBoundingPoly []image.Point
// Landmarks are detected face landmarks.
Face FaceLandmarks
// RollAngle indicates the amount of clockwise/anti-clockwise rotation of
// the face relative to the image vertical, about the axis perpendicular to
// the face. Range [-180,180].
RollAngle float32
// PanAngle is the yaw angle: the leftward/rightward angle that the face is
// pointing, relative to the vertical plane perpendicular to the image. Range
// [-180,180].
PanAngle float32
// TiltAngle is the pitch angle: the upwards/downwards angle that the face is
// pointing relative to the image's horizontal plane. Range [-180,180].
TiltAngle float32
// DetectionConfidence is the detection confidence. The range is [0, 1].
DetectionConfidence float32
// LandmarkingConfidence is the face landmarking confidence. The range is [0, 1].
LandmarkingConfidence float32
// Likelihoods expresses the likelihood of various aspects of the face.
Likelihoods *FaceLikelihoods
}
func faceAnnotationFromProto(pfa *pb.FaceAnnotation) *FaceAnnotation {
fa := &FaceAnnotation{
BoundingPoly: boundingPolyFromProto(pfa.BoundingPoly),
FDBoundingPoly: boundingPolyFromProto(pfa.FdBoundingPoly),
RollAngle: pfa.RollAngle,
PanAngle: pfa.PanAngle,
TiltAngle: pfa.TiltAngle,
DetectionConfidence: pfa.DetectionConfidence,
LandmarkingConfidence: pfa.LandmarkingConfidence,
Likelihoods: &FaceLikelihoods{
Joy: Likelihood(pfa.JoyLikelihood),
Sorrow: Likelihood(pfa.SorrowLikelihood),
Anger: Likelihood(pfa.AngerLikelihood),
Surprise: Likelihood(pfa.SurpriseLikelihood),
UnderExposed: Likelihood(pfa.UnderExposedLikelihood),
Blurred: Likelihood(pfa.BlurredLikelihood),
Headwear: Likelihood(pfa.HeadwearLikelihood),
},
}
populateFaceLandmarks(pfa.Landmarks, &fa.Face)
return fa
}
// An EntityAnnotation describes the results of a landmark, label, logo or text
// detection on an image.
type EntityAnnotation struct {
// ID is an opaque entity ID. Some IDs might be available in Knowledge Graph(KG).
// For more details on KG please see:
// https://developers.google.com/knowledge-graph/
ID string
// Locale is the language code for the locale in which the entity textual
// description (next field) is expressed.
Locale string
// Description is the entity textual description, expressed in the language of Locale.
Description string
// Score is the overall score of the result. Range [0, 1].
Score float32
// Confidence is the accuracy of the entity detection in an image.
// For example, for an image containing the Eiffel Tower, this field represents
// the confidence that there is a tower in the query image. Range [0, 1].
Confidence float32
// Topicality is the relevancy of the ICA (Image Content Annotation) label to the
// image. For example, the relevancy of 'tower' to an image containing
// 'Eiffel Tower' is likely higher than an image containing a distant towering
// building, though the confidence that there is a tower may be the same.
// Range [0, 1].
Topicality float32
// BoundingPoly is the image region to which this entity belongs. Not filled currently
// for label detection. For text detection, BoundingPolys
// are produced for the entire text detected in an image region, followed by
// BoundingPolys for each word within the detected text.
BoundingPoly []image.Point
// Locations contains the location information for the detected entity.
// Multiple LatLng structs can be present since one location may indicate the
// location of the scene in the query image, and another the location of the
// place where the query image was taken. Location information is usually
// present for landmarks.
Locations []LatLng
// Properties are additional optional Property fields.
// For example a different kind of score or string that qualifies the entity.
Properties []Property
}
func entityAnnotationFromProto(e *pb.EntityAnnotation) *EntityAnnotation {
var locs []LatLng
for _, li := range e.Locations {
locs = append(locs, latLngFromProto(li.LatLng))
}
var props []Property
for _, p := range e.Properties {
props = append(props, propertyFromProto(p))
}
return &EntityAnnotation{
ID: e.Mid,
Locale: e.Locale,
Description: e.Description,
Score: e.Score,
Confidence: e.Confidence,
Topicality: e.Topicality,
BoundingPoly: boundingPolyFromProto(e.BoundingPoly),
Locations: locs,
Properties: props,
}
}
// TextAnnotation contains a structured representation of OCR extracted text.
// The hierarchy of an OCR extracted text structure looks like:
// TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol
// Each structural component, starting from Page, may further have its own
// properties. Properties describe detected languages, breaks etc.
type TextAnnotation struct {
// List of pages detected by OCR.
Pages []*Page
// UTF-8 text detected on the pages.
Text string
}
func textAnnotationFromProto(pta *pb.TextAnnotation) *TextAnnotation {
if pta == nil {
return nil
}
var pages []*Page
for _, p := range pta.Pages {
pages = append(pages, pageFromProto(p))
}
return &TextAnnotation{
Pages: pages,
Text: pta.Text,
}
}
// A Page is a page of text detected from OCR.
type Page struct {
// Additional information detected on the page.
Properties *TextProperties
// Page width in pixels.
Width int32
// Page height in pixels.
Height int32
// List of blocks of text, images etc on this page.
Blocks []*Block
}
func pageFromProto(p *pb.Page) *Page {
if p == nil {
return nil
}
var blocks []*Block
for _, b := range p.Blocks {
blocks = append(blocks, blockFromProto(b))
}
return &Page{
Properties: textPropertiesFromProto(p.Property),
Width: p.Width,
Height: p.Height,
Blocks: blocks,
}
}
// A Block is a logical element on the page.
type Block struct {
// Additional information detected for the block.
Properties *TextProperties
// The bounding box for the block.
// The vertices are in the order of top-left, top-right, bottom-right,
// bottom-left. When a rotation of the bounding box is detected the rotation
// is represented as around the top-left corner as defined when the text is
// read in the 'natural' orientation.
// For example:
// * when the text is horizontal it might look like:
// 0----1
// | |
// 3----2
// * when it's rotated 180 degrees around the top-left corner it becomes:
// 2----3
// | |
// 1----0
// and the vertice order will still be (0, 1, 2, 3).
BoundingBox []image.Point
// List of paragraphs in this block (if this blocks is of type text).
Paragraphs []*Paragraph
// Detected block type (text, image etc) for this block.
BlockType BlockType
}
// A BlockType represents the kind of Block (text, image, etc.)
type BlockType int
const (
// Unknown block type.
UnknownBlock BlockType = BlockType(pb.Block_UNKNOWN)
// Regular text block.
TextBlock BlockType = BlockType(pb.Block_TEXT)
// Table block.
TableBlock BlockType = BlockType(pb.Block_TABLE)
// Image block.
PictureBlock BlockType = BlockType(pb.Block_PICTURE)
// Horizontal/vertical line box.
RulerBlock BlockType = BlockType(pb.Block_RULER)
// Barcode block.
BarcodeBlock BlockType = BlockType(pb.Block_BARCODE)
)
func blockFromProto(p *pb.Block) *Block {
if p == nil {
return nil
}
var paras []*Paragraph
for _, pa := range p.Paragraphs {
paras = append(paras, paragraphFromProto(pa))
}
return &Block{
Properties: textPropertiesFromProto(p.Property),
BoundingBox: boundingPolyFromProto(p.BoundingBox),
Paragraphs: paras,
BlockType: BlockType(p.BlockType),
}
}
// A Paragraph is a structural unit of text representing a number of words in
// certain order.
type Paragraph struct {
// Additional information detected for the paragraph.
Properties *TextProperties
// The bounding box for the paragraph.
// The vertices are in the order of top-left, top-right, bottom-right,
// bottom-left. When a rotation of the bounding box is detected the rotation
// is represented as around the top-left corner as defined when the text is
// read in the 'natural' orientation.
// For example:
// * when the text is horizontal it might look like:
// 0----1
// | |
// 3----2
// * when it's rotated 180 degrees around the top-left corner it becomes:
// 2----3
// | |
// 1----0
// and the vertice order will still be (0, 1, 2, 3).
BoundingBox []image.Point
// List of words in this paragraph.
Words []*Word
}
func paragraphFromProto(p *pb.Paragraph) *Paragraph {
if p == nil {
return nil
}
var words []*Word
for _, w := range p.Words {
words = append(words, wordFromProto(w))
}
return &Paragraph{
Properties: textPropertiesFromProto(p.Property),
BoundingBox: boundingPolyFromProto(p.BoundingBox),
Words: words,
}
}
// A Word is a word in a text document.
type Word struct {
// Additional information detected for the word.
Properties *TextProperties
// The bounding box for the word.
// The vertices are in the order of top-left, top-right, bottom-right,
// bottom-left. When a rotation of the bounding box is detected the rotation
// is represented as around the top-left corner as defined when the text is
// read in the 'natural' orientation.
// For example:
// * when the text is horizontal it might look like:
// 0----1
// | |
// 3----2
// * when it's rotated 180 degrees around the top-left corner it becomes:
// 2----3
// | |
// 1----0
// and the vertice order will still be (0, 1, 2, 3).
BoundingBox []image.Point
// List of symbols in the word.
// The order of the symbols follows the natural reading order.
Symbols []*Symbol
}
func wordFromProto(p *pb.Word) *Word {
if p == nil {
return nil
}
var syms []*Symbol
for _, s := range p.Symbols {
syms = append(syms, symbolFromProto(s))
}
return &Word{
Properties: textPropertiesFromProto(p.Property),
BoundingBox: boundingPolyFromProto(p.BoundingBox),
Symbols: syms,
}
}
// A Symbol is a symbol in a text document.
type Symbol struct {
// Additional information detected for the symbol.
Properties *TextProperties
// The bounding box for the symbol.
// The vertices are in the order of top-left, top-right, bottom-right,
// bottom-left. When a rotation of the bounding box is detected the rotation
// is represented as around the top-left corner as defined when the text is
// read in the 'natural' orientation.
// For example:
// * when the text is horizontal it might look like:
// 0----1
// | |
// 3----2
// * when it's rotated 180 degrees around the top-left corner it becomes:
// 2----3
// | |
// 1----0
// and the vertice order will still be (0, 1, 2, 3).
BoundingBox []image.Point
// The actual UTF-8 representation of the symbol.
Text string
}
func symbolFromProto(p *pb.Symbol) *Symbol {
if p == nil {
return nil
}
return &Symbol{
Properties: textPropertiesFromProto(p.Property),
BoundingBox: boundingPolyFromProto(p.BoundingBox),
Text: p.Text,
}
}
// TextProperties contains additional information about an OCR structural component.
type TextProperties struct {
// A list of detected languages together with confidence.
DetectedLanguages []*DetectedLanguage
// Detected start or end of a text segment.
DetectedBreak *DetectedBreak
}
// Detected language for a structural component.
type DetectedLanguage struct {
// The BCP-47 language code, such as "en-US" or "sr-Latn".
Code language.Tag
// The confidence of the detected language, in the range [0, 1].
Confidence float32
}
// DetectedBreak is the detected start or end of a structural component.
type DetectedBreak struct {
// The type of break.
Type DetectedBreakType
// True if break prepends the element.
IsPrefix bool
}
type DetectedBreakType int
const (
// Unknown break label type.
UnknownBreak = DetectedBreakType(pb.TextAnnotation_DetectedBreak_UNKNOWN)
// Regular space.
SpaceBreak = DetectedBreakType(pb.TextAnnotation_DetectedBreak_SPACE)
// Sure space (very wide).
SureSpaceBreak = DetectedBreakType(pb.TextAnnotation_DetectedBreak_SURE_SPACE)
// Line-wrapping break.
EOLSureSpaceBreak = DetectedBreakType(pb.TextAnnotation_DetectedBreak_EOL_SURE_SPACE)
// End-line hyphen that is not present in text; does not co-occur with SPACE, LEADER_SPACE, or LINE_BREAK.
HyphenBreak = DetectedBreakType(pb.TextAnnotation_DetectedBreak_HYPHEN)
// Line break that ends a paragraph.
LineBreak = DetectedBreakType(pb.TextAnnotation_DetectedBreak_LINE_BREAK)
)
func textPropertiesFromProto(p *pb.TextAnnotation_TextProperty) *TextProperties {
var dls []*DetectedLanguage
for _, dl := range p.DetectedLanguages {
tag, _ := language.Parse(dl.LanguageCode)
// Ignore error. If err != nil the returned tag will not be garbage,
// but a best-effort attempt at a parse. At worst it will be
// language.Und, the documented "undefined" Tag.
dls = append(dls, &DetectedLanguage{Code: tag, Confidence: dl.Confidence})
}
var db *DetectedBreak
if p.DetectedBreak != nil {
db = &DetectedBreak{
Type: DetectedBreakType(p.DetectedBreak.Type),
IsPrefix: p.DetectedBreak.IsPrefix,
}
}
return &TextProperties{
DetectedLanguages: dls,
DetectedBreak: db,
}
}
// SafeSearchAnnotation describes the results of a SafeSearch detection on an image.
type SafeSearchAnnotation struct {
// Adult is the likelihood that the image contains adult content.
Adult Likelihood
// Spoof is the likelihood that an obvious modification was made to the
// image's canonical version to make it appear funny or offensive.
Spoof Likelihood
// Medical is the likelihood that this is a medical image.
Medical Likelihood
// Violence is the likelihood that this image represents violence.
Violence Likelihood
}
func safeSearchAnnotationFromProto(s *pb.SafeSearchAnnotation) *SafeSearchAnnotation {
if s == nil {
return nil
}
return &SafeSearchAnnotation{
Adult: Likelihood(s.Adult),
Spoof: Likelihood(s.Spoof),
Medical: Likelihood(s.Medical),
Violence: Likelihood(s.Violence),
}
}
// ImageProps describes properties of the image itself, like the dominant colors.
type ImageProps struct {
// DominantColors describes the dominant colors of the image.
DominantColors []*ColorInfo
}
func imagePropertiesFromProto(ip *pb.ImageProperties) *ImageProps {
if ip == nil || ip.DominantColors == nil {
return nil
}
var cinfos []*ColorInfo
for _, ci := range ip.DominantColors.Colors {
cinfos = append(cinfos, colorInfoFromProto(ci))
}
return &ImageProps{DominantColors: cinfos}
}
// WebDetection contains relevant information for the image from the Internet.
type WebDetection struct {
// Deduced entities from similar images on the Internet.
WebEntities []*WebEntity
// Fully matching images from the Internet.
// They're definite neardups and most often a copy of the query image with
// merely a size change.
FullMatchingImages []*WebImage
// Partial matching images from the Internet.
// Those images are similar enough to share some key-point features. For
// example an original image will likely have partial matching for its crops.
PartialMatchingImages []*WebImage
// Web pages containing the matching images from the Internet.
PagesWithMatchingImages []*WebPage
}
func webDetectionFromProto(p *pb.WebDetection) *WebDetection {
if p == nil {
return nil
}
var (
wes []*WebEntity
fmis, pmis []*WebImage
wps []*WebPage
)
for _, e := range p.WebEntities {
wes = append(wes, webEntityFromProto(e))
}
for _, m := range p.FullMatchingImages {
fmis = append(fmis, webImageFromProto(m))
}
for _, m := range p.PartialMatchingImages {
pmis = append(fmis, webImageFromProto(m))
}
for _, g := range p.PagesWithMatchingImages {
wps = append(wps, webPageFromProto(g))
}
return &WebDetection{
WebEntities: wes,
FullMatchingImages: fmis,
PartialMatchingImages: pmis,
PagesWithMatchingImages: wps,
}
}
// A WebEntity is an entity deduced from similar images on the Internet.
type WebEntity struct {
// Opaque entity ID.
ID string
// Overall relevancy score for the entity.
// Not normalized and not comparable across different image queries.
Score float32
// Canonical description of the entity, in English.
Description string
}
func webEntityFromProto(p *pb.WebDetection_WebEntity) *WebEntity {
return &WebEntity{
ID: p.EntityId,
Score: p.Score,
Description: p.Description,
}
}
// WebImage contains metadata for online images.
type WebImage struct {
// The result image URL.
URL string
// Overall relevancy score for the image.
// Not normalized and not comparable across different image queries.
Score float32
}
func webImageFromProto(p *pb.WebDetection_WebImage) *WebImage {
return &WebImage{
URL: p.Url,
Score: p.Score,
}
}
// A WebPage contains metadata for web pages.
type WebPage struct {
// The result web page URL.
URL string
// Overall relevancy score for the web page.
// Not normalized and not comparable across different image queries.
Score float32
}
func webPageFromProto(p *pb.WebDetection_WebPage) *WebPage {
return &WebPage{
URL: p.Url,
Score: p.Score,
}
}
// CropHint is a single crop hint that is used to generate a new crop when
// serving an image.
type CropHint struct {
// The bounding polygon for the crop region. The coordinates of the bounding
// box are in the original image's scale, as returned in `ImageParams`.
BoundingPoly []image.Point
// Confidence of this being a salient region. Range [0, 1].
Confidence float32
// Fraction of importance of this salient region with respect to the original
// image.
ImportanceFraction float32
}
func cropHintsFromProto(p *pb.CropHintsAnnotation) []*CropHint {
if p == nil {
return nil
}
var chs []*CropHint
for _, pch := range p.CropHints {
chs = append(chs, cropHintFromProto(pch))
}
return chs
}
func cropHintFromProto(pch *pb.CropHint) *CropHint {
return &CropHint{
BoundingPoly: boundingPolyFromProto(pch.BoundingPoly),
Confidence: pch.Confidence,
ImportanceFraction: pch.ImportanceFraction,
}
}

View File

@ -14,14 +14,12 @@
// AUTO-GENERATED CODE. DO NOT EDIT. // AUTO-GENERATED CODE. DO NOT EDIT.
// Package vision is an experimental, auto-generated package for the // Package vision is an auto-generated package for the
// Google Cloud Vision API. // Google Cloud Vision API.
// //
// Integrates Google Vision features, including image labeling, face, logo, // Integrates Google Vision features, including image labeling, face, logo,
// and landmark detection, optical character recognition (OCR), and detection // and landmark detection, optical character recognition (OCR), and detection
// of explicit content, into applications. // of explicit content, into applications.
//
// Use the client at cloud.google.com/go/vision in preference to this.
package vision // import "cloud.google.com/go/vision/apiv1" package vision // import "cloud.google.com/go/vision/apiv1"
import ( import (

View File

@ -92,7 +92,7 @@ func NewImageAnnotatorClient(ctx context.Context, opts ...option.ClientOption) (
imageAnnotatorClient: visionpb.NewImageAnnotatorClient(conn), imageAnnotatorClient: visionpb.NewImageAnnotatorClient(conn),
} }
c.SetGoogleClientInfo() c.setGoogleClientInfo()
return c, nil return c, nil
} }
@ -107,10 +107,10 @@ func (c *ImageAnnotatorClient) Close() error {
return c.conn.Close() return c.conn.Close()
} }
// SetGoogleClientInfo sets the name and version of the application in // setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for // the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients. // use by Google-written clients.
func (c *ImageAnnotatorClient) SetGoogleClientInfo(keyval ...string) { func (c *ImageAnnotatorClient) setGoogleClientInfo(keyval ...string) {
kv := append([]string{"gl-go", version.Go()}, keyval...) kv := append([]string{"gl-go", version.Go()}, keyval...)
kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version) kv = append(kv, "gapic", version.Repo, "gax", gax.Version, "grpc", grpc.Version)
c.xGoogHeader = []string{gax.XGoogHeader(kv...)} c.xGoogHeader = []string{gax.XGoogHeader(kv...)}

View File

@ -1,105 +0,0 @@
// Copyright 2016 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.
/*
NOTE: This package is deprecated. Use cloud.google.com/go/vision/apiv1 instead.
Package vision provides a client for the Google Cloud Vision API.
Google Cloud Vision allows easy integration of vision detection features
into developer applications, including image labeling, face and landmark
detection, optical character recognition (OCR), and tagging of explicit
content. For more information about Cloud Vision, read the Google Cloud Vision API
Documentation at https://cloud.google.com/vision/docs.
Note: This package is in beta. Some backwards-incompatible changes may occur.
Creating Images
The Cloud Vision API supports a variety of image file formats, including JPEG,
PNG8, PNG24, Animated GIF (first frame only), and RAW. See
https://cloud.google.com/vision/docs/image-best-practices#image_types for the
complete list of formats. Be aware that Cloud Vision sets upper limits on file
size as well as on the total combined size of all images in a request. Reducing
your file size can significantly improve throughput; however, be careful not to
reduce image quality in the process. See
https://cloud.google.com/vision/docs/image-best-practices#image_sizing for
current file size limits.
Creating an Image instance does not perform an API request.
Use NewImageFromReader to obtain an image from any io.Reader, such as an open file:
f, err := os.Open("path/to/image.jpg")
if err != nil { ... }
defer f.Close()
img, err := vision.NewImageFromReader(f)
if err != nil { ... }
Use NewImageFromURI to refer to an image in Google Cloud Storage or a public URL:
img := vision.NewImageFromURI("gs://my-bucket/my-image.png")
Annotating Images
Client.Annotate is the most general method in the package. It can run multiple
detections on multiple images with a single API call.
To describe the detections you want to perform on an image, create an
AnnotateRequest and specify the maximum number of results to return for each
detection of interest. The exceptions are safe search and image properties,
where a boolean is used instead.
resultSlice, err := client.Annotate(ctx, &vision.AnnotateRequest{
Image: img,
MaxLogos: 5,
MaxTexts: 100,
SafeSearch: true,
})
if err != nil { ... }
You can pass as many AnnotateRequests as desired to client.Annotate. The return
value is a slice of an Annotations. Each Annotations value may contain an Error
along with one or more successful results. The failed detections will have a nil annotation.
result := resultSlice[0]
if result.Error != nil { ... } // some detections failed
for _, logo := range result.Logos { ... }
for _, text := range result.Texts { ... }
if result.SafeSearch != nil { ... }
Other methods on Client run a single detection on a single image. For instance,
Client.DetectFaces will run face detection on the provided Image. These methods
return a single annotation of the appropriate type (for example, DetectFaces
returns a FaceAnnotation). The error return value incorporates both API call
errors and the detection errors stored in Annotations.Error, simplifying your
logic.
faces, err := client.DetectFaces(ctx, 10) // maximum of 10 faces
if err != nil { ... }
Here faces is a slice of FaceAnnotations. The Face field of each FaceAnnotation
provides easy access to the positions of facial features:
fmt.Println(faces[0].Face.Nose.Tip)
fmt.Println(faces[0].Face.Eyes.Left.Pupil)
Authentication
See examples of authorization and authentication at
https://godoc.org/cloud.google.com/go#pkg-examples.
*/
package vision // import "cloud.google.com/go/vision"

View File

@ -1,99 +0,0 @@
// Copyright 2016 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 vision_test
import (
"fmt"
"os"
"cloud.google.com/go/vision"
"golang.org/x/net/context"
)
func ExampleNewClient() {
ctx := context.Background()
client, err := vision.NewClient(ctx)
if err != nil {
// TODO: handle error.
}
// Use the client.
// Close the client when finished.
if err := client.Close(); err != nil {
// TODO: handle error.
}
}
func Example_NewImageFromReader() {
f, err := os.Open("path/to/image.jpg")
if err != nil {
// TODO: handle error.
}
img, err := vision.NewImageFromReader(f)
if err != nil {
// TODO: handle error.
}
fmt.Println(img)
}
func Example_NewImageFromURI() {
img := vision.NewImageFromURI("gs://my-bucket/my-image.png")
fmt.Println(img)
}
func ExampleClient_Annotate_oneImage() {
ctx := context.Background()
client, err := vision.NewClient(ctx)
if err != nil {
// TODO: handle error.
}
annsSlice, err := client.Annotate(ctx, &vision.AnnotateRequest{
Image: vision.NewImageFromURI("gs://my-bucket/my-image.png"),
MaxLogos: 100,
MaxTexts: 100,
SafeSearch: true,
})
if err != nil {
// TODO: handle error.
}
anns := annsSlice[0]
if anns.Logos != nil {
fmt.Println(anns.Logos)
}
if anns.Texts != nil {
fmt.Println(anns.Texts)
}
if anns.SafeSearch != nil {
fmt.Println(anns.SafeSearch)
}
if anns.Error != nil {
fmt.Printf("at least one of the features failed: %v", anns.Error)
}
}
func ExampleClient_DetectFaces() {
ctx := context.Background()
client, err := vision.NewClient(ctx)
if err != nil {
// TODO: handle error.
}
img := vision.NewImageFromURI("gs://my-bucket/my-image.png")
faces, err := client.DetectFaces(ctx, img, 10)
if err != nil {
// TODO: handle error.
}
fmt.Println(faces[0].Face.Nose.Tip)
fmt.Println(faces[0].Face.Eyes.Left.Pupil)
}

View File

@ -1,172 +0,0 @@
// Copyright 2016 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 vision
import (
"log"
"github.com/golang/geo/r3"
pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
)
// FaceLandmarks contains the positions of facial features detected by the service.
// TODO(jba): write doc for all
type FaceLandmarks struct {
Eyebrows Eyebrows
Eyes Eyes
Ears Ears
Nose Nose
Mouth Mouth
Chin Chin
Forehead *r3.Vector
}
type Eyebrows struct {
Left, Right Eyebrow
}
type Eyebrow struct {
Top, Left, Right *r3.Vector
}
type Eyes struct {
Left, Right Eye
}
type Eye struct {
Left, Right, Top, Bottom, Center, Pupil *r3.Vector
}
type Ears struct {
Left, Right *r3.Vector
}
type Nose struct {
Left, Right, Top, Bottom, Tip *r3.Vector
}
type Mouth struct {
Left, Center, Right, UpperLip, LowerLip *r3.Vector
}
type Chin struct {
Left, Center, Right *r3.Vector
}
// FaceLikelihoods expresses the likelihood of various aspects of a face.
type FaceLikelihoods struct {
// Joy is the likelihood that the face expresses joy.
Joy Likelihood
// Sorrow is the likelihood that the face expresses sorrow.
Sorrow Likelihood
// Anger is the likelihood that the face expresses anger.
Anger Likelihood
// Surprise is the likelihood that the face expresses surprise.
Surprise Likelihood
// UnderExposed is the likelihood that the face is under-exposed.
UnderExposed Likelihood
// Blurred is the likelihood that the face is blurred.
Blurred Likelihood
// Headwear is the likelihood that the face has headwear.
Headwear Likelihood
}
func populateFaceLandmarks(landmarks []*pb.FaceAnnotation_Landmark, face *FaceLandmarks) {
for _, lm := range landmarks {
pos := &r3.Vector{
X: float64(lm.Position.X),
Y: float64(lm.Position.Y),
Z: float64(lm.Position.Z),
}
switch lm.Type {
case pb.FaceAnnotation_Landmark_LEFT_OF_LEFT_EYEBROW:
face.Eyebrows.Left.Left = pos
case pb.FaceAnnotation_Landmark_RIGHT_OF_LEFT_EYEBROW:
face.Eyebrows.Left.Right = pos
case pb.FaceAnnotation_Landmark_LEFT_OF_RIGHT_EYEBROW:
face.Eyebrows.Right.Left = pos
case pb.FaceAnnotation_Landmark_RIGHT_OF_RIGHT_EYEBROW:
face.Eyebrows.Right.Right = pos
case pb.FaceAnnotation_Landmark_LEFT_EYEBROW_UPPER_MIDPOINT:
face.Eyebrows.Left.Top = pos
case pb.FaceAnnotation_Landmark_RIGHT_EYEBROW_UPPER_MIDPOINT:
face.Eyebrows.Right.Top = pos
case pb.FaceAnnotation_Landmark_MIDPOINT_BETWEEN_EYES:
face.Nose.Top = pos
case pb.FaceAnnotation_Landmark_NOSE_TIP:
face.Nose.Tip = pos
case pb.FaceAnnotation_Landmark_UPPER_LIP:
face.Mouth.UpperLip = pos
case pb.FaceAnnotation_Landmark_LOWER_LIP:
face.Mouth.LowerLip = pos
case pb.FaceAnnotation_Landmark_MOUTH_LEFT:
face.Mouth.Left = pos
case pb.FaceAnnotation_Landmark_MOUTH_RIGHT:
face.Mouth.Right = pos
case pb.FaceAnnotation_Landmark_MOUTH_CENTER:
face.Mouth.Center = pos
case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_RIGHT:
face.Nose.Right = pos
case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_LEFT:
face.Nose.Left = pos
case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_CENTER:
face.Nose.Bottom = pos
case pb.FaceAnnotation_Landmark_LEFT_EYE:
face.Eyes.Left.Center = pos
case pb.FaceAnnotation_Landmark_RIGHT_EYE:
face.Eyes.Right.Center = pos
case pb.FaceAnnotation_Landmark_LEFT_EYE_TOP_BOUNDARY:
face.Eyes.Left.Top = pos
case pb.FaceAnnotation_Landmark_LEFT_EYE_RIGHT_CORNER:
face.Eyes.Left.Right = pos
case pb.FaceAnnotation_Landmark_LEFT_EYE_BOTTOM_BOUNDARY:
face.Eyes.Left.Bottom = pos
case pb.FaceAnnotation_Landmark_LEFT_EYE_LEFT_CORNER:
face.Eyes.Left.Left = pos
case pb.FaceAnnotation_Landmark_RIGHT_EYE_TOP_BOUNDARY:
face.Eyes.Right.Top = pos
case pb.FaceAnnotation_Landmark_RIGHT_EYE_RIGHT_CORNER:
face.Eyes.Right.Right = pos
case pb.FaceAnnotation_Landmark_RIGHT_EYE_BOTTOM_BOUNDARY:
face.Eyes.Right.Bottom = pos
case pb.FaceAnnotation_Landmark_RIGHT_EYE_LEFT_CORNER:
face.Eyes.Right.Left = pos
case pb.FaceAnnotation_Landmark_LEFT_EYE_PUPIL:
face.Eyes.Left.Pupil = pos
case pb.FaceAnnotation_Landmark_RIGHT_EYE_PUPIL:
face.Eyes.Right.Pupil = pos
case pb.FaceAnnotation_Landmark_LEFT_EAR_TRAGION:
face.Ears.Left = pos
case pb.FaceAnnotation_Landmark_RIGHT_EAR_TRAGION:
face.Ears.Right = pos
case pb.FaceAnnotation_Landmark_FOREHEAD_GLABELLA:
face.Forehead = pos
case pb.FaceAnnotation_Landmark_CHIN_GNATHION:
face.Chin.Center = pos
case pb.FaceAnnotation_Landmark_CHIN_LEFT_GONION:
face.Chin.Left = pos
case pb.FaceAnnotation_Landmark_CHIN_RIGHT_GONION:
face.Chin.Right = pos
default:
log.Printf("vision: ignoring unknown face annotation landmark %s", lm.Type)
}
}
}

View File

@ -1,36 +0,0 @@
// Copyright 2016 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 vision
import (
"image"
pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
)
func pointFromProto(v *pb.Vertex) image.Point {
return image.Point{X: int(v.X), Y: int(v.Y)}
}
func boundingPolyFromProto(b *pb.BoundingPoly) []image.Point {
if b == nil {
return nil
}
var ps []image.Point
for _, v := range b.Vertices {
ps = append(ps, pointFromProto(v))
}
return ps
}

View File

@ -1,91 +0,0 @@
// Copyright 2016 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 vision
import (
"io"
"io/ioutil"
pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
)
// An Image represents the contents of an image to run detection algorithms on,
// along with metadata. Images may be described by their raw bytes, or by a
// reference to a a Google Cloude Storage (GCS) object.
type Image struct {
// Exactly one of content and gcsURI will be non-zero.
content []byte // raw image bytes
uri string // URI of the form "gs://BUCKET/OBJECT", or public URL
// Rect is a rectangle on the Earth's surface represented by the
// image. It is optional.
Rect *LatLngRect
// LanguageHints is a list of languages to use for text detection. In most
// cases, leaving this field nil yields the best results since it enables
// automatic language detection. For languages based on the Latin alphabet,
// setting LanguageHints is not needed. In rare cases, when the language of
// the text in the image is known, setting a hint will help get better
// results (although it will be a significant hindrance if the hint is
// wrong). Text detection returns an error if one or more of the specified
// languages is not one of the supported languages (See
// https://cloud.google.com/translate/v2/translate-reference#supported_languages).
LanguageHints []string
}
// NewImageFromReader reads the bytes of an image from rc, then closes rc.
//
// You may optionally set Rect and LanguageHints on the returned Image before
// using it.
func NewImageFromReader(r io.ReadCloser) (*Image, error) {
bytes, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
if err := r.Close(); err != nil {
return nil, err
}
return &Image{content: bytes}, nil
}
// NewImageFromURI returns an image that refers to an object in Google Cloud Storage
// (when the uri is of the form "gs://BUCKET/OBJECT") or at a public URL.
//
// You may optionally set Rect and LanguageHints on the returned Image before
// using it.
func NewImageFromURI(uri string) *Image {
return &Image{uri: uri}
}
// toProtos converts the Image to the two underlying API protos it represents,
// pb.Image and pb.ImageContext.
func (img *Image) toProtos() (*pb.Image, *pb.ImageContext) {
var pimg *pb.Image
switch {
case img.content != nil:
pimg = &pb.Image{Content: img.content}
case img.uri != "":
pimg = &pb.Image{Source: &pb.ImageSource{ImageUri: img.uri}}
}
var pctx *pb.ImageContext
if img.Rect != nil || len(img.LanguageHints) > 0 {
pctx = &pb.ImageContext{
LatLongRect: img.Rect.toProto(),
LanguageHints: img.LanguageHints,
}
}
return pimg, pctx
}

View File

@ -1,42 +0,0 @@
// Copyright 2016 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 vision
import (
"testing"
"cloud.google.com/go/internal/testutil"
pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
)
func TestImageToProtos(t *testing.T) {
const url = "https://www.example.com/test.jpg"
langHints := []string{"en", "fr"}
img := NewImageFromURI("https://www.example.com/test.jpg")
img.LanguageHints = langHints
goti, gotc := img.toProtos()
wanti := &pb.Image{Source: &pb.ImageSource{ImageUri: url}}
if !testutil.Equal(goti, wanti) {
t.Errorf("got %+v, want %+v", goti, wanti)
}
wantc := &pb.ImageContext{
LanguageHints: langHints,
}
if !testutil.Equal(gotc, wantc) {
t.Errorf("got %+v, want %+v", gotc, wantc)
}
}

View File

@ -1,58 +0,0 @@
// Copyright 2016 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 vision
import (
pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
llpb "google.golang.org/genproto/googleapis/type/latlng"
)
// A LatLng is a point on the Earth's surface, represented with a latitude and longitude.
type LatLng struct {
// Lat is the latitude in degrees. It must be in the range [-90.0, +90.0].
Lat float64
// Lng is the longitude in degrees. It must be in the range [-180.0, +180.0].
Lng float64
}
func (l LatLng) toProto() *llpb.LatLng {
return &llpb.LatLng{
Latitude: l.Lat,
Longitude: l.Lng,
}
}
func latLngFromProto(ll *llpb.LatLng) LatLng {
return LatLng{
Lat: ll.Latitude,
Lng: ll.Longitude,
}
}
// A LatLngRect is a rectangular area on the Earth's surface, represented by a
// minimum and maximum latitude and longitude.
type LatLngRect struct {
Min, Max LatLng
}
func (r *LatLngRect) toProto() *pb.LatLongRect {
if r == nil {
return nil
}
return &pb.LatLongRect{
MinLatLng: r.Min.toProto(),
MaxLatLng: r.Max.toProto(),
}
}

View File

@ -1,16 +0,0 @@
The following files were copied from https://github.com/GoogleCloudPlatform/cloud-vision/tree/master/data:
cat.jpg
face.jpg
faulkner.jpg
mountain.jpg
no-text.jpg
eiffel-tower.jpg is from
https://commons.wikimedia.org/wiki/File:Tour_Eiffel_Wikimedia_Commons_(cropped).jpg.
google.png is from the Google home page:
https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,356 +0,0 @@
// Copyright 2016 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 vision
import (
"image/color"
"math"
"cloud.google.com/go/internal/version"
vkit "cloud.google.com/go/vision/apiv1"
"golang.org/x/net/context"
"google.golang.org/api/option"
pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
cpb "google.golang.org/genproto/googleapis/type/color"
)
// Scope is the OAuth2 scope required by the Google Cloud Vision API.
const Scope = "https://www.googleapis.com/auth/cloud-platform"
// Client is a Google Cloud Vision API client.
type Client struct {
client *vkit.ImageAnnotatorClient
}
// NewClient creates a new vision client.
//
// Deprecated: Use NewImageAnnotatorClient from cloud.google.com/go/vision/apiv1 instead.
func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
c, err := vkit.NewImageAnnotatorClient(ctx, opts...)
if err != nil {
return nil, err
}
c.SetGoogleClientInfo("gccl", version.Repo)
return &Client{client: c}, nil
}
// Close closes the client.
func (c *Client) Close() error {
return c.client.Close()
}
// Annotate annotates multiple images, each with a potentially different set
// of features.
func (c *Client) Annotate(ctx context.Context, requests ...*AnnotateRequest) ([]*Annotations, error) {
var reqs []*pb.AnnotateImageRequest
for _, r := range requests {
reqs = append(reqs, r.toProto())
}
res, err := c.client.BatchAnnotateImages(ctx, &pb.BatchAnnotateImagesRequest{Requests: reqs})
if err != nil {
return nil, err
}
var results []*Annotations
for _, res := range res.Responses {
results = append(results, annotationsFromProto(res))
}
return results, nil
}
// An AnnotateRequest specifies an image to annotate and the features to look for in that image.
type AnnotateRequest struct {
// Image is the image to annotate.
Image *Image
// MaxFaces is the maximum number of faces to detect in the image.
// Specifying a number greater than zero enables face detection.
MaxFaces int
// MaxLandmarks is the maximum number of landmarks to detect in the image.
// Specifying a number greater than zero enables landmark detection.
MaxLandmarks int
// MaxLogos is the maximum number of logos to detect in the image.
// Specifying a number greater than zero enables logo detection.
MaxLogos int
// MaxLabels is the maximum number of labels to detect in the image.
// Specifying a number greater than zero enables labels detection.
MaxLabels int
// MaxTexts is the maximum number of separate pieces of text to detect in the
// image. Specifying a number greater than zero enables text detection.
MaxTexts int
// DocumentText specifies whether a dense text document OCR should be run
// on the image. When true, takes precedence over MaxTexts.
DocumentText bool
// SafeSearch specifies whether a safe-search detection should be run on the image.
SafeSearch bool
// ImageProps specifies whether image properties should be obtained for the image.
ImageProps bool
// Web specifies whether web annotations should be obtained for the image.
Web bool
// CropHints specifies whether crop hints should be computed for the image.
CropHints *CropHintsParams
}
func (ar *AnnotateRequest) toProto() *pb.AnnotateImageRequest {
img, ictx := ar.Image.toProtos()
var features []*pb.Feature
add := func(typ pb.Feature_Type, max int) {
var mr int32
if max > math.MaxInt32 {
mr = math.MaxInt32
} else {
mr = int32(max)
}
features = append(features, &pb.Feature{Type: typ, MaxResults: mr})
}
if ar.MaxFaces > 0 {
add(pb.Feature_FACE_DETECTION, ar.MaxFaces)
}
if ar.MaxLandmarks > 0 {
add(pb.Feature_LANDMARK_DETECTION, ar.MaxLandmarks)
}
if ar.MaxLogos > 0 {
add(pb.Feature_LOGO_DETECTION, ar.MaxLogos)
}
if ar.MaxLabels > 0 {
add(pb.Feature_LABEL_DETECTION, ar.MaxLabels)
}
if ar.MaxTexts > 0 {
add(pb.Feature_TEXT_DETECTION, ar.MaxTexts)
}
if ar.DocumentText {
add(pb.Feature_DOCUMENT_TEXT_DETECTION, 0)
}
if ar.SafeSearch {
add(pb.Feature_SAFE_SEARCH_DETECTION, 0)
}
if ar.ImageProps {
add(pb.Feature_IMAGE_PROPERTIES, 0)
}
if ar.Web {
add(pb.Feature_WEB_DETECTION, 0)
}
if ar.CropHints != nil {
add(pb.Feature_CROP_HINTS, 0)
if ictx == nil {
ictx = &pb.ImageContext{}
}
ictx.CropHintsParams = &pb.CropHintsParams{
AspectRatios: ar.CropHints.AspectRatios,
}
}
return &pb.AnnotateImageRequest{
Image: img,
Features: features,
ImageContext: ictx,
}
}
// CropHintsParams are parameters for a request for crop hints.
type CropHintsParams struct {
// Aspect ratios for desired crop hints, representing the ratio of the
// width to the height of the image. For example, if the desired aspect
// ratio is 4:3, the corresponding float value should be 1.33333. If not
// specified, the best possible crop is returned. The number of provided
// aspect ratios is limited to a maximum of 16; any aspect ratios provided
// after the 16th are ignored.
AspectRatios []float32
}
// Called for a single image and a single feature.
func (c *Client) annotateOne(ctx context.Context, req *AnnotateRequest) (*Annotations, error) {
annsSlice, err := c.Annotate(ctx, req)
if err != nil {
return nil, err
}
anns := annsSlice[0]
// When there is only one image and one feature, the Annotations.Error field is
// unambiguously about that one detection, so we "promote" it to the error return value.
return anns, anns.Error
}
// TODO(jba): add examples for all single-feature functions (below).
// DetectFaces performs face detection on the image.
// At most maxResults results are returned.
func (c *Client) DetectFaces(ctx context.Context, img *Image, maxResults int) ([]*FaceAnnotation, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, MaxFaces: maxResults})
if err != nil {
return nil, err
}
return anns.Faces, nil
}
// DetectLandmarks performs landmark detection on the image.
// At most maxResults results are returned.
func (c *Client) DetectLandmarks(ctx context.Context, img *Image, maxResults int) ([]*EntityAnnotation, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, MaxLandmarks: maxResults})
if err != nil {
return nil, err
}
return anns.Landmarks, nil
}
// DetectLogos performs logo detection on the image.
// At most maxResults results are returned.
func (c *Client) DetectLogos(ctx context.Context, img *Image, maxResults int) ([]*EntityAnnotation, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, MaxLogos: maxResults})
if err != nil {
return nil, err
}
return anns.Logos, nil
}
// DetectLabels performs label detection on the image.
// At most maxResults results are returned.
func (c *Client) DetectLabels(ctx context.Context, img *Image, maxResults int) ([]*EntityAnnotation, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, MaxLabels: maxResults})
if err != nil {
return nil, err
}
return anns.Labels, nil
}
// DetectTexts performs text detection on the image.
// At most maxResults results are returned.
func (c *Client) DetectTexts(ctx context.Context, img *Image, maxResults int) ([]*EntityAnnotation, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, MaxTexts: maxResults})
if err != nil {
return nil, err
}
return anns.Texts, nil
}
// DetectDocumentText performs full text (OCR) detection on the image.
func (c *Client) DetectDocumentText(ctx context.Context, img *Image) (*TextAnnotation, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, DocumentText: true})
if err != nil {
return nil, err
}
return anns.FullText, nil
}
// DetectSafeSearch performs safe-search detection on the image.
func (c *Client) DetectSafeSearch(ctx context.Context, img *Image) (*SafeSearchAnnotation, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, SafeSearch: true})
if err != nil {
return nil, err
}
return anns.SafeSearch, nil
}
// DetectImageProps computes properties of the image.
func (c *Client) DetectImageProps(ctx context.Context, img *Image) (*ImageProps, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, ImageProps: true})
if err != nil {
return nil, err
}
return anns.ImageProps, nil
}
// DetectWeb computes a web annotation on the image.
func (c *Client) DetectWeb(ctx context.Context, img *Image) (*WebDetection, error) {
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, Web: true})
if err != nil {
return nil, err
}
return anns.Web, nil
}
// CropHints computes crop hints for the image.
func (c *Client) CropHints(ctx context.Context, img *Image, params *CropHintsParams) ([]*CropHint, error) {
// A nil AnnotateRequest.CropHints means do not perform CropHints. But
// here the user is explicitly asking for CropHints, so treat nil as
// an empty CropHintsParams.
if params == nil {
params = &CropHintsParams{}
}
anns, err := c.annotateOne(ctx, &AnnotateRequest{Image: img, CropHints: params})
if err != nil {
return nil, err
}
return anns.CropHints, nil
}
// A Likelihood is an approximate representation of a probability.
type Likelihood int
const (
// LikelihoodUnknown means the likelihood is unknown.
LikelihoodUnknown = Likelihood(pb.Likelihood_UNKNOWN)
// VeryUnlikely means the image is very unlikely to belong to the feature specified.
VeryUnlikely = Likelihood(pb.Likelihood_VERY_UNLIKELY)
// Unlikely means the image is unlikely to belong to the feature specified.
Unlikely = Likelihood(pb.Likelihood_UNLIKELY)
// Possible means the image possibly belongs to the feature specified.
Possible = Likelihood(pb.Likelihood_POSSIBLE)
// Likely means the image is likely to belong to the feature specified.
Likely = Likelihood(pb.Likelihood_LIKELY)
// VeryLikely means the image is very likely to belong to the feature specified.
VeryLikely = Likelihood(pb.Likelihood_VERY_LIKELY)
)
// A Property is an arbitrary name-value pair.
type Property struct {
Name string
Value string
}
func propertyFromProto(p *pb.Property) Property {
return Property{Name: p.Name, Value: p.Value}
}
// ColorInfo consists of RGB channels, score and fraction of
// image the color occupies in the image.
type ColorInfo struct {
// RGB components of the color.
Color color.NRGBA64
// Score is the image-specific score for this color, in the range [0, 1].
Score float32
// PixelFraction is the fraction of pixels the color occupies in the image,
// in the range [0, 1].
PixelFraction float32
}
func colorInfoFromProto(ci *pb.ColorInfo) *ColorInfo {
return &ColorInfo{
Color: colorFromProto(ci.Color),
Score: ci.Score,
PixelFraction: ci.PixelFraction,
}
}
// Should this go into protobuf/ptypes? The color proto is in google/types, so
// not specific to this API.
func colorFromProto(c *cpb.Color) color.NRGBA64 {
// Convert a color component from [0.0, 1.0] to a uint16.
cvt := func(f float32) uint16 { return uint16(f*math.MaxUint16 + 0.5) }
var alpha float32 = 1
if c.Alpha != nil {
alpha = c.Alpha.Value
}
return color.NRGBA64{
R: cvt(c.Red),
G: cvt(c.Green),
B: cvt(c.Blue),
A: cvt(alpha),
}
}

View File

@ -1,7 +1,6 @@
sudo: false sudo: false
language: go language: go
go: go:
- 1.8 - 1.8
- 1.9 - 1.9
@ -16,6 +15,7 @@ install:
script: script:
- bash rungas.sh - bash rungas.sh
- grep -L -r --include *.go --exclude-dir vendor -P "Copyright (\d{4}|\(c\)) Microsoft" ./ | tee /dev/stderr | test -z "$(< /dev/stdin)"
- test -z "$(gofmt -s -l $(find ./arm/* -type d -print) | tee /dev/stderr)" - test -z "$(gofmt -s -l $(find ./arm/* -type d -print) | tee /dev/stderr)"
- test -z "$(gofmt -s -l -w management | tee /dev/stderr)" - test -z "$(gofmt -s -l -w management | tee /dev/stderr)"
- test -z "$(gofmt -s -l -w storage | tee /dev/stderr)" - test -z "$(gofmt -s -l -w storage | tee /dev/stderr)"

View File

@ -1,5 +1,52 @@
# CHANGELOG # CHANGELOG
## `v11.0.0-beta`
### ARM
| api | version | note |
|:------------------------------------|:-------------------|:------------------------------------|
| arm/analysisservices | 2017-08-01-beta | update |
| arm/batch | 2017-05-01 | update |
| arm/cdn | 2017-04-02 | update |
| arm/cognitiveservices | 2017-04-18 | update |
| arm/compute | multiple | update |
| arm/containerregistry | 2017-10-01 | update |
| arm/customerinsights | 2017-04-26 | update |
| arm/eventgrid | 2017-09-15-preview | update |
| arm/eventhub | 2017-04-01 | update |
| arm/graphrbac | 1.6 | update |
| arm/iothub | 2017-07-01 | update |
| arm/keyvault | 2016-10-01 | update |
| arm/marketplaceordering | 2015-06-01 | new |
| arm/opertionalinsights | multiple | update |
| arm/operationsmanagement | 2015-11-01-preview | new |
| arm/recoveryservices | multiple | update |
| arm/recoveryservicesbackup | multiple | update |
| arm/redis | 2017-02-01 | update |
| arm/relay | 2017-04-01 | update |
| arm/resourcehealth | 017-07-01 | update |
| arm/resources/resources | 2017-05-10 | update |
| arm/servicebus | 2017-04-01 | update |
| arm/storage | 2017-06-01 | update |
| arm/streamanalytics | 2016-03-01 | update |
| arm/trafficmanager | 2017-09-01-preview | update |
| arm/visualstudio | 2014-04-01-preview | update |
### Data plane
| dataplane/cognitiveservices/face | 1.0 | new |
| dataplane/cognitiveservices/textanalytics | v2.0 | new |
### Storage
- Support for queue SAS.
- Refactored GetSASURI blob operation to be more complete.
- Added a SAS client for some operations (`container.Exists()`, and `container.ListBlobs()`)
- [Azure REST API specs](https://github.com/Azure/azure-rest-api-specs) commit: 0c2a12b50d8598f68d6715b507f7dd53e163407e
- [AutoRest Go Generator](https://github.com/Azure/autorest.go) commit: 678110f012c7cde6528a1e61d125bdc7ea636b7f
## `v10.3.1-beta` ## `v10.3.1-beta`
- Added Apache notice file. - Added Apache notice file.
@ -54,8 +101,6 @@
## `v10.1.0-beta` ## `v10.1.0-beta`
### ARM ### ARM
| api | version | note |
|:------------------------------------|:-------------------|:------------------------------------|
| arm/recoveryservicessiterecovery | 2016-08-10 | new | | arm/recoveryservicessiterecovery | 2016-08-10 | new |
| arm/managedapplications | 2016-09-01-preview | new | | arm/managedapplications | 2016-09-01-preview | new |
| arm/storsimple8000series | 2017-06-01 | new | | arm/storsimple8000series | 2017-06-01 | new |

View File

@ -1,5 +1,19 @@
package main package main
// Copyright 2017 Microsoft Corporation
//
// 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.
// To run this package... // To run this package...
// go run gen.go -- --sdk 3.14.16 // go run gen.go -- --sdk 3.14.16
@ -11,6 +25,8 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
"sync"
"time"
do "gopkg.in/godo.v2" do "gopkg.in/godo.v2"
) )
@ -35,13 +51,21 @@ type mapping struct {
Services []service Services []service
} }
type failList []string
type failLocker struct {
sync.Mutex
failList
}
var ( var (
start time.Time
gopath = os.Getenv("GOPATH") gopath = os.Getenv("GOPATH")
sdkVersion string sdkVersion string
autorestDir string autorestDir string
swaggersDir string swaggersDir string
testGen bool testGen bool
deps do.S deps do.P
services = []*service{} services = []*service{}
servicesMapping = []mapping{ servicesMapping = []mapping{
{ {
@ -51,24 +75,36 @@ var (
{Name: "advisor"}, {Name: "advisor"},
{Name: "analysisservices"}, {Name: "analysisservices"},
// { // {
// Autorest Bug // Autorest Bug, duplicate files
// Name: "apimanagement", // Name: "apimanagement",
// }, // },
{Name: "appinsights"}, {Name: "appinsights"},
{Name: "authorization"}, {Name: "authorization"},
{Name: "automation"}, {Name: "automation"},
// {
// Name: "commerce",
// Input: "azsadmin/resource-manager/commerce",
// Output: "azsadmin/commerce",
// },
// {
// Name: "fabric",
// Input: "azsadmin/resource-manager/fabric",
// Output: "azsadmin/fabric",
// },
// {
// Name: "infrastructureinsights",
// Input: "azsadmin/resource-manager/InfrastructureInsights",
// Output: "azsadmin/infrastructureinsights",
// },
{Name: "batch"}, {Name: "batch"},
{Name: "billing"}, {Name: "billing"},
{Name: "cdn"}, {Name: "cdn"},
// { {Name: "cognitiveservices"},
// bug in AutoRest (duplicated files)
// Name: "cognitiveservices",
// },
{Name: "commerce"}, {Name: "commerce"},
{Name: "compute"}, {Name: "compute"},
{ {
Name: "containerservice", Name: "containerservice",
Input: "compute", Input: "compute/resource-manager",
Tag: "package-container-service-2017-01", Tag: "package-container-service-2017-01",
}, },
{Name: "consumption"}, {Name: "consumption"},
@ -78,12 +114,12 @@ var (
{Name: "customer-insights"}, {Name: "customer-insights"},
{ {
Name: "account", Name: "account",
Input: "datalake-analytics", Input: "datalake-analytics/resource-manager",
Output: "datalake-analytics/account", Output: "datalake-analytics/account",
}, },
{ {
Name: "account", Name: "account",
Input: "datalake-store", Input: "datalake-store/resource-manager",
Output: "datalake-store/account", Output: "datalake-store/account",
}, },
{Name: "devtestlabs"}, {Name: "devtestlabs"},
@ -97,73 +133,75 @@ var (
{Name: "logic"}, {Name: "logic"},
{ {
Name: "commitmentplans", Name: "commitmentplans",
Input: "machinelearning", Input: "machinelearning/resource-manager",
Output: "machinelearning/commitmentPlans", Output: "machinelearning/commitmentplans",
Tag: "package-commitmentPlans-2016-05-preview", Tag: "package-commitmentPlans-2016-05-preview",
}, },
{ {
Name: "webservices", Name: "webservices",
Input: "machinelearning", Input: "machinelearning/resource-manager",
Output: "machinelearning/webservices", Output: "machinelearning/webservices",
Tag: "package-webservices-2017-01", Tag: "package-webservices-2017-01",
}, },
{Name: "marketplaceordering"},
{Name: "mediaservices"}, {Name: "mediaservices"},
{Name: "mobileengagement"}, {Name: "mobileengagement"},
{Name: "monitor"}, {Name: "monitor"},
{Name: "mysql"}, {Name: "mysql"},
{Name: "network"}, {Name: "network"},
{Name: "notificationhubs"}, {Name: "notificationhubs"},
// { {Name: "operationalinsights"},
// bug in the Go generator https://github.com/Azure/autorest/issues/2219 {Name: "operationsmanagement"},
// Name: "operationalinsights",
// },
{Name: "postgresql"}, {Name: "postgresql"},
{Name: "powerbiembedded"}, {Name: "powerbiembedded"},
{Name: "recoveryservices"}, {Name: "recoveryservices"},
{Name: "recoveryservicesbackup"}, {Name: "recoveryservicesbackup"},
{Name: "recoveryservicessiterecovery"}, {Name: "recoveryservicessiterecovery"},
{Name: "redis"}, {
Name: "redis",
Tag: "package-2016-04",
},
{Name: "relay"}, {Name: "relay"},
{Name: "resourcehealth"}, {Name: "resourcehealth"},
{ {
Name: "features", Name: "features",
Input: "resources", Input: "resources/resource-manager",
Output: "resources/features", Output: "resources/features",
Tag: "package-features-2015-12", Tag: "package-features-2015-12",
}, },
{ {
Name: "links", Name: "links",
Input: "resources", Input: "resources/resource-manager",
Output: "resources/links", Output: "resources/links",
Tag: "package-links-2016-09", Tag: "package-links-2016-09",
}, },
{ {
Name: "locks", Name: "locks",
Input: "resources", Input: "resources/resource-manager",
Output: "resources/locks", Output: "resources/locks",
Tag: "package-locks-2016-09", Tag: "package-locks-2016-09",
}, },
{ {
Name: "managedapplications", Name: "managedapplications",
Input: "resources", Input: "resources/resource-manager",
Output: "resources/managedapplications", Output: "resources/managedapplications",
Tag: "package-managedapplications-2016-09", Tag: "package-managedapplications-2016-09",
}, },
{ {
Name: "policy", Name: "policy",
Input: "resources", Input: "resources/resource-manager",
Output: "resources/policy", Output: "resources/policy",
Tag: "package-policy-2016-12", Tag: "package-policy-2016-12",
}, },
{ {
Name: "resources", Name: "resources",
Input: "resources", Input: "resources/resource-manager",
Output: "resources/resources", Output: "resources/resources",
Tag: "package-resources-2017-05", Tag: "package-resources-2017-05",
}, },
{ {
Name: "subscriptions", Name: "subscriptions",
Input: "resources", Input: "resources/resource-manager",
Output: "resources/subscriptions", Output: "resources/subscriptions",
Tag: "package-subscriptions-2016-06", Tag: "package-subscriptions-2016-06",
}, },
@ -180,7 +218,8 @@ var (
{Name: "streamanalytics"}, {Name: "streamanalytics"},
// { // {
// error in the modeler // error in the modeler
// Name: "timeseriesinsights", // https://github.com/Azure/autorest/issues/2579
// Name: "timeseriesinsights",
// }, // },
{Name: "trafficmanager"}, {Name: "trafficmanager"},
{Name: "visualstudio"}, {Name: "visualstudio"},
@ -191,8 +230,16 @@ var (
PlaneOutput: "dataplane", PlaneOutput: "dataplane",
PlaneInput: "data-plane", PlaneInput: "data-plane",
Services: []service{ Services: []service{
{Name: "keyvault"},
{ {
Name: "keyvault", Name: "face",
Input: "cognitiveservices/data-plane/Face",
Output: "cognitiveservices/face",
},
{
Name: "textanalytics",
Input: "cognitiveservices/data-plane/TextAnalytics",
Output: "cognitiveservices/textanalytics",
}, },
}, },
}, },
@ -201,7 +248,7 @@ var (
Services: []service{ Services: []service{
{ {
Name: "filesystem", Name: "filesystem",
Input: "datalake-store", Input: "datalake-store/data-plane",
Output: "datalake-store/filesystem", Output: "datalake-store/filesystem",
}, },
}, },
@ -210,15 +257,15 @@ var (
PlaneOutput: "arm", PlaneOutput: "arm",
PlaneInput: "data-plane", PlaneInput: "data-plane",
Services: []service{ Services: []service{
{ {Name: "graphrbac"},
Name: "graphrbac",
},
}, },
}, },
} }
fails = failLocker{}
) )
func main() { func init() {
start = time.Now()
for _, swaggerGroup := range servicesMapping { for _, swaggerGroup := range servicesMapping {
swg := swaggerGroup swg := swaggerGroup
for _, service := range swg.Services { for _, service := range swg.Services {
@ -226,6 +273,9 @@ func main() {
initAndAddService(&s, swg.PlaneInput, swg.PlaneOutput) initAndAddService(&s, swg.PlaneInput, swg.PlaneOutput)
} }
} }
}
func main() {
do.Godo(tasks) do.Godo(tasks)
} }
@ -233,7 +283,13 @@ func initAndAddService(service *service, planeInput, planeOutput string) {
if service.Input == "" { if service.Input == "" {
service.Input = service.Name service.Input = service.Name
} }
service.Input = filepath.Join(service.Input, planeInput, "readme.md") path := []string{service.Input}
if service.Input == service.Name {
path = append(path, planeInput)
}
path = append(path, "readme.md")
service.Input = filepath.Join(path...)
if service.Output == "" { if service.Output == "" {
service.Output = service.Name service.Output = service.Name
} }
@ -247,7 +303,7 @@ func initAndAddService(service *service, planeInput, planeOutput string) {
} }
func tasks(p *do.Project) { func tasks(p *do.Project) {
p.Task("default", do.S{"setvars", "generate:all", "management"}, nil) p.Task("default", do.S{"setvars", "generate:all", "management", "report"}, nil)
p.Task("setvars", nil, setVars) p.Task("setvars", nil, setVars)
p.Use("generate", generateTasks) p.Use("generate", generateTasks)
p.Use("gofmt", formatTasks) p.Use("gofmt", formatTasks)
@ -256,6 +312,7 @@ func tasks(p *do.Project) {
p.Use("govet", vetTasks) p.Use("govet", vetTasks)
p.Task("management", do.S{"setvars"}, managementVersion) p.Task("management", do.S{"setvars"}, managementVersion)
p.Task("addVersion", nil, addVersion) p.Task("addVersion", nil, addVersion)
p.Task("report", nil, report)
} }
func setVars(c *do.Context) { func setVars(c *do.Context) {
@ -294,7 +351,7 @@ func generate(service *service) {
commandArgs := []string{ commandArgs := []string{
fullInput, fullInput,
codegen, codegen,
"--license-header=MICROSOFT_APACHE", "--license-header=MICROSOFT_APACHE_NO_VERSION",
fmt.Sprintf("--namespace=%s", service.Name), fmt.Sprintf("--namespace=%s", service.Name),
fmt.Sprintf("--output-folder=%s", service.Output), fmt.Sprintf("--output-folder=%s", service.Output),
fmt.Sprintf("--package-version=%s", sdkVersion), fmt.Sprintf("--package-version=%s", sdkVersion),
@ -318,8 +375,8 @@ func generate(service *service) {
fmt.Println(commandArgs) fmt.Println(commandArgs)
if _, err := runner(autorest); err != nil { if _, stderr, err := runner(autorest); err != nil {
panic(fmt.Errorf("Autorest error: %s", err)) fails.Add(fmt.Sprintf("%s: autorest error: %s: %s", service.Fullname, err, stderr))
} }
format(service) format(service)
@ -335,9 +392,9 @@ func formatTasks(p *do.Project) {
func format(service *service) { func format(service *service) {
fmt.Printf("Formatting %s...\n\n", service.Fullname) fmt.Printf("Formatting %s...\n\n", service.Fullname)
gofmt := exec.Command("gofmt", "-w", service.Output) gofmt := exec.Command("gofmt", "-w", service.Output)
_, err := runner(gofmt) _, stderr, err := runner(gofmt)
if err != nil { if err != nil {
panic(fmt.Errorf("gofmt error: %s", err)) fails.Add(fmt.Sprintf("%s: gofmt error:%s: %s", service.Fullname, err, stderr))
} }
} }
@ -348,9 +405,9 @@ func buildTasks(p *do.Project) {
func build(service *service) { func build(service *service) {
fmt.Printf("Building %s...\n\n", service.Fullname) fmt.Printf("Building %s...\n\n", service.Fullname)
gobuild := exec.Command("go", "build", service.Namespace) gobuild := exec.Command("go", "build", service.Namespace)
_, err := runner(gobuild) _, stderr, err := runner(gobuild)
if err != nil { if err != nil {
panic(fmt.Errorf("go build error: %s", err)) fails.Add(fmt.Sprintf("%s: build error: %s: %s", service.Fullname, err, stderr))
} }
} }
@ -361,9 +418,9 @@ func lintTasks(p *do.Project) {
func lint(service *service) { func lint(service *service) {
fmt.Printf("Linting %s...\n\n", service.Fullname) fmt.Printf("Linting %s...\n\n", service.Fullname)
golint := exec.Command(filepath.Join(gopath, "bin", "golint"), service.Namespace) golint := exec.Command(filepath.Join(gopath, "bin", "golint"), service.Namespace)
_, err := runner(golint) _, stderr, err := runner(golint)
if err != nil { if err != nil {
panic(fmt.Errorf("golint error: %s", err)) fails.Add(fmt.Sprintf("%s: golint error: %s: %s", service.Fullname, err, stderr))
} }
} }
@ -374,15 +431,15 @@ func vetTasks(p *do.Project) {
func vet(service *service) { func vet(service *service) {
fmt.Printf("Vetting %s...\n\n", service.Fullname) fmt.Printf("Vetting %s...\n\n", service.Fullname)
govet := exec.Command("go", "vet", service.Namespace) govet := exec.Command("go", "vet", service.Namespace)
_, err := runner(govet) _, stderr, err := runner(govet)
if err != nil { if err != nil {
panic(fmt.Errorf("go vet error: %s", err)) fails.Add(fmt.Sprintf("%s: go vet error: %s: %s", service.Fullname, err, stderr))
} }
} }
func addVersion(c *do.Context) { func addVersion(c *do.Context) {
gitStatus := exec.Command("git", "status", "-s") gitStatus := exec.Command("git", "status", "-s")
out, err := runner(gitStatus) out, _, err := runner(gitStatus)
if err != nil { if err != nil {
panic(fmt.Errorf("Git error: %s", err)) panic(fmt.Errorf("Git error: %s", err))
} }
@ -391,7 +448,7 @@ func addVersion(c *do.Context) {
for _, f := range files { for _, f := range files {
if strings.HasPrefix(f, " M ") && strings.HasSuffix(f, "version.go") { if strings.HasPrefix(f, " M ") && strings.HasSuffix(f, "version.go") {
gitAdd := exec.Command("git", "add", f[3:]) gitAdd := exec.Command("git", "add", f[3:])
_, err := runner(gitAdd) _, _, err := runner(gitAdd)
if err != nil { if err != nil {
panic(fmt.Errorf("Git error: %s", err)) panic(fmt.Errorf("Git error: %s", err))
} }
@ -406,10 +463,24 @@ func managementVersion(c *do.Context) {
func version(packageName string) { func version(packageName string) {
versionFile := filepath.Join(packageName, "version.go") versionFile := filepath.Join(packageName, "version.go")
os.Remove(versionFile) os.Remove(versionFile)
template := `// +build go1.7 template := `// +build go1.7
package %s package %s
// Copyright 2017 Microsoft Corporation
//
// 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.
var ( var (
sdkVersion = "%s" sdkVersion = "%s"
) )
@ -428,7 +499,7 @@ func addTasks(fn func(*service), p *do.Project) {
p.Task("all", deps, nil) p.Task("all", deps, nil)
} }
func runner(cmd *exec.Cmd) (string, error) { func runner(cmd *exec.Cmd) (string, string, error) {
var stdout, stderr bytes.Buffer var stdout, stderr bytes.Buffer
cmd.Stdout, cmd.Stderr = &stdout, &stderr cmd.Stdout, cmd.Stderr = &stdout, &stderr
err := cmd.Run() err := cmd.Run()
@ -438,5 +509,19 @@ func runner(cmd *exec.Cmd) (string, error) {
if stderr.Len() > 0 { if stderr.Len() > 0 {
fmt.Println(stderr.String()) fmt.Println(stderr.String())
} }
return stdout.String(), err return stdout.String(), stderr.String(), err
}
func (fl *failLocker) Add(fail string) {
fl.Lock()
defer fl.Unlock()
fl.failList = append(fl.failList, fail)
}
func report(c *do.Context) {
fmt.Printf("Script ran for %s\n", time.Since(start))
for _, f := range fails.failList {
fmt.Println(f)
fmt.Println("==========")
}
} }

View File

@ -1,5 +1,4 @@
// Package advisor implements the Azure ARM Advisor service API version // Package advisor implements the Azure ARM Advisor service API version 2017-04-19.
// 2017-04-19.
// //
// REST APIs for Azure Advisor // REST APIs for Azure Advisor
package advisor package advisor
@ -18,9 +17,8 @@ package advisor
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"

View File

@ -14,15 +14,14 @@ package advisor
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/date" "github.com/Azure/go-autorest/autorest/date"
"github.com/Azure/go-autorest/autorest/to" "github.com/Azure/go-autorest/autorest/to"
"github.com/satori/uuid" uuid "github.com/satori/go.uuid"
"net/http" "net/http"
) )
@ -152,8 +151,8 @@ type ShortDescription struct {
Solution *string `json:"solution,omitempty"` Solution *string `json:"solution,omitempty"`
} }
// SuppressionContract is the details of the snoozed or dismissed rule; for // SuppressionContract is the details of the snoozed or dismissed rule; for example, the duration, name, and GUID
// example, the duration, name, and GUID associated with the rule. // associated with the rule.
type SuppressionContract struct { type SuppressionContract struct {
autorest.Response `json:"-"` autorest.Response `json:"-"`
ID *string `json:"id,omitempty"` ID *string `json:"id,omitempty"`

View File

@ -14,9 +14,8 @@ package advisor
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -24,7 +23,7 @@ import (
"net/http" "net/http"
) )
// OperationsClient is the rEST APIs for Azure Advisor // OperationsClient is the REST APIs for Azure Advisor
type OperationsClient struct { type OperationsClient struct {
ManagementClient ManagementClient
} }
@ -34,8 +33,7 @@ func NewOperationsClient(subscriptionID string) OperationsClient {
return NewOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewOperationsClientWithBaseURI creates an instance of the OperationsClient // NewOperationsClientWithBaseURI creates an instance of the OperationsClient client.
// client.
func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string) OperationsClient { func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string) OperationsClient {
return OperationsClient{NewWithBaseURI(baseURI, subscriptionID)} return OperationsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
@ -120,3 +118,48 @@ func (client OperationsClient) ListNextResults(lastResults OperationEntityListRe
return return
} }
// ListComplete gets all elements from the list without paging.
func (client OperationsClient) ListComplete(cancel <-chan struct{}) (<-chan OperationEntity, <-chan error) {
resultChan := make(chan OperationEntity)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List()
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,37 +14,33 @@ package advisor
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/azure"
"github.com/satori/uuid" uuid "github.com/satori/go.uuid"
"net/http" "net/http"
) )
// RecommendationsClient is the rEST APIs for Azure Advisor // RecommendationsClient is the REST APIs for Azure Advisor
type RecommendationsClient struct { type RecommendationsClient struct {
ManagementClient ManagementClient
} }
// NewRecommendationsClient creates an instance of the RecommendationsClient // NewRecommendationsClient creates an instance of the RecommendationsClient client.
// client.
func NewRecommendationsClient(subscriptionID string) RecommendationsClient { func NewRecommendationsClient(subscriptionID string) RecommendationsClient {
return NewRecommendationsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewRecommendationsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewRecommendationsClientWithBaseURI creates an instance of the // NewRecommendationsClientWithBaseURI creates an instance of the RecommendationsClient client.
// RecommendationsClient client.
func NewRecommendationsClientWithBaseURI(baseURI string, subscriptionID string) RecommendationsClient { func NewRecommendationsClientWithBaseURI(baseURI string, subscriptionID string) RecommendationsClient {
return RecommendationsClient{NewWithBaseURI(baseURI, subscriptionID)} return RecommendationsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// Generate initiates the recommendation generation or computation process for // Generate initiates the recommendation generation or computation process for a subscription. This operation is
// a subscription. This operation is asynchronous. The generated // asynchronous. The generated recommendations are stored in a cache in the Advisor service.
// recommendations are stored in a cache in the Advisor service.
func (client RecommendationsClient) Generate() (result autorest.Response, err error) { func (client RecommendationsClient) Generate() (result autorest.Response, err error) {
req, err := client.GeneratePreparer() req, err := client.GeneratePreparer()
if err != nil { if err != nil {
@ -106,9 +102,8 @@ func (client RecommendationsClient) GenerateResponder(resp *http.Response) (resu
// Get obtains details of a cached recommendation. // Get obtains details of a cached recommendation.
// //
// resourceURI is the fully qualified Azure Resource Manager identifier of the // resourceURI is the fully qualified Azure Resource Manager identifier of the resource to which the recommendation
// resource to which the recommendation applies. recommendationID is the // applies. recommendationID is the recommendation ID.
// recommendation ID.
func (client RecommendationsClient) Get(resourceURI string, recommendationID string) (result ResourceRecommendationBase, err error) { func (client RecommendationsClient) Get(resourceURI string, recommendationID string) (result ResourceRecommendationBase, err error) {
req, err := client.GetPreparer(resourceURI, recommendationID) req, err := client.GetPreparer(resourceURI, recommendationID)
if err != nil { if err != nil {
@ -170,13 +165,12 @@ func (client RecommendationsClient) GetResponder(resp *http.Response) (result Re
return return
} }
// GetGenerateStatus retrieves the status of the recommendation computation or // GetGenerateStatus retrieves the status of the recommendation computation or generation process. Invoke this API
// generation process. Invoke this API after calling the generation // after calling the generation recommendation. The URI of this API is returned in the Location field of the response
// recommendation. The URI of this API is returned in the Location field of the // header.
// response header.
// //
// operationID is the operation ID, which can be found from the Location field // operationID is the operation ID, which can be found from the Location field in the generate recommendation response
// in the generate recommendation response header. // header.
func (client RecommendationsClient) GetGenerateStatus(operationID uuid.UUID) (result autorest.Response, err error) { func (client RecommendationsClient) GetGenerateStatus(operationID uuid.UUID) (result autorest.Response, err error) {
req, err := client.GetGenerateStatusPreparer(operationID) req, err := client.GetGenerateStatusPreparer(operationID)
if err != nil { if err != nil {
@ -237,13 +231,11 @@ func (client RecommendationsClient) GetGenerateStatusResponder(resp *http.Respon
return return
} }
// List obtains cached recommendations for a subscription. The recommendations // List obtains cached recommendations for a subscription. The recommendations are generated or computed by invoking
// are generated or computed by invoking generateRecommendations. // generateRecommendations.
// //
// filter is the filter to apply to the recommendations. top is the number of // filter is the filter to apply to the recommendations. top is the number of recommendations per page if a paged
// recommendations per page if a paged version of this API is being used. // version of this API is being used. skipToken is the page-continuation token to use with a paged version of this API.
// skipToken is the page-continuation token to use with a paged version of this
// API.
func (client RecommendationsClient) List(filter string, top *int32, skipToken string) (result ResourceRecommendationBaseListResult, err error) { func (client RecommendationsClient) List(filter string, top *int32, skipToken string) (result ResourceRecommendationBaseListResult, err error) {
req, err := client.ListPreparer(filter, top, skipToken) req, err := client.ListPreparer(filter, top, skipToken)
if err != nil { if err != nil {
@ -336,3 +328,48 @@ func (client RecommendationsClient) ListNextResults(lastResults ResourceRecommen
return return
} }
// ListComplete gets all elements from the list without paging.
func (client RecommendationsClient) ListComplete(filter string, top *int32, skipToken string, cancel <-chan struct{}) (<-chan ResourceRecommendationBase, <-chan error) {
resultChan := make(chan ResourceRecommendationBase)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List(filter, top, skipToken)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,9 +14,8 @@ package advisor
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -24,7 +23,7 @@ import (
"net/http" "net/http"
) )
// SuppressionsClient is the rEST APIs for Azure Advisor // SuppressionsClient is the REST APIs for Azure Advisor
type SuppressionsClient struct { type SuppressionsClient struct {
ManagementClient ManagementClient
} }
@ -34,20 +33,17 @@ func NewSuppressionsClient(subscriptionID string) SuppressionsClient {
return NewSuppressionsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewSuppressionsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewSuppressionsClientWithBaseURI creates an instance of the // NewSuppressionsClientWithBaseURI creates an instance of the SuppressionsClient client.
// SuppressionsClient client.
func NewSuppressionsClientWithBaseURI(baseURI string, subscriptionID string) SuppressionsClient { func NewSuppressionsClientWithBaseURI(baseURI string, subscriptionID string) SuppressionsClient {
return SuppressionsClient{NewWithBaseURI(baseURI, subscriptionID)} return SuppressionsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// Create enables the snoozed or dismissed attribute of a recommendation. The // Create enables the snoozed or dismissed attribute of a recommendation. The snoozed or dismissed attribute is
// snoozed or dismissed attribute is referred to as a suppression. Use this API // referred to as a suppression. Use this API to create or update the snoozed or dismissed status of a recommendation.
// to create or update the snoozed or dismissed status of a recommendation.
// //
// resourceURI is the fully qualified Azure Resource Manager identifier of the // resourceURI is the fully qualified Azure Resource Manager identifier of the resource to which the recommendation
// resource to which the recommendation applies. recommendationID is the // applies. recommendationID is the recommendation ID. name is the name of the suppression. suppressionContract is the
// recommendation ID. name is the name of the suppression. suppressionContract // snoozed or dismissed attribute; for example, the snooze duration.
// is the snoozed or dismissed attribute; for example, the snooze duration.
func (client SuppressionsClient) Create(resourceURI string, recommendationID string, name string, suppressionContract SuppressionContract) (result SuppressionContract, err error) { func (client SuppressionsClient) Create(resourceURI string, recommendationID string, name string, suppressionContract SuppressionContract) (result SuppressionContract, err error) {
req, err := client.CreatePreparer(resourceURI, recommendationID, name, suppressionContract) req, err := client.CreatePreparer(resourceURI, recommendationID, name, suppressionContract)
if err != nil { if err != nil {
@ -112,13 +108,11 @@ func (client SuppressionsClient) CreateResponder(resp *http.Response) (result Su
return return
} }
// Delete enables the activation of a snoozed or dismissed recommendation. The // Delete enables the activation of a snoozed or dismissed recommendation. The snoozed or dismissed attribute of a
// snoozed or dismissed attribute of a recommendation is referred to as a // recommendation is referred to as a suppression.
// suppression.
// //
// resourceURI is the fully qualified Azure Resource Manager identifier of the // resourceURI is the fully qualified Azure Resource Manager identifier of the resource to which the recommendation
// resource to which the recommendation applies. recommendationID is the // applies. recommendationID is the recommendation ID. name is the name of the suppression.
// recommendation ID. name is the name of the suppression.
func (client SuppressionsClient) Delete(resourceURI string, recommendationID string, name string) (result autorest.Response, err error) { func (client SuppressionsClient) Delete(resourceURI string, recommendationID string, name string) (result autorest.Response, err error) {
req, err := client.DeletePreparer(resourceURI, recommendationID, name) req, err := client.DeletePreparer(resourceURI, recommendationID, name)
if err != nil { if err != nil {
@ -182,9 +176,8 @@ func (client SuppressionsClient) DeleteResponder(resp *http.Response) (result au
// Get obtains the details of a suppression. // Get obtains the details of a suppression.
// //
// resourceURI is the fully qualified Azure Resource Manager identifier of the // resourceURI is the fully qualified Azure Resource Manager identifier of the resource to which the recommendation
// resource to which the recommendation applies. recommendationID is the // applies. recommendationID is the recommendation ID. name is the name of the suppression.
// recommendation ID. name is the name of the suppression.
func (client SuppressionsClient) Get(resourceURI string, recommendationID string, name string) (result SuppressionContract, err error) { func (client SuppressionsClient) Get(resourceURI string, recommendationID string, name string) (result SuppressionContract, err error) {
req, err := client.GetPreparer(resourceURI, recommendationID, name) req, err := client.GetPreparer(resourceURI, recommendationID, name)
if err != nil { if err != nil {
@ -247,13 +240,11 @@ func (client SuppressionsClient) GetResponder(resp *http.Response) (result Suppr
return return
} }
// List retrieves the list of snoozed or dismissed suppressions for a // List retrieves the list of snoozed or dismissed suppressions for a subscription. The snoozed or dismissed attribute
// subscription. The snoozed or dismissed attribute of a recommendation is // of a recommendation is referred to as a suppression.
// referred to as a suppression.
// //
// top is the number of suppressions per page if a paged version of this API is // top is the number of suppressions per page if a paged version of this API is being used. skipToken is the
// being used. skipToken is the page-continuation token to use with a paged // page-continuation token to use with a paged version of this API.
// version of this API.
func (client SuppressionsClient) List(top *int32, skipToken string) (result SuppressionContractListResult, err error) { func (client SuppressionsClient) List(top *int32, skipToken string) (result SuppressionContractListResult, err error) {
req, err := client.ListPreparer(top, skipToken) req, err := client.ListPreparer(top, skipToken)
if err != nil { if err != nil {
@ -343,3 +334,48 @@ func (client SuppressionsClient) ListNextResults(lastResults SuppressionContract
return return
} }
// ListComplete gets all elements from the list without paging.
func (client SuppressionsClient) ListComplete(top *int32, skipToken string, cancel <-chan struct{}) (<-chan SuppressionContract, <-chan error) {
resultChan := make(chan SuppressionContract)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List(top, skipToken)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,15 +14,15 @@ package advisor
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 2.2.18.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated. // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// UserAgent returns the UserAgent string to use when sending http.Requests. // UserAgent returns the UserAgent string to use when sending http.Requests.
func UserAgent() string { func UserAgent() string {
return "Azure-SDK-For-Go/v10.3.1-beta arm-advisor/2017-04-19" return "Azure-SDK-For-Go/v11.0.0-beta arm-advisor/2017-04-19"
} }
// Version returns the semantic version (see http://semver.org) of the client. // Version returns the semantic version (see http://semver.org) of the client.
func Version() string { func Version() string {
return "v10.3.1-beta" return "v11.0.0-beta"
} }

View File

@ -1,9 +1,7 @@
// Package analysisservices implements the Azure ARM Analysisservices service // Package analysisservices implements the Azure ARM Analysisservices service API version 2017-08-01-beta.
// API version 2016-05-16.
// //
// The Azure Analysis Services Web API provides a RESTful set of web services // The Azure Analysis Services Web API provides a RESTful set of web services that enables users to create, retrieve,
// that enables users to create, retrieve, update, and delete Analysis Services // update, and delete Analysis Services servers
// servers
package analysisservices package analysisservices
// Copyright (c) Microsoft and contributors. All rights reserved. // Copyright (c) Microsoft and contributors. All rights reserved.
@ -20,9 +18,8 @@ package analysisservices
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"

View File

@ -14,12 +14,23 @@ package analysisservices
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
"net/http"
)
// ConnectionMode enumerates the values for connection mode.
type ConnectionMode string
const (
// All specifies the all state for connection mode.
All ConnectionMode = "All"
// ReadOnly specifies the read only state for connection mode.
ReadOnly ConnectionMode = "ReadOnly"
) )
// ProvisioningState enumerates the values for provisioning state. // ProvisioningState enumerates the values for provisioning state.
@ -52,26 +63,6 @@ const (
Updating ProvisioningState = "Updating" Updating ProvisioningState = "Updating"
) )
// SkuName enumerates the values for sku name.
type SkuName string
const (
// B1 specifies the b1 state for sku name.
B1 SkuName = "B1"
// B2 specifies the b2 state for sku name.
B2 SkuName = "B2"
// D1 specifies the d1 state for sku name.
D1 SkuName = "D1"
// S0 specifies the s0 state for sku name.
S0 SkuName = "S0"
// S1 specifies the s1 state for sku name.
S1 SkuName = "S1"
// S2 specifies the s2 state for sku name.
S2 SkuName = "S2"
// S4 specifies the s4 state for sku name.
S4 SkuName = "S4"
)
// SkuTier enumerates the values for sku tier. // SkuTier enumerates the values for sku tier.
type SkuTier string type SkuTier string
@ -114,11 +105,88 @@ const (
StateUpdating State = "Updating" StateUpdating State = "Updating"
) )
// BackupConfiguration is an object that represents backup configurations // Status enumerates the values for status.
type BackupConfiguration struct { type Status string
StorageAccount *string `json:"storageAccount,omitempty"`
BlobContainer *string `json:"blobContainer,omitempty"` const (
AccessKey *string `json:"accessKey,omitempty"` // Live specifies the live state for status.
Live Status = "Live"
)
// ErrorResponse is describes the format of Error response.
type ErrorResponse struct {
Code *string `json:"code,omitempty"`
Message *string `json:"message,omitempty"`
}
// GatewayDetails is the gateway details.
type GatewayDetails struct {
GatewayResourceID *string `json:"gatewayResourceId,omitempty"`
GatewayObjectID *string `json:"gatewayObjectId,omitempty"`
DmtsClusterURI *string `json:"dmtsClusterUri,omitempty"`
}
// GatewayError is detail of gateway errors.
type GatewayError struct {
Code *string `json:"code,omitempty"`
Message *string `json:"message,omitempty"`
}
// GatewayListStatusError is status of gateway is error.
type GatewayListStatusError struct {
Error *GatewayError `json:"error,omitempty"`
}
// GatewayListStatusLive is status of gateway is live.
type GatewayListStatusLive struct {
autorest.Response `json:"-"`
Status Status `json:"status,omitempty"`
}
// IPv4FirewallRule is the detail of firewall rule.
type IPv4FirewallRule struct {
FirewallRuleName *string `json:"firewallRuleName,omitempty"`
RangeStart *string `json:"rangeStart,omitempty"`
RangeEnd *string `json:"rangeEnd,omitempty"`
}
// IPv4FirewallSettings is an array of firewall rules.
type IPv4FirewallSettings struct {
FirewallRules *[]IPv4FirewallRule `json:"firewallRules,omitempty"`
EnablePowerBIService *string `json:"enablePowerBIService,omitempty"`
}
// Operation is a Consumption REST API operation.
type Operation struct {
Name *string `json:"name,omitempty"`
Display *OperationDisplay `json:"display,omitempty"`
}
// OperationDisplay is the object that represents the operation.
type OperationDisplay struct {
Provider *string `json:"provider,omitempty"`
Resource *string `json:"resource,omitempty"`
Operation *string `json:"operation,omitempty"`
}
// OperationListResult is result of listing consumption operations. It contains a list of operations and a URL link to
// get the next set of results.
type OperationListResult struct {
autorest.Response `json:"-"`
Value *[]Operation `json:"value,omitempty"`
NextLink *string `json:"nextLink,omitempty"`
}
// OperationListResultPreparer prepares a request to retrieve the next set of results. It returns
// nil if no more results exist.
func (client OperationListResult) OperationListResultPreparer() (*http.Request, error) {
if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 {
return nil, nil
}
return autorest.Prepare(&http.Request{},
autorest.AsJSON(),
autorest.AsGet(),
autorest.WithBaseURL(to.String(client.NextLink)))
} }
// Resource is represents an instance of an Analysis Services resource. // Resource is represents an instance of an Analysis Services resource.
@ -131,11 +199,11 @@ type Resource struct {
Tags *map[string]*string `json:"tags,omitempty"` Tags *map[string]*string `json:"tags,omitempty"`
} }
// ResourceSku is represents the SKU name and Azure pricing tier for Analysis // ResourceSku is represents the SKU name and Azure pricing tier for Analysis Services resource.
// Services resource.
type ResourceSku struct { type ResourceSku struct {
Name SkuName `json:"name,omitempty"` Name *string `json:"name,omitempty"`
Tier SkuTier `json:"tier,omitempty"` Tier SkuTier `json:"tier,omitempty"`
Capacity *int32 `json:"capacity,omitempty"`
} }
// Server is represents an instance of an Analysis Services resource. // Server is represents an instance of an Analysis Services resource.
@ -150,25 +218,30 @@ type Server struct {
*ServerProperties `json:"properties,omitempty"` *ServerProperties `json:"properties,omitempty"`
} }
// ServerAdministrators is an array of administrator user identities // ServerAdministrators is an array of administrator user identities.
type ServerAdministrators struct { type ServerAdministrators struct {
Members *[]string `json:"members,omitempty"` Members *[]string `json:"members,omitempty"`
} }
// ServerMutableProperties is an object that represents a set of mutable // ServerMutableProperties is an object that represents a set of mutable Analysis Services resource properties.
// Analysis Services resource properties.
type ServerMutableProperties struct { type ServerMutableProperties struct {
AsAdministrators *ServerAdministrators `json:"asAdministrators,omitempty"` AsAdministrators *ServerAdministrators `json:"asAdministrators,omitempty"`
BackupConfiguration *BackupConfiguration `json:"backupConfiguration,omitempty"` BackupBlobContainerURI *string `json:"backupBlobContainerUri,omitempty"`
GatewayDetails *GatewayDetails `json:"gatewayDetails,omitempty"`
IPV4FirewallSettings *IPv4FirewallSettings `json:"ipV4FirewallSettings,omitempty"`
QuerypoolConnectionMode ConnectionMode `json:"querypoolConnectionMode,omitempty"`
} }
// ServerProperties is properties of Analysis Services resource. // ServerProperties is properties of Analysis Services resource.
type ServerProperties struct { type ServerProperties struct {
AsAdministrators *ServerAdministrators `json:"asAdministrators,omitempty"` AsAdministrators *ServerAdministrators `json:"asAdministrators,omitempty"`
BackupConfiguration *BackupConfiguration `json:"backupConfiguration,omitempty"` BackupBlobContainerURI *string `json:"backupBlobContainerUri,omitempty"`
State State `json:"state,omitempty"` GatewayDetails *GatewayDetails `json:"gatewayDetails,omitempty"`
ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` IPV4FirewallSettings *IPv4FirewallSettings `json:"ipV4FirewallSettings,omitempty"`
ServerFullName *string `json:"serverFullName,omitempty"` QuerypoolConnectionMode ConnectionMode `json:"querypoolConnectionMode,omitempty"`
State State `json:"state,omitempty"`
ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
ServerFullName *string `json:"serverFullName,omitempty"`
} }
// Servers is an array of Analysis Services resources. // Servers is an array of Analysis Services resources.
@ -183,3 +256,20 @@ type ServerUpdateParameters struct {
Tags *map[string]*string `json:"tags,omitempty"` Tags *map[string]*string `json:"tags,omitempty"`
*ServerMutableProperties `json:"properties,omitempty"` *ServerMutableProperties `json:"properties,omitempty"`
} }
// SkuDetailsForExistingResource is an object that represents SKU details for existing resources.
type SkuDetailsForExistingResource struct {
Sku *ResourceSku `json:"sku,omitempty"`
}
// SkuEnumerationForExistingResourceResult is an object that represents enumerating SKUs for existing resources.
type SkuEnumerationForExistingResourceResult struct {
autorest.Response `json:"-"`
Value *[]SkuDetailsForExistingResource `json:"value,omitempty"`
}
// SkuEnumerationForNewResourceResult is an object that represents enumerating SKUs for new resources.
type SkuEnumerationForNewResourceResult struct {
autorest.Response `json:"-"`
Value *[]ResourceSku `json:"value,omitempty"`
}

View File

@ -0,0 +1,166 @@
package analysisservices
// Copyright (c) Microsoft and contributors. 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.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
import (
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure"
"net/http"
)
// OperationsClient is the the Azure Analysis Services Web API provides a RESTful set of web services that enables
// users to create, retrieve, update, and delete Analysis Services servers
type OperationsClient struct {
ManagementClient
}
// NewOperationsClient creates an instance of the OperationsClient client.
func NewOperationsClient(subscriptionID string) OperationsClient {
return NewOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID)
}
// NewOperationsClientWithBaseURI creates an instance of the OperationsClient client.
func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string) OperationsClient {
return OperationsClient{NewWithBaseURI(baseURI, subscriptionID)}
}
// List lists all of the available consumption REST API operations.
func (client OperationsClient) List() (result OperationListResult, err error) {
req, err := client.ListPreparer()
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.OperationsClient", "List", nil, "Failure preparing request")
return
}
resp, err := client.ListSender(req)
if err != nil {
result.Response = autorest.Response{Response: resp}
err = autorest.NewErrorWithError(err, "analysisservices.OperationsClient", "List", resp, "Failure sending request")
return
}
result, err = client.ListResponder(resp)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.OperationsClient", "List", resp, "Failure responding to request")
}
return
}
// ListPreparer prepares the List request.
func (client OperationsClient) ListPreparer() (*http.Request, error) {
const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{
"api-version": APIVersion,
}
preparer := autorest.CreatePreparer(
autorest.AsGet(),
autorest.WithBaseURL(client.BaseURI),
autorest.WithPath("/providers/Microsoft.AnalysisServices/operations"),
autorest.WithQueryParameters(queryParameters))
return preparer.Prepare(&http.Request{})
}
// ListSender sends the List request. The method will close the
// http.Response Body if it receives an error.
func (client OperationsClient) ListSender(req *http.Request) (*http.Response, error) {
return autorest.SendWithSender(client, req)
}
// ListResponder handles the response to the List request. The method always
// closes the http.Response Body.
func (client OperationsClient) ListResponder(resp *http.Response) (result OperationListResult, err error) {
err = autorest.Respond(
resp,
client.ByInspecting(),
azure.WithErrorUnlessStatusCode(http.StatusOK),
autorest.ByUnmarshallingJSON(&result),
autorest.ByClosing())
result.Response = autorest.Response{Response: resp}
return
}
// ListNextResults retrieves the next set of results, if any.
func (client OperationsClient) ListNextResults(lastResults OperationListResult) (result OperationListResult, err error) {
req, err := lastResults.OperationListResultPreparer()
if err != nil {
return result, autorest.NewErrorWithError(err, "analysisservices.OperationsClient", "List", nil, "Failure preparing next results request")
}
if req == nil {
return
}
resp, err := client.ListSender(req)
if err != nil {
result.Response = autorest.Response{Response: resp}
return result, autorest.NewErrorWithError(err, "analysisservices.OperationsClient", "List", resp, "Failure sending next results request")
}
result, err = client.ListResponder(resp)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.OperationsClient", "List", resp, "Failure responding to next results request")
}
return
}
// ListComplete gets all elements from the list without paging.
func (client OperationsClient) ListComplete(cancel <-chan struct{}) (<-chan Operation, <-chan error) {
resultChan := make(chan Operation)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List()
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,9 +14,8 @@ package analysisservices
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,9 +24,8 @@ import (
"net/http" "net/http"
) )
// ServersClient is the the Azure Analysis Services Web API provides a RESTful // ServersClient is the the Azure Analysis Services Web API provides a RESTful set of web services that enables users
// set of web services that enables users to create, retrieve, update, and // to create, retrieve, update, and delete Analysis Services servers
// delete Analysis Services servers
type ServersClient struct { type ServersClient struct {
ManagementClient ManagementClient
} }
@ -42,17 +40,14 @@ func NewServersClientWithBaseURI(baseURI string, subscriptionID string) ServersC
return ServersClient{NewWithBaseURI(baseURI, subscriptionID)} return ServersClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// Create provisions the specified Analysis Services server based on the // Create provisions the specified Analysis Services server based on the configuration specified in the request. This
// configuration specified in the request. This method may poll for completion. // method may poll for completion. Polling can be canceled by passing the cancel channel argument. The channel will be
// Polling can be canceled by passing the cancel channel argument. The channel // used to cancel polling and any outstanding HTTP requests.
// will be used to cancel polling and any outstanding HTTP requests.
// //
// resourceGroupName is the name of the Azure Resource group of which a given // resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// Analysis Services server is part. This name must be at least 1 character in // name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// length, and no more than 90. serverName is the name of the Analysis Services // server. It must be a minimum of 3 characters, and a maximum of 63. serverParameters is contains the information used
// server. It must be a minimum of 3 characters, and a maximum of 63. // to provision the Analysis Services server.
// serverParameters is contains the information used to provision the Analysis
// Services server.
func (client ServersClient) Create(resourceGroupName string, serverName string, serverParameters Server, cancel <-chan struct{}) (<-chan Server, <-chan error) { func (client ServersClient) Create(resourceGroupName string, serverName string, serverParameters Server, cancel <-chan struct{}) (<-chan Server, <-chan error) {
resultChan := make(chan Server, 1) resultChan := make(chan Server, 1)
errChan := make(chan error, 1) errChan := make(chan error, 1)
@ -75,8 +70,10 @@ func (client ServersClient) Create(resourceGroupName string, serverName string,
var err error var err error
var result Server var result Server
defer func() { defer func() {
if err != nil {
errChan <- err
}
resultChan <- result resultChan <- result
errChan <- err
close(resultChan) close(resultChan)
close(errChan) close(errChan)
}() }()
@ -109,7 +106,7 @@ func (client ServersClient) CreatePreparer(resourceGroupName string, serverName
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2016-05-16" const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
@ -145,14 +142,12 @@ func (client ServersClient) CreateResponder(resp *http.Response) (result Server,
return return
} }
// Delete deletes the specified Analysis Services server. This method may poll // Delete deletes the specified Analysis Services server. This method may poll for completion. Polling can be canceled
// for completion. Polling can be canceled by passing the cancel channel // by passing the cancel channel argument. The channel will be used to cancel polling and any outstanding HTTP
// argument. The channel will be used to cancel polling and any outstanding // requests.
// HTTP requests.
// //
// resourceGroupName is the name of the Azure Resource group of which a given // resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// Analysis Services server is part. This name must be at least 1 character in // name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// length, and no more than 90. serverName is the name of the Analysis Services
// server. It must be at least 3 characters in length, and no more than 63. // server. It must be at least 3 characters in length, and no more than 63.
func (client ServersClient) Delete(resourceGroupName string, serverName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) { func (client ServersClient) Delete(resourceGroupName string, serverName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) {
resultChan := make(chan autorest.Response, 1) resultChan := make(chan autorest.Response, 1)
@ -176,8 +171,10 @@ func (client ServersClient) Delete(resourceGroupName string, serverName string,
var err error var err error
var result autorest.Response var result autorest.Response
defer func() { defer func() {
if err != nil {
errChan <- err
}
resultChan <- result resultChan <- result
errChan <- err
close(resultChan) close(resultChan)
close(errChan) close(errChan)
}() }()
@ -210,7 +207,7 @@ func (client ServersClient) DeletePreparer(resourceGroupName string, serverName
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2016-05-16" const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
@ -243,11 +240,88 @@ func (client ServersClient) DeleteResponder(resp *http.Response) (result autores
return return
} }
// DissociateGateway dissociates a Unified Gateway associated with the server.
//
// resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// server. It must be at least 3 characters in length, and no more than 63.
func (client ServersClient) DissociateGateway(resourceGroupName string, serverName string) (result autorest.Response, err error) {
if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName,
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
{TargetValue: serverName,
Constraints: []validation.Constraint{{Target: "serverName", Name: validation.MaxLength, Rule: 63, Chain: nil},
{Target: "serverName", Name: validation.MinLength, Rule: 3, Chain: nil},
{Target: "serverName", Name: validation.Pattern, Rule: `^[a-z][a-z0-9]*$`, Chain: nil}}}}); err != nil {
return result, validation.NewErrorWithValidationError(err, "analysisservices.ServersClient", "DissociateGateway")
}
req, err := client.DissociateGatewayPreparer(resourceGroupName, serverName)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "DissociateGateway", nil, "Failure preparing request")
return
}
resp, err := client.DissociateGatewaySender(req)
if err != nil {
result.Response = resp
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "DissociateGateway", resp, "Failure sending request")
return
}
result, err = client.DissociateGatewayResponder(resp)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "DissociateGateway", resp, "Failure responding to request")
}
return
}
// DissociateGatewayPreparer prepares the DissociateGateway request.
func (client ServersClient) DissociateGatewayPreparer(resourceGroupName string, serverName string) (*http.Request, error) {
pathParameters := map[string]interface{}{
"resourceGroupName": autorest.Encode("path", resourceGroupName),
"serverName": autorest.Encode("path", serverName),
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
}
const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{
"api-version": APIVersion,
}
preparer := autorest.CreatePreparer(
autorest.AsPost(),
autorest.WithBaseURL(client.BaseURI),
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AnalysisServices/servers/{serverName}/dissociateGateway", pathParameters),
autorest.WithQueryParameters(queryParameters))
return preparer.Prepare(&http.Request{})
}
// DissociateGatewaySender sends the DissociateGateway request. The method will close the
// http.Response Body if it receives an error.
func (client ServersClient) DissociateGatewaySender(req *http.Request) (*http.Response, error) {
return autorest.SendWithSender(client, req)
}
// DissociateGatewayResponder handles the response to the DissociateGateway request. The method always
// closes the http.Response Body.
func (client ServersClient) DissociateGatewayResponder(resp *http.Response) (result autorest.Response, err error) {
err = autorest.Respond(
resp,
client.ByInspecting(),
azure.WithErrorUnlessStatusCode(http.StatusOK),
autorest.ByClosing())
result.Response = resp
return
}
// GetDetails gets details about the specified Analysis Services server. // GetDetails gets details about the specified Analysis Services server.
// //
// resourceGroupName is the name of the Azure Resource group of which a given // resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// Analysis Services server is part. This name must be at least 1 character in // name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// length, and no more than 90. serverName is the name of the Analysis Services
// server. It must be a minimum of 3 characters, and a maximum of 63. // server. It must be a minimum of 3 characters, and a maximum of 63.
func (client ServersClient) GetDetails(resourceGroupName string, serverName string) (result Server, err error) { func (client ServersClient) GetDetails(resourceGroupName string, serverName string) (result Server, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
@ -291,7 +365,7 @@ func (client ServersClient) GetDetailsPreparer(resourceGroupName string, serverN
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2016-05-16" const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
@ -352,7 +426,7 @@ func (client ServersClient) ListPreparer() (*http.Request, error) {
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2016-05-16" const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
@ -384,12 +458,10 @@ func (client ServersClient) ListResponder(resp *http.Response) (result Servers,
return return
} }
// ListByResourceGroup gets all the Analysis Services servers for the given // ListByResourceGroup gets all the Analysis Services servers for the given resource group.
// resource group.
// //
// resourceGroupName is the name of the Azure Resource group of which a given // resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// Analysis Services server is part. This name must be at least 1 character in // name must be at least 1 character in length, and no more than 90.
// length, and no more than 90.
func (client ServersClient) ListByResourceGroup(resourceGroupName string) (result Servers, err error) { func (client ServersClient) ListByResourceGroup(resourceGroupName string) (result Servers, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -427,7 +499,7 @@ func (client ServersClient) ListByResourceGroupPreparer(resourceGroupName string
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2016-05-16" const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
@ -459,14 +531,231 @@ func (client ServersClient) ListByResourceGroupResponder(resp *http.Response) (r
return return
} }
// Resume resumes operation of the specified Analysis Services server instance. // ListGatewayStatus return the gateway status of the specified Analysis Services server instance.
// This method may poll for completion. Polling can be canceled by passing the //
// cancel channel argument. The channel will be used to cancel polling and any // resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// server.
func (client ServersClient) ListGatewayStatus(resourceGroupName string, serverName string) (result GatewayListStatusLive, err error) {
if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName,
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
{TargetValue: serverName,
Constraints: []validation.Constraint{{Target: "serverName", Name: validation.MaxLength, Rule: 63, Chain: nil},
{Target: "serverName", Name: validation.MinLength, Rule: 3, Chain: nil},
{Target: "serverName", Name: validation.Pattern, Rule: `^[a-z][a-z0-9]*$`, Chain: nil}}}}); err != nil {
return result, validation.NewErrorWithValidationError(err, "analysisservices.ServersClient", "ListGatewayStatus")
}
req, err := client.ListGatewayStatusPreparer(resourceGroupName, serverName)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListGatewayStatus", nil, "Failure preparing request")
return
}
resp, err := client.ListGatewayStatusSender(req)
if err != nil {
result.Response = autorest.Response{Response: resp}
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListGatewayStatus", resp, "Failure sending request")
return
}
result, err = client.ListGatewayStatusResponder(resp)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListGatewayStatus", resp, "Failure responding to request")
}
return
}
// ListGatewayStatusPreparer prepares the ListGatewayStatus request.
func (client ServersClient) ListGatewayStatusPreparer(resourceGroupName string, serverName string) (*http.Request, error) {
pathParameters := map[string]interface{}{
"resourceGroupName": autorest.Encode("path", resourceGroupName),
"serverName": autorest.Encode("path", serverName),
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
}
const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{
"api-version": APIVersion,
}
preparer := autorest.CreatePreparer(
autorest.AsPost(),
autorest.WithBaseURL(client.BaseURI),
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AnalysisServices/servers/{serverName}/listGatewayStatus", pathParameters),
autorest.WithQueryParameters(queryParameters))
return preparer.Prepare(&http.Request{})
}
// ListGatewayStatusSender sends the ListGatewayStatus request. The method will close the
// http.Response Body if it receives an error.
func (client ServersClient) ListGatewayStatusSender(req *http.Request) (*http.Response, error) {
return autorest.SendWithSender(client, req)
}
// ListGatewayStatusResponder handles the response to the ListGatewayStatus request. The method always
// closes the http.Response Body.
func (client ServersClient) ListGatewayStatusResponder(resp *http.Response) (result GatewayListStatusLive, err error) {
err = autorest.Respond(
resp,
client.ByInspecting(),
azure.WithErrorUnlessStatusCode(http.StatusOK),
autorest.ByUnmarshallingJSON(&result),
autorest.ByClosing())
result.Response = autorest.Response{Response: resp}
return
}
// ListSkusForExisting lists eligible SKUs for an Analysis Services resource.
//
// resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// server. It must be at least 3 characters in length, and no more than 63.
func (client ServersClient) ListSkusForExisting(resourceGroupName string, serverName string) (result SkuEnumerationForExistingResourceResult, err error) {
if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName,
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
{TargetValue: serverName,
Constraints: []validation.Constraint{{Target: "serverName", Name: validation.MaxLength, Rule: 63, Chain: nil},
{Target: "serverName", Name: validation.MinLength, Rule: 3, Chain: nil},
{Target: "serverName", Name: validation.Pattern, Rule: `^[a-z][a-z0-9]*$`, Chain: nil}}}}); err != nil {
return result, validation.NewErrorWithValidationError(err, "analysisservices.ServersClient", "ListSkusForExisting")
}
req, err := client.ListSkusForExistingPreparer(resourceGroupName, serverName)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListSkusForExisting", nil, "Failure preparing request")
return
}
resp, err := client.ListSkusForExistingSender(req)
if err != nil {
result.Response = autorest.Response{Response: resp}
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListSkusForExisting", resp, "Failure sending request")
return
}
result, err = client.ListSkusForExistingResponder(resp)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListSkusForExisting", resp, "Failure responding to request")
}
return
}
// ListSkusForExistingPreparer prepares the ListSkusForExisting request.
func (client ServersClient) ListSkusForExistingPreparer(resourceGroupName string, serverName string) (*http.Request, error) {
pathParameters := map[string]interface{}{
"resourceGroupName": autorest.Encode("path", resourceGroupName),
"serverName": autorest.Encode("path", serverName),
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
}
const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{
"api-version": APIVersion,
}
preparer := autorest.CreatePreparer(
autorest.AsGet(),
autorest.WithBaseURL(client.BaseURI),
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AnalysisServices/servers/{serverName}/skus", pathParameters),
autorest.WithQueryParameters(queryParameters))
return preparer.Prepare(&http.Request{})
}
// ListSkusForExistingSender sends the ListSkusForExisting request. The method will close the
// http.Response Body if it receives an error.
func (client ServersClient) ListSkusForExistingSender(req *http.Request) (*http.Response, error) {
return autorest.SendWithSender(client, req)
}
// ListSkusForExistingResponder handles the response to the ListSkusForExisting request. The method always
// closes the http.Response Body.
func (client ServersClient) ListSkusForExistingResponder(resp *http.Response) (result SkuEnumerationForExistingResourceResult, err error) {
err = autorest.Respond(
resp,
client.ByInspecting(),
azure.WithErrorUnlessStatusCode(http.StatusOK),
autorest.ByUnmarshallingJSON(&result),
autorest.ByClosing())
result.Response = autorest.Response{Response: resp}
return
}
// ListSkusForNew lists eligible SKUs for Analysis Services resource provider.
func (client ServersClient) ListSkusForNew() (result SkuEnumerationForNewResourceResult, err error) {
req, err := client.ListSkusForNewPreparer()
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListSkusForNew", nil, "Failure preparing request")
return
}
resp, err := client.ListSkusForNewSender(req)
if err != nil {
result.Response = autorest.Response{Response: resp}
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListSkusForNew", resp, "Failure sending request")
return
}
result, err = client.ListSkusForNewResponder(resp)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "ListSkusForNew", resp, "Failure responding to request")
}
return
}
// ListSkusForNewPreparer prepares the ListSkusForNew request.
func (client ServersClient) ListSkusForNewPreparer() (*http.Request, error) {
pathParameters := map[string]interface{}{
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
}
const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{
"api-version": APIVersion,
}
preparer := autorest.CreatePreparer(
autorest.AsGet(),
autorest.WithBaseURL(client.BaseURI),
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.AnalysisServices/skus", pathParameters),
autorest.WithQueryParameters(queryParameters))
return preparer.Prepare(&http.Request{})
}
// ListSkusForNewSender sends the ListSkusForNew request. The method will close the
// http.Response Body if it receives an error.
func (client ServersClient) ListSkusForNewSender(req *http.Request) (*http.Response, error) {
return autorest.SendWithSender(client, req)
}
// ListSkusForNewResponder handles the response to the ListSkusForNew request. The method always
// closes the http.Response Body.
func (client ServersClient) ListSkusForNewResponder(resp *http.Response) (result SkuEnumerationForNewResourceResult, err error) {
err = autorest.Respond(
resp,
client.ByInspecting(),
azure.WithErrorUnlessStatusCode(http.StatusOK),
autorest.ByUnmarshallingJSON(&result),
autorest.ByClosing())
result.Response = autorest.Response{Response: resp}
return
}
// Resume resumes operation of the specified Analysis Services server instance. This method may poll for completion.
// Polling can be canceled by passing the cancel channel argument. The channel will be used to cancel polling and any
// outstanding HTTP requests. // outstanding HTTP requests.
// //
// resourceGroupName is the name of the Azure Resource group of which a given // resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// Analysis Services server is part. This name must be at least 1 character in // name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// length, and no more than 90. serverName is the name of the Analysis Services
// server. It must be at least 3 characters in length, and no more than 63. // server. It must be at least 3 characters in length, and no more than 63.
func (client ServersClient) Resume(resourceGroupName string, serverName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) { func (client ServersClient) Resume(resourceGroupName string, serverName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) {
resultChan := make(chan autorest.Response, 1) resultChan := make(chan autorest.Response, 1)
@ -490,8 +779,10 @@ func (client ServersClient) Resume(resourceGroupName string, serverName string,
var err error var err error
var result autorest.Response var result autorest.Response
defer func() { defer func() {
if err != nil {
errChan <- err
}
resultChan <- result resultChan <- result
errChan <- err
close(resultChan) close(resultChan)
close(errChan) close(errChan)
}() }()
@ -524,7 +815,7 @@ func (client ServersClient) ResumePreparer(resourceGroupName string, serverName
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2016-05-16" const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
@ -557,14 +848,12 @@ func (client ServersClient) ResumeResponder(resp *http.Response) (result autores
return return
} }
// Suspend supends operation of the specified Analysis Services server // Suspend supends operation of the specified Analysis Services server instance. This method may poll for completion.
// instance. This method may poll for completion. Polling can be canceled by // Polling can be canceled by passing the cancel channel argument. The channel will be used to cancel polling and any
// passing the cancel channel argument. The channel will be used to cancel // outstanding HTTP requests.
// polling and any outstanding HTTP requests.
// //
// resourceGroupName is the name of the Azure Resource group of which a given // resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// Analysis Services server is part. This name must be at least 1 character in // name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// length, and no more than 90. serverName is the name of the Analysis Services
// server. It must be at least 3 characters in length, and no more than 63. // server. It must be at least 3 characters in length, and no more than 63.
func (client ServersClient) Suspend(resourceGroupName string, serverName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) { func (client ServersClient) Suspend(resourceGroupName string, serverName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) {
resultChan := make(chan autorest.Response, 1) resultChan := make(chan autorest.Response, 1)
@ -588,8 +877,10 @@ func (client ServersClient) Suspend(resourceGroupName string, serverName string,
var err error var err error
var result autorest.Response var result autorest.Response
defer func() { defer func() {
if err != nil {
errChan <- err
}
resultChan <- result resultChan <- result
errChan <- err
close(resultChan) close(resultChan)
close(errChan) close(errChan)
}() }()
@ -622,7 +913,7 @@ func (client ServersClient) SuspendPreparer(resourceGroupName string, serverName
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2016-05-16" const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
@ -655,15 +946,17 @@ func (client ServersClient) SuspendResponder(resp *http.Response) (result autore
return return
} }
// Update updates the current state of the specified Analysis Services server. // Update updates the current state of the specified Analysis Services server. This method may poll for completion.
// Polling can be canceled by passing the cancel channel argument. The channel will be used to cancel polling and any
// outstanding HTTP requests.
// //
// resourceGroupName is the name of the Azure Resource group of which a given // resourceGroupName is the name of the Azure Resource group of which a given Analysis Services server is part. This
// Analysis Services server is part. This name must be at least 1 character in // name must be at least 1 character in length, and no more than 90. serverName is the name of the Analysis Services
// length, and no more than 90. serverName is the name of the Analysis Services // server. It must be at least 3 characters in length, and no more than 63. serverUpdateParameters is request object
// server. It must be at least 3 characters in length, and no more than 63. // that contains the updated information for the server.
// serverUpdateParameters is request object that contains the updated func (client ServersClient) Update(resourceGroupName string, serverName string, serverUpdateParameters ServerUpdateParameters, cancel <-chan struct{}) (<-chan Server, <-chan error) {
// information for the server. resultChan := make(chan Server, 1)
func (client ServersClient) Update(resourceGroupName string, serverName string, serverUpdateParameters ServerUpdateParameters) (result Server, err error) { errChan := make(chan error, 1)
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
@ -673,39 +966,53 @@ func (client ServersClient) Update(resourceGroupName string, serverName string,
Constraints: []validation.Constraint{{Target: "serverName", Name: validation.MaxLength, Rule: 63, Chain: nil}, Constraints: []validation.Constraint{{Target: "serverName", Name: validation.MaxLength, Rule: 63, Chain: nil},
{Target: "serverName", Name: validation.MinLength, Rule: 3, Chain: nil}, {Target: "serverName", Name: validation.MinLength, Rule: 3, Chain: nil},
{Target: "serverName", Name: validation.Pattern, Rule: `^[a-z][a-z0-9]*$`, Chain: nil}}}}); err != nil { {Target: "serverName", Name: validation.Pattern, Rule: `^[a-z][a-z0-9]*$`, Chain: nil}}}}); err != nil {
return result, validation.NewErrorWithValidationError(err, "analysisservices.ServersClient", "Update") errChan <- validation.NewErrorWithValidationError(err, "analysisservices.ServersClient", "Update")
close(errChan)
close(resultChan)
return resultChan, errChan
} }
req, err := client.UpdatePreparer(resourceGroupName, serverName, serverUpdateParameters) go func() {
if err != nil { var err error
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "Update", nil, "Failure preparing request") var result Server
return defer func() {
} if err != nil {
errChan <- err
}
resultChan <- result
close(resultChan)
close(errChan)
}()
req, err := client.UpdatePreparer(resourceGroupName, serverName, serverUpdateParameters, cancel)
if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "Update", nil, "Failure preparing request")
return
}
resp, err := client.UpdateSender(req) resp, err := client.UpdateSender(req)
if err != nil { if err != nil {
result.Response = autorest.Response{Response: resp} result.Response = autorest.Response{Response: resp}
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "Update", resp, "Failure sending request") err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "Update", resp, "Failure sending request")
return return
} }
result, err = client.UpdateResponder(resp) result, err = client.UpdateResponder(resp)
if err != nil { if err != nil {
err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "Update", resp, "Failure responding to request") err = autorest.NewErrorWithError(err, "analysisservices.ServersClient", "Update", resp, "Failure responding to request")
} }
}()
return return resultChan, errChan
} }
// UpdatePreparer prepares the Update request. // UpdatePreparer prepares the Update request.
func (client ServersClient) UpdatePreparer(resourceGroupName string, serverName string, serverUpdateParameters ServerUpdateParameters) (*http.Request, error) { func (client ServersClient) UpdatePreparer(resourceGroupName string, serverName string, serverUpdateParameters ServerUpdateParameters, cancel <-chan struct{}) (*http.Request, error) {
pathParameters := map[string]interface{}{ pathParameters := map[string]interface{}{
"resourceGroupName": autorest.Encode("path", resourceGroupName), "resourceGroupName": autorest.Encode("path", resourceGroupName),
"serverName": autorest.Encode("path", serverName), "serverName": autorest.Encode("path", serverName),
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2016-05-16" const APIVersion = "2017-08-01-beta"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
@ -717,13 +1024,15 @@ func (client ServersClient) UpdatePreparer(resourceGroupName string, serverName
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AnalysisServices/servers/{serverName}", pathParameters), autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.AnalysisServices/servers/{serverName}", pathParameters),
autorest.WithJSON(serverUpdateParameters), autorest.WithJSON(serverUpdateParameters),
autorest.WithQueryParameters(queryParameters)) autorest.WithQueryParameters(queryParameters))
return preparer.Prepare(&http.Request{}) return preparer.Prepare(&http.Request{Cancel: cancel})
} }
// UpdateSender sends the Update request. The method will close the // UpdateSender sends the Update request. The method will close the
// http.Response Body if it receives an error. // http.Response Body if it receives an error.
func (client ServersClient) UpdateSender(req *http.Request) (*http.Response, error) { func (client ServersClient) UpdateSender(req *http.Request) (*http.Response, error) {
return autorest.SendWithSender(client, req) return autorest.SendWithSender(client,
req,
azure.DoPollForAsynchronous(client.PollingDelay))
} }
// UpdateResponder handles the response to the Update request. The method always // UpdateResponder handles the response to the Update request. The method always
@ -732,7 +1041,7 @@ func (client ServersClient) UpdateResponder(resp *http.Response) (result Server,
err = autorest.Respond( err = autorest.Respond(
resp, resp,
client.ByInspecting(), client.ByInspecting(),
azure.WithErrorUnlessStatusCode(http.StatusOK), azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
autorest.ByUnmarshallingJSON(&result), autorest.ByUnmarshallingJSON(&result),
autorest.ByClosing()) autorest.ByClosing())
result.Response = autorest.Response{Response: resp} result.Response = autorest.Response{Response: resp}

View File

@ -14,15 +14,15 @@ package analysisservices
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 2.2.18.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated. // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// UserAgent returns the UserAgent string to use when sending http.Requests. // UserAgent returns the UserAgent string to use when sending http.Requests.
func UserAgent() string { func UserAgent() string {
return "Azure-SDK-For-Go/v10.3.1-beta arm-analysisservices/2017-08-01-beta" return "Azure-SDK-For-Go/v11.0.0-beta arm-analysisservices/2017-08-01-beta"
} }
// Version returns the semantic version (see http://semver.org) of the client. // Version returns the semantic version (see http://semver.org) of the client.
func Version() string { func Version() string {
return "v10.3.1-beta" return "v11.0.0-beta"
} }

View File

@ -1,5 +1,4 @@
// Package appinsights implements the Azure ARM Appinsights service API version // Package appinsights implements the Azure ARM Appinsights service API version 2015-05-01.
// .
// //
// Composite Swagger for Application Insights Management Client // Composite Swagger for Application Insights Management Client
package appinsights package appinsights
@ -18,9 +17,8 @@ package appinsights
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"

View File

@ -14,9 +14,8 @@ package appinsights
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,8 +24,7 @@ import (
"net/http" "net/http"
) )
// ComponentsClient is the composite Swagger for Application Insights // ComponentsClient is the composite Swagger for Application Insights Management Client
// Management Client
type ComponentsClient struct { type ComponentsClient struct {
ManagementClient ManagementClient
} }
@ -36,20 +34,16 @@ func NewComponentsClient(subscriptionID string) ComponentsClient {
return NewComponentsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewComponentsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewComponentsClientWithBaseURI creates an instance of the ComponentsClient // NewComponentsClientWithBaseURI creates an instance of the ComponentsClient client.
// client.
func NewComponentsClientWithBaseURI(baseURI string, subscriptionID string) ComponentsClient { func NewComponentsClientWithBaseURI(baseURI string, subscriptionID string) ComponentsClient {
return ComponentsClient{NewWithBaseURI(baseURI, subscriptionID)} return ComponentsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// CreateOrUpdate creates (or updates) an Application Insights component. Note: // CreateOrUpdate creates (or updates) an Application Insights component. Note: You cannot specify a different value
// You cannot specify a different value for InstrumentationKey nor AppId in the // for InstrumentationKey nor AppId in the Put operation.
// Put operation.
// //
// resourceGroupName is the name of the resource group. resourceName is the // resourceGroupName is the name of the resource group. resourceName is the name of the Application Insights component
// name of the Application Insights component resource. insightProperties is // resource. insightProperties is properties that need to be specified to create an Application Insights component.
// properties that need to be specified to create an Application Insights
// component.
func (client ComponentsClient) CreateOrUpdate(resourceGroupName string, resourceName string, insightProperties ApplicationInsightsComponent) (result ApplicationInsightsComponent, err error) { func (client ComponentsClient) CreateOrUpdate(resourceGroupName string, resourceName string, insightProperties ApplicationInsightsComponent) (result ApplicationInsightsComponent, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: insightProperties, {TargetValue: insightProperties,
@ -122,8 +116,8 @@ func (client ComponentsClient) CreateOrUpdateResponder(resp *http.Response) (res
// Delete deletes an Application Insights component. // Delete deletes an Application Insights component.
// //
// resourceGroupName is the name of the resource group. resourceName is the // resourceGroupName is the name of the resource group. resourceName is the name of the Application Insights component
// name of the Application Insights component resource. // resource.
func (client ComponentsClient) Delete(resourceGroupName string, resourceName string) (result autorest.Response, err error) { func (client ComponentsClient) Delete(resourceGroupName string, resourceName string) (result autorest.Response, err error) {
req, err := client.DeletePreparer(resourceGroupName, resourceName) req, err := client.DeletePreparer(resourceGroupName, resourceName)
if err != nil { if err != nil {
@ -187,8 +181,8 @@ func (client ComponentsClient) DeleteResponder(resp *http.Response) (result auto
// Get returns an Application Insights component. // Get returns an Application Insights component.
// //
// resourceGroupName is the name of the resource group. resourceName is the // resourceGroupName is the name of the resource group. resourceName is the name of the Application Insights component
// name of the Application Insights component resource. // resource.
func (client ComponentsClient) Get(resourceGroupName string, resourceName string) (result ApplicationInsightsComponent, err error) { func (client ComponentsClient) Get(resourceGroupName string, resourceName string) (result ApplicationInsightsComponent, err error) {
req, err := client.GetPreparer(resourceGroupName, resourceName) req, err := client.GetPreparer(resourceGroupName, resourceName)
if err != nil { if err != nil {
@ -251,8 +245,7 @@ func (client ComponentsClient) GetResponder(resp *http.Response) (result Applica
return return
} }
// List gets a list of all Application Insights components within a // List gets a list of all Application Insights components within a subscription.
// subscription.
func (client ComponentsClient) List() (result ApplicationInsightsComponentListResult, err error) { func (client ComponentsClient) List() (result ApplicationInsightsComponentListResult, err error) {
req, err := client.ListPreparer() req, err := client.ListPreparer()
if err != nil { if err != nil {
@ -337,8 +330,52 @@ func (client ComponentsClient) ListNextResults(lastResults ApplicationInsightsCo
return return
} }
// ListByResourceGroup gets a list of Application Insights components within a // ListComplete gets all elements from the list without paging.
// resource group. func (client ComponentsClient) ListComplete(cancel <-chan struct{}) (<-chan ApplicationInsightsComponent, <-chan error) {
resultChan := make(chan ApplicationInsightsComponent)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List()
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// ListByResourceGroup gets a list of Application Insights components within a resource group.
// //
// resourceGroupName is the name of the resource group. // resourceGroupName is the name of the resource group.
func (client ComponentsClient) ListByResourceGroup(resourceGroupName string) (result ApplicationInsightsComponentListResult, err error) { func (client ComponentsClient) ListByResourceGroup(resourceGroupName string) (result ApplicationInsightsComponentListResult, err error) {
@ -426,12 +463,55 @@ func (client ComponentsClient) ListByResourceGroupNextResults(lastResults Applic
return return
} }
// UpdateTags updates an existing component's tags. To update other fields use // ListByResourceGroupComplete gets all elements from the list without paging.
// the CreateOrUpdate method. func (client ComponentsClient) ListByResourceGroupComplete(resourceGroupName string, cancel <-chan struct{}) (<-chan ApplicationInsightsComponent, <-chan error) {
resultChan := make(chan ApplicationInsightsComponent)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByResourceGroup(resourceGroupName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByResourceGroupNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// UpdateTags updates an existing component's tags. To update other fields use the CreateOrUpdate method.
// //
// resourceGroupName is the name of the resource group. resourceName is the // resourceGroupName is the name of the resource group. resourceName is the name of the Application Insights component
// name of the Application Insights component resource. componentTags is // resource. componentTags is updated tag information to set into the component instance.
// updated tag information to set into the component instance.
func (client ComponentsClient) UpdateTags(resourceGroupName string, resourceName string, componentTags TagsResource) (result ApplicationInsightsComponent, err error) { func (client ComponentsClient) UpdateTags(resourceGroupName string, resourceName string, componentTags TagsResource) (result ApplicationInsightsComponent, err error) {
req, err := client.UpdateTagsPreparer(resourceGroupName, resourceName, componentTags) req, err := client.UpdateTagsPreparer(resourceGroupName, resourceName, componentTags)
if err != nil { if err != nil {

View File

@ -14,9 +14,8 @@ package appinsights
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -61,8 +60,7 @@ const (
Ping WebTestKind = "ping" Ping WebTestKind = "ping"
) )
// ApplicationInsightsComponent is an Application Insights component // ApplicationInsightsComponent is an Application Insights component definition.
// definition.
type ApplicationInsightsComponent struct { type ApplicationInsightsComponent struct {
autorest.Response `json:"-"` autorest.Response `json:"-"`
ID *string `json:"id,omitempty"` ID *string `json:"id,omitempty"`
@ -74,8 +72,7 @@ type ApplicationInsightsComponent struct {
*ApplicationInsightsComponentProperties `json:"properties,omitempty"` *ApplicationInsightsComponentProperties `json:"properties,omitempty"`
} }
// ApplicationInsightsComponentListResult is describes the list of Application // ApplicationInsightsComponentListResult is describes the list of Application Insights Resources.
// Insights Resources.
type ApplicationInsightsComponentListResult struct { type ApplicationInsightsComponentListResult struct {
autorest.Response `json:"-"` autorest.Response `json:"-"`
Value *[]ApplicationInsightsComponent `json:"value,omitempty"` Value *[]ApplicationInsightsComponent `json:"value,omitempty"`
@ -94,8 +91,7 @@ func (client ApplicationInsightsComponentListResult) ApplicationInsightsComponen
autorest.WithBaseURL(to.String(client.NextLink))) autorest.WithBaseURL(to.String(client.NextLink)))
} }
// ApplicationInsightsComponentProperties is properties that define an // ApplicationInsightsComponentProperties is properties that define an Application Insights component resource.
// Application Insights component resource.
type ApplicationInsightsComponentProperties struct { type ApplicationInsightsComponentProperties struct {
ApplicationID *string `json:"ApplicationId,omitempty"` ApplicationID *string `json:"ApplicationId,omitempty"`
AppID *string `json:"AppId,omitempty"` AppID *string `json:"AppId,omitempty"`
@ -111,14 +107,14 @@ type ApplicationInsightsComponentProperties struct {
SamplingPercentage *float64 `json:"SamplingPercentage,omitempty"` SamplingPercentage *float64 `json:"SamplingPercentage,omitempty"`
} }
// ErrorResponse is error reponse indicates Insights service is not able to // ErrorResponse is error reponse indicates Insights service is not able to process the incoming request. The reason is
// process the incoming request. The reason is provided in the error message. // provided in the error message.
type ErrorResponse struct { type ErrorResponse struct {
Code *string `json:"code,omitempty"` Code *string `json:"code,omitempty"`
Message *string `json:"message,omitempty"` Message *string `json:"message,omitempty"`
} }
// Operation is cDN REST API operation // Operation is CDN REST API operation
type Operation struct { type Operation struct {
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
Display *OperationDisplay `json:"display,omitempty"` Display *OperationDisplay `json:"display,omitempty"`
@ -131,8 +127,8 @@ type OperationDisplay struct {
Operation *string `json:"operation,omitempty"` Operation *string `json:"operation,omitempty"`
} }
// OperationListResult is result of the request to list CDN operations. It // OperationListResult is result of the request to list CDN operations. It contains a list of operations and a URL link
// contains a list of operations and a URL link to get the next set of results. // to get the next set of results.
type OperationListResult struct { type OperationListResult struct {
autorest.Response `json:"-"` autorest.Response `json:"-"`
Value *[]Operation `json:"value,omitempty"` Value *[]Operation `json:"value,omitempty"`
@ -160,8 +156,8 @@ type Resource struct {
Tags *map[string]*string `json:"tags,omitempty"` Tags *map[string]*string `json:"tags,omitempty"`
} }
// TagsResource is a container holding only the Tags for a resource, allowing // TagsResource is a container holding only the Tags for a resource, allowing the user to update the tags on a WebTest
// the user to update the tags on a WebTest instance. // instance.
type TagsResource struct { type TagsResource struct {
Tags *map[string]*string `json:"tags,omitempty"` Tags *map[string]*string `json:"tags,omitempty"`
} }
@ -178,14 +174,13 @@ type WebTest struct {
*WebTestProperties `json:"properties,omitempty"` *WebTestProperties `json:"properties,omitempty"`
} }
// WebTestGeolocation is geo-physical location to run a web test from. You must // WebTestGeolocation is geo-physical location to run a web test from. You must specify one or more locations for the
// specify one or more locations for the test to run from. // test to run from.
type WebTestGeolocation struct { type WebTestGeolocation struct {
Location *string `json:"Id,omitempty"` Location *string `json:"Id,omitempty"`
} }
// WebTestListResult is a list of 0 or more Application Insights web test // WebTestListResult is a list of 0 or more Application Insights web test definitions.
// definitions.
type WebTestListResult struct { type WebTestListResult struct {
autorest.Response `json:"-"` autorest.Response `json:"-"`
Value *[]WebTest `json:"value,omitempty"` Value *[]WebTest `json:"value,omitempty"`
@ -219,8 +214,7 @@ type WebTestProperties struct {
ProvisioningState *string `json:"provisioningState,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"`
} }
// WebTestPropertiesConfiguration is an XML configuration specification for a // WebTestPropertiesConfiguration is an XML configuration specification for a WebTest.
// WebTest.
type WebTestPropertiesConfiguration struct { type WebTestPropertiesConfiguration struct {
WebTest *string `json:"WebTest,omitempty"` WebTest *string `json:"WebTest,omitempty"`
} }

View File

@ -14,9 +14,8 @@ package appinsights
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -24,8 +23,7 @@ import (
"net/http" "net/http"
) )
// OperationsClient is the composite Swagger for Application Insights // OperationsClient is the composite Swagger for Application Insights Management Client
// Management Client
type OperationsClient struct { type OperationsClient struct {
ManagementClient ManagementClient
} }
@ -35,8 +33,7 @@ func NewOperationsClient(subscriptionID string) OperationsClient {
return NewOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewOperationsClientWithBaseURI creates an instance of the OperationsClient // NewOperationsClientWithBaseURI creates an instance of the OperationsClient client.
// client.
func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string) OperationsClient { func NewOperationsClientWithBaseURI(baseURI string, subscriptionID string) OperationsClient {
return OperationsClient{NewWithBaseURI(baseURI, subscriptionID)} return OperationsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
@ -121,3 +118,48 @@ func (client OperationsClient) ListNextResults(lastResults OperationListResult)
return return
} }
// ListComplete gets all elements from the list without paging.
func (client OperationsClient) ListComplete(cancel <-chan struct{}) (<-chan Operation, <-chan error) {
resultChan := make(chan Operation)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List()
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,15 +14,15 @@ package appinsights
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 2.2.18.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated. // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// UserAgent returns the UserAgent string to use when sending http.Requests. // UserAgent returns the UserAgent string to use when sending http.Requests.
func UserAgent() string { func UserAgent() string {
return "Azure-SDK-For-Go/v10.3.1-beta arm-appinsights/2015-05-01" return "Azure-SDK-For-Go/v11.0.0-beta arm-appinsights/2015-05-01"
} }
// Version returns the semantic version (see http://semver.org) of the client. // Version returns the semantic version (see http://semver.org) of the client.
func Version() string { func Version() string {
return "v10.3.1-beta" return "v11.0.0-beta"
} }

View File

@ -14,9 +14,8 @@ package appinsights
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,8 +24,7 @@ import (
"net/http" "net/http"
) )
// WebTestsClient is the composite Swagger for Application Insights Management // WebTestsClient is the composite Swagger for Application Insights Management Client
// Client
type WebTestsClient struct { type WebTestsClient struct {
ManagementClient ManagementClient
} }
@ -36,19 +34,16 @@ func NewWebTestsClient(subscriptionID string) WebTestsClient {
return NewWebTestsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewWebTestsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewWebTestsClientWithBaseURI creates an instance of the WebTestsClient // NewWebTestsClientWithBaseURI creates an instance of the WebTestsClient client.
// client.
func NewWebTestsClientWithBaseURI(baseURI string, subscriptionID string) WebTestsClient { func NewWebTestsClientWithBaseURI(baseURI string, subscriptionID string) WebTestsClient {
return WebTestsClient{NewWithBaseURI(baseURI, subscriptionID)} return WebTestsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// CreateOrUpdate creates or updates an Application Insights web test // CreateOrUpdate creates or updates an Application Insights web test definition.
// definition.
// //
// resourceGroupName is the name of the resource group. webTestName is the name // resourceGroupName is the name of the resource group. webTestName is the name of the Application Insights webtest
// of the Application Insights webtest resource. webTestDefinition is // resource. webTestDefinition is properties that need to be specified to create or update an Application Insights web
// properties that need to be specified to create or update an Application // test definition.
// Insights web test definition.
func (client WebTestsClient) CreateOrUpdate(resourceGroupName string, webTestName string, webTestDefinition WebTest) (result WebTest, err error) { func (client WebTestsClient) CreateOrUpdate(resourceGroupName string, webTestName string, webTestDefinition WebTest) (result WebTest, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: webTestDefinition, {TargetValue: webTestDefinition,
@ -125,8 +120,8 @@ func (client WebTestsClient) CreateOrUpdateResponder(resp *http.Response) (resul
// Delete deletes an Application Insights web test. // Delete deletes an Application Insights web test.
// //
// resourceGroupName is the name of the resource group. webTestName is the name // resourceGroupName is the name of the resource group. webTestName is the name of the Application Insights webtest
// of the Application Insights webtest resource. // resource.
func (client WebTestsClient) Delete(resourceGroupName string, webTestName string) (result autorest.Response, err error) { func (client WebTestsClient) Delete(resourceGroupName string, webTestName string) (result autorest.Response, err error) {
req, err := client.DeletePreparer(resourceGroupName, webTestName) req, err := client.DeletePreparer(resourceGroupName, webTestName)
if err != nil { if err != nil {
@ -190,8 +185,8 @@ func (client WebTestsClient) DeleteResponder(resp *http.Response) (result autore
// Get get a specific Application Insights web test definition. // Get get a specific Application Insights web test definition.
// //
// resourceGroupName is the name of the resource group. webTestName is the name // resourceGroupName is the name of the resource group. webTestName is the name of the Application Insights webtest
// of the Application Insights webtest resource. // resource.
func (client WebTestsClient) Get(resourceGroupName string, webTestName string) (result WebTest, err error) { func (client WebTestsClient) Get(resourceGroupName string, webTestName string) (result WebTest, err error) {
req, err := client.GetPreparer(resourceGroupName, webTestName) req, err := client.GetPreparer(resourceGroupName, webTestName)
if err != nil { if err != nil {
@ -254,8 +249,7 @@ func (client WebTestsClient) GetResponder(resp *http.Response) (result WebTest,
return return
} }
// List get all Application Insights web test alerts definitioned within a // List get all Application Insights web test alerts definitioned within a subscription.
// subscription.
func (client WebTestsClient) List() (result WebTestListResult, err error) { func (client WebTestsClient) List() (result WebTestListResult, err error) {
req, err := client.ListPreparer() req, err := client.ListPreparer()
if err != nil { if err != nil {
@ -340,8 +334,52 @@ func (client WebTestsClient) ListNextResults(lastResults WebTestListResult) (res
return return
} }
// ListByResourceGroup get all Application Insights web tests defined within a // ListComplete gets all elements from the list without paging.
// specified resource group. func (client WebTestsClient) ListComplete(cancel <-chan struct{}) (<-chan WebTest, <-chan error) {
resultChan := make(chan WebTest)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List()
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// ListByResourceGroup get all Application Insights web tests defined within a specified resource group.
// //
// resourceGroupName is the name of the resource group. // resourceGroupName is the name of the resource group.
func (client WebTestsClient) ListByResourceGroup(resourceGroupName string) (result WebTestListResult, err error) { func (client WebTestsClient) ListByResourceGroup(resourceGroupName string) (result WebTestListResult, err error) {
@ -429,11 +467,55 @@ func (client WebTestsClient) ListByResourceGroupNextResults(lastResults WebTestL
return return
} }
// ListByResourceGroupComplete gets all elements from the list without paging.
func (client WebTestsClient) ListByResourceGroupComplete(resourceGroupName string, cancel <-chan struct{}) (<-chan WebTest, <-chan error) {
resultChan := make(chan WebTest)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByResourceGroup(resourceGroupName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByResourceGroupNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// UpdateTags creates or updates an Application Insights web test definition. // UpdateTags creates or updates an Application Insights web test definition.
// //
// resourceGroupName is the name of the resource group. webTestName is the name // resourceGroupName is the name of the resource group. webTestName is the name of the Application Insights webtest
// of the Application Insights webtest resource. webTestTags is updated tag // resource. webTestTags is updated tag information to set into the web test instance.
// information to set into the web test instance.
func (client WebTestsClient) UpdateTags(resourceGroupName string, webTestName string, webTestTags TagsResource) (result WebTest, err error) { func (client WebTestsClient) UpdateTags(resourceGroupName string, webTestName string, webTestTags TagsResource) (result WebTest, err error) {
req, err := client.UpdateTagsPreparer(resourceGroupName, webTestName, webTestTags) req, err := client.UpdateTagsPreparer(resourceGroupName, webTestName, webTestTags)
if err != nil { if err != nil {

View File

@ -14,9 +14,8 @@ package authorization
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -24,30 +23,25 @@ import (
"net/http" "net/http"
) )
// ClassicAdministratorsClient is the role based access control provides you a // ClassicAdministratorsClient is the role based access control provides you a way to apply granular level policy
// way to apply granular level policy administration down to individual // administration down to individual resources or resource groups. These operations enable you to manage role
// resources or resource groups. These operations enable you to manage role // definitions and role assignments. A role definition describes the set of actions that can be performed on resources.
// definitions and role assignments. A role definition describes the set of // A role assignment grants access to Azure Active Directory users.
// actions that can be performed on resources. A role assignment grants access
// to Azure Active Directory users.
type ClassicAdministratorsClient struct { type ClassicAdministratorsClient struct {
ManagementClient ManagementClient
} }
// NewClassicAdministratorsClient creates an instance of the // NewClassicAdministratorsClient creates an instance of the ClassicAdministratorsClient client.
// ClassicAdministratorsClient client.
func NewClassicAdministratorsClient(subscriptionID string) ClassicAdministratorsClient { func NewClassicAdministratorsClient(subscriptionID string) ClassicAdministratorsClient {
return NewClassicAdministratorsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewClassicAdministratorsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewClassicAdministratorsClientWithBaseURI creates an instance of the // NewClassicAdministratorsClientWithBaseURI creates an instance of the ClassicAdministratorsClient client.
// ClassicAdministratorsClient client.
func NewClassicAdministratorsClientWithBaseURI(baseURI string, subscriptionID string) ClassicAdministratorsClient { func NewClassicAdministratorsClientWithBaseURI(baseURI string, subscriptionID string) ClassicAdministratorsClient {
return ClassicAdministratorsClient{NewWithBaseURI(baseURI, subscriptionID)} return ClassicAdministratorsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// List gets service administrator, account administrator, and // List gets service administrator, account administrator, and co-administrators for the subscription.
// co-administrators for the subscription.
func (client ClassicAdministratorsClient) List() (result ClassicAdministratorListResult, err error) { func (client ClassicAdministratorsClient) List() (result ClassicAdministratorListResult, err error) {
req, err := client.ListPreparer() req, err := client.ListPreparer()
if err != nil { if err != nil {
@ -131,3 +125,48 @@ func (client ClassicAdministratorsClient) ListNextResults(lastResults ClassicAdm
return return
} }
// ListComplete gets all elements from the list without paging.
func (client ClassicAdministratorsClient) ListComplete(cancel <-chan struct{}) (<-chan ClassicAdministrator, <-chan error) {
resultChan := make(chan ClassicAdministrator)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List()
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -1,11 +1,9 @@
// Package authorization implements the Azure ARM Authorization service API // Package authorization implements the Azure ARM Authorization service API version 2015-07-01.
// version 2015-07-01.
// //
// Role based access control provides you a way to apply granular level policy // Role based access control provides you a way to apply granular level policy administration down to individual
// administration down to individual resources or resource groups. These // resources or resource groups. These operations enable you to manage role definitions and role assignments. A role
// operations enable you to manage role definitions and role assignments. A // definition describes the set of actions that can be performed on resources. A role assignment grants access to Azure
// role definition describes the set of actions that can be performed on // Active Directory users.
// resources. A role assignment grants access to Azure Active Directory users.
package authorization package authorization
// Copyright (c) Microsoft and contributors. All rights reserved. // Copyright (c) Microsoft and contributors. All rights reserved.
@ -22,9 +20,8 @@ package authorization
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"

View File

@ -14,9 +14,8 @@ package authorization
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -32,8 +31,7 @@ type ClassicAdministrator struct {
Properties *ClassicAdministratorProperties `json:"properties,omitempty"` Properties *ClassicAdministratorProperties `json:"properties,omitempty"`
} }
// ClassicAdministratorListResult is classicAdministrator list result // ClassicAdministratorListResult is classicAdministrator list result information.
// information.
type ClassicAdministratorListResult struct { type ClassicAdministratorListResult struct {
autorest.Response `json:"-"` autorest.Response `json:"-"`
Value *[]ClassicAdministrator `json:"value,omitempty"` Value *[]ClassicAdministrator `json:"value,omitempty"`

View File

@ -14,9 +14,8 @@ package authorization
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -24,12 +23,10 @@ import (
"net/http" "net/http"
) )
// PermissionsClient is the role based access control provides you a way to // PermissionsClient is the role based access control provides you a way to apply granular level policy administration
// apply granular level policy administration down to individual resources or // down to individual resources or resource groups. These operations enable you to manage role definitions and role
// resource groups. These operations enable you to manage role definitions and // assignments. A role definition describes the set of actions that can be performed on resources. A role assignment
// role assignments. A role definition describes the set of actions that can be // grants access to Azure Active Directory users.
// performed on resources. A role assignment grants access to Azure Active
// Directory users.
type PermissionsClient struct { type PermissionsClient struct {
ManagementClient ManagementClient
} }
@ -39,19 +36,17 @@ func NewPermissionsClient(subscriptionID string) PermissionsClient {
return NewPermissionsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewPermissionsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewPermissionsClientWithBaseURI creates an instance of the PermissionsClient // NewPermissionsClientWithBaseURI creates an instance of the PermissionsClient client.
// client.
func NewPermissionsClientWithBaseURI(baseURI string, subscriptionID string) PermissionsClient { func NewPermissionsClientWithBaseURI(baseURI string, subscriptionID string) PermissionsClient {
return PermissionsClient{NewWithBaseURI(baseURI, subscriptionID)} return PermissionsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// ListForResource gets all permissions the caller has for a resource. // ListForResource gets all permissions the caller has for a resource.
// //
// resourceGroupName is the name of the resource group containing the resource. // resourceGroupName is the name of the resource group containing the resource. The name is case insensitive.
// The name is case insensitive. resourceProviderNamespace is the namespace of // resourceProviderNamespace is the namespace of the resource provider. parentResourcePath is the parent resource
// the resource provider. parentResourcePath is the parent resource identity. // identity. resourceType is the resource type of the resource. resourceName is the name of the resource to get the
// resourceType is the resource type of the resource. resourceName is the name // permissions for.
// of the resource to get the permissions for.
func (client PermissionsClient) ListForResource(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result PermissionGetResult, err error) { func (client PermissionsClient) ListForResource(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result PermissionGetResult, err error) {
req, err := client.ListForResourcePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName) req, err := client.ListForResourcePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName)
if err != nil { if err != nil {
@ -141,11 +136,54 @@ func (client PermissionsClient) ListForResourceNextResults(lastResults Permissio
return return
} }
// ListForResourceGroup gets all permissions the caller has for a resource // ListForResourceComplete gets all elements from the list without paging.
// group. func (client PermissionsClient) ListForResourceComplete(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, cancel <-chan struct{}) (<-chan Permission, <-chan error) {
resultChan := make(chan Permission)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListForResource(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListForResourceNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// ListForResourceGroup gets all permissions the caller has for a resource group.
// //
// resourceGroupName is the name of the resource group to get the permissions // resourceGroupName is the name of the resource group to get the permissions for. The name is case insensitive.
// for. The name is case insensitive.
func (client PermissionsClient) ListForResourceGroup(resourceGroupName string) (result PermissionGetResult, err error) { func (client PermissionsClient) ListForResourceGroup(resourceGroupName string) (result PermissionGetResult, err error) {
req, err := client.ListForResourceGroupPreparer(resourceGroupName) req, err := client.ListForResourceGroupPreparer(resourceGroupName)
if err != nil { if err != nil {
@ -230,3 +268,48 @@ func (client PermissionsClient) ListForResourceGroupNextResults(lastResults Perm
return return
} }
// ListForResourceGroupComplete gets all elements from the list without paging.
func (client PermissionsClient) ListForResourceGroupComplete(resourceGroupName string, cancel <-chan struct{}) (<-chan Permission, <-chan error) {
resultChan := make(chan Permission)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListForResourceGroup(resourceGroupName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListForResourceGroupNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,9 +14,8 @@ package authorization
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -24,32 +23,28 @@ import (
"net/http" "net/http"
) )
// ProviderOperationsMetadataClient is the role based access control provides // ProviderOperationsMetadataClient is the role based access control provides you a way to apply granular level policy
// you a way to apply granular level policy administration down to individual // administration down to individual resources or resource groups. These operations enable you to manage role
// resources or resource groups. These operations enable you to manage role // definitions and role assignments. A role definition describes the set of actions that can be performed on resources.
// definitions and role assignments. A role definition describes the set of // A role assignment grants access to Azure Active Directory users.
// actions that can be performed on resources. A role assignment grants access
// to Azure Active Directory users.
type ProviderOperationsMetadataClient struct { type ProviderOperationsMetadataClient struct {
ManagementClient ManagementClient
} }
// NewProviderOperationsMetadataClient creates an instance of the // NewProviderOperationsMetadataClient creates an instance of the ProviderOperationsMetadataClient client.
// ProviderOperationsMetadataClient client.
func NewProviderOperationsMetadataClient(subscriptionID string) ProviderOperationsMetadataClient { func NewProviderOperationsMetadataClient(subscriptionID string) ProviderOperationsMetadataClient {
return NewProviderOperationsMetadataClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewProviderOperationsMetadataClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewProviderOperationsMetadataClientWithBaseURI creates an instance of the // NewProviderOperationsMetadataClientWithBaseURI creates an instance of the ProviderOperationsMetadataClient client.
// ProviderOperationsMetadataClient client.
func NewProviderOperationsMetadataClientWithBaseURI(baseURI string, subscriptionID string) ProviderOperationsMetadataClient { func NewProviderOperationsMetadataClientWithBaseURI(baseURI string, subscriptionID string) ProviderOperationsMetadataClient {
return ProviderOperationsMetadataClient{NewWithBaseURI(baseURI, subscriptionID)} return ProviderOperationsMetadataClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// Get gets provider operations metadata for the specified resource provider. // Get gets provider operations metadata for the specified resource provider.
// //
// resourceProviderNamespace is the namespace of the resource provider. expand // resourceProviderNamespace is the namespace of the resource provider. expand is specifies whether to expand the
// is specifies whether to expand the values. // values.
func (client ProviderOperationsMetadataClient) Get(resourceProviderNamespace string, expand string) (result ProviderOperationsMetadata, err error) { func (client ProviderOperationsMetadataClient) Get(resourceProviderNamespace string, expand string) (result ProviderOperationsMetadata, err error) {
req, err := client.GetPreparer(resourceProviderNamespace, expand) req, err := client.GetPreparer(resourceProviderNamespace, expand)
if err != nil { if err != nil {
@ -198,3 +193,48 @@ func (client ProviderOperationsMetadataClient) ListNextResults(lastResults Provi
return return
} }
// ListComplete gets all elements from the list without paging.
func (client ProviderOperationsMetadataClient) ListComplete(expand string, cancel <-chan struct{}) (<-chan ProviderOperationsMetadata, <-chan error) {
resultChan := make(chan ProviderOperationsMetadata)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List(expand)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,9 +14,8 @@ package authorization
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -24,39 +23,32 @@ import (
"net/http" "net/http"
) )
// RoleAssignmentsClient is the role based access control provides you a way to // RoleAssignmentsClient is the role based access control provides you a way to apply granular level policy
// apply granular level policy administration down to individual resources or // administration down to individual resources or resource groups. These operations enable you to manage role
// resource groups. These operations enable you to manage role definitions and // definitions and role assignments. A role definition describes the set of actions that can be performed on resources.
// role assignments. A role definition describes the set of actions that can be // A role assignment grants access to Azure Active Directory users.
// performed on resources. A role assignment grants access to Azure Active
// Directory users.
type RoleAssignmentsClient struct { type RoleAssignmentsClient struct {
ManagementClient ManagementClient
} }
// NewRoleAssignmentsClient creates an instance of the RoleAssignmentsClient // NewRoleAssignmentsClient creates an instance of the RoleAssignmentsClient client.
// client.
func NewRoleAssignmentsClient(subscriptionID string) RoleAssignmentsClient { func NewRoleAssignmentsClient(subscriptionID string) RoleAssignmentsClient {
return NewRoleAssignmentsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewRoleAssignmentsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewRoleAssignmentsClientWithBaseURI creates an instance of the // NewRoleAssignmentsClientWithBaseURI creates an instance of the RoleAssignmentsClient client.
// RoleAssignmentsClient client.
func NewRoleAssignmentsClientWithBaseURI(baseURI string, subscriptionID string) RoleAssignmentsClient { func NewRoleAssignmentsClientWithBaseURI(baseURI string, subscriptionID string) RoleAssignmentsClient {
return RoleAssignmentsClient{NewWithBaseURI(baseURI, subscriptionID)} return RoleAssignmentsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// Create creates a role assignment. // Create creates a role assignment.
// //
// scope is the scope of the role assignment to create. The scope can be any // scope is the scope of the role assignment to create. The scope can be any REST resource instance. For example, use
// REST resource instance. For example, use '/subscriptions/{subscription-id}/' // '/subscriptions/{subscription-id}/' for a subscription,
// for a subscription, // '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}' for a resource group, and
// '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}' for
// a resource group, and
// '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}' // '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}'
// for a resource. roleAssignmentName is the name of the role assignment to // for a resource. roleAssignmentName is the name of the role assignment to create. It can be any valid GUID.
// create. It can be any valid GUID. parameters is parameters for the role // parameters is parameters for the role assignment.
// assignment.
func (client RoleAssignmentsClient) Create(scope string, roleAssignmentName string, parameters RoleAssignmentCreateParameters) (result RoleAssignment, err error) { func (client RoleAssignmentsClient) Create(scope string, roleAssignmentName string, parameters RoleAssignmentCreateParameters) (result RoleAssignment, err error) {
req, err := client.CreatePreparer(scope, roleAssignmentName, parameters) req, err := client.CreatePreparer(scope, roleAssignmentName, parameters)
if err != nil { if err != nil {
@ -122,8 +114,7 @@ func (client RoleAssignmentsClient) CreateResponder(resp *http.Response) (result
// CreateByID creates a role assignment by ID. // CreateByID creates a role assignment by ID.
// //
// roleAssignmentID is the ID of the role assignment to create. parameters is // roleAssignmentID is the ID of the role assignment to create. parameters is parameters for the role assignment.
// parameters for the role assignment.
func (client RoleAssignmentsClient) CreateByID(roleAssignmentID string, parameters RoleAssignmentCreateParameters) (result RoleAssignment, err error) { func (client RoleAssignmentsClient) CreateByID(roleAssignmentID string, parameters RoleAssignmentCreateParameters) (result RoleAssignment, err error) {
req, err := client.CreateByIDPreparer(roleAssignmentID, parameters) req, err := client.CreateByIDPreparer(roleAssignmentID, parameters)
if err != nil { if err != nil {
@ -188,8 +179,8 @@ func (client RoleAssignmentsClient) CreateByIDResponder(resp *http.Response) (re
// Delete deletes a role assignment. // Delete deletes a role assignment.
// //
// scope is the scope of the role assignment to delete. roleAssignmentName is // scope is the scope of the role assignment to delete. roleAssignmentName is the name of the role assignment to
// the name of the role assignment to delete. // delete.
func (client RoleAssignmentsClient) Delete(scope string, roleAssignmentName string) (result RoleAssignment, err error) { func (client RoleAssignmentsClient) Delete(scope string, roleAssignmentName string) (result RoleAssignment, err error) {
req, err := client.DeletePreparer(scope, roleAssignmentName) req, err := client.DeletePreparer(scope, roleAssignmentName)
if err != nil { if err != nil {
@ -316,8 +307,7 @@ func (client RoleAssignmentsClient) DeleteByIDResponder(resp *http.Response) (re
// Get get the specified role assignment. // Get get the specified role assignment.
// //
// scope is the scope of the role assignment. roleAssignmentName is the name of // scope is the scope of the role assignment. roleAssignmentName is the name of the role assignment to get.
// the role assignment to get.
func (client RoleAssignmentsClient) Get(scope string, roleAssignmentName string) (result RoleAssignment, err error) { func (client RoleAssignmentsClient) Get(scope string, roleAssignmentName string) (result RoleAssignment, err error) {
req, err := client.GetPreparer(scope, roleAssignmentName) req, err := client.GetPreparer(scope, roleAssignmentName)
if err != nil { if err != nil {
@ -444,10 +434,9 @@ func (client RoleAssignmentsClient) GetByIDResponder(resp *http.Response) (resul
// List gets all role assignments for the subscription. // List gets all role assignments for the subscription.
// //
// filter is the filter to apply on the operation. Use $filter=atScope() to // filter is the filter to apply on the operation. Use $filter=atScope() to return all role assignments at or above the
// return all role assignments at or above the scope. Use $filter=principalId // scope. Use $filter=principalId eq {id} to return all role assignments at, above or below the scope for the specified
// eq {id} to return all role assignments at, above or below the scope for the // principal.
// specified principal.
func (client RoleAssignmentsClient) List(filter string) (result RoleAssignmentListResult, err error) { func (client RoleAssignmentsClient) List(filter string) (result RoleAssignmentListResult, err error) {
req, err := client.ListPreparer(filter) req, err := client.ListPreparer(filter)
if err != nil { if err != nil {
@ -535,16 +524,58 @@ func (client RoleAssignmentsClient) ListNextResults(lastResults RoleAssignmentLi
return return
} }
// ListComplete gets all elements from the list without paging.
func (client RoleAssignmentsClient) ListComplete(filter string, cancel <-chan struct{}) (<-chan RoleAssignment, <-chan error) {
resultChan := make(chan RoleAssignment)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List(filter)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// ListForResource gets role assignments for a resource. // ListForResource gets role assignments for a resource.
// //
// resourceGroupName is the name of the resource group. // resourceGroupName is the name of the resource group. resourceProviderNamespace is the namespace of the resource
// resourceProviderNamespace is the namespace of the resource provider. // provider. parentResourcePath is the parent resource identity. resourceType is the resource type of the resource.
// parentResourcePath is the parent resource identity. resourceType is the // resourceName is the name of the resource to get role assignments for. filter is the filter to apply on the
// resource type of the resource. resourceName is the name of the resource to // operation. Use $filter=atScope() to return all role assignments at or above the scope. Use $filter=principalId eq
// get role assignments for. filter is the filter to apply on the operation. // {id} to return all role assignments at, above or below the scope for the specified principal.
// Use $filter=atScope() to return all role assignments at or above the scope.
// Use $filter=principalId eq {id} to return all role assignments at, above or
// below the scope for the specified principal.
func (client RoleAssignmentsClient) ListForResource(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, filter string) (result RoleAssignmentListResult, err error) { func (client RoleAssignmentsClient) ListForResource(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, filter string) (result RoleAssignmentListResult, err error) {
req, err := client.ListForResourcePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, filter) req, err := client.ListForResourcePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, filter)
if err != nil { if err != nil {
@ -637,12 +668,56 @@ func (client RoleAssignmentsClient) ListForResourceNextResults(lastResults RoleA
return return
} }
// ListForResourceComplete gets all elements from the list without paging.
func (client RoleAssignmentsClient) ListForResourceComplete(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, filter string, cancel <-chan struct{}) (<-chan RoleAssignment, <-chan error) {
resultChan := make(chan RoleAssignment)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListForResource(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, filter)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListForResourceNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// ListForResourceGroup gets role assignments for a resource group. // ListForResourceGroup gets role assignments for a resource group.
// //
// resourceGroupName is the name of the resource group. filter is the filter to // resourceGroupName is the name of the resource group. filter is the filter to apply on the operation. Use
// apply on the operation. Use $filter=atScope() to return all role assignments // $filter=atScope() to return all role assignments at or above the scope. Use $filter=principalId eq {id} to return
// at or above the scope. Use $filter=principalId eq {id} to return all role // all role assignments at, above or below the scope for the specified principal.
// assignments at, above or below the scope for the specified principal.
func (client RoleAssignmentsClient) ListForResourceGroup(resourceGroupName string, filter string) (result RoleAssignmentListResult, err error) { func (client RoleAssignmentsClient) ListForResourceGroup(resourceGroupName string, filter string) (result RoleAssignmentListResult, err error) {
req, err := client.ListForResourceGroupPreparer(resourceGroupName, filter) req, err := client.ListForResourceGroupPreparer(resourceGroupName, filter)
if err != nil { if err != nil {
@ -731,12 +806,56 @@ func (client RoleAssignmentsClient) ListForResourceGroupNextResults(lastResults
return return
} }
// ListForResourceGroupComplete gets all elements from the list without paging.
func (client RoleAssignmentsClient) ListForResourceGroupComplete(resourceGroupName string, filter string, cancel <-chan struct{}) (<-chan RoleAssignment, <-chan error) {
resultChan := make(chan RoleAssignment)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListForResourceGroup(resourceGroupName, filter)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListForResourceGroupNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// ListForScope gets role assignments for a scope. // ListForScope gets role assignments for a scope.
// //
// scope is the scope of the role assignments. filter is the filter to apply on // scope is the scope of the role assignments. filter is the filter to apply on the operation. Use $filter=atScope() to
// the operation. Use $filter=atScope() to return all role assignments at or // return all role assignments at or above the scope. Use $filter=principalId eq {id} to return all role assignments
// above the scope. Use $filter=principalId eq {id} to return all role // at, above or below the scope for the specified principal.
// assignments at, above or below the scope for the specified principal.
func (client RoleAssignmentsClient) ListForScope(scope string, filter string) (result RoleAssignmentListResult, err error) { func (client RoleAssignmentsClient) ListForScope(scope string, filter string) (result RoleAssignmentListResult, err error) {
req, err := client.ListForScopePreparer(scope, filter) req, err := client.ListForScopePreparer(scope, filter)
if err != nil { if err != nil {
@ -823,3 +942,48 @@ func (client RoleAssignmentsClient) ListForScopeNextResults(lastResults RoleAssi
return return
} }
// ListForScopeComplete gets all elements from the list without paging.
func (client RoleAssignmentsClient) ListForScopeComplete(scope string, filter string, cancel <-chan struct{}) (<-chan RoleAssignment, <-chan error) {
resultChan := make(chan RoleAssignment)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListForScope(scope, filter)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListForScopeNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,9 +14,8 @@ package authorization
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -24,32 +23,28 @@ import (
"net/http" "net/http"
) )
// RoleDefinitionsClient is the role based access control provides you a way to // RoleDefinitionsClient is the role based access control provides you a way to apply granular level policy
// apply granular level policy administration down to individual resources or // administration down to individual resources or resource groups. These operations enable you to manage role
// resource groups. These operations enable you to manage role definitions and // definitions and role assignments. A role definition describes the set of actions that can be performed on resources.
// role assignments. A role definition describes the set of actions that can be // A role assignment grants access to Azure Active Directory users.
// performed on resources. A role assignment grants access to Azure Active
// Directory users.
type RoleDefinitionsClient struct { type RoleDefinitionsClient struct {
ManagementClient ManagementClient
} }
// NewRoleDefinitionsClient creates an instance of the RoleDefinitionsClient // NewRoleDefinitionsClient creates an instance of the RoleDefinitionsClient client.
// client.
func NewRoleDefinitionsClient(subscriptionID string) RoleDefinitionsClient { func NewRoleDefinitionsClient(subscriptionID string) RoleDefinitionsClient {
return NewRoleDefinitionsClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewRoleDefinitionsClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewRoleDefinitionsClientWithBaseURI creates an instance of the // NewRoleDefinitionsClientWithBaseURI creates an instance of the RoleDefinitionsClient client.
// RoleDefinitionsClient client.
func NewRoleDefinitionsClientWithBaseURI(baseURI string, subscriptionID string) RoleDefinitionsClient { func NewRoleDefinitionsClientWithBaseURI(baseURI string, subscriptionID string) RoleDefinitionsClient {
return RoleDefinitionsClient{NewWithBaseURI(baseURI, subscriptionID)} return RoleDefinitionsClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// CreateOrUpdate creates or updates a role definition. // CreateOrUpdate creates or updates a role definition.
// //
// scope is the scope of the role definition. roleDefinitionID is the ID of the // scope is the scope of the role definition. roleDefinitionID is the ID of the role definition. roleDefinition is the
// role definition. roleDefinition is the values for the role definition. // values for the role definition.
func (client RoleDefinitionsClient) CreateOrUpdate(scope string, roleDefinitionID string, roleDefinition RoleDefinition) (result RoleDefinition, err error) { func (client RoleDefinitionsClient) CreateOrUpdate(scope string, roleDefinitionID string, roleDefinition RoleDefinition) (result RoleDefinition, err error) {
req, err := client.CreateOrUpdatePreparer(scope, roleDefinitionID, roleDefinition) req, err := client.CreateOrUpdatePreparer(scope, roleDefinitionID, roleDefinition)
if err != nil { if err != nil {
@ -115,8 +110,7 @@ func (client RoleDefinitionsClient) CreateOrUpdateResponder(resp *http.Response)
// Delete deletes a role definition. // Delete deletes a role definition.
// //
// scope is the scope of the role definition. roleDefinitionID is the ID of the // scope is the scope of the role definition. roleDefinitionID is the ID of the role definition to delete.
// role definition to delete.
func (client RoleDefinitionsClient) Delete(scope string, roleDefinitionID string) (result RoleDefinition, err error) { func (client RoleDefinitionsClient) Delete(scope string, roleDefinitionID string) (result RoleDefinition, err error) {
req, err := client.DeletePreparer(scope, roleDefinitionID) req, err := client.DeletePreparer(scope, roleDefinitionID)
if err != nil { if err != nil {
@ -180,8 +174,7 @@ func (client RoleDefinitionsClient) DeleteResponder(resp *http.Response) (result
// Get get role definition by name (GUID). // Get get role definition by name (GUID).
// //
// scope is the scope of the role definition. roleDefinitionID is the ID of the // scope is the scope of the role definition. roleDefinitionID is the ID of the role definition.
// role definition.
func (client RoleDefinitionsClient) Get(scope string, roleDefinitionID string) (result RoleDefinition, err error) { func (client RoleDefinitionsClient) Get(scope string, roleDefinitionID string) (result RoleDefinition, err error) {
req, err := client.GetPreparer(scope, roleDefinitionID) req, err := client.GetPreparer(scope, roleDefinitionID)
if err != nil { if err != nil {
@ -308,9 +301,8 @@ func (client RoleDefinitionsClient) GetByIDResponder(resp *http.Response) (resul
// List get all role definitions that are applicable at scope and above. // List get all role definitions that are applicable at scope and above.
// //
// scope is the scope of the role definition. filter is the filter to apply on // scope is the scope of the role definition. filter is the filter to apply on the operation. Use atScopeAndBelow
// the operation. Use atScopeAndBelow filter to search below the given scope as // filter to search below the given scope as well.
// well.
func (client RoleDefinitionsClient) List(scope string, filter string) (result RoleDefinitionListResult, err error) { func (client RoleDefinitionsClient) List(scope string, filter string) (result RoleDefinitionListResult, err error) {
req, err := client.ListPreparer(scope, filter) req, err := client.ListPreparer(scope, filter)
if err != nil { if err != nil {
@ -397,3 +389,48 @@ func (client RoleDefinitionsClient) ListNextResults(lastResults RoleDefinitionLi
return return
} }
// ListComplete gets all elements from the list without paging.
func (client RoleDefinitionsClient) ListComplete(scope string, filter string, cancel <-chan struct{}) (<-chan RoleDefinition, <-chan error) {
resultChan := make(chan RoleDefinition)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List(scope, filter)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,15 +14,15 @@ package authorization
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 2.2.18.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated. // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// UserAgent returns the UserAgent string to use when sending http.Requests. // UserAgent returns the UserAgent string to use when sending http.Requests.
func UserAgent() string { func UserAgent() string {
return "Azure-SDK-For-Go/v10.3.1-beta arm-authorization/2015-07-01" return "Azure-SDK-For-Go/v11.0.0-beta arm-authorization/2015-07-01"
} }
// Version returns the semantic version (see http://semver.org) of the client. // Version returns the semantic version (see http://semver.org) of the client.
func Version() string { func Version() string {
return "v10.3.1-beta" return "v11.0.0-beta"
} }

View File

@ -14,9 +14,8 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,7 +24,7 @@ import (
"net/http" "net/http"
) )
// AccountClient is the composite Swagger json for Azure Automation Client // AccountClient is the automation Client
type AccountClient struct { type AccountClient struct {
ManagementClient ManagementClient
} }
@ -42,9 +41,8 @@ func NewAccountClientWithBaseURI(baseURI string, subscriptionID string) AccountC
// CreateOrUpdate create or update automation account. // CreateOrUpdate create or update automation account.
// //
// resourceGroupName is the resource group name. automationAccountName is // resourceGroupName is the resource group name. automationAccountName is parameters supplied to the create or update
// parameters supplied to the create or update automation account. parameters // automation account. parameters is parameters supplied to the create or update automation account.
// is parameters supplied to the create or update automation account.
func (client AccountClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, parameters AccountCreateOrUpdateParameters) (result Account, err error) { func (client AccountClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, parameters AccountCreateOrUpdateParameters) (result Account, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -117,8 +115,7 @@ func (client AccountClient) CreateOrUpdateResponder(resp *http.Response) (result
// Delete delete an automation account. // Delete delete an automation account.
// //
// resourceGroupName is the resource group name. automationAccountName is // resourceGroupName is the resource group name. automationAccountName is automation account name.
// automation account name.
func (client AccountClient) Delete(resourceGroupName string, automationAccountName string) (result autorest.Response, err error) { func (client AccountClient) Delete(resourceGroupName string, automationAccountName string) (result autorest.Response, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -188,8 +185,7 @@ func (client AccountClient) DeleteResponder(resp *http.Response) (result autores
// Get get information about an Automation Account. // Get get information about an Automation Account.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name.
func (client AccountClient) Get(resourceGroupName string, automationAccountName string) (result Account, err error) { func (client AccountClient) Get(resourceGroupName string, automationAccountName string) (result Account, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -343,8 +339,52 @@ func (client AccountClient) ListNextResults(lastResults AccountListResult) (resu
return return
} }
// ListByResourceGroup retrieve a list of accounts within a given resource // ListComplete gets all elements from the list without paging.
// group. func (client AccountClient) ListComplete(cancel <-chan struct{}) (<-chan Account, <-chan error) {
resultChan := make(chan Account)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.List()
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// ListByResourceGroup retrieve a list of accounts within a given resource group.
// //
// resourceGroupName is the resource group name. // resourceGroupName is the resource group name.
func (client AccountClient) ListByResourceGroup(resourceGroupName string) (result AccountListResult, err error) { func (client AccountClient) ListByResourceGroup(resourceGroupName string) (result AccountListResult, err error) {
@ -438,11 +478,55 @@ func (client AccountClient) ListByResourceGroupNextResults(lastResults AccountLi
return return
} }
// ListByResourceGroupComplete gets all elements from the list without paging.
func (client AccountClient) ListByResourceGroupComplete(resourceGroupName string, cancel <-chan struct{}) (<-chan Account, <-chan error) {
resultChan := make(chan Account)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByResourceGroup(resourceGroupName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByResourceGroupNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// Update update an automation account. // Update update an automation account.
// //
// resourceGroupName is the resource group name. automationAccountName is // resourceGroupName is the resource group name. automationAccountName is automation account name. parameters is
// automation account name. parameters is parameters supplied to the update // parameters supplied to the update automation account.
// automation account.
func (client AccountClient) Update(resourceGroupName string, automationAccountName string, parameters AccountUpdateParameters) (result Account, err error) { func (client AccountClient) Update(resourceGroupName string, automationAccountName string, parameters AccountUpdateParameters) (result Account, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,

View File

@ -14,9 +14,8 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,7 +24,7 @@ import (
"net/http" "net/http"
) )
// ActivityClient is the composite Swagger json for Azure Automation Client // ActivityClient is the automation Client
type ActivityClient struct { type ActivityClient struct {
ManagementClient ManagementClient
} }
@ -35,18 +34,15 @@ func NewActivityClient(subscriptionID string) ActivityClient {
return NewActivityClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewActivityClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewActivityClientWithBaseURI creates an instance of the ActivityClient // NewActivityClientWithBaseURI creates an instance of the ActivityClient client.
// client.
func NewActivityClientWithBaseURI(baseURI string, subscriptionID string) ActivityClient { func NewActivityClientWithBaseURI(baseURI string, subscriptionID string) ActivityClient {
return ActivityClient{NewWithBaseURI(baseURI, subscriptionID)} return ActivityClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// Get retrieve the activity in the module identified by module name and // Get retrieve the activity in the module identified by module name and activity name.
// activity name.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. moduleName is
// automation account name. moduleName is the name of module. activityName is // the name of module. activityName is the name of activity.
// the name of activity.
func (client ActivityClient) Get(resourceGroupName string, automationAccountName string, moduleName string, activityName string) (result Activity, err error) { func (client ActivityClient) Get(resourceGroupName string, automationAccountName string, moduleName string, activityName string) (result Activity, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -117,11 +113,10 @@ func (client ActivityClient) GetResponder(resp *http.Response) (result Activity,
return return
} }
// ListByModule retrieve a list of activities in the module identified by // ListByModule retrieve a list of activities in the module identified by module name.
// module name.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. moduleName is
// automation account name. moduleName is the name of module. // the name of module.
func (client ActivityClient) ListByModule(resourceGroupName string, automationAccountName string, moduleName string) (result ActivityListResult, err error) { func (client ActivityClient) ListByModule(resourceGroupName string, automationAccountName string, moduleName string) (result ActivityListResult, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -214,3 +209,48 @@ func (client ActivityClient) ListByModuleNextResults(lastResults ActivityListRes
return return
} }
// ListByModuleComplete gets all elements from the list without paging.
func (client ActivityClient) ListByModuleComplete(resourceGroupName string, automationAccountName string, moduleName string, cancel <-chan struct{}) (<-chan Activity, <-chan error) {
resultChan := make(chan Activity)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByModule(resourceGroupName, automationAccountName, moduleName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByModuleNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,9 +14,8 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,28 +24,25 @@ import (
"net/http" "net/http"
) )
// AgentRegistrationInformationClient is the composite Swagger json for Azure // AgentRegistrationInformationClient is the automation Client
// Automation Client
type AgentRegistrationInformationClient struct { type AgentRegistrationInformationClient struct {
ManagementClient ManagementClient
} }
// NewAgentRegistrationInformationClient creates an instance of the // NewAgentRegistrationInformationClient creates an instance of the AgentRegistrationInformationClient client.
// AgentRegistrationInformationClient client.
func NewAgentRegistrationInformationClient(subscriptionID string) AgentRegistrationInformationClient { func NewAgentRegistrationInformationClient(subscriptionID string) AgentRegistrationInformationClient {
return NewAgentRegistrationInformationClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewAgentRegistrationInformationClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewAgentRegistrationInformationClientWithBaseURI creates an instance of the // NewAgentRegistrationInformationClientWithBaseURI creates an instance of the AgentRegistrationInformationClient
// AgentRegistrationInformationClient client. // client.
func NewAgentRegistrationInformationClientWithBaseURI(baseURI string, subscriptionID string) AgentRegistrationInformationClient { func NewAgentRegistrationInformationClientWithBaseURI(baseURI string, subscriptionID string) AgentRegistrationInformationClient {
return AgentRegistrationInformationClient{NewWithBaseURI(baseURI, subscriptionID)} return AgentRegistrationInformationClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// Get retrieve the automation agent registration information. // Get retrieve the automation agent registration information.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name.
func (client AgentRegistrationInformationClient) Get(resourceGroupName string, automationAccountName string) (result AgentRegistration, err error) { func (client AgentRegistrationInformationClient) Get(resourceGroupName string, automationAccountName string) (result AgentRegistration, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -117,9 +113,8 @@ func (client AgentRegistrationInformationClient) GetResponder(resp *http.Respons
// RegenerateKey regenerate a primary or secondary agent registration key // RegenerateKey regenerate a primary or secondary agent registration key
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. parameters is
// automation account name. parameters is the name of the agent registration // the name of the agent registration key to be regenerated
// key to be regenerated
func (client AgentRegistrationInformationClient) RegenerateKey(resourceGroupName string, automationAccountName string, parameters AgentRegistrationRegenerateKeyParameter) (result AgentRegistration, err error) { func (client AgentRegistrationInformationClient) RegenerateKey(resourceGroupName string, automationAccountName string, parameters AgentRegistrationRegenerateKeyParameter) (result AgentRegistration, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,

View File

@ -14,9 +14,8 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,7 +24,7 @@ import (
"net/http" "net/http"
) )
// CertificateClient is the composite Swagger json for Azure Automation Client // CertificateClient is the automation Client
type CertificateClient struct { type CertificateClient struct {
ManagementClient ManagementClient
} }
@ -35,18 +34,16 @@ func NewCertificateClient(subscriptionID string) CertificateClient {
return NewCertificateClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewCertificateClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewCertificateClientWithBaseURI creates an instance of the CertificateClient // NewCertificateClientWithBaseURI creates an instance of the CertificateClient client.
// client.
func NewCertificateClientWithBaseURI(baseURI string, subscriptionID string) CertificateClient { func NewCertificateClientWithBaseURI(baseURI string, subscriptionID string) CertificateClient {
return CertificateClient{NewWithBaseURI(baseURI, subscriptionID)} return CertificateClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// CreateOrUpdate create a certificate. // CreateOrUpdate create a certificate.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. certificateName
// automation account name. certificateName is the parameters supplied to the // is the parameters supplied to the create or update certificate operation. parameters is the parameters supplied to
// create or update certificate operation. parameters is the parameters // the create or update certificate operation.
// supplied to the create or update certificate operation.
func (client CertificateClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, certificateName string, parameters CertificateCreateOrUpdateParameters) (result Certificate, err error) { func (client CertificateClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, certificateName string, parameters CertificateCreateOrUpdateParameters) (result Certificate, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -124,8 +121,8 @@ func (client CertificateClient) CreateOrUpdateResponder(resp *http.Response) (re
// Delete delete the certificate. // Delete delete the certificate.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. certificateName
// automation account name. certificateName is the name of certificate. // is the name of certificate.
func (client CertificateClient) Delete(resourceGroupName string, automationAccountName string, certificateName string) (result autorest.Response, err error) { func (client CertificateClient) Delete(resourceGroupName string, automationAccountName string, certificateName string) (result autorest.Response, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -196,8 +193,8 @@ func (client CertificateClient) DeleteResponder(resp *http.Response) (result aut
// Get retrieve the certificate identified by certificate name. // Get retrieve the certificate identified by certificate name.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. certificateName
// automation account name. certificateName is the name of certificate. // is the name of certificate.
func (client CertificateClient) Get(resourceGroupName string, automationAccountName string, certificateName string) (result Certificate, err error) { func (client CertificateClient) Get(resourceGroupName string, automationAccountName string, certificateName string) (result Certificate, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -269,8 +266,7 @@ func (client CertificateClient) GetResponder(resp *http.Response) (result Certif
// ListByAutomationAccount retrieve a list of certificates. // ListByAutomationAccount retrieve a list of certificates.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name.
func (client CertificateClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string) (result CertificateListResult, err error) { func (client CertificateClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string) (result CertificateListResult, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -363,12 +359,56 @@ func (client CertificateClient) ListByAutomationAccountNextResults(lastResults C
return return
} }
// ListByAutomationAccountComplete gets all elements from the list without paging.
func (client CertificateClient) ListByAutomationAccountComplete(resourceGroupName string, automationAccountName string, cancel <-chan struct{}) (<-chan Certificate, <-chan error) {
resultChan := make(chan Certificate)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByAutomationAccount(resourceGroupName, automationAccountName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByAutomationAccountNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// Update update a certificate. // Update update a certificate.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. certificateName
// automation account name. certificateName is the parameters supplied to the // is the parameters supplied to the update certificate operation. parameters is the parameters supplied to the update
// update certificate operation. parameters is the parameters supplied to the // certificate operation.
// update certificate operation.
func (client CertificateClient) Update(resourceGroupName string, automationAccountName string, certificateName string, parameters CertificateUpdateParameters) (result Certificate, err error) { func (client CertificateClient) Update(resourceGroupName string, automationAccountName string, certificateName string, parameters CertificateUpdateParameters) (result Certificate, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,

View File

@ -1,6 +1,6 @@
// Package automation implements the Azure ARM Automation service API version . // Package automation implements the Azure ARM Automation service API version 2015-10-31.
// //
// Composite Swagger json for Azure Automation Client // Automation Client
package automation package automation
// Copyright (c) Microsoft and contributors. All rights reserved. // Copyright (c) Microsoft and contributors. All rights reserved.
@ -17,9 +17,8 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"

View File

@ -14,9 +14,8 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,7 +24,7 @@ import (
"net/http" "net/http"
) )
// ConnectionClient is the composite Swagger json for Azure Automation Client // ConnectionClient is the automation Client
type ConnectionClient struct { type ConnectionClient struct {
ManagementClient ManagementClient
} }
@ -35,18 +34,16 @@ func NewConnectionClient(subscriptionID string) ConnectionClient {
return NewConnectionClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewConnectionClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewConnectionClientWithBaseURI creates an instance of the ConnectionClient // NewConnectionClientWithBaseURI creates an instance of the ConnectionClient client.
// client.
func NewConnectionClientWithBaseURI(baseURI string, subscriptionID string) ConnectionClient { func NewConnectionClientWithBaseURI(baseURI string, subscriptionID string) ConnectionClient {
return ConnectionClient{NewWithBaseURI(baseURI, subscriptionID)} return ConnectionClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// CreateOrUpdate create or update a connection. // CreateOrUpdate create or update a connection.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. connectionName
// automation account name. connectionName is the parameters supplied to the // is the parameters supplied to the create or update connection operation. parameters is the parameters supplied to
// create or update connection operation. parameters is the parameters supplied // the create or update connection operation.
// to the create or update connection operation.
func (client ConnectionClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, connectionName string, parameters ConnectionCreateOrUpdateParameters) (result Connection, err error) { func (client ConnectionClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, connectionName string, parameters ConnectionCreateOrUpdateParameters) (result Connection, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -124,8 +121,8 @@ func (client ConnectionClient) CreateOrUpdateResponder(resp *http.Response) (res
// Delete delete the connection. // Delete delete the connection.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. connectionName
// automation account name. connectionName is the name of connection. // is the name of connection.
func (client ConnectionClient) Delete(resourceGroupName string, automationAccountName string, connectionName string) (result Connection, err error) { func (client ConnectionClient) Delete(resourceGroupName string, automationAccountName string, connectionName string) (result Connection, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -197,8 +194,8 @@ func (client ConnectionClient) DeleteResponder(resp *http.Response) (result Conn
// Get retrieve the connection identified by connection name. // Get retrieve the connection identified by connection name.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. connectionName
// automation account name. connectionName is the name of connection. // is the name of connection.
func (client ConnectionClient) Get(resourceGroupName string, automationAccountName string, connectionName string) (result Connection, err error) { func (client ConnectionClient) Get(resourceGroupName string, automationAccountName string, connectionName string) (result Connection, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -270,8 +267,7 @@ func (client ConnectionClient) GetResponder(resp *http.Response) (result Connect
// ListByAutomationAccount retrieve a list of connections. // ListByAutomationAccount retrieve a list of connections.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name.
func (client ConnectionClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string) (result ConnectionListResult, err error) { func (client ConnectionClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string) (result ConnectionListResult, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -364,12 +360,56 @@ func (client ConnectionClient) ListByAutomationAccountNextResults(lastResults Co
return return
} }
// ListByAutomationAccountComplete gets all elements from the list without paging.
func (client ConnectionClient) ListByAutomationAccountComplete(resourceGroupName string, automationAccountName string, cancel <-chan struct{}) (<-chan Connection, <-chan error) {
resultChan := make(chan Connection)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByAutomationAccount(resourceGroupName, automationAccountName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByAutomationAccountNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// Update update a connection. // Update update a connection.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. connectionName
// automation account name. connectionName is the parameters supplied to the // is the parameters supplied to the update a connection operation. parameters is the parameters supplied to the update
// update a connection operation. parameters is the parameters supplied to the // a connection operation.
// update a connection operation.
func (client ConnectionClient) Update(resourceGroupName string, automationAccountName string, connectionName string, parameters ConnectionUpdateParameters) (result Connection, err error) { func (client ConnectionClient) Update(resourceGroupName string, automationAccountName string, connectionName string, parameters ConnectionUpdateParameters) (result Connection, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,

View File

@ -14,9 +14,8 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,30 +24,26 @@ import (
"net/http" "net/http"
) )
// ConnectionTypeClient is the composite Swagger json for Azure Automation // ConnectionTypeClient is the automation Client
// Client
type ConnectionTypeClient struct { type ConnectionTypeClient struct {
ManagementClient ManagementClient
} }
// NewConnectionTypeClient creates an instance of the ConnectionTypeClient // NewConnectionTypeClient creates an instance of the ConnectionTypeClient client.
// client.
func NewConnectionTypeClient(subscriptionID string) ConnectionTypeClient { func NewConnectionTypeClient(subscriptionID string) ConnectionTypeClient {
return NewConnectionTypeClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewConnectionTypeClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewConnectionTypeClientWithBaseURI creates an instance of the // NewConnectionTypeClientWithBaseURI creates an instance of the ConnectionTypeClient client.
// ConnectionTypeClient client.
func NewConnectionTypeClientWithBaseURI(baseURI string, subscriptionID string) ConnectionTypeClient { func NewConnectionTypeClientWithBaseURI(baseURI string, subscriptionID string) ConnectionTypeClient {
return ConnectionTypeClient{NewWithBaseURI(baseURI, subscriptionID)} return ConnectionTypeClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// CreateOrUpdate create a connectiontype. // CreateOrUpdate create a connectiontype.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name. connectionTypeName is the parameters supplied to // connectionTypeName is the parameters supplied to the create or update connectiontype operation. parameters is the
// the create or update connectiontype operation. parameters is the parameters // parameters supplied to the create or update connectiontype operation.
// supplied to the create or update connectiontype operation.
func (client ConnectionTypeClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, connectionTypeName string, parameters ConnectionTypeCreateOrUpdateParameters) (result ConnectionType, err error) { func (client ConnectionTypeClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, connectionTypeName string, parameters ConnectionTypeCreateOrUpdateParameters) (result ConnectionType, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -126,8 +121,8 @@ func (client ConnectionTypeClient) CreateOrUpdateResponder(resp *http.Response)
// Delete delete the connectiontype. // Delete delete the connectiontype.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name. connectionTypeName is the name of connectiontype. // connectionTypeName is the name of connectiontype.
func (client ConnectionTypeClient) Delete(resourceGroupName string, automationAccountName string, connectionTypeName string) (result autorest.Response, err error) { func (client ConnectionTypeClient) Delete(resourceGroupName string, automationAccountName string, connectionTypeName string) (result autorest.Response, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -198,8 +193,8 @@ func (client ConnectionTypeClient) DeleteResponder(resp *http.Response) (result
// Get retrieve the connectiontype identified by connectiontype name. // Get retrieve the connectiontype identified by connectiontype name.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name. connectionTypeName is the name of connectiontype. // connectionTypeName is the name of connectiontype.
func (client ConnectionTypeClient) Get(resourceGroupName string, automationAccountName string, connectionTypeName string) (result ConnectionType, err error) { func (client ConnectionTypeClient) Get(resourceGroupName string, automationAccountName string, connectionTypeName string) (result ConnectionType, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -271,8 +266,7 @@ func (client ConnectionTypeClient) GetResponder(resp *http.Response) (result Con
// ListByAutomationAccount retrieve a list of connectiontypes. // ListByAutomationAccount retrieve a list of connectiontypes.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name.
func (client ConnectionTypeClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string) (result ConnectionTypeListResult, err error) { func (client ConnectionTypeClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string) (result ConnectionTypeListResult, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -364,3 +358,48 @@ func (client ConnectionTypeClient) ListByAutomationAccountNextResults(lastResult
return return
} }
// ListByAutomationAccountComplete gets all elements from the list without paging.
func (client ConnectionTypeClient) ListByAutomationAccountComplete(resourceGroupName string, automationAccountName string, cancel <-chan struct{}) (<-chan ConnectionType, <-chan error) {
resultChan := make(chan ConnectionType)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByAutomationAccount(resourceGroupName, automationAccountName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByAutomationAccountNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

View File

@ -14,9 +14,8 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
@ -25,7 +24,7 @@ import (
"net/http" "net/http"
) )
// CredentialClient is the composite Swagger json for Azure Automation Client // CredentialClient is the automation Client
type CredentialClient struct { type CredentialClient struct {
ManagementClient ManagementClient
} }
@ -35,18 +34,16 @@ func NewCredentialClient(subscriptionID string) CredentialClient {
return NewCredentialClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewCredentialClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewCredentialClientWithBaseURI creates an instance of the CredentialClient // NewCredentialClientWithBaseURI creates an instance of the CredentialClient client.
// client.
func NewCredentialClientWithBaseURI(baseURI string, subscriptionID string) CredentialClient { func NewCredentialClientWithBaseURI(baseURI string, subscriptionID string) CredentialClient {
return CredentialClient{NewWithBaseURI(baseURI, subscriptionID)} return CredentialClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// CreateOrUpdate create a credential. // CreateOrUpdate create a credential.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. credentialName
// automation account name. credentialName is the parameters supplied to the // is the parameters supplied to the create or update credential operation. parameters is the parameters supplied to
// create or update credential operation. parameters is the parameters supplied // the create or update credential operation.
// to the create or update credential operation.
func (client CredentialClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, credentialName string, parameters CredentialCreateOrUpdateParameters) (result Credential, err error) { func (client CredentialClient) CreateOrUpdate(resourceGroupName string, automationAccountName string, credentialName string, parameters CredentialCreateOrUpdateParameters) (result Credential, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -126,8 +123,8 @@ func (client CredentialClient) CreateOrUpdateResponder(resp *http.Response) (res
// Delete delete the credential. // Delete delete the credential.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. credentialName
// automation account name. credentialName is the name of credential. // is the name of credential.
func (client CredentialClient) Delete(resourceGroupName string, automationAccountName string, credentialName string) (result autorest.Response, err error) { func (client CredentialClient) Delete(resourceGroupName string, automationAccountName string, credentialName string) (result autorest.Response, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -198,8 +195,8 @@ func (client CredentialClient) DeleteResponder(resp *http.Response) (result auto
// Get retrieve the credential identified by credential name. // Get retrieve the credential identified by credential name.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. credentialName
// automation account name. credentialName is the name of credential. // is the name of credential.
func (client CredentialClient) Get(resourceGroupName string, automationAccountName string, credentialName string) (result Credential, err error) { func (client CredentialClient) Get(resourceGroupName string, automationAccountName string, credentialName string) (result Credential, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -271,8 +268,7 @@ func (client CredentialClient) GetResponder(resp *http.Response) (result Credent
// ListByAutomationAccount retrieve a list of credentials. // ListByAutomationAccount retrieve a list of credentials.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name.
// automation account name.
func (client CredentialClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string) (result CredentialListResult, err error) { func (client CredentialClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string) (result CredentialListResult, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -365,12 +361,56 @@ func (client CredentialClient) ListByAutomationAccountNextResults(lastResults Cr
return return
} }
// ListByAutomationAccountComplete gets all elements from the list without paging.
func (client CredentialClient) ListByAutomationAccountComplete(resourceGroupName string, automationAccountName string, cancel <-chan struct{}) (<-chan Credential, <-chan error) {
resultChan := make(chan Credential)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByAutomationAccount(resourceGroupName, automationAccountName)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByAutomationAccountNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}
// Update update a credential. // Update update a credential.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. credentialName
// automation account name. credentialName is the parameters supplied to the // is the parameters supplied to the Update credential operation. parameters is the parameters supplied to the Update
// Update credential operation. parameters is the parameters supplied to the // credential operation.
// Update credential operation.
func (client CredentialClient) Update(resourceGroupName string, automationAccountName string, credentialName string, parameters CredentialUpdateParameters) (result Credential, err error) { func (client CredentialClient) Update(resourceGroupName string, automationAccountName string, credentialName string, parameters CredentialUpdateParameters) (result Credential, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,

View File

@ -14,42 +14,36 @@ package automation
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// //
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0 // Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is // Changes may cause incorrect behavior and will be lost if the code is regenerated.
// regenerated.
import ( import (
"github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/validation" "github.com/Azure/go-autorest/autorest/validation"
"github.com/satori/uuid" uuid "github.com/satori/go.uuid"
"net/http" "net/http"
) )
// DscCompilationJobClient is the composite Swagger json for Azure Automation // DscCompilationJobClient is the automation Client
// Client
type DscCompilationJobClient struct { type DscCompilationJobClient struct {
ManagementClient ManagementClient
} }
// NewDscCompilationJobClient creates an instance of the // NewDscCompilationJobClient creates an instance of the DscCompilationJobClient client.
// DscCompilationJobClient client.
func NewDscCompilationJobClient(subscriptionID string) DscCompilationJobClient { func NewDscCompilationJobClient(subscriptionID string) DscCompilationJobClient {
return NewDscCompilationJobClientWithBaseURI(DefaultBaseURI, subscriptionID) return NewDscCompilationJobClientWithBaseURI(DefaultBaseURI, subscriptionID)
} }
// NewDscCompilationJobClientWithBaseURI creates an instance of the // NewDscCompilationJobClientWithBaseURI creates an instance of the DscCompilationJobClient client.
// DscCompilationJobClient client.
func NewDscCompilationJobClientWithBaseURI(baseURI string, subscriptionID string) DscCompilationJobClient { func NewDscCompilationJobClientWithBaseURI(baseURI string, subscriptionID string) DscCompilationJobClient {
return DscCompilationJobClient{NewWithBaseURI(baseURI, subscriptionID)} return DscCompilationJobClient{NewWithBaseURI(baseURI, subscriptionID)}
} }
// Create creates the Dsc compilation job of the configuration. // Create creates the Dsc compilation job of the configuration.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. compilationJobID
// automation account name. compilationJobID is the the DSC configuration Id. // is the the DSC configuration Id. parameters is the parameters supplied to the create compilation job operation.
// parameters is the parameters supplied to the create compilation job
// operation.
func (client DscCompilationJobClient) Create(resourceGroupName string, automationAccountName string, compilationJobID uuid.UUID, parameters DscCompilationJobCreateParameters) (result DscCompilationJob, err error) { func (client DscCompilationJobClient) Create(resourceGroupName string, automationAccountName string, compilationJobID uuid.UUID, parameters DscCompilationJobCreateParameters) (result DscCompilationJob, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -126,9 +120,8 @@ func (client DscCompilationJobClient) CreateResponder(resp *http.Response) (resu
// Get retrieve the Dsc configuration compilation job identified by job id. // Get retrieve the Dsc configuration compilation job identified by job id.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. compilationJobID
// automation account name. compilationJobID is the Dsc configuration // is the Dsc configuration compilation job id.
// compilation job id.
func (client DscCompilationJobClient) Get(resourceGroupName string, automationAccountName string, compilationJobID uuid.UUID) (result DscCompilationJob, err error) { func (client DscCompilationJobClient) Get(resourceGroupName string, automationAccountName string, compilationJobID uuid.UUID) (result DscCompilationJob, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -200,9 +193,8 @@ func (client DscCompilationJobClient) GetResponder(resp *http.Response) (result
// GetStream retrieve the job stream identified by job stream id. // GetStream retrieve the job stream identified by job stream id.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. jobID is the job
// automation account name. jobID is the job id. jobStreamID is the job stream // id. jobStreamID is the job stream id.
// id.
func (client DscCompilationJobClient) GetStream(resourceGroupName string, automationAccountName string, jobID uuid.UUID, jobStreamID string) (result JobStream, err error) { func (client DscCompilationJobClient) GetStream(resourceGroupName string, automationAccountName string, jobID uuid.UUID, jobStreamID string) (result JobStream, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -275,8 +267,8 @@ func (client DscCompilationJobClient) GetStreamResponder(resp *http.Response) (r
// ListByAutomationAccount retrieve a list of dsc compilation jobs. // ListByAutomationAccount retrieve a list of dsc compilation jobs.
// //
// resourceGroupName is the resource group name. automationAccountName is the // resourceGroupName is the resource group name. automationAccountName is the automation account name. filter is the
// automation account name. filter is the filter to apply on the operation. // filter to apply on the operation.
func (client DscCompilationJobClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string, filter string) (result DscCompilationJobListResult, err error) { func (client DscCompilationJobClient) ListByAutomationAccount(resourceGroupName string, automationAccountName string, filter string) (result DscCompilationJobListResult, err error) {
if err := validation.Validate([]validation.Validation{ if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName, {TargetValue: resourceGroupName,
@ -371,3 +363,48 @@ func (client DscCompilationJobClient) ListByAutomationAccountNextResults(lastRes
return return
} }
// ListByAutomationAccountComplete gets all elements from the list without paging.
func (client DscCompilationJobClient) ListByAutomationAccountComplete(resourceGroupName string, automationAccountName string, filter string, cancel <-chan struct{}) (<-chan DscCompilationJob, <-chan error) {
resultChan := make(chan DscCompilationJob)
errChan := make(chan error, 1)
go func() {
defer func() {
close(resultChan)
close(errChan)
}()
list, err := client.ListByAutomationAccount(resourceGroupName, automationAccountName, filter)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
for list.NextLink != nil {
list, err = client.ListByAutomationAccountNextResults(list)
if err != nil {
errChan <- err
return
}
if list.Value != nil {
for _, item := range *list.Value {
select {
case <-cancel:
return
case resultChan <- item:
// Intentionally left blank
}
}
}
}
}()
return resultChan, errChan
}

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