Add tablestore config to store state lock
This commit is contained in:
parent
b887d44712
commit
3f44dd9dec
|
@ -4,6 +4,15 @@ package addrs
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[InvalidResourceMode-0]
|
||||||
|
_ = x[ManagedResourceMode-77]
|
||||||
|
_ = x[DataResourceMode-68]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_ResourceMode_name_0 = "InvalidResourceMode"
|
_ResourceMode_name_0 = "InvalidResourceMode"
|
||||||
_ResourceMode_name_1 = "DataResourceMode"
|
_ResourceMode_name_1 = "DataResourceMode"
|
||||||
|
|
|
@ -4,6 +4,15 @@ package local
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[countHookActionAdd-0]
|
||||||
|
_ = x[countHookActionChange-1]
|
||||||
|
_ = x[countHookActionRemove-2]
|
||||||
|
}
|
||||||
|
|
||||||
const _countHookAction_name = "countHookActionAddcountHookActionChangecountHookActionRemove"
|
const _countHookAction_name = "countHookActionAddcountHookActionChangecountHookActionRemove"
|
||||||
|
|
||||||
var _countHookAction_index = [...]uint8{0, 18, 39, 60}
|
var _countHookAction_index = [...]uint8{0, 18, 39, 60}
|
||||||
|
|
|
@ -4,6 +4,16 @@ package backend
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[OperationTypeInvalid-0]
|
||||||
|
_ = x[OperationTypeRefresh-1]
|
||||||
|
_ = x[OperationTypePlan-2]
|
||||||
|
_ = x[OperationTypeApply-3]
|
||||||
|
}
|
||||||
|
|
||||||
const _OperationType_name = "OperationTypeInvalidOperationTypeRefreshOperationTypePlanOperationTypeApply"
|
const _OperationType_name = "OperationTypeInvalidOperationTypeRefreshOperationTypePlanOperationTypeApply"
|
||||||
|
|
||||||
var _OperationType_index = [...]uint8{0, 20, 40, 57, 75}
|
var _OperationType_index = [...]uint8{0, 20, 40, 57, 75}
|
||||||
|
|
|
@ -11,9 +11,8 @@ import (
|
||||||
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/resource"
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/services/location"
|
"github.com/aliyun/alibaba-cloud-sdk-go/services/location"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
|
||||||
"github.com/hashicorp/go-cleanhttp"
|
"github.com/hashicorp/go-cleanhttp"
|
||||||
"github.com/hashicorp/terraform/version"
|
"github.com/hashicorp/terraform/version"
|
||||||
"log"
|
"log"
|
||||||
|
@ -44,7 +43,7 @@ func New() backend.Backend {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "Alibaba Cloud Security Token",
|
Description: "Alibaba Cloud Security Token",
|
||||||
DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_SECURITY_TOKEN", os.Getenv("SECURITY_TOKEN")),
|
DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_SECURITY_TOKEN", ""),
|
||||||
},
|
},
|
||||||
|
|
||||||
"region": &schema.Schema{
|
"region": &schema.Schema{
|
||||||
|
@ -53,7 +52,12 @@ func New() backend.Backend {
|
||||||
Description: "The region of the OSS bucket.",
|
Description: "The region of the OSS bucket.",
|
||||||
DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_REGION", os.Getenv("ALICLOUD_DEFAULT_REGION")),
|
DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_REGION", os.Getenv("ALICLOUD_DEFAULT_REGION")),
|
||||||
},
|
},
|
||||||
|
"tablestore_endpoint": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "A custom endpoint for the TableStore API",
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_TABLESTORE_ENDPOINT", ""),
|
||||||
|
},
|
||||||
"endpoint": {
|
"endpoint": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
@ -67,30 +71,38 @@ func New() backend.Backend {
|
||||||
Description: "The name of the OSS bucket",
|
Description: "The name of the OSS bucket",
|
||||||
},
|
},
|
||||||
|
|
||||||
"path": &schema.Schema{
|
"prefix": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "The path relative to your object storage directory where the state file will be stored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"name": &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The name of the state file inside the bucket",
|
Description: "The directory where state files will be saved inside the bucket",
|
||||||
|
Default: "env:",
|
||||||
|
ValidateFunc: func(v interface{}, s string) ([]string, []error) {
|
||||||
|
prefix := v.(string)
|
||||||
|
if strings.HasPrefix(prefix, "/") || strings.HasPrefix(prefix, "./") {
|
||||||
|
return nil, []error{fmt.Errorf("workspace_key_prefix must not start with '/' or './'")}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"key": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The path of the state file inside the bucket",
|
||||||
ValidateFunc: func(v interface{}, s string) ([]string, []error) {
|
ValidateFunc: func(v interface{}, s string) ([]string, []error) {
|
||||||
if strings.HasPrefix(v.(string), "/") || strings.HasSuffix(v.(string), "/") {
|
if strings.HasPrefix(v.(string), "/") || strings.HasSuffix(v.(string), "/") {
|
||||||
return nil, []error{fmt.Errorf("name can not start and end with '/'")}
|
return nil, []error{fmt.Errorf("key can not start and end with '/'")}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
},
|
},
|
||||||
Default: "terraform.tfstate",
|
Default: "terraform.tfstate",
|
||||||
},
|
},
|
||||||
|
|
||||||
"lock": &schema.Schema{
|
"tablestore_table": {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "Whether to lock state access. Defaults to true",
|
Description: "TableStore table for state locking and consistency",
|
||||||
Default: true,
|
Default: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
"encrypt": &schema.Schema{
|
"encrypt": &schema.Schema{
|
||||||
|
@ -130,14 +142,16 @@ type Backend struct {
|
||||||
|
|
||||||
// The fields below are set from configure
|
// The fields below are set from configure
|
||||||
ossClient *oss.Client
|
ossClient *oss.Client
|
||||||
|
otsClient *tablestore.TableStoreClient
|
||||||
|
|
||||||
bucketName string
|
bucketName string
|
||||||
statePath string
|
statePrefix string
|
||||||
stateName string
|
stateKey string
|
||||||
serverSideEncryption bool
|
serverSideEncryption bool
|
||||||
acl string
|
acl string
|
||||||
endpoint string
|
endpoint string
|
||||||
lock bool
|
otsEndpoint string
|
||||||
|
otsTable string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) configure(ctx context.Context) error {
|
func (b *Backend) configure(ctx context.Context) error {
|
||||||
|
@ -149,27 +163,20 @@ func (b *Backend) configure(ctx context.Context) error {
|
||||||
d := schema.FromContextBackendConfig(ctx)
|
d := schema.FromContextBackendConfig(ctx)
|
||||||
|
|
||||||
b.bucketName = d.Get("bucket").(string)
|
b.bucketName = d.Get("bucket").(string)
|
||||||
dir := strings.Trim(d.Get("path").(string), "/")
|
b.statePrefix = strings.TrimPrefix(strings.Trim(d.Get("prefix").(string), "/"), "./")
|
||||||
if strings.HasPrefix(dir, "./") {
|
b.stateKey = d.Get("key").(string)
|
||||||
dir = strings.TrimPrefix(dir, "./")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
b.statePath = dir
|
|
||||||
b.stateName = d.Get("name").(string)
|
|
||||||
b.serverSideEncryption = d.Get("encrypt").(bool)
|
b.serverSideEncryption = d.Get("encrypt").(bool)
|
||||||
b.acl = d.Get("acl").(string)
|
b.acl = d.Get("acl").(string)
|
||||||
b.lock = d.Get("lock").(bool)
|
|
||||||
|
|
||||||
access_key := d.Get("access_key").(string)
|
accessKey := d.Get("access_key").(string)
|
||||||
secret_key := d.Get("secret_key").(string)
|
secretKey := d.Get("secret_key").(string)
|
||||||
security_token := d.Get("security_token").(string)
|
securityToken := d.Get("security_token").(string)
|
||||||
region := d.Get("region").(string)
|
region := d.Get("region").(string)
|
||||||
endpoint := d.Get("endpoint").(string)
|
endpoint := d.Get("endpoint").(string)
|
||||||
schma := "https"
|
schma := "https"
|
||||||
|
|
||||||
if endpoint == "" {
|
if endpoint == "" {
|
||||||
endpointItem, _ := b.getOSSEndpointByRegion(access_key, secret_key, security_token, region)
|
endpointItem, _ := b.getOSSEndpointByRegion(accessKey, secretKey, securityToken, region)
|
||||||
if endpointItem != nil && len(endpointItem.Endpoint) > 0 {
|
if endpointItem != nil && len(endpointItem.Endpoint) > 0 {
|
||||||
if len(endpointItem.Protocols.Protocols) > 0 {
|
if len(endpointItem.Protocols.Protocols) > 0 {
|
||||||
// HTTP or HTTPS
|
// HTTP or HTTPS
|
||||||
|
@ -191,13 +198,23 @@ func (b *Backend) configure(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
log.Printf("[DEBUG] Instantiate OSS client using endpoint: %#v", endpoint)
|
log.Printf("[DEBUG] Instantiate OSS client using endpoint: %#v", endpoint)
|
||||||
var options []oss.ClientOption
|
var options []oss.ClientOption
|
||||||
if security_token != "" {
|
if securityToken != "" {
|
||||||
options = append(options, oss.SecurityToken(security_token))
|
options = append(options, oss.SecurityToken(securityToken))
|
||||||
}
|
}
|
||||||
options = append(options, oss.UserAgent(fmt.Sprintf("%s/%s", TerraformUA, TerraformVersion)))
|
options = append(options, oss.UserAgent(fmt.Sprintf("%s/%s", TerraformUA, TerraformVersion)))
|
||||||
|
|
||||||
client, err := oss.New(endpoint, access_key, secret_key, options...)
|
client, err := oss.New(endpoint, accessKey, secretKey, options...)
|
||||||
b.ossClient = client
|
b.ossClient = client
|
||||||
|
otsEndpoint := d.Get("tablestore_endpoint").(string)
|
||||||
|
if otsEndpoint != "" {
|
||||||
|
if !strings.HasPrefix(otsEndpoint, "http") {
|
||||||
|
otsEndpoint = fmt.Sprintf("%s://%s", schma, otsEndpoint)
|
||||||
|
}
|
||||||
|
b.otsEndpoint = otsEndpoint
|
||||||
|
parts := strings.Split(strings.TrimPrefix(strings.TrimPrefix(otsEndpoint, "https://"), "http://"), ".")
|
||||||
|
b.otsClient = tablestore.NewClientWithConfig(otsEndpoint, parts[0], accessKey, secretKey, securityToken, tablestore.NewDefaultTableStoreConfig())
|
||||||
|
}
|
||||||
|
b.otsTable = d.Get("tablestore_table").(string)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -222,11 +239,6 @@ func (b *Backend) getOSSEndpointByRegion(access_key, secret_key, security_token,
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSdkConfig() *sdk.Config {
|
func getSdkConfig() *sdk.Config {
|
||||||
// Fix bug "open /usr/local/go/lib/time/zoneinfo.zip: no such file or directory" which happened in windows.
|
|
||||||
if data, ok := resource.GetTZData("GMT"); ok {
|
|
||||||
utils.TZData = data
|
|
||||||
utils.LoadLocationFromTZData = time.LoadLocationFromTZData
|
|
||||||
}
|
|
||||||
return sdk.NewConfig().
|
return sdk.NewConfig().
|
||||||
WithMaxRetryTime(5).
|
WithMaxRetryTime(5).
|
||||||
WithTimeout(time.Duration(30) * time.Second).
|
WithTimeout(time.Duration(30) * time.Second).
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/hashicorp/terraform/state/remote"
|
"github.com/hashicorp/terraform/state/remote"
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
|
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
|
||||||
"log"
|
"log"
|
||||||
"path"
|
"path"
|
||||||
)
|
)
|
||||||
|
@ -33,7 +34,32 @@ func (b *Backend) remoteClient(name string) (*RemoteClient, error) {
|
||||||
lockFile: b.lockFile(name),
|
lockFile: b.lockFile(name),
|
||||||
serverSideEncryption: b.serverSideEncryption,
|
serverSideEncryption: b.serverSideEncryption,
|
||||||
acl: b.acl,
|
acl: b.acl,
|
||||||
doLock: b.lock,
|
otsTable: b.otsTable,
|
||||||
|
otsClient: b.otsClient,
|
||||||
|
}
|
||||||
|
if b.otsEndpoint != "" && b.otsTable != "" {
|
||||||
|
table, err := b.otsClient.DescribeTable(&tablestore.DescribeTableRequest{
|
||||||
|
TableName: b.otsTable,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return client, fmt.Errorf("Error describing table store %s: %#v", b.otsTable, err)
|
||||||
|
}
|
||||||
|
for _, t := range table.TableMeta.SchemaEntry {
|
||||||
|
pkMeta := TableStorePrimaryKeyMeta{
|
||||||
|
PKName: *t.Name,
|
||||||
|
}
|
||||||
|
if *t.Type == tablestore.PrimaryKeyType_INTEGER {
|
||||||
|
pkMeta.PKType = "Integer"
|
||||||
|
} else if *t.Type == tablestore.PrimaryKeyType_STRING {
|
||||||
|
pkMeta.PKType = "String"
|
||||||
|
} else if *t.Type == tablestore.PrimaryKeyType_BINARY {
|
||||||
|
pkMeta.PKType = "Binary"
|
||||||
|
} else {
|
||||||
|
return client, fmt.Errorf("Unsupported PrimaryKey type: %d.", *t.Type)
|
||||||
|
}
|
||||||
|
client.otsTabkePK = pkMeta
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return client, nil
|
return client, nil
|
||||||
|
@ -46,7 +72,7 @@ func (b *Backend) Workspaces() ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var options []oss.Option
|
var options []oss.Option
|
||||||
options = append(options, oss.Prefix(b.statePath))
|
options = append(options, oss.Prefix(b.statePrefix+"/"))
|
||||||
resp, err := bucket.ListObjects(options...)
|
resp, err := bucket.ListObjects(options...)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -54,9 +80,17 @@ func (b *Backend) Workspaces() ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
result := []string{backend.DefaultStateName}
|
result := []string{backend.DefaultStateName}
|
||||||
|
prefix := b.statePrefix
|
||||||
for _, obj := range resp.Objects {
|
for _, obj := range resp.Objects {
|
||||||
if b.keyEnv(obj.Key) != "" {
|
// we have 3 parts, the state prefix, the workspace name, and the state file: <prefix>/<worksapce-name>/<key>
|
||||||
result = append(result, b.keyEnv(obj.Key))
|
if path.Join(b.statePrefix, b.stateKey) == obj.Key {
|
||||||
|
// filter the default workspace
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(strings.TrimPrefix(obj.Key, prefix+"/"), "/")
|
||||||
|
if len(parts) > 0 && parts[0] != "" {
|
||||||
|
result = append(result, parts[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,16 +117,13 @@ func (b *Backend) StateMgr(name string) (state.State, error) {
|
||||||
}
|
}
|
||||||
stateMgr := &remote.State{Client: client}
|
stateMgr := &remote.State{Client: client}
|
||||||
|
|
||||||
if !b.lock {
|
|
||||||
stateMgr.DisableLocks()
|
|
||||||
}
|
|
||||||
// Check to see if this state already exists.
|
// Check to see if this state already exists.
|
||||||
existing, err := b.Workspaces()
|
existing, err := b.Workspaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] Current state name: %s. All States:%#v", name, existing)
|
log.Printf("[DEBUG] Current workspace name: %s. All workspaces:%#v", name, existing)
|
||||||
|
|
||||||
exists := false
|
exists := false
|
||||||
for _, s := range existing {
|
for _, s := range existing {
|
||||||
|
@ -146,41 +177,15 @@ func (b *Backend) StateMgr(name string) (state.State, error) {
|
||||||
return stateMgr, nil
|
return stateMgr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract the object name from the OSS key
|
|
||||||
func (b *Backend) keyEnv(key string) string {
|
|
||||||
// we have 3 parts, the state path, the state name, and the state file
|
|
||||||
parts := strings.Split(key, "/")
|
|
||||||
length := len(parts)
|
|
||||||
if length < 3 {
|
|
||||||
// use default state
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// shouldn't happen since we listed by prefix
|
|
||||||
if strings.Join(parts[0:length-2], "/") != b.statePath {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// not our key, so don't include it in our listing
|
|
||||||
if parts[length-1] != b.stateName {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts[length-2]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Backend) stateFile(name string) string {
|
func (b *Backend) stateFile(name string) string {
|
||||||
if name == backend.DefaultStateName {
|
if name == backend.DefaultStateName {
|
||||||
return path.Join(b.statePath, b.stateName)
|
return path.Join(b.statePrefix, b.stateKey)
|
||||||
}
|
}
|
||||||
return path.Join(b.statePath, name, b.stateName)
|
return path.Join(b.statePrefix, name, b.stateKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) lockFile(name string) string {
|
func (b *Backend) lockFile(name string) string {
|
||||||
if name == backend.DefaultStateName {
|
return b.stateFile(name) + lockFileSuffix
|
||||||
return path.Join(b.statePath, b.stateName+lockFileSuffix)
|
|
||||||
}
|
|
||||||
return path.Join(b.statePath, name, b.stateName+lockFileSuffix)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const stateUnlockError = `
|
const stateUnlockError = `
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
"github.com/hashicorp/terraform/config/hcl2shim"
|
"github.com/hashicorp/terraform/config/hcl2shim"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -31,24 +32,26 @@ func TestBackend_impl(t *testing.T) {
|
||||||
func TestBackendConfig(t *testing.T) {
|
func TestBackendConfig(t *testing.T) {
|
||||||
testACC(t)
|
testACC(t)
|
||||||
config := map[string]interface{}{
|
config := map[string]interface{}{
|
||||||
"region": "cn-beijing",
|
"region": "cn-beijing",
|
||||||
"bucket": "terraform-backend-oss-test",
|
"bucket": "terraform-backend-oss-test",
|
||||||
"path": "mystate",
|
"prefix": "mystate",
|
||||||
"name": "first.tfstate",
|
"key": "first.tfstate",
|
||||||
|
"tablestore_endpoint": "https://terraformstate.cn-beijing.ots.aliyuncs.com",
|
||||||
|
"tablestore_table": "TableStore",
|
||||||
}
|
}
|
||||||
|
|
||||||
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend)
|
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend)
|
||||||
|
|
||||||
if !strings.HasPrefix(b.ossClient.Config.Endpoint, "http://oss-cn-beijing") {
|
if !strings.HasPrefix(b.ossClient.Config.Endpoint, "https://oss-cn-beijing") {
|
||||||
t.Fatalf("Incorrect region was provided")
|
t.Fatalf("Incorrect region was provided")
|
||||||
}
|
}
|
||||||
if b.bucketName != "terraform-backend-oss-test" {
|
if b.bucketName != "terraform-backend-oss-test" {
|
||||||
t.Fatalf("Incorrect bucketName was provided")
|
t.Fatalf("Incorrect bucketName was provided")
|
||||||
}
|
}
|
||||||
if b.statePath != "mystate" {
|
if b.statePrefix != "mystate" {
|
||||||
t.Fatalf("Incorrect state file path was provided")
|
t.Fatalf("Incorrect state file path was provided")
|
||||||
}
|
}
|
||||||
if b.stateName != "first.tfstate" {
|
if b.stateKey != "first.tfstate" {
|
||||||
t.Fatalf("Incorrect keyName was provided")
|
t.Fatalf("Incorrect keyName was provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,10 +66,12 @@ func TestBackendConfig(t *testing.T) {
|
||||||
func TestBackendConfig_invalidKey(t *testing.T) {
|
func TestBackendConfig_invalidKey(t *testing.T) {
|
||||||
testACC(t)
|
testACC(t)
|
||||||
cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{
|
cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{
|
||||||
"region": "cn-beijing",
|
"region": "cn-beijing",
|
||||||
"bucket": "terraform-backend-oss-test",
|
"bucket": "terraform-backend-oss-test",
|
||||||
"path": "/leading-slash",
|
"prefix": "/leading-slash",
|
||||||
"name": "/test.tfstate",
|
"name": "/test.tfstate",
|
||||||
|
"tablestore_endpoint": "https://terraformstate.cn-beijing.ots.aliyuncs.com",
|
||||||
|
"tablestore_table": "TableStore",
|
||||||
})
|
})
|
||||||
|
|
||||||
_, results := New().PrepareConfig(cfg)
|
_, results := New().PrepareConfig(cfg)
|
||||||
|
@ -79,16 +84,16 @@ func TestBackend(t *testing.T) {
|
||||||
testACC(t)
|
testACC(t)
|
||||||
|
|
||||||
bucketName := fmt.Sprintf("terraform-remote-oss-test-%x", time.Now().Unix())
|
bucketName := fmt.Sprintf("terraform-remote-oss-test-%x", time.Now().Unix())
|
||||||
statePath := "multi/level/path/"
|
statePrefix := "multi/level/path/"
|
||||||
|
|
||||||
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
"bucket": bucketName,
|
"bucket": bucketName,
|
||||||
"path": statePath,
|
"prefix": statePrefix,
|
||||||
})).(*Backend)
|
})).(*Backend)
|
||||||
|
|
||||||
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
"bucket": bucketName,
|
"bucket": bucketName,
|
||||||
"path": statePath,
|
"prefix": statePrefix,
|
||||||
})).(*Backend)
|
})).(*Backend)
|
||||||
|
|
||||||
createOSSBucket(t, b1.ossClient, bucketName)
|
createOSSBucket(t, b1.ossClient, bucketName)
|
||||||
|
@ -132,3 +137,35 @@ func deleteOSSBucket(t *testing.T, ossClient *oss.Client, bucketName string) {
|
||||||
t.Logf(warning, err)
|
t.Logf(warning, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create the dynamoDB table, and wait until we can query it.
|
||||||
|
func createTablestoreTable(t *testing.T, otsClient *tablestore.TableStoreClient, tableName string) {
|
||||||
|
tableMeta := new(tablestore.TableMeta)
|
||||||
|
tableMeta.TableName = tableName
|
||||||
|
tableMeta.AddPrimaryKeyColumn("testbackend", tablestore.PrimaryKeyType_STRING)
|
||||||
|
|
||||||
|
tableOption := new(tablestore.TableOption)
|
||||||
|
tableOption.TimeToAlive = -1
|
||||||
|
tableOption.MaxVersion = 1
|
||||||
|
|
||||||
|
reservedThroughput := new(tablestore.ReservedThroughput)
|
||||||
|
|
||||||
|
_, err := otsClient.CreateTable(&tablestore.CreateTableRequest{
|
||||||
|
TableMeta: tableMeta,
|
||||||
|
TableOption: tableOption,
|
||||||
|
ReservedThroughput: reservedThroughput,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteTablestoreTable(t *testing.T, otsClient *tablestore.TableStoreClient, tableName string) {
|
||||||
|
params := &tablestore.DeleteTableRequest{
|
||||||
|
TableName: tableName,
|
||||||
|
}
|
||||||
|
_, err := otsClient.DeleteTable(params)
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("WARNING: Failed to delete the test TableStore table %q. It has been left in your Alibaba Cloud account and may incur charges. (error was %s)", tableName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,132 +7,106 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"encoding/hex"
|
||||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
|
||||||
|
"github.com/hashicorp/go-multierror"
|
||||||
uuid "github.com/hashicorp/go-uuid"
|
uuid "github.com/hashicorp/go-uuid"
|
||||||
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
"github.com/hashicorp/terraform/state"
|
"github.com/hashicorp/terraform/state"
|
||||||
"github.com/hashicorp/terraform/state/remote"
|
"github.com/hashicorp/terraform/state/remote"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Store the last saved serial in tablestore with this suffix for consistency checks.
|
||||||
|
const (
|
||||||
|
stateIDSuffix = "-md5"
|
||||||
|
statePKValue = "terraform-remote-state-lock"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// The amount of time we will retry a state waiting for it to match the
|
||||||
|
// expected checksum.
|
||||||
|
consistencyRetryTimeout = 10 * time.Second
|
||||||
|
|
||||||
|
// delay when polling the state
|
||||||
|
consistencyRetryPollInterval = 2 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
// test hook called when checksums don't match
|
||||||
|
var testChecksumHook func()
|
||||||
|
|
||||||
|
type TableStorePrimaryKeyMeta struct {
|
||||||
|
PKName string
|
||||||
|
PKType string
|
||||||
|
}
|
||||||
|
|
||||||
type RemoteClient struct {
|
type RemoteClient struct {
|
||||||
ossClient *oss.Client
|
ossClient *oss.Client
|
||||||
|
otsClient *tablestore.TableStoreClient
|
||||||
bucketName string
|
bucketName string
|
||||||
stateFile string
|
stateFile string
|
||||||
lockFile string
|
lockFile string
|
||||||
serverSideEncryption bool
|
serverSideEncryption bool
|
||||||
acl string
|
acl string
|
||||||
doLock bool
|
|
||||||
info *state.LockInfo
|
info *state.LockInfo
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
otsTable string
|
||||||
|
otsTabkePK TableStorePrimaryKeyMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RemoteClient) Get() (payload *remote.Payload, err error) {
|
func (c *RemoteClient) Get() (payload *remote.Payload, err error) {
|
||||||
c.mu.Lock()
|
deadline := time.Now().Add(consistencyRetryTimeout)
|
||||||
defer c.mu.Unlock()
|
|
||||||
|
|
||||||
buf, err := c.getObj(c.stateFile)
|
// If we have a checksum, and the returned payload doesn't match, we retry
|
||||||
if err != nil {
|
// up until deadline.
|
||||||
return nil, err
|
for {
|
||||||
}
|
payload, err = c.getObj()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// If there was no data, then return nil
|
// If the remote state was manually removed the payload will be nil,
|
||||||
if buf == nil || len(buf.Bytes()) == 0 {
|
// but if there's still a digest entry for that state we will still try
|
||||||
log.Printf("[DEBUG] State %s has no data.", c.stateFile)
|
// to compare the MD5 below.
|
||||||
return nil, nil
|
var digest []byte
|
||||||
}
|
if payload != nil {
|
||||||
md5 := md5.Sum(buf.Bytes())
|
digest = payload.MD5
|
||||||
|
}
|
||||||
|
|
||||||
payload = &remote.Payload{
|
// verify that this state is what we expect
|
||||||
Data: buf.Bytes(),
|
if expected, err := c.getMD5(); err != nil {
|
||||||
MD5: md5[:],
|
log.Printf("[WARN] failed to fetch state md5: %s", err)
|
||||||
|
} else if len(expected) > 0 && !bytes.Equal(expected, digest) {
|
||||||
|
log.Printf("[WARN] state md5 mismatch: expected '%x', got '%x'", expected, digest)
|
||||||
|
|
||||||
|
if testChecksumHook != nil {
|
||||||
|
testChecksumHook()
|
||||||
|
}
|
||||||
|
|
||||||
|
if time.Now().Before(deadline) {
|
||||||
|
time.Sleep(consistencyRetryPollInterval)
|
||||||
|
log.Println("[INFO] retrying OSS RemoteClient.Get...")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf(errBadChecksumFmt, digest)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
}
|
}
|
||||||
return payload, nil
|
return payload, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RemoteClient) Put(data []byte) error {
|
func (c *RemoteClient) Put(data []byte) error {
|
||||||
c.mu.Lock()
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
|
|
||||||
return c.putObj(c.stateFile, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RemoteClient) Delete() error {
|
|
||||||
c.mu.Lock()
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
|
|
||||||
return c.deleteObj(c.stateFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) {
|
|
||||||
c.mu.Lock()
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
|
|
||||||
if !c.doLock {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
bucket, err := c.ossClient.Bucket(c.bucketName)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("Error getting bucket: %#v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
infoJson, err := json.Marshal(info)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.ID == "" {
|
|
||||||
lockID, err := uuid.GenerateUUID()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
info.ID = lockID
|
|
||||||
}
|
|
||||||
|
|
||||||
info.Path = c.lockFile
|
|
||||||
exist, err := bucket.IsObjectExist(info.Path)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("Error checking object %s: %#v", info.Path, err)
|
|
||||||
}
|
|
||||||
if !exist {
|
|
||||||
if err := c.putObj(info.Path, infoJson); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
} else if _, err := c.validLock(info.ID); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return info.ID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RemoteClient) Unlock(id string) error {
|
|
||||||
c.mu.Lock()
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
|
|
||||||
if !c.doLock {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
lockInfo, err := c.validLock(id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.deleteObj(c.lockFile); err != nil {
|
|
||||||
return &state.LockError{
|
|
||||||
Info: lockInfo,
|
|
||||||
Err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RemoteClient) putObj(key string, data []byte) error {
|
|
||||||
bucket, err := c.ossClient.Bucket(c.bucketName)
|
bucket, err := c.ossClient.Bucket(c.bucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting bucket: %#v", err)
|
return fmt.Errorf("Error getting bucket: %#v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
body := bytes.NewReader(data)
|
body := bytes.NewReader(data)
|
||||||
|
|
||||||
var options []oss.Option
|
var options []oss.Option
|
||||||
|
@ -146,28 +120,321 @@ func (c *RemoteClient) putObj(key string, data []byte) error {
|
||||||
options = append(options, oss.ContentLength(int64(len(data))))
|
options = append(options, oss.ContentLength(int64(len(data))))
|
||||||
|
|
||||||
if body != nil {
|
if body != nil {
|
||||||
if err := bucket.PutObject(key, body, options...); err != nil {
|
if err := bucket.PutObject(c.stateFile, body, options...); err != nil {
|
||||||
return fmt.Errorf("failed to upload %s: %#v", key, err)
|
return fmt.Errorf("Failed to upload state %s: %#v", c.stateFile, err)
|
||||||
}
|
}
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
sum := md5.Sum(data)
|
||||||
|
if err := c.putMD5(sum[:]); err != nil {
|
||||||
|
// if this errors out, we unfortunately have to error out altogether,
|
||||||
|
// since the next Get will inevitably fail.
|
||||||
|
return fmt.Errorf("Failed to store state MD5: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RemoteClient) getObj(key string) (*bytes.Buffer, error) {
|
func (c *RemoteClient) Delete() error {
|
||||||
bucket, err := c.ossClient.Bucket(c.bucketName)
|
bucket, err := c.ossClient.Bucket(c.bucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error getting bucket: %#v", err)
|
return fmt.Errorf("Error getting bucket %s: %#v", c.bucketName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if exist, err := bucket.IsObjectExist(key); err != nil {
|
log.Printf("[DEBUG] Deleting remote state from OSS: %#v", c.stateFile)
|
||||||
return nil, fmt.Errorf("Estimating object %s is exist got an error: %#v", key, err)
|
|
||||||
|
if err := bucket.DeleteObject(c.stateFile); err != nil {
|
||||||
|
return fmt.Errorf("Error deleting state %s: %#v", c.stateFile, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.deleteMD5(); err != nil {
|
||||||
|
log.Printf("[WARN] Error deleting state MD5: %s", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) {
|
||||||
|
if c.otsTable == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.ID == "" {
|
||||||
|
lockID, err := uuid.GenerateUUID()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
info.ID = lockID
|
||||||
|
}
|
||||||
|
|
||||||
|
putParams := &tablestore.PutRowChange{
|
||||||
|
TableName: c.otsTable,
|
||||||
|
PrimaryKey: &tablestore.PrimaryKey{
|
||||||
|
PrimaryKeys: []*tablestore.PrimaryKeyColumn{
|
||||||
|
{
|
||||||
|
ColumnName: c.otsTabkePK.PKName,
|
||||||
|
Value: c.getPKValue(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Columns: []tablestore.AttributeColumn{
|
||||||
|
{
|
||||||
|
ColumnName: "LockID",
|
||||||
|
Value: c.lockFile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ColumnName: "Info",
|
||||||
|
Value: string(info.Marshal()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Condition: &tablestore.RowCondition{
|
||||||
|
RowExistenceExpectation: tablestore.RowExistenceExpectation_EXPECT_NOT_EXIST,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Recoring state lock in tablestore: %#v", putParams)
|
||||||
|
|
||||||
|
_, err := c.otsClient.PutRow(&tablestore.PutRowRequest{
|
||||||
|
PutRowChange: putParams,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[WARN] Error storing state lock in tablestore: %#v", err)
|
||||||
|
lockInfo, infoErr := c.getLockInfo()
|
||||||
|
if infoErr != nil {
|
||||||
|
log.Printf("[WARN] Error getting lock info: %#v", err)
|
||||||
|
err = multierror.Append(err, infoErr)
|
||||||
|
}
|
||||||
|
lockErr := &state.LockError{
|
||||||
|
Err: err,
|
||||||
|
Info: lockInfo,
|
||||||
|
}
|
||||||
|
log.Printf("[WARN] state lock error: %#v", lockErr)
|
||||||
|
return "", lockErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return info.ID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RemoteClient) getMD5() ([]byte, error) {
|
||||||
|
if c.otsTable == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
getParams := &tablestore.SingleRowQueryCriteria{
|
||||||
|
TableName: c.otsTable,
|
||||||
|
PrimaryKey: &tablestore.PrimaryKey{
|
||||||
|
PrimaryKeys: []*tablestore.PrimaryKeyColumn{
|
||||||
|
{
|
||||||
|
ColumnName: c.otsTabkePK.PKName,
|
||||||
|
Value: c.getPKValue(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ColumnsToGet: []string{"LockID", "Digest"},
|
||||||
|
MaxVersion: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Retrieving state serial in tablestore: %#v", getParams)
|
||||||
|
|
||||||
|
object, err := c.otsClient.GetRow(&tablestore.GetRowRequest{
|
||||||
|
SingleRowQueryCriteria: getParams,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var val string
|
||||||
|
if v, ok := object.GetColumnMap().Columns["Digest"]; ok && len(v) > 0 {
|
||||||
|
val = v[0].Value.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
sum, err := hex.DecodeString(val)
|
||||||
|
if err != nil || len(sum) != md5.Size {
|
||||||
|
return nil, errors.New("invalid md5")
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the hash of the state to that clients can check for stale state files.
|
||||||
|
func (c *RemoteClient) putMD5(sum []byte) error {
|
||||||
|
if c.otsTable == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sum) != md5.Size {
|
||||||
|
return errors.New("invalid payload md5")
|
||||||
|
}
|
||||||
|
|
||||||
|
putParams := &tablestore.PutRowChange{
|
||||||
|
TableName: c.otsTable,
|
||||||
|
PrimaryKey: &tablestore.PrimaryKey{
|
||||||
|
PrimaryKeys: []*tablestore.PrimaryKeyColumn{
|
||||||
|
{
|
||||||
|
ColumnName: c.otsTabkePK.PKName,
|
||||||
|
Value: c.getPKValue(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Columns: []tablestore.AttributeColumn{
|
||||||
|
{
|
||||||
|
ColumnName: "LockID",
|
||||||
|
Value: c.lockPath() + stateIDSuffix,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ColumnName: "Digest",
|
||||||
|
Value: hex.EncodeToString(sum),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Condition: &tablestore.RowCondition{
|
||||||
|
RowExistenceExpectation: tablestore.RowExistenceExpectation_EXPECT_NOT_EXIST,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Recoring state serial in tablestore: %#v", putParams)
|
||||||
|
|
||||||
|
_, err := c.otsClient.PutRow(&tablestore.PutRowRequest{
|
||||||
|
PutRowChange: putParams,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[WARN] failed to record state serial in tablestore: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the hash value for a deleted state
|
||||||
|
func (c *RemoteClient) deleteMD5() error {
|
||||||
|
if c.otsTable == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
params := &tablestore.DeleteRowRequest{
|
||||||
|
DeleteRowChange: &tablestore.DeleteRowChange{
|
||||||
|
TableName: c.otsTable,
|
||||||
|
PrimaryKey: &tablestore.PrimaryKey{
|
||||||
|
PrimaryKeys: []*tablestore.PrimaryKeyColumn{
|
||||||
|
{
|
||||||
|
ColumnName: c.otsTabkePK.PKName,
|
||||||
|
Value: c.getPKValue(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Condition: &tablestore.RowCondition{
|
||||||
|
RowExistenceExpectation: tablestore.RowExistenceExpectation_EXPECT_EXIST,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting state serial in tablestore: %#v", params)
|
||||||
|
|
||||||
|
if _, err := c.otsClient.DeleteRow(params); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) {
|
||||||
|
getParams := &tablestore.SingleRowQueryCriteria{
|
||||||
|
TableName: c.otsTable,
|
||||||
|
PrimaryKey: &tablestore.PrimaryKey{
|
||||||
|
PrimaryKeys: []*tablestore.PrimaryKeyColumn{
|
||||||
|
{
|
||||||
|
ColumnName: c.otsTabkePK.PKName,
|
||||||
|
Value: c.getPKValue(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ColumnsToGet: []string{"LockID", "Info"},
|
||||||
|
MaxVersion: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Retrieving state lock info from tablestore: %#v", getParams)
|
||||||
|
|
||||||
|
object, err := c.otsClient.GetRow(&tablestore.GetRowRequest{
|
||||||
|
SingleRowQueryCriteria: getParams,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var infoData string
|
||||||
|
if v, ok := object.GetColumnMap().Columns["Info"]; ok && len(v) > 0 {
|
||||||
|
infoData = v[0].Value.(string)
|
||||||
|
}
|
||||||
|
lockInfo := &state.LockInfo{}
|
||||||
|
err = json.Unmarshal([]byte(infoData), lockInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return lockInfo, nil
|
||||||
|
}
|
||||||
|
func (c *RemoteClient) Unlock(id string) error {
|
||||||
|
if c.otsTable == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
lockErr := &state.LockError{}
|
||||||
|
|
||||||
|
lockInfo, err := c.getLockInfo()
|
||||||
|
if err != nil {
|
||||||
|
lockErr.Err = fmt.Errorf("failed to retrieve lock info: %s", err)
|
||||||
|
return lockErr
|
||||||
|
}
|
||||||
|
lockErr.Info = lockInfo
|
||||||
|
|
||||||
|
if lockInfo.ID != id {
|
||||||
|
lockErr.Err = fmt.Errorf("lock id %q does not match existing lock", id)
|
||||||
|
return lockErr
|
||||||
|
}
|
||||||
|
params := &tablestore.DeleteRowRequest{
|
||||||
|
DeleteRowChange: &tablestore.DeleteRowChange{
|
||||||
|
TableName: c.otsTable,
|
||||||
|
PrimaryKey: &tablestore.PrimaryKey{
|
||||||
|
PrimaryKeys: []*tablestore.PrimaryKeyColumn{
|
||||||
|
{
|
||||||
|
ColumnName: c.otsTabkePK.PKName,
|
||||||
|
Value: c.getPKValue(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Condition: &tablestore.RowCondition{
|
||||||
|
RowExistenceExpectation: tablestore.RowExistenceExpectation_EXPECT_EXIST,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Deleting state lock from tablestore: %#v", params)
|
||||||
|
|
||||||
|
_, err = c.otsClient.DeleteRow(params)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
lockErr.Err = err
|
||||||
|
return lockErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RemoteClient) lockPath() string {
|
||||||
|
return fmt.Sprintf("%s/%s", c.bucketName, c.stateFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RemoteClient) getObj() (*remote.Payload, error) {
|
||||||
|
bucket, err := c.ossClient.Bucket(c.bucketName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error getting bucket %s: %#v", c.bucketName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if exist, err := bucket.IsObjectExist(c.stateFile); err != nil {
|
||||||
|
return nil, fmt.Errorf("Estimating object %s is exist got an error: %#v", c.stateFile, err)
|
||||||
} else if !exist {
|
} else if !exist {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var options []oss.Option
|
var options []oss.Option
|
||||||
output, err := bucket.GetObject(key, options...)
|
output, err := bucket.GetObject(c.stateFile, options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error getting object: %#v", err)
|
return nil, fmt.Errorf("Error getting object: %#v", err)
|
||||||
}
|
}
|
||||||
|
@ -176,51 +443,42 @@ func (c *RemoteClient) getObj(key string) (*bytes.Buffer, error) {
|
||||||
if _, err := io.Copy(buf, output); err != nil {
|
if _, err := io.Copy(buf, output); err != nil {
|
||||||
return nil, fmt.Errorf("Failed to read remote state: %s", err)
|
return nil, fmt.Errorf("Failed to read remote state: %s", err)
|
||||||
}
|
}
|
||||||
return buf, nil
|
sum := md5.Sum(buf.Bytes())
|
||||||
}
|
payload := &remote.Payload{
|
||||||
|
Data: buf.Bytes(),
|
||||||
func (c *RemoteClient) deleteObj(key string) error {
|
MD5: sum[:],
|
||||||
bucket, err := c.ossClient.Bucket(c.bucketName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error getting bucket: %#v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bucket.DeleteObject(key); err != nil {
|
// If there was no data, then return nil
|
||||||
return fmt.Errorf("Error deleting object %s: %#v", key, err)
|
if len(payload.Data) == 0 {
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// lockInfo reads the lock file, parses its contents and returns the parsed
|
|
||||||
// LockInfo struct.
|
|
||||||
func (c *RemoteClient) lockInfo() (*state.LockInfo, error) {
|
|
||||||
buf, err := c.getObj(c.lockFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if buf == nil || len(buf.Bytes()) == 0 {
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
info := &state.LockInfo{}
|
|
||||||
if err := json.Unmarshal(buf.Bytes(), info); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return info, nil
|
return payload, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RemoteClient) validLock(id string) (*state.LockInfo, *state.LockError) {
|
func (c *RemoteClient) getPKValue() (value interface{}) {
|
||||||
lockErr := &state.LockError{}
|
value = statePKValue
|
||||||
lockInfo, err := c.lockInfo()
|
if c.otsTabkePK.PKType == "Integer" {
|
||||||
if err != nil {
|
value = hashcode.String(statePKValue)
|
||||||
lockErr.Err = fmt.Errorf("failed to retrieve lock info: %s", err)
|
} else if c.otsTabkePK.PKType == "Binary" {
|
||||||
return nil, lockErr
|
value = stringToBin(statePKValue)
|
||||||
}
|
}
|
||||||
lockErr.Info = lockInfo
|
return
|
||||||
|
|
||||||
if lockInfo.ID != id {
|
|
||||||
lockErr.Err = fmt.Errorf("lock id %q does not match existing lock", id)
|
|
||||||
return nil, lockErr
|
|
||||||
}
|
|
||||||
return lockInfo, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stringToBin(s string) (binString string) {
|
||||||
|
for _, c := range s {
|
||||||
|
binString = fmt.Sprintf("%s%b", binString, c)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const errBadChecksumFmt = `state data in OSS does not have the expected content.
|
||||||
|
|
||||||
|
This may be caused by unusually long delays in OSS processing a previous state
|
||||||
|
update. Please wait for a minute or two and try again. If this problem
|
||||||
|
persists, and neither OSS nor TableStore are experiencing an outage, you may need
|
||||||
|
to manually verify the remote state and update the Digest value stored in the
|
||||||
|
TableStore table to the following value: %x
|
||||||
|
`
|
||||||
|
|
|
@ -2,14 +2,21 @@ package oss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
"github.com/hashicorp/terraform/backend"
|
"github.com/hashicorp/terraform/backend"
|
||||||
"github.com/hashicorp/terraform/state"
|
"github.com/hashicorp/terraform/state"
|
||||||
"github.com/hashicorp/terraform/state/remote"
|
"github.com/hashicorp/terraform/state/remote"
|
||||||
|
"github.com/hashicorp/terraform/states/statefile"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NOTE: Before running this testcase, please create a OTS instance called 'tf-oss-remote'
|
||||||
|
var RemoteTestUsedOTSEndpoint = "https://tf-oss-remote.cn-hangzhou.ots.aliyuncs.com"
|
||||||
|
|
||||||
func TestRemoteClient_impl(t *testing.T) {
|
func TestRemoteClient_impl(t *testing.T) {
|
||||||
var _ remote.Client = new(RemoteClient)
|
var _ remote.Client = new(RemoteClient)
|
||||||
var _ remote.ClientLocker = new(RemoteClient)
|
var _ remote.ClientLocker = new(RemoteClient)
|
||||||
|
@ -17,12 +24,12 @@ func TestRemoteClient_impl(t *testing.T) {
|
||||||
|
|
||||||
func TestRemoteClient(t *testing.T) {
|
func TestRemoteClient(t *testing.T) {
|
||||||
testACC(t)
|
testACC(t)
|
||||||
bucketName := fmt.Sprintf("terraform-remote-oss-test-%x", time.Now().Unix())
|
bucketName := fmt.Sprintf("tf-remote-oss-test-%x", time.Now().Unix())
|
||||||
path := "testState"
|
path := "testState"
|
||||||
|
|
||||||
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
"bucket": bucketName,
|
"bucket": bucketName,
|
||||||
"path": path,
|
"prefix": path,
|
||||||
"encrypt": true,
|
"encrypt": true,
|
||||||
})).(*Backend)
|
})).(*Backend)
|
||||||
|
|
||||||
|
@ -37,76 +44,287 @@ func TestRemoteClient(t *testing.T) {
|
||||||
remote.TestClient(t, state.(*remote.State).Client)
|
remote.TestClient(t, state.(*remote.State).Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOSS_stateLock(t *testing.T) {
|
func TestRemoteClientLocks(t *testing.T) {
|
||||||
testACC(t)
|
testACC(t)
|
||||||
bucketName := fmt.Sprintf("terraform-remote-oss-test-%x", time.Now().Unix())
|
bucketName := fmt.Sprintf("tf-remote-oss-test-%x", time.Now().Unix())
|
||||||
|
tableName := fmt.Sprintf("tfRemoteTestForce%x", time.Now().Unix())
|
||||||
path := "testState"
|
path := "testState"
|
||||||
|
|
||||||
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
"bucket": bucketName,
|
"bucket": bucketName,
|
||||||
"path": path,
|
"prefix": path,
|
||||||
"encrypt": true,
|
"encrypt": true,
|
||||||
|
"tablestore_table": tableName,
|
||||||
|
"tablestore_endpoint": RemoteTestUsedOTSEndpoint,
|
||||||
})).(*Backend)
|
})).(*Backend)
|
||||||
|
|
||||||
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
"bucket": bucketName,
|
"bucket": bucketName,
|
||||||
"path": path,
|
"prefix": path,
|
||||||
"encrypt": true,
|
"encrypt": true,
|
||||||
|
"tablestore_table": tableName,
|
||||||
|
"tablestore_endpoint": RemoteTestUsedOTSEndpoint,
|
||||||
})).(*Backend)
|
})).(*Backend)
|
||||||
|
|
||||||
createOSSBucket(t, b1.ossClient, bucketName)
|
createOSSBucket(t, b1.ossClient, bucketName)
|
||||||
defer deleteOSSBucket(t, b1.ossClient, bucketName)
|
defer deleteOSSBucket(t, b1.ossClient, bucketName)
|
||||||
|
createTablestoreTable(t, b1.otsClient, tableName)
|
||||||
|
defer deleteTablestoreTable(t, b1.otsClient, tableName)
|
||||||
|
|
||||||
s1, err := b1.StateMgr(backend.DefaultStateName)
|
s1, err := b1.StateMgr(backend.DefaultStateName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s2, err := b2.StateMgr(backend.DefaultStateName)
|
s2, err := b2.StateMgr(backend.DefaultStateName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
remote.TestRemoteLocks(t, s1.(*remote.State).Client, s2.(*remote.State).Client)
|
remote.TestRemoteLocks(t, s1.(*remote.State).Client, s2.(*remote.State).Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify that we can unlock a state with an existing lock
|
// verify that we can unlock a state with an existing lock
|
||||||
func TestOSS_destroyLock(t *testing.T) {
|
func TestRemoteForceUnlock(t *testing.T) {
|
||||||
testACC(t)
|
testACC(t)
|
||||||
bucketName := fmt.Sprintf("terraform-remote-oss-test-%x", time.Now().Unix())
|
bucketName := fmt.Sprintf("tf-remote-oss-test-force-%x", time.Now().Unix())
|
||||||
|
tableName := fmt.Sprintf("tfRemoteTestForce%x", time.Now().Unix())
|
||||||
|
path := "testState"
|
||||||
|
|
||||||
|
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
|
"bucket": bucketName,
|
||||||
|
"prefix": path,
|
||||||
|
"encrypt": true,
|
||||||
|
"tablestore_table": tableName,
|
||||||
|
"tablestore_endpoint": RemoteTestUsedOTSEndpoint,
|
||||||
|
})).(*Backend)
|
||||||
|
|
||||||
|
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
|
"bucket": bucketName,
|
||||||
|
"prefix": path,
|
||||||
|
"encrypt": true,
|
||||||
|
"tablestore_table": tableName,
|
||||||
|
"tablestore_endpoint": RemoteTestUsedOTSEndpoint,
|
||||||
|
})).(*Backend)
|
||||||
|
|
||||||
|
createOSSBucket(t, b1.ossClient, bucketName)
|
||||||
|
defer deleteOSSBucket(t, b1.ossClient, bucketName)
|
||||||
|
createTablestoreTable(t, b1.otsClient, tableName)
|
||||||
|
defer deleteTablestoreTable(t, b1.otsClient, tableName)
|
||||||
|
|
||||||
|
// first test with default
|
||||||
|
s1, err := b1.StateMgr(backend.DefaultStateName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
info := state.NewLockInfo()
|
||||||
|
info.Operation = "test"
|
||||||
|
info.Who = "clientA"
|
||||||
|
|
||||||
|
lockID, err := s1.Lock(info)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("unable to get initial lock:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// s1 is now locked, get the same state through s2 and unlock it
|
||||||
|
s2, err := b2.StateMgr(backend.DefaultStateName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to get default state to force unlock:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s2.Unlock(lockID); err != nil {
|
||||||
|
t.Fatal("failed to force-unlock default state")
|
||||||
|
}
|
||||||
|
|
||||||
|
// now try the same thing with a named state
|
||||||
|
// first test with default
|
||||||
|
s1, err = b1.StateMgr("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
info = state.NewLockInfo()
|
||||||
|
info.Operation = "test"
|
||||||
|
info.Who = "clientA"
|
||||||
|
|
||||||
|
lockID, err = s1.Lock(info)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("unable to get initial lock:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// s1 is now locked, get the same state through s2 and unlock it
|
||||||
|
s2, err = b2.StateMgr("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to get named state to force unlock:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = s2.Unlock(lockID); err != nil {
|
||||||
|
t.Fatal("failed to force-unlock named state")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoteClient_clientMD5(t *testing.T) {
|
||||||
|
testACC(t)
|
||||||
|
|
||||||
|
bucketName := fmt.Sprintf("tf-remote-oss-test-%x", time.Now().Unix())
|
||||||
|
tableName := fmt.Sprintf("tfRemoteTestForce%x", time.Now().Unix())
|
||||||
path := "testState"
|
path := "testState"
|
||||||
|
|
||||||
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
"bucket": bucketName,
|
"bucket": bucketName,
|
||||||
"path": path,
|
"prefix": path,
|
||||||
"encrypt": true,
|
"tablestore_table": tableName,
|
||||||
|
"tablestore_endpoint": RemoteTestUsedOTSEndpoint,
|
||||||
})).(*Backend)
|
})).(*Backend)
|
||||||
|
|
||||||
createOSSBucket(t, b.ossClient, bucketName)
|
createOSSBucket(t, b.ossClient, bucketName)
|
||||||
defer deleteOSSBucket(t, b.ossClient, bucketName)
|
defer deleteOSSBucket(t, b.ossClient, bucketName)
|
||||||
|
createTablestoreTable(t, b.otsClient, tableName)
|
||||||
|
defer deleteTablestoreTable(t, b.otsClient, tableName)
|
||||||
|
|
||||||
s, err := b.StateMgr(backend.DefaultStateName)
|
s, err := b.StateMgr(backend.DefaultStateName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
client := s.(*remote.State).Client.(*RemoteClient)
|
||||||
|
|
||||||
|
sum := md5.Sum([]byte("test"))
|
||||||
|
|
||||||
|
if err := client.putMD5(sum[:]); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := s.(*remote.State).Client.(*RemoteClient)
|
getSum, err := client.getMD5()
|
||||||
|
|
||||||
info := state.NewLockInfo()
|
|
||||||
id, err := c.Lock(info)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Unlock(id); err != nil {
|
if !bytes.Equal(getSum, sum[:]) {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("getMD5 returned the wrong checksum: expected %x, got %x", sum[:], getSum)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.getObj(c.lockFile)
|
if err := client.deleteMD5(); err != nil {
|
||||||
if err != nil {
|
t.Fatal(err)
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
}
|
||||||
if res != nil && res.String() != "" {
|
|
||||||
t.Fatalf("lock key not cleaned up at: %s", string(c.stateFile))
|
if getSum, err := client.getMD5(); err == nil {
|
||||||
|
t.Fatalf("expected getMD5 error, got none. checksum: %x", getSum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify that a client won't return a state with an incorrect checksum.
|
||||||
|
func TestRemoteClient_stateChecksum(t *testing.T) {
|
||||||
|
testACC(t)
|
||||||
|
|
||||||
|
bucketName := fmt.Sprintf("tf-remote-oss-test-%x", time.Now().Unix())
|
||||||
|
tableName := fmt.Sprintf("tfRemoteTestForce%x", time.Now().Unix())
|
||||||
|
path := "testState"
|
||||||
|
|
||||||
|
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
|
"bucket": bucketName,
|
||||||
|
"prefix": path,
|
||||||
|
"tablestore_table": tableName,
|
||||||
|
"tablestore_endpoint": RemoteTestUsedOTSEndpoint,
|
||||||
|
})).(*Backend)
|
||||||
|
|
||||||
|
createOSSBucket(t, b1.ossClient, bucketName)
|
||||||
|
defer deleteOSSBucket(t, b1.ossClient, bucketName)
|
||||||
|
createTablestoreTable(t, b1.otsClient, tableName)
|
||||||
|
defer deleteTablestoreTable(t, b1.otsClient, tableName)
|
||||||
|
|
||||||
|
s1, err := b1.StateMgr(backend.DefaultStateName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
client1 := s1.(*remote.State).Client
|
||||||
|
|
||||||
|
// create an old and new state version to persist
|
||||||
|
s := state.TestStateInitial()
|
||||||
|
sf := &statefile.File{State: s}
|
||||||
|
var oldState bytes.Buffer
|
||||||
|
if err := statefile.Write(sf, &oldState); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
sf.Serial++
|
||||||
|
var newState bytes.Buffer
|
||||||
|
if err := statefile.Write(sf, &newState); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use b2 without a tablestore_table to bypass the lock table to write the state directly.
|
||||||
|
// client2 will write the "incorrect" state, simulating oss eventually consistency delays
|
||||||
|
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||||
|
"bucket": bucketName,
|
||||||
|
"prefix": path,
|
||||||
|
})).(*Backend)
|
||||||
|
s2, err := b2.StateMgr(backend.DefaultStateName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
client2 := s2.(*remote.State).Client
|
||||||
|
|
||||||
|
// write the new state through client2 so that there is no checksum yet
|
||||||
|
if err := client2.Put(newState.Bytes()); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify that we can pull a state without a checksum
|
||||||
|
if _, err := client1.Get(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the new state back with its checksum
|
||||||
|
if err := client1.Put(newState.Bytes()); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// put an empty state in place to check for panics during get
|
||||||
|
if err := client2.Put([]byte{}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the timeouts so we can fail immediately
|
||||||
|
origTimeout := consistencyRetryTimeout
|
||||||
|
origInterval := consistencyRetryPollInterval
|
||||||
|
defer func() {
|
||||||
|
consistencyRetryTimeout = origTimeout
|
||||||
|
consistencyRetryPollInterval = origInterval
|
||||||
|
}()
|
||||||
|
consistencyRetryTimeout = 0
|
||||||
|
consistencyRetryPollInterval = 0
|
||||||
|
|
||||||
|
// fetching an empty state through client1 should now error out due to a
|
||||||
|
// mismatched checksum.
|
||||||
|
if _, err := client1.Get(); !strings.HasPrefix(err.Error(), errBadChecksumFmt[:80]) {
|
||||||
|
t.Fatalf("expected state checksum error: got %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// put the old state in place of the new, without updating the checksum
|
||||||
|
if err := client2.Put(oldState.Bytes()); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetching the wrong state through client1 should now error out due to a
|
||||||
|
// mismatched checksum.
|
||||||
|
if _, err := client1.Get(); !strings.HasPrefix(err.Error(), errBadChecksumFmt[:80]) {
|
||||||
|
t.Fatalf("expected state checksum error: got %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the state with the correct one after we Get again
|
||||||
|
testChecksumHook = func() {
|
||||||
|
if err := client2.Put(newState.Bytes()); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
testChecksumHook = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
consistencyRetryTimeout = origTimeout
|
||||||
|
|
||||||
|
// this final Get will fail to fail the checksum verification, the above
|
||||||
|
// callback will update the state with the correct version, and Get should
|
||||||
|
// retry automatically.
|
||||||
|
if _, err := client1.Get(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,14 @@ package config
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[ManagedResourceMode-0]
|
||||||
|
_ = x[DataResourceMode-1]
|
||||||
|
}
|
||||||
|
|
||||||
const _ResourceMode_name = "ManagedResourceModeDataResourceMode"
|
const _ResourceMode_name = "ManagedResourceModeDataResourceMode"
|
||||||
|
|
||||||
var _ResourceMode_index = [...]uint8{0, 19, 35}
|
var _ResourceMode_index = [...]uint8{0, 19, 35}
|
||||||
|
|
|
@ -4,6 +4,15 @@ package configs
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[ProvisionerOnFailureInvalid-0]
|
||||||
|
_ = x[ProvisionerOnFailureContinue-1]
|
||||||
|
_ = x[ProvisionerOnFailureFail-2]
|
||||||
|
}
|
||||||
|
|
||||||
const _ProvisionerOnFailure_name = "ProvisionerOnFailureInvalidProvisionerOnFailureContinueProvisionerOnFailureFail"
|
const _ProvisionerOnFailure_name = "ProvisionerOnFailureInvalidProvisionerOnFailureContinueProvisionerOnFailureFail"
|
||||||
|
|
||||||
var _ProvisionerOnFailure_index = [...]uint8{0, 27, 55, 79}
|
var _ProvisionerOnFailure_index = [...]uint8{0, 27, 55, 79}
|
||||||
|
|
|
@ -4,6 +4,15 @@ package configs
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[ProvisionerWhenInvalid-0]
|
||||||
|
_ = x[ProvisionerWhenCreate-1]
|
||||||
|
_ = x[ProvisionerWhenDestroy-2]
|
||||||
|
}
|
||||||
|
|
||||||
const _ProvisionerWhen_name = "ProvisionerWhenInvalidProvisionerWhenCreateProvisionerWhenDestroy"
|
const _ProvisionerWhen_name = "ProvisionerWhenInvalidProvisionerWhenCreateProvisionerWhenDestroy"
|
||||||
|
|
||||||
var _ProvisionerWhen_index = [...]uint8{0, 22, 43, 65}
|
var _ProvisionerWhen_index = [...]uint8{0, 22, 43, 65}
|
||||||
|
|
|
@ -4,6 +4,16 @@ package configs
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[TypeHintNone-0]
|
||||||
|
_ = x[TypeHintString-83]
|
||||||
|
_ = x[TypeHintList-76]
|
||||||
|
_ = x[TypeHintMap-77]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_VariableTypeHint_name_0 = "TypeHintNone"
|
_VariableTypeHint_name_0 = "TypeHintNone"
|
||||||
_VariableTypeHint_name_1 = "TypeHintListTypeHintMap"
|
_VariableTypeHint_name_1 = "TypeHintListTypeHintMap"
|
||||||
|
|
7
go.mod
7
go.mod
|
@ -8,14 +8,16 @@ require (
|
||||||
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af // indirect
|
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af // indirect
|
||||||
github.com/agext/levenshtein v1.2.2
|
github.com/agext/levenshtein v1.2.2
|
||||||
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 // indirect
|
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 // indirect
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190104080739-ef2ef6084d8f
|
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70
|
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70
|
||||||
|
github.com/aliyun/aliyun-tablestore-go-sdk v4.1.2+incompatible
|
||||||
github.com/apparentlymart/go-cidr v1.0.0
|
github.com/apparentlymart/go-cidr v1.0.0
|
||||||
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0
|
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0
|
||||||
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
|
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
|
||||||
github.com/armon/go-radix v1.0.0 // indirect
|
github.com/armon/go-radix v1.0.0 // indirect
|
||||||
github.com/aws/aws-sdk-go v1.16.36
|
github.com/aws/aws-sdk-go v1.16.36
|
||||||
|
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
|
||||||
github.com/blang/semver v3.5.1+incompatible
|
github.com/blang/semver v3.5.1+incompatible
|
||||||
github.com/boltdb/bolt v1.3.1 // indirect
|
github.com/boltdb/bolt v1.3.1 // indirect
|
||||||
github.com/chzyer/logex v1.1.10 // indirect
|
github.com/chzyer/logex v1.1.10 // indirect
|
||||||
|
@ -97,7 +99,7 @@ require (
|
||||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||||
github.com/packer-community/winrmcp v0.0.0-20180102160824-81144009af58
|
github.com/packer-community/winrmcp v0.0.0-20180102160824-81144009af58
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c // indirect
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c // indirect
|
||||||
github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17 // indirect
|
github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17
|
||||||
github.com/posener/complete v1.2.1
|
github.com/posener/complete v1.2.1
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
|
||||||
github.com/sirupsen/logrus v1.1.1 // indirect
|
github.com/sirupsen/logrus v1.1.1 // indirect
|
||||||
|
@ -121,6 +123,7 @@ require (
|
||||||
golang.org/x/oauth2 v0.0.0-20190220154721-9b3c75971fc9
|
golang.org/x/oauth2 v0.0.0-20190220154721-9b3c75971fc9
|
||||||
google.golang.org/api v0.1.0
|
google.golang.org/api v0.1.0
|
||||||
google.golang.org/grpc v1.18.0
|
google.golang.org/grpc v1.18.0
|
||||||
|
gopkg.in/ini.v1 v1.42.0 // indirect
|
||||||
gopkg.in/vmihailenco/msgpack.v2 v2.9.1 // indirect
|
gopkg.in/vmihailenco/msgpack.v2 v2.9.1 // indirect
|
||||||
labix.org/v2/mgo v0.0.0-20140701140051-000000000287 // indirect
|
labix.org/v2/mgo v0.0.0-20140701140051-000000000287 // indirect
|
||||||
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect
|
||||||
|
|
10
go.sum
10
go.sum
|
@ -28,10 +28,12 @@ github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXva
|
||||||
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||||
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 h1:LoeFxdq5zUCBQPhbQKE6zvoGwHMxCBlqwbH9+9kHoHA=
|
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6 h1:LoeFxdq5zUCBQPhbQKE6zvoGwHMxCBlqwbH9+9kHoHA=
|
||||||
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190104080739-ef2ef6084d8f h1:pM8wn2zKfEVQkR9cj//GkywiJXMwtZ9feuNsEkHqBC8=
|
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a h1:APorzFpCcv6wtD5vmRWYqNm4N55kbepL7c7kTq9XI6A=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190104080739-ef2ef6084d8f/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA=
|
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA=
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70 h1:FrF4uxA24DF3ARNXVbUin3wa5fDLaB1Cy8mKks/LRz4=
|
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70 h1:FrF4uxA24DF3ARNXVbUin3wa5fDLaB1Cy8mKks/LRz4=
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||||
|
github.com/aliyun/aliyun-tablestore-go-sdk v4.1.2+incompatible h1:ABQ7FF+IxSFHDMOTtjCfmMDMHiCq6EsAoCV/9sFinaM=
|
||||||
|
github.com/aliyun/aliyun-tablestore-go-sdk v4.1.2+incompatible/go.mod h1:LDQHRZylxvcg8H7wBIDfvO5g/cy4/sz1iucBlc2l3Jw=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e h1:ptBAamGVd6CfRsUtyHD+goy2JGhv1QC32v3gqM8mYAM=
|
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e h1:ptBAamGVd6CfRsUtyHD+goy2JGhv1QC32v3gqM8mYAM=
|
||||||
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
|
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
|
||||||
|
@ -55,6 +57,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI
|
||||||
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
|
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
|
||||||
github.com/aws/aws-sdk-go v1.16.36 h1:POeH34ZME++pr7GBGh+ZO6Y5kOwSMQpqp5BGUgooJ6k=
|
github.com/aws/aws-sdk-go v1.16.36 h1:POeH34ZME++pr7GBGh+ZO6Y5kOwSMQpqp5BGUgooJ6k=
|
||||||
github.com/aws/aws-sdk-go v1.16.36/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.16.36/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
|
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
|
||||||
|
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
|
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
|
||||||
|
@ -514,6 +518,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
||||||
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
|
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
|
||||||
|
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/vmihailenco/msgpack.v2 v2.9.1 h1:kb0VV7NuIojvRfzwslQeP3yArBqJHW9tOl4t38VS1jM=
|
gopkg.in/vmihailenco/msgpack.v2 v2.9.1 h1:kb0VV7NuIojvRfzwslQeP3yArBqJHW9tOl4t38VS1jM=
|
||||||
gopkg.in/vmihailenco/msgpack.v2 v2.9.1/go.mod h1:/3Dn1Npt9+MYyLpYYXjInO/5jvMLamn+AEGwNEOatn8=
|
gopkg.in/vmihailenco/msgpack.v2 v2.9.1/go.mod h1:/3Dn1Npt9+MYyLpYYXjInO/5jvMLamn+AEGwNEOatn8=
|
||||||
|
|
|
@ -4,6 +4,18 @@ package schema
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[getSourceState-1]
|
||||||
|
_ = x[getSourceConfig-2]
|
||||||
|
_ = x[getSourceDiff-4]
|
||||||
|
_ = x[getSourceSet-8]
|
||||||
|
_ = x[getSourceExact-16]
|
||||||
|
_ = x[getSourceLevelMask-15]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_getSource_name_0 = "getSourceStategetSourceConfig"
|
_getSource_name_0 = "getSourceStategetSourceConfig"
|
||||||
_getSource_name_1 = "getSourceDiff"
|
_getSource_name_1 = "getSourceDiff"
|
||||||
|
|
|
@ -4,6 +4,21 @@ package schema
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[TypeInvalid-0]
|
||||||
|
_ = x[TypeBool-1]
|
||||||
|
_ = x[TypeInt-2]
|
||||||
|
_ = x[TypeFloat-3]
|
||||||
|
_ = x[TypeString-4]
|
||||||
|
_ = x[TypeList-5]
|
||||||
|
_ = x[TypeMap-6]
|
||||||
|
_ = x[TypeSet-7]
|
||||||
|
_ = x[typeObject-8]
|
||||||
|
}
|
||||||
|
|
||||||
const _ValueType_name = "TypeInvalidTypeBoolTypeIntTypeFloatTypeStringTypeListTypeMapTypeSettypeObject"
|
const _ValueType_name = "TypeInvalidTypeBoolTypeIntTypeFloatTypeStringTypeListTypeMapTypeSettypeObject"
|
||||||
|
|
||||||
var _ValueType_index = [...]uint8{0, 11, 19, 26, 35, 45, 53, 60, 67, 77}
|
var _ValueType_index = [...]uint8{0, 11, 19, 26, 35, 45, 53, 60, 67, 77}
|
||||||
|
|
|
@ -4,6 +4,19 @@ package plans
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[NoOp-0]
|
||||||
|
_ = x[Create-43]
|
||||||
|
_ = x[Read-8592]
|
||||||
|
_ = x[Update-126]
|
||||||
|
_ = x[DeleteThenCreate-8723]
|
||||||
|
_ = x[CreateThenDelete-177]
|
||||||
|
_ = x[Delete-45]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_Action_name_0 = "NoOp"
|
_Action_name_0 = "NoOp"
|
||||||
_Action_name_1 = "Create"
|
_Action_name_1 = "Create"
|
||||||
|
|
|
@ -4,6 +4,15 @@ package states
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[NoEach-0]
|
||||||
|
_ = x[EachList-76]
|
||||||
|
_ = x[EachMap-77]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_EachMode_name_0 = "NoEach"
|
_EachMode_name_0 = "NoEach"
|
||||||
_EachMode_name_1 = "EachListEachMap"
|
_EachMode_name_1 = "EachListEachMap"
|
||||||
|
|
|
@ -4,6 +4,15 @@ package states
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[ObjectReady-82]
|
||||||
|
_ = x[ObjectTainted-84]
|
||||||
|
_ = x[ObjectPlanned-80]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_ObjectStatus_name_0 = "ObjectPlanned"
|
_ObjectStatus_name_0 = "ObjectPlanned"
|
||||||
_ObjectStatus_name_1 = "ObjectReady"
|
_ObjectStatus_name_1 = "ObjectReady"
|
||||||
|
|
|
@ -4,6 +4,17 @@ package statemgr
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[SnapshotOlder-60]
|
||||||
|
_ = x[SnapshotNewer-62]
|
||||||
|
_ = x[SnapshotEqual-61]
|
||||||
|
_ = x[SnapshotUnrelated-33]
|
||||||
|
_ = x[SnapshotLegacy-63]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_SnapshotMetaRel_name_0 = "SnapshotUnrelated"
|
_SnapshotMetaRel_name_0 = "SnapshotUnrelated"
|
||||||
_SnapshotMetaRel_name_1 = "SnapshotOlderSnapshotEqualSnapshotNewerSnapshotLegacy"
|
_SnapshotMetaRel_name_1 = "SnapshotOlderSnapshotEqualSnapshotNewerSnapshotLegacy"
|
||||||
|
|
|
@ -4,6 +4,20 @@ package terraform
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[GraphTypeInvalid-0]
|
||||||
|
_ = x[GraphTypeLegacy-1]
|
||||||
|
_ = x[GraphTypeRefresh-2]
|
||||||
|
_ = x[GraphTypePlan-3]
|
||||||
|
_ = x[GraphTypePlanDestroy-4]
|
||||||
|
_ = x[GraphTypeApply-5]
|
||||||
|
_ = x[GraphTypeValidate-6]
|
||||||
|
_ = x[GraphTypeEval-7]
|
||||||
|
}
|
||||||
|
|
||||||
const _GraphType_name = "GraphTypeInvalidGraphTypeLegacyGraphTypeRefreshGraphTypePlanGraphTypePlanDestroyGraphTypeApplyGraphTypeValidateGraphTypeEval"
|
const _GraphType_name = "GraphTypeInvalidGraphTypeLegacyGraphTypeRefreshGraphTypePlanGraphTypePlanDestroyGraphTypeApplyGraphTypeValidateGraphTypeEval"
|
||||||
|
|
||||||
var _GraphType_index = [...]uint8{0, 16, 31, 47, 60, 80, 94, 111, 124}
|
var _GraphType_index = [...]uint8{0, 16, 31, 47, 60, 80, 94, 111, 124}
|
||||||
|
|
|
@ -4,6 +4,16 @@ package terraform
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[TypeInvalid-0]
|
||||||
|
_ = x[TypePrimary-1]
|
||||||
|
_ = x[TypeTainted-2]
|
||||||
|
_ = x[TypeDeposed-3]
|
||||||
|
}
|
||||||
|
|
||||||
const _InstanceType_name = "TypeInvalidTypePrimaryTypeTaintedTypeDeposed"
|
const _InstanceType_name = "TypeInvalidTypePrimaryTypeTaintedTypeDeposed"
|
||||||
|
|
||||||
var _InstanceType_index = [...]uint8{0, 11, 22, 33, 44}
|
var _InstanceType_index = [...]uint8{0, 11, 22, 33, 44}
|
||||||
|
|
|
@ -4,6 +4,21 @@ package terraform
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[ValueFromUnknown-0]
|
||||||
|
_ = x[ValueFromConfig-67]
|
||||||
|
_ = x[ValueFromAutoFile-70]
|
||||||
|
_ = x[ValueFromNamedFile-78]
|
||||||
|
_ = x[ValueFromCLIArg-65]
|
||||||
|
_ = x[ValueFromEnvVar-69]
|
||||||
|
_ = x[ValueFromInput-73]
|
||||||
|
_ = x[ValueFromPlan-80]
|
||||||
|
_ = x[ValueFromCaller-83]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_ValueSourceType_name_0 = "ValueFromUnknown"
|
_ValueSourceType_name_0 = "ValueFromUnknown"
|
||||||
_ValueSourceType_name_1 = "ValueFromCLIArg"
|
_ValueSourceType_name_1 = "ValueFromCLIArg"
|
||||||
|
|
|
@ -4,6 +4,21 @@ package terraform
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[walkInvalid-0]
|
||||||
|
_ = x[walkApply-1]
|
||||||
|
_ = x[walkPlan-2]
|
||||||
|
_ = x[walkPlanDestroy-3]
|
||||||
|
_ = x[walkRefresh-4]
|
||||||
|
_ = x[walkValidate-5]
|
||||||
|
_ = x[walkDestroy-6]
|
||||||
|
_ = x[walkImport-7]
|
||||||
|
_ = x[walkEval-8]
|
||||||
|
}
|
||||||
|
|
||||||
const _walkOperation_name = "walkInvalidwalkApplywalkPlanwalkPlanDestroywalkRefreshwalkValidatewalkDestroywalkImportwalkEval"
|
const _walkOperation_name = "walkInvalidwalkApplywalkPlanwalkPlanDestroywalkRefreshwalkValidatewalkDestroywalkImportwalkEval"
|
||||||
|
|
||||||
var _walkOperation_index = [...]uint8{0, 11, 20, 28, 43, 54, 66, 77, 87, 95}
|
var _walkOperation_index = [...]uint8{0, 11, 20, 28, 43, 54, 66, 77, 87, 95}
|
||||||
|
|
|
@ -4,6 +4,14 @@ package tfdiags
|
||||||
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[Error-69]
|
||||||
|
_ = x[Warning-87]
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_Severity_name_0 = "Error"
|
_Severity_name_0 = "Error"
|
||||||
_Severity_name_1 = "Warning"
|
_Severity_name_1 = "Warning"
|
||||||
|
|
12
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go
generated
vendored
Normal file
12
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package credentials
|
||||||
|
|
||||||
|
type BearerTokenCredential struct {
|
||||||
|
BearerToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBearerTokenCredential return a BearerTokenCredential object
|
||||||
|
func NewBearerTokenCredential(token string) *BearerTokenCredential {
|
||||||
|
return &BearerTokenCredential{
|
||||||
|
BearerToken: token,
|
||||||
|
}
|
||||||
|
}
|
24
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go
generated
vendored
24
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go
generated
vendored
|
@ -1,17 +1,5 @@
|
||||||
package credentials
|
package credentials
|
||||||
|
|
||||||
// Deprecated: Use EcsRamRoleCredential in this package instead.
|
|
||||||
type StsRoleNameOnEcsCredential struct {
|
|
||||||
RoleName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Use NewEcsRamRoleCredential in this package instead.
|
|
||||||
func NewStsRoleNameOnEcsCredential(roleName string) *StsRoleNameOnEcsCredential {
|
|
||||||
return &StsRoleNameOnEcsCredential{
|
|
||||||
RoleName: roleName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (oldCred *StsRoleNameOnEcsCredential) ToEcsRamRoleCredential() *EcsRamRoleCredential {
|
func (oldCred *StsRoleNameOnEcsCredential) ToEcsRamRoleCredential() *EcsRamRoleCredential {
|
||||||
return &EcsRamRoleCredential{
|
return &EcsRamRoleCredential{
|
||||||
RoleName: oldCred.RoleName,
|
RoleName: oldCred.RoleName,
|
||||||
|
@ -27,3 +15,15 @@ func NewEcsRamRoleCredential(roleName string) *EcsRamRoleCredential {
|
||||||
RoleName: roleName,
|
RoleName: roleName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use EcsRamRoleCredential in this package instead.
|
||||||
|
type StsRoleNameOnEcsCredential struct {
|
||||||
|
RoleName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NewEcsRamRoleCredential in this package instead.
|
||||||
|
func NewStsRoleNameOnEcsCredential(roleName string) *StsRoleNameOnEcsCredential {
|
||||||
|
return &StsRoleNameOnEcsCredential{
|
||||||
|
RoleName: roleName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
30
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go
generated
vendored
Normal file
30
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
||||||
|
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EnvProvider struct{}
|
||||||
|
|
||||||
|
var ProviderEnv = new(EnvProvider)
|
||||||
|
|
||||||
|
func NewEnvProvider() Provider {
|
||||||
|
return &EnvProvider{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *EnvProvider) Resolve() (auth.Credential, error) {
|
||||||
|
accessKeyID, ok1 := os.LookupEnv(ENVAccessKeyID)
|
||||||
|
accessKeySecret, ok2 := os.LookupEnv(ENVAccessKeySecret)
|
||||||
|
if !ok1 || !ok2 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if accessKeyID == "" || accessKeySecret == "" {
|
||||||
|
return nil, errors.New("Environmental variable (ALIBABACLOUD_ACCESS_KEY_ID or ALIBABACLOUD_ACCESS_KEY_SECRET) is empty")
|
||||||
|
}
|
||||||
|
return credentials.NewAccessKeyCredential(accessKeyID, accessKeySecret), nil
|
||||||
|
}
|
92
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go
generated
vendored
Normal file
92
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/"
|
||||||
|
|
||||||
|
type InstanceCredentialsProvider struct{}
|
||||||
|
|
||||||
|
var ProviderInstance = new(InstanceCredentialsProvider)
|
||||||
|
|
||||||
|
var HookGet = func(fn func(string) (int, []byte, error)) func(string) (int, []byte, error) {
|
||||||
|
return fn
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInstanceCredentialsProvider() Provider {
|
||||||
|
return &InstanceCredentialsProvider{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *InstanceCredentialsProvider) Resolve() (auth.Credential, error) {
|
||||||
|
roleName, ok := os.LookupEnv(ENVEcsMetadata)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if roleName == "" {
|
||||||
|
return nil, errors.New("Environmental variable 'ALIBABA_CLOUD_ECS_METADATA' are empty")
|
||||||
|
}
|
||||||
|
status, content, err := HookGet(get)(securityCredURL + roleName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if status != 200 {
|
||||||
|
if status == 404 {
|
||||||
|
return nil, fmt.Errorf("The role was not found in the instance")
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Received %d when getting security credentials for %s", status, roleName)
|
||||||
|
}
|
||||||
|
body := make(map[string]interface{})
|
||||||
|
|
||||||
|
if err := json.Unmarshal(content, &body); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
accessKeyID, err := extractString(body, "AccessKeyId")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
accessKeySecret, err := extractString(body, "AccessKeySecret")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
securityToken, err := extractString(body, "SecurityToken")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentials.NewStsTokenCredential(accessKeyID, accessKeySecret, securityToken), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func get(url string) (status int, content []byte, err error) {
|
||||||
|
httpClient := http.DefaultClient
|
||||||
|
httpClient.Timeout = time.Second * 1
|
||||||
|
resp, err := httpClient.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
content, err = ioutil.ReadAll(resp.Body)
|
||||||
|
return resp.StatusCode, content, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractString(m map[string]interface{}, key string) (string, error) {
|
||||||
|
raw, ok := m[key]
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("%s not in map", key)
|
||||||
|
}
|
||||||
|
str, ok := raw.(string)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("%s is not a string in map", key)
|
||||||
|
}
|
||||||
|
return str, nil
|
||||||
|
}
|
158
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go
generated
vendored
Normal file
158
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go
generated
vendored
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
||||||
|
|
||||||
|
ini "gopkg.in/ini.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProfileProvider struct {
|
||||||
|
Profile string
|
||||||
|
}
|
||||||
|
|
||||||
|
var ProviderProfile = NewProfileProvider()
|
||||||
|
|
||||||
|
// NewProfileProvider receive zero or more parameters,
|
||||||
|
// when length of name is 0, the value of field Profile will be "default",
|
||||||
|
// and when there are multiple inputs, the function will take the
|
||||||
|
// first one and discard the other values.
|
||||||
|
func NewProfileProvider(name ...string) Provider {
|
||||||
|
p := new(ProfileProvider)
|
||||||
|
if len(name) == 0 {
|
||||||
|
p.Profile = "default"
|
||||||
|
} else {
|
||||||
|
p.Profile = name[0]
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve implements the Provider interface
|
||||||
|
// when credential type is rsa_key_pair, the content of private_key file
|
||||||
|
// must be able to be parsed directly into the required string
|
||||||
|
// that NewRsaKeyPairCredential function needed
|
||||||
|
func (p *ProfileProvider) Resolve() (auth.Credential, error) {
|
||||||
|
path, ok := os.LookupEnv(ENVCredentialFile)
|
||||||
|
if !ok {
|
||||||
|
path, err := checkDefaultPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if path == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
} else if path == "" {
|
||||||
|
return nil, errors.New("Environment variable '" + ENVCredentialFile + "' cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
ini, err := ini.Load(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("ERROR: Can not open file" + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
section, err := ini.GetSection(p.Profile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("ERROR: Can not load section" + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := section.GetKey("type")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("ERROR: Can not find credential type" + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
switch value.String() {
|
||||||
|
case "access_key":
|
||||||
|
value1, err1 := section.GetKey("access_key_id")
|
||||||
|
value2, err2 := section.GetKey("access_key_secret")
|
||||||
|
if err1 != nil || err2 != nil {
|
||||||
|
return nil, errors.New("ERROR: Failed to get value")
|
||||||
|
}
|
||||||
|
if value1.String() == "" || value2.String() == "" {
|
||||||
|
return nil, errors.New("ERROR: Value can't be empty")
|
||||||
|
}
|
||||||
|
return credentials.NewAccessKeyCredential(value1.String(), value2.String()), nil
|
||||||
|
case "ecs_ram_role":
|
||||||
|
value1, err1 := section.GetKey("role_name")
|
||||||
|
if err1 != nil {
|
||||||
|
return nil, errors.New("ERROR: Failed to get value")
|
||||||
|
}
|
||||||
|
if value1.String() == "" {
|
||||||
|
return nil, errors.New("ERROR: Value can't be empty")
|
||||||
|
}
|
||||||
|
return credentials.NewEcsRamRoleCredential(value1.String()), nil
|
||||||
|
case "ram_role_arn":
|
||||||
|
value1, err1 := section.GetKey("access_key_id")
|
||||||
|
value2, err2 := section.GetKey("access_key_secret")
|
||||||
|
value3, err3 := section.GetKey("role_arn")
|
||||||
|
value4, err4 := section.GetKey("role_session_name")
|
||||||
|
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
|
||||||
|
return nil, errors.New("ERROR: Failed to get value")
|
||||||
|
}
|
||||||
|
if value1.String() == "" || value2.String() == "" || value3.String() == "" || value4.String() == "" {
|
||||||
|
return nil, errors.New("ERROR: Value can't be empty")
|
||||||
|
}
|
||||||
|
return credentials.NewRamRoleArnCredential(value1.String(), value2.String(), value3.String(), value4.String(), 3600), nil
|
||||||
|
case "rsa_key_pair":
|
||||||
|
value1, err1 := section.GetKey("public_key_id")
|
||||||
|
value2, err2 := section.GetKey("private_key_file")
|
||||||
|
if err1 != nil || err2 != nil {
|
||||||
|
return nil, errors.New("ERROR: Failed to get value")
|
||||||
|
}
|
||||||
|
if value1.String() == "" || value2.String() == "" {
|
||||||
|
return nil, errors.New("ERROR: Value can't be empty")
|
||||||
|
}
|
||||||
|
file, err := os.Open(value2.String())
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("ERROR: Can not get private_key")
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
var privateKey string
|
||||||
|
scan := bufio.NewScanner(file)
|
||||||
|
var data string
|
||||||
|
for scan.Scan() {
|
||||||
|
if strings.HasPrefix(scan.Text(), "----") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
data += scan.Text() + "\n"
|
||||||
|
}
|
||||||
|
return credentials.NewRsaKeyPairCredential(privateKey, value1.String(), 3600), nil
|
||||||
|
default:
|
||||||
|
return nil, errors.New("ERROR: Failed to get credential")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHomePath return home directory according to the system.
|
||||||
|
// if the environmental virables does not exist, will return empty
|
||||||
|
func GetHomePath() string {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
path, ok := os.LookupEnv("USERPROFILE")
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
path, ok := os.LookupEnv("HOME")
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDefaultPath() (path string, err error) {
|
||||||
|
path = GetHomePath()
|
||||||
|
if path == "" {
|
||||||
|
return "", errors.New("The default credential file path is invalid")
|
||||||
|
}
|
||||||
|
path = strings.Replace("~/.alibabacloud/credentials", "~", path, 1)
|
||||||
|
_, err = os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
19
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go
generated
vendored
Normal file
19
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Environmental virables that may be used by the provider
|
||||||
|
const (
|
||||||
|
ENVAccessKeyID = "ALIBABA_CLOUD_ACCESS_KEY_ID"
|
||||||
|
ENVAccessKeySecret = "ALIBABA_CLOUD_ACCESS_KEY_SECRET"
|
||||||
|
ENVCredentialFile = "ALIBABA_CLOUD_CREDENTIALS_FILE"
|
||||||
|
ENVEcsMetadata = "ALIBABA_CLOUD_ECS_METADATA"
|
||||||
|
PATHCredentialFile = "~/.alibabacloud/credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
// When you want to customize the provider, you only need to implement the method of the interface.
|
||||||
|
type Provider interface {
|
||||||
|
Resolve() (auth.Credential, error)
|
||||||
|
}
|
34
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go
generated
vendored
Normal file
34
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProviderChain struct {
|
||||||
|
Providers []Provider
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultproviders = []Provider{ProviderEnv, ProviderProfile, ProviderInstance}
|
||||||
|
var DefaultChain = NewProviderChain(defaultproviders)
|
||||||
|
|
||||||
|
func NewProviderChain(providers []Provider) Provider {
|
||||||
|
return &ProviderChain{
|
||||||
|
Providers: providers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProviderChain) Resolve() (auth.Credential, error) {
|
||||||
|
for _, provider := range p.Providers {
|
||||||
|
creds, err := provider.Resolve()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if err == nil && creds == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return creds, err
|
||||||
|
}
|
||||||
|
return nil, errors.New("No credential found")
|
||||||
|
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ type RamRoleArnCredential struct {
|
||||||
RoleArn string
|
RoleArn string
|
||||||
RoleSessionName string
|
RoleSessionName string
|
||||||
RoleSessionExpiration int
|
RoleSessionExpiration int
|
||||||
|
Policy string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: Use RamRoleArnCredential in this package instead.
|
// Deprecated: Use RamRoleArnCredential in this package instead.
|
||||||
|
@ -47,3 +48,14 @@ func NewRamRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionN
|
||||||
RoleSessionExpiration: roleSessionExpiration,
|
RoleSessionExpiration: roleSessionExpiration,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewRamRoleArnWithPolicyCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string, roleSessionExpiration int) *RamRoleArnCredential {
|
||||||
|
return &RamRoleArnCredential{
|
||||||
|
AccessKeyId: accessKeyId,
|
||||||
|
AccessKeySecret: accessKeySecret,
|
||||||
|
RoleArn: roleArn,
|
||||||
|
RoleSessionName: roleSessionName,
|
||||||
|
RoleSessionExpiration: roleSessionExpiration,
|
||||||
|
Policy: policy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
5
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go
generated
vendored
5
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go
generated
vendored
|
@ -62,7 +62,10 @@ func completeROASignParams(request requests.AcsRequest, signer Signer, regionId
|
||||||
headerParams["x-acs-security-token"] = value
|
headerParams["x-acs-security-token"] = value
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if key == "BearerToken" {
|
||||||
|
headerParams["x-acs-bearer-token"] = value
|
||||||
|
continue
|
||||||
|
}
|
||||||
queryParams[key] = value
|
queryParams[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,10 @@ func NewSignerWithCredential(credential Credential, commonApi func(request *requ
|
||||||
{
|
{
|
||||||
signer = signers.NewStsTokenSigner(instance)
|
signer = signers.NewStsTokenSigner(instance)
|
||||||
}
|
}
|
||||||
|
case *credentials.BearerTokenCredential:
|
||||||
|
{
|
||||||
|
signer = signers.NewBearerTokenSigner(instance)
|
||||||
|
}
|
||||||
case *credentials.RamRoleArnCredential:
|
case *credentials.RamRoleArnCredential:
|
||||||
{
|
{
|
||||||
signer, err = signers.NewRamRoleArnSigner(instance, commonApi)
|
signer, err = signers.NewRamRoleArnSigner(instance, commonApi)
|
||||||
|
|
|
@ -34,6 +34,7 @@ func ShaHmac1(source, secret string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Sha256WithRsa(source, secret string) string {
|
func Sha256WithRsa(source, secret string) string {
|
||||||
|
// block, _ := pem.Decode([]byte(secret))
|
||||||
decodeString, err := base64.StdEncoding.DecodeString(secret)
|
decodeString, err := base64.StdEncoding.DecodeString(secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
2
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go
generated
vendored
2
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go
generated
vendored
|
@ -21,7 +21,7 @@ import (
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultInAdvanceScale = 0.8
|
const defaultInAdvanceScale = 0.95
|
||||||
|
|
||||||
type credentialUpdater struct {
|
type credentialUpdater struct {
|
||||||
credentialExpiration int
|
credentialExpiration int
|
||||||
|
|
35
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go
generated
vendored
Normal file
35
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package signers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BearerTokenSigner struct {
|
||||||
|
credential *credentials.BearerTokenCredential
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBearerTokenSigner(credential *credentials.BearerTokenCredential) *BearerTokenSigner {
|
||||||
|
return &BearerTokenSigner{
|
||||||
|
credential: credential,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (signer *BearerTokenSigner) GetExtraParam() map[string]string {
|
||||||
|
return map[string]string{"BearerToken": signer.credential.BearerToken}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*BearerTokenSigner) GetName() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
func (*BearerTokenSigner) GetType() string {
|
||||||
|
return "BEARERTOKEN"
|
||||||
|
}
|
||||||
|
func (*BearerTokenSigner) GetVersion() string {
|
||||||
|
return "1.0"
|
||||||
|
}
|
||||||
|
func (signer *BearerTokenSigner) GetAccessKeyId() (accessKeyId string, err error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
func (signer *BearerTokenSigner) Sign(stringToSign, secretSuffix string) string {
|
||||||
|
return ""
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ import (
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
||||||
"github.com/jmespath/go-jmespath"
|
jmespath "github.com/jmespath/go-jmespath"
|
||||||
)
|
)
|
||||||
|
|
||||||
var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/"
|
var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/"
|
||||||
|
@ -88,7 +88,7 @@ func (signer *EcsRamRoleSigner) GetExtraParam() map[string]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (signer *EcsRamRoleSigner) Sign(stringToSign, secretSuffix string) string {
|
func (signer *EcsRamRoleSigner) Sign(stringToSign, secretSuffix string) string {
|
||||||
secret := signer.sessionCredential.AccessKeyId + secretSuffix
|
secret := signer.sessionCredential.AccessKeySecret + secretSuffix
|
||||||
return ShaHmac1(stringToSign, secret)
|
return ShaHmac1(stringToSign, secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go
generated
vendored
5
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go
generated
vendored
|
@ -24,7 +24,7 @@ import (
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
||||||
"github.com/jmespath/go-jmespath"
|
jmespath "github.com/jmespath/go-jmespath"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SignerKeyPair struct {
|
type SignerKeyPair struct {
|
||||||
|
@ -97,7 +97,7 @@ func (signer *SignerKeyPair) GetExtraParam() map[string]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (signer *SignerKeyPair) Sign(stringToSign, secretSuffix string) string {
|
func (signer *SignerKeyPair) Sign(stringToSign, secretSuffix string) string {
|
||||||
secret := signer.sessionCredential.AccessKeyId + secretSuffix
|
secret := signer.sessionCredential.AccessKeySecret + secretSuffix
|
||||||
return ShaHmac1(stringToSign, secret)
|
return ShaHmac1(stringToSign, secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ func (signer *SignerKeyPair) buildCommonRequest() (request *requests.CommonReque
|
||||||
request.Version = "2015-04-01"
|
request.Version = "2015-04-01"
|
||||||
request.ApiName = "GenerateSessionAccessKey"
|
request.ApiName = "GenerateSessionAccessKey"
|
||||||
request.Scheme = requests.HTTPS
|
request.Scheme = requests.HTTPS
|
||||||
|
request.SetDomain("sts.ap-northeast-1.aliyuncs.com")
|
||||||
request.QueryParams["PublicKeyId"] = signer.credential.PublicKeyId
|
request.QueryParams["PublicKeyId"] = signer.credential.PublicKeyId
|
||||||
request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration)
|
request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration)
|
||||||
return
|
return
|
||||||
|
|
|
@ -25,7 +25,7 @@ import (
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
||||||
"github.com/jmespath/go-jmespath"
|
jmespath "github.com/jmespath/go-jmespath"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -119,6 +119,9 @@ func (signer *RamRoleArnSigner) buildCommonRequest() (request *requests.CommonRe
|
||||||
request.ApiName = "AssumeRole"
|
request.ApiName = "AssumeRole"
|
||||||
request.Scheme = requests.HTTPS
|
request.Scheme = requests.HTTPS
|
||||||
request.QueryParams["RoleArn"] = signer.credential.RoleArn
|
request.QueryParams["RoleArn"] = signer.credential.RoleArn
|
||||||
|
if signer.credential.Policy != "" {
|
||||||
|
request.QueryParams["Policy"] = signer.credential.Policy
|
||||||
|
}
|
||||||
request.QueryParams["RoleSessionName"] = signer.credential.RoleSessionName
|
request.QueryParams["RoleSessionName"] = signer.credential.RoleSessionName
|
||||||
request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration)
|
request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration)
|
||||||
return
|
return
|
||||||
|
|
|
@ -15,12 +15,20 @@
|
||||||
package sdk
|
package sdk
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider"
|
||||||
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
||||||
|
@ -39,6 +47,8 @@ func init() {
|
||||||
|
|
||||||
// Version this value will be replaced while build: -ldflags="-X sdk.version=x.x.x"
|
// Version this value will be replaced while build: -ldflags="-X sdk.version=x.x.x"
|
||||||
var Version = "0.0.1"
|
var Version = "0.0.1"
|
||||||
|
var defaultConnectTimeout = 5 * time.Second
|
||||||
|
var defaultReadTimeout = 10 * time.Second
|
||||||
|
|
||||||
var DefaultUserAgent = fmt.Sprintf("AlibabaCloud (%s; %s) Golang/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version)
|
var DefaultUserAgent = fmt.Sprintf("AlibabaCloud (%s; %s) Golang/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version)
|
||||||
|
|
||||||
|
@ -48,12 +58,18 @@ var hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *
|
||||||
|
|
||||||
// Client the type Client
|
// Client the type Client
|
||||||
type Client struct {
|
type Client struct {
|
||||||
|
isInsecure bool
|
||||||
regionId string
|
regionId string
|
||||||
config *Config
|
config *Config
|
||||||
|
httpProxy string
|
||||||
|
httpsProxy string
|
||||||
|
noProxy string
|
||||||
userAgent map[string]string
|
userAgent map[string]string
|
||||||
signer auth.Signer
|
signer auth.Signer
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
asyncTaskQueue chan func()
|
asyncTaskQueue chan func()
|
||||||
|
readTimeout time.Duration
|
||||||
|
connectTimeout time.Duration
|
||||||
|
|
||||||
debug bool
|
debug bool
|
||||||
isRunning bool
|
isRunning bool
|
||||||
|
@ -65,6 +81,51 @@ func (client *Client) Init() (err error) {
|
||||||
panic("not support yet")
|
panic("not support yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetHTTPSInsecure(isInsecure bool) {
|
||||||
|
client.isInsecure = isInsecure
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) GetHTTPSInsecure() bool {
|
||||||
|
return client.isInsecure
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetHttpsProxy(httpsProxy string) {
|
||||||
|
client.httpsProxy = httpsProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) GetHttpsProxy() string {
|
||||||
|
return client.httpsProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetHttpProxy(httpProxy string) {
|
||||||
|
client.httpProxy = httpProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) GetHttpProxy() string {
|
||||||
|
return client.httpProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetNoProxy(noProxy string) {
|
||||||
|
client.noProxy = noProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) GetNoProxy() string {
|
||||||
|
return client.noProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitWithProviderChain will get credential from the providerChain,
|
||||||
|
// the RsaKeyPairCredential Only applicable to regionID `ap-northeast-1`,
|
||||||
|
// if your providerChain may return a credential type with RsaKeyPairCredential,
|
||||||
|
// please ensure your regionID is `ap-northeast-1`.
|
||||||
|
func (client *Client) InitWithProviderChain(regionId string, provider provider.Provider) (err error) {
|
||||||
|
config := client.InitClientConfig()
|
||||||
|
credential, err := provider.Resolve()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return client.InitWithOptions(regionId, config, credential)
|
||||||
|
}
|
||||||
|
|
||||||
func (client *Client) InitWithOptions(regionId string, config *Config, credential auth.Credential) (err error) {
|
func (client *Client) InitWithOptions(regionId string, config *Config, credential auth.Credential) (err error) {
|
||||||
client.isRunning = true
|
client.isRunning = true
|
||||||
client.asyncChanLock = new(sync.RWMutex)
|
client.asyncChanLock = new(sync.RWMutex)
|
||||||
|
@ -89,6 +150,57 @@ func (client *Client) InitWithOptions(regionId string, config *Config, credentia
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetReadTimeout(readTimeout time.Duration) {
|
||||||
|
client.readTimeout = readTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetConnectTimeout(connectTimeout time.Duration) {
|
||||||
|
client.connectTimeout = connectTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) GetReadTimeout() time.Duration {
|
||||||
|
return client.readTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) GetConnectTimeout() time.Duration {
|
||||||
|
return client.connectTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) getHttpProxy(scheme string) (proxy *url.URL, err error) {
|
||||||
|
if scheme == "https" {
|
||||||
|
if client.GetHttpsProxy() != "" {
|
||||||
|
proxy, err = url.Parse(client.httpsProxy)
|
||||||
|
} else if rawurl := os.Getenv("HTTPS_PROXY"); rawurl != "" {
|
||||||
|
proxy, err = url.Parse(rawurl)
|
||||||
|
} else if rawurl := os.Getenv("https_proxy"); rawurl != "" {
|
||||||
|
proxy, err = url.Parse(rawurl)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if client.GetHttpProxy() != "" {
|
||||||
|
proxy, err = url.Parse(client.httpProxy)
|
||||||
|
} else if rawurl := os.Getenv("HTTP_PROXY"); rawurl != "" {
|
||||||
|
proxy, err = url.Parse(rawurl)
|
||||||
|
} else if rawurl := os.Getenv("http_proxy"); rawurl != "" {
|
||||||
|
proxy, err = url.Parse(rawurl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxy, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) getNoProxy(scheme string) []string {
|
||||||
|
var urls []string
|
||||||
|
if client.GetNoProxy() != "" {
|
||||||
|
urls = strings.Split(client.noProxy, ",")
|
||||||
|
} else if rawurl := os.Getenv("NO_PROXY"); rawurl != "" {
|
||||||
|
urls = strings.Split(rawurl, ",")
|
||||||
|
} else if rawurl := os.Getenv("no_proxy"); rawurl != "" {
|
||||||
|
urls = strings.Split(rawurl, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
return urls
|
||||||
|
}
|
||||||
|
|
||||||
// EnableAsync enable the async task queue
|
// EnableAsync enable the async task queue
|
||||||
func (client *Client) EnableAsync(routinePoolSize, maxTaskQueueSize int) {
|
func (client *Client) EnableAsync(routinePoolSize, maxTaskQueueSize int) {
|
||||||
client.asyncTaskQueue = make(chan func(), maxTaskQueueSize)
|
client.asyncTaskQueue = make(chan func(), maxTaskQueueSize)
|
||||||
|
@ -136,6 +248,18 @@ func (client *Client) InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret,
|
||||||
return client.InitWithOptions(regionId, config, credential)
|
return client.InitWithOptions(regionId, config, credential)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *Client) InitWithRamRoleArnAndPolicy(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string) (err error) {
|
||||||
|
config := client.InitClientConfig()
|
||||||
|
credential := &credentials.RamRoleArnCredential{
|
||||||
|
AccessKeyId: accessKeyId,
|
||||||
|
AccessKeySecret: accessKeySecret,
|
||||||
|
RoleArn: roleArn,
|
||||||
|
RoleSessionName: roleSessionName,
|
||||||
|
Policy: policy,
|
||||||
|
}
|
||||||
|
return client.InitWithOptions(regionId, config, credential)
|
||||||
|
}
|
||||||
|
|
||||||
func (client *Client) InitWithRsaKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) {
|
func (client *Client) InitWithRsaKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) {
|
||||||
config := client.InitClientConfig()
|
config := client.InitClientConfig()
|
||||||
credential := &credentials.RsaKeyPairCredential{
|
credential := &credentials.RsaKeyPairCredential{
|
||||||
|
@ -154,6 +278,14 @@ func (client *Client) InitWithEcsRamRole(regionId, roleName string) (err error)
|
||||||
return client.InitWithOptions(regionId, config, credential)
|
return client.InitWithOptions(regionId, config, credential)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *Client) InitWithBearerToken(regionId, bearerToken string) (err error) {
|
||||||
|
config := client.InitClientConfig()
|
||||||
|
credential := &credentials.BearerTokenCredential{
|
||||||
|
BearerToken: bearerToken,
|
||||||
|
}
|
||||||
|
return client.InitWithOptions(regionId, config, credential)
|
||||||
|
}
|
||||||
|
|
||||||
func (client *Client) InitClientConfig() (config *Config) {
|
func (client *Client) InitClientConfig() (config *Config) {
|
||||||
if client.config != nil {
|
if client.config != nil {
|
||||||
return client.config
|
return client.config
|
||||||
|
@ -260,13 +392,103 @@ func (client *Client) BuildRequestWithSigner(request requests.AcsRequest, signer
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *Client) getTimeout(request requests.AcsRequest) (time.Duration, time.Duration) {
|
||||||
|
readTimeout := defaultReadTimeout
|
||||||
|
connectTimeout := defaultConnectTimeout
|
||||||
|
|
||||||
|
reqReadTimeout := request.GetReadTimeout()
|
||||||
|
reqConnectTimeout := request.GetConnectTimeout()
|
||||||
|
if reqReadTimeout != 0*time.Millisecond {
|
||||||
|
readTimeout = reqReadTimeout
|
||||||
|
} else if client.readTimeout != 0*time.Millisecond {
|
||||||
|
readTimeout = client.readTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
if reqConnectTimeout != 0*time.Millisecond {
|
||||||
|
connectTimeout = reqConnectTimeout
|
||||||
|
} else if client.connectTimeout != 0*time.Millisecond {
|
||||||
|
connectTimeout = client.connectTimeout
|
||||||
|
}
|
||||||
|
return readTimeout, connectTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func Timeout(connectTimeout, readTimeout time.Duration) func(cxt context.Context, net, addr string) (c net.Conn, err error) {
|
||||||
|
return func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
conn, err := (&net.Dialer{
|
||||||
|
Timeout: connectTimeout,
|
||||||
|
KeepAlive: 0 * time.Second,
|
||||||
|
DualStack: true,
|
||||||
|
}).DialContext(ctx, network, address)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
conn.SetDeadline(time.Now().Add(readTimeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) setTimeout(request requests.AcsRequest) {
|
||||||
|
readTimeout, connectTimeout := client.getTimeout(request)
|
||||||
|
if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil {
|
||||||
|
trans.DialContext = Timeout(connectTimeout, readTimeout)
|
||||||
|
client.httpClient.Transport = trans
|
||||||
|
} else {
|
||||||
|
client.httpClient.Transport = &http.Transport{
|
||||||
|
DialContext: Timeout(connectTimeout, readTimeout),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) getHTTPSInsecure(request requests.AcsRequest) (insecure bool) {
|
||||||
|
if request.GetHTTPSInsecure() != nil {
|
||||||
|
insecure = *request.GetHTTPSInsecure()
|
||||||
|
} else {
|
||||||
|
insecure = client.GetHTTPSInsecure()
|
||||||
|
}
|
||||||
|
return insecure
|
||||||
|
}
|
||||||
|
|
||||||
func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) {
|
func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) {
|
||||||
httpRequest, err := client.buildRequestWithSigner(request, signer)
|
httpRequest, err := client.buildRequestWithSigner(request, signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
client.setTimeout(request)
|
||||||
|
proxy, err := client.getHttpProxy(httpRequest.URL.Scheme)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
noProxy := client.getNoProxy(httpRequest.URL.Scheme)
|
||||||
|
|
||||||
|
var flag bool
|
||||||
|
for _, value := range noProxy {
|
||||||
|
if value == httpRequest.Host {
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set whether to ignore certificate validation.
|
||||||
|
// Default InsecureSkipVerify is false.
|
||||||
|
if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil {
|
||||||
|
trans.TLSClientConfig = &tls.Config{
|
||||||
|
InsecureSkipVerify: client.getHTTPSInsecure(request),
|
||||||
|
}
|
||||||
|
if proxy != nil && !flag {
|
||||||
|
trans.Proxy = http.ProxyURL(proxy)
|
||||||
|
}
|
||||||
|
client.httpClient.Transport = trans
|
||||||
|
}
|
||||||
|
|
||||||
var httpResponse *http.Response
|
var httpResponse *http.Response
|
||||||
for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
|
for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
|
||||||
|
if proxy != nil && proxy.User != nil{
|
||||||
|
if password, passwordSet := proxy.User.Password(); passwordSet {
|
||||||
|
httpRequest.SetBasicAuth(proxy.User.Username(), password)
|
||||||
|
}
|
||||||
|
}
|
||||||
debug("> %s %s %s", httpRequest.Method, httpRequest.URL.RequestURI(), httpRequest.Proto)
|
debug("> %s %s %s", httpRequest.Method, httpRequest.URL.RequestURI(), httpRequest.Proto)
|
||||||
debug("> Host: %s", httpRequest.Host)
|
debug("> Host: %s", httpRequest.Host)
|
||||||
for key, value := range httpRequest.Header {
|
for key, value := range httpRequest.Header {
|
||||||
|
@ -287,13 +509,19 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
|
||||||
return
|
return
|
||||||
} else if retryTimes >= client.config.MaxRetryTime {
|
} else if retryTimes >= client.config.MaxRetryTime {
|
||||||
// timeout but reached the max retry times, return
|
// timeout but reached the max retry times, return
|
||||||
timeoutErrorMsg := fmt.Sprintf(errors.TimeoutErrorMessage, strconv.Itoa(retryTimes+1), strconv.Itoa(retryTimes+1))
|
var timeoutErrorMsg string
|
||||||
|
if strings.Contains(err.Error(), "read tcp") {
|
||||||
|
timeoutErrorMsg = fmt.Sprintf(errors.TimeoutErrorMessage, strconv.Itoa(retryTimes+1), strconv.Itoa(retryTimes+1)) + " Read timeout. Please set a valid ReadTimeout."
|
||||||
|
} else {
|
||||||
|
timeoutErrorMsg = fmt.Sprintf(errors.TimeoutErrorMessage, strconv.Itoa(retryTimes+1), strconv.Itoa(retryTimes+1)) + " Connect timeout. Please set a valid ConnectTimeout."
|
||||||
|
}
|
||||||
err = errors.NewClientError(errors.TimeoutErrorCode, timeoutErrorMsg, err)
|
err = errors.NewClientError(errors.TimeoutErrorCode, timeoutErrorMsg, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if status code >= 500 or timeout, will trigger retry
|
// if status code >= 500 or timeout, will trigger retry
|
||||||
if client.config.AutoRetry && (err != nil || isServerError(httpResponse)) {
|
if client.config.AutoRetry && (err != nil || isServerError(httpResponse)) {
|
||||||
|
client.setTimeout(request)
|
||||||
// rewrite signatureNonce and signature
|
// rewrite signatureNonce and signature
|
||||||
httpRequest, err = client.buildRequestWithSigner(request, signer)
|
httpRequest, err = client.buildRequestWithSigner(request, signer)
|
||||||
// buildHttpRequest(request, finalSigner, regionId)
|
// buildHttpRequest(request, finalSigner, regionId)
|
||||||
|
@ -304,6 +532,7 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat())
|
err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat())
|
||||||
// wrap server errors
|
// wrap server errors
|
||||||
if serverErr, ok := err.(*errors.ServerError); ok {
|
if serverErr, ok := err.(*errors.ServerError); ok {
|
||||||
|
@ -368,6 +597,18 @@ func NewClient() (client *Client, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewClientWithProvider(regionId string, providers ...provider.Provider) (client *Client, err error) {
|
||||||
|
client = &Client{}
|
||||||
|
var pc provider.Provider
|
||||||
|
if len(providers) == 0 {
|
||||||
|
pc = provider.DefaultChain
|
||||||
|
} else {
|
||||||
|
pc = provider.NewProviderChain(providers)
|
||||||
|
}
|
||||||
|
err = client.InitWithProviderChain(regionId, pc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func NewClientWithOptions(regionId string, config *Config, credential auth.Credential) (client *Client, err error) {
|
func NewClientWithOptions(regionId string, config *Config, credential auth.Credential) (client *Client, err error) {
|
||||||
client = &Client{}
|
client = &Client{}
|
||||||
err = client.InitWithOptions(regionId, config, credential)
|
err = client.InitWithOptions(regionId, config, credential)
|
||||||
|
@ -392,6 +633,12 @@ func NewClientWithRamRoleArn(regionId string, accessKeyId, accessKeySecret, role
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewClientWithRamRoleArnAndPolicy(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string) (client *Client, err error) {
|
||||||
|
client = &Client{}
|
||||||
|
err = client.InitWithRamRoleArnAndPolicy(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func NewClientWithEcsRamRole(regionId string, roleName string) (client *Client, err error) {
|
func NewClientWithEcsRamRole(regionId string, roleName string) (client *Client, err error) {
|
||||||
client = &Client{}
|
client = &Client{}
|
||||||
err = client.InitWithEcsRamRole(regionId, roleName)
|
err = client.InitWithEcsRamRole(regionId, roleName)
|
||||||
|
@ -404,14 +651,10 @@ func NewClientWithRsaKeyPair(regionId string, publicKeyId, privateKey string, se
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: Use NewClientWithRamRoleArn in this package instead.
|
func NewClientWithBearerToken(regionId, bearerToken string) (client *Client, err error) {
|
||||||
func NewClientWithStsRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) {
|
client = &Client{}
|
||||||
return NewClientWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName)
|
err = client.InitWithBearerToken(regionId, bearerToken)
|
||||||
}
|
return
|
||||||
|
|
||||||
// Deprecated: Use NewClientWithEcsRamRole in this package instead.
|
|
||||||
func NewClientWithStsRoleNameOnEcs(regionId string, roleName string) (client *Client, err error) {
|
|
||||||
return NewClientWithEcsRamRole(regionId, roleName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) ProcessCommonRequest(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
|
func (client *Client) ProcessCommonRequest(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
|
||||||
|
@ -440,3 +683,13 @@ func (client *Client) Shutdown() {
|
||||||
}
|
}
|
||||||
client.isRunning = false
|
client.isRunning = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NewClientWithRamRoleArn in this package instead.
|
||||||
|
func NewClientWithStsRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) {
|
||||||
|
return NewClientWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NewClientWithEcsRamRole in this package instead.
|
||||||
|
func NewClientWithStsRoleNameOnEcs(regionId string, roleName string) (client *Client, err error) {
|
||||||
|
return NewClientWithEcsRamRole(regionId, roleName)
|
||||||
|
}
|
||||||
|
|
|
@ -1,409 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 sdk
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
|
||||||
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
type signertest struct {
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *signertest) GetName() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *signertest) GetType() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *signertest) GetVersion() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *signertest) GetAccessKeyId() (string, error) {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *signertest) GetExtraParam() map[string]string {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *signertest) Sign(stringToSign, secretSuffix string) string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_Client(t *testing.T) {
|
|
||||||
defer func() {
|
|
||||||
err := recover()
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
assert.Equal(t, "not support yet", err)
|
|
||||||
}()
|
|
||||||
NewClient()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_NewClientWithOptions(t *testing.T) {
|
|
||||||
c := NewConfig()
|
|
||||||
c.HttpTransport = &http.Transport{
|
|
||||||
IdleConnTimeout: time.Duration(10 * time.Second),
|
|
||||||
}
|
|
||||||
c.EnableAsync = true
|
|
||||||
c.GoRoutinePoolSize = 1
|
|
||||||
c.MaxTaskQueueSize = 1
|
|
||||||
credential := credentials.NewAccessKeyCredential("acesskeyid", "accesskeysecret")
|
|
||||||
client, err := NewClientWithOptions("regionid", c, credential)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_NewClientWithAccessKey(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_NewClientWithStsToken(t *testing.T) {
|
|
||||||
client, err := NewClientWithStsToken("regionid", "acesskeyid", "accesskeysecret", "token")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_NewClientWithRamRoleArn(t *testing.T) {
|
|
||||||
client, err := NewClientWithRamRoleArn("regionid", "acesskeyid", "accesskeysecret", "roleArn", "roleSessionName")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
config := client.InitClientConfig()
|
|
||||||
assert.NotNil(t, config)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_NewClientWithEcsRamRole(t *testing.T) {
|
|
||||||
client, err := NewClientWithEcsRamRole("regionid", "roleName")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_NewClientWithRsaKeyPair(t *testing.T) {
|
|
||||||
client, err := NewClientWithRsaKeyPair("regionid", "publicKey", "privateKey", 3600)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
}
|
|
||||||
|
|
||||||
func mockResponse(statusCode int, content string) (res *http.Response, err error) {
|
|
||||||
status := strconv.Itoa(statusCode)
|
|
||||||
res = &http.Response{
|
|
||||||
Proto: "HTTP/1.1",
|
|
||||||
ProtoMajor: 1,
|
|
||||||
Header: make(http.Header),
|
|
||||||
StatusCode: statusCode,
|
|
||||||
Status: status + " " + http.StatusText(statusCode),
|
|
||||||
}
|
|
||||||
res.Body = ioutil.NopCloser(bytes.NewReader([]byte(content)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_DoAction(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.QueryParams["PageNumber"] = "1"
|
|
||||||
request.QueryParams["PageSize"] = "30"
|
|
||||||
request.TransToAcsRequest()
|
|
||||||
response := responses.NewCommonResponse()
|
|
||||||
origTestHookDo := hookDo
|
|
||||||
defer func() { hookDo = origTestHookDo }()
|
|
||||||
hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
|
|
||||||
return func(req *http.Request) (*http.Response, error) {
|
|
||||||
return mockResponse(200, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = client.DoAction(request, response)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, 200, response.GetHttpStatus())
|
|
||||||
assert.Equal(t, "", response.GetHttpContentString())
|
|
||||||
client.Shutdown()
|
|
||||||
assert.Equal(t, false, client.isRunning)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_DoAction_Timeout(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.QueryParams["PageNumber"] = "1"
|
|
||||||
request.QueryParams["PageSize"] = "30"
|
|
||||||
request.TransToAcsRequest()
|
|
||||||
response := responses.NewCommonResponse()
|
|
||||||
origTestHookDo := hookDo
|
|
||||||
defer func() { hookDo = origTestHookDo }()
|
|
||||||
hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
|
|
||||||
return func(req *http.Request) (*http.Response, error) {
|
|
||||||
return mockResponse(200, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = client.DoAction(request, response)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, 200, response.GetHttpStatus())
|
|
||||||
assert.Equal(t, "", response.GetHttpContentString())
|
|
||||||
client.Shutdown()
|
|
||||||
assert.Equal(t, false, client.isRunning)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_ProcessCommonRequest(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.QueryParams["PageNumber"] = "1"
|
|
||||||
request.QueryParams["PageSize"] = "30"
|
|
||||||
|
|
||||||
origTestHookDo := hookDo
|
|
||||||
defer func() { hookDo = origTestHookDo }()
|
|
||||||
hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
|
|
||||||
return func(req *http.Request) (*http.Response, error) {
|
|
||||||
return mockResponse(200, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response, err := client.ProcessCommonRequest(request)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, 200, response.GetHttpStatus())
|
|
||||||
assert.Equal(t, "", response.GetHttpContentString())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_DoAction_With500(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.QueryParams["PageNumber"] = "1"
|
|
||||||
request.QueryParams["PageSize"] = "30"
|
|
||||||
request.TransToAcsRequest()
|
|
||||||
response := responses.NewCommonResponse()
|
|
||||||
origTestHookDo := hookDo
|
|
||||||
defer func() { hookDo = origTestHookDo }()
|
|
||||||
hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
|
|
||||||
return func(req *http.Request) (*http.Response, error) {
|
|
||||||
return mockResponse(500, "Server Internel Error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = client.DoAction(request, response)
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
assert.Equal(t, "SDK.ServerError\nErrorCode: \nRecommend: \nRequestId: \nMessage: Server Internel Error", err.Error())
|
|
||||||
assert.Equal(t, 500, response.GetHttpStatus())
|
|
||||||
assert.Equal(t, "Server Internel Error", response.GetHttpContentString())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_BuildRequestWithSigner(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.QueryParams["PageNumber"] = "1"
|
|
||||||
request.QueryParams["PageSize"] = "30"
|
|
||||||
request.RegionId = "regionid"
|
|
||||||
request.TransToAcsRequest()
|
|
||||||
client.config.UserAgent = "user_agent"
|
|
||||||
err = client.BuildRequestWithSigner(request, nil)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_BuildRequestWithSigner1(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.QueryParams["PageNumber"] = "1"
|
|
||||||
request.QueryParams["PageSize"] = "30"
|
|
||||||
request.RegionId = "regionid"
|
|
||||||
request.TransToAcsRequest()
|
|
||||||
signer := &signertest{
|
|
||||||
name: "signer",
|
|
||||||
}
|
|
||||||
err = client.BuildRequestWithSigner(request, signer)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_ProcessCommonRequestWithSigner(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.QueryParams["PageNumber"] = "1"
|
|
||||||
request.QueryParams["PageSize"] = "30"
|
|
||||||
request.RegionId = "regionid"
|
|
||||||
signer := &signertest{
|
|
||||||
name: "signer",
|
|
||||||
}
|
|
||||||
_, err = client.ProcessCommonRequestWithSigner(request, signer)
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_AppendUserAgent(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.RegionId = "regionid"
|
|
||||||
signer := &signertest{
|
|
||||||
name: "signer",
|
|
||||||
}
|
|
||||||
request.TransToAcsRequest()
|
|
||||||
httpRequest, err := client.buildRequestWithSigner(request, signer)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, DefaultUserAgent, httpRequest.Header.Get("User-Agent"))
|
|
||||||
|
|
||||||
client.AppendUserAgent("test", "1.01")
|
|
||||||
httpRequest, err = client.buildRequestWithSigner(request, signer)
|
|
||||||
assert.Equal(t, DefaultUserAgent+" test/1.01", httpRequest.Header.Get("User-Agent"))
|
|
||||||
|
|
||||||
request.AppendUserAgent("test", "2.01")
|
|
||||||
httpRequest, err = client.buildRequestWithSigner(request, signer)
|
|
||||||
assert.Equal(t, DefaultUserAgent+" test/2.01", httpRequest.Header.Get("User-Agent"))
|
|
||||||
|
|
||||||
request.AppendUserAgent("test", "2.02")
|
|
||||||
httpRequest, err = client.buildRequestWithSigner(request, signer)
|
|
||||||
assert.Equal(t, DefaultUserAgent+" test/2.02", httpRequest.Header.Get("User-Agent"))
|
|
||||||
|
|
||||||
client.AppendUserAgent("test", "2.01")
|
|
||||||
httpRequest, err = client.buildRequestWithSigner(request, signer)
|
|
||||||
assert.Equal(t, DefaultUserAgent+" test/2.02", httpRequest.Header.Get("User-Agent"))
|
|
||||||
|
|
||||||
client.AppendUserAgent("core", "1.01")
|
|
||||||
httpRequest, err = client.buildRequestWithSigner(request, signer)
|
|
||||||
assert.Equal(t, DefaultUserAgent+" test/2.02", httpRequest.Header.Get("User-Agent"))
|
|
||||||
|
|
||||||
request.AppendUserAgent("core", "1.01")
|
|
||||||
httpRequest, err = client.buildRequestWithSigner(request, signer)
|
|
||||||
assert.Equal(t, DefaultUserAgent+" test/2.02", httpRequest.Header.Get("User-Agent"))
|
|
||||||
|
|
||||||
request1 := requests.NewCommonRequest()
|
|
||||||
request1.Domain = "ecs.aliyuncs.com"
|
|
||||||
request1.Version = "2014-05-26"
|
|
||||||
request1.ApiName = "DescribeRegions"
|
|
||||||
request1.RegionId = "regionid"
|
|
||||||
request1.AppendUserAgent("sys", "1.01")
|
|
||||||
request1.TransToAcsRequest()
|
|
||||||
httpRequest, err = client.buildRequestWithSigner(request1, signer)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, DefaultUserAgent+" test/2.01 sys/1.01", httpRequest.Header.Get("User-Agent"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_ProcessCommonRequestWithSigner_Error(t *testing.T) {
|
|
||||||
client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
request := requests.NewCommonRequest()
|
|
||||||
request.Domain = "ecs.aliyuncs.com"
|
|
||||||
request.Version = "2014-05-26"
|
|
||||||
request.ApiName = "DescribeInstanceStatus"
|
|
||||||
|
|
||||||
request.QueryParams["PageNumber"] = "1"
|
|
||||||
request.QueryParams["PageSize"] = "30"
|
|
||||||
request.RegionId = "regionid"
|
|
||||||
defer func() {
|
|
||||||
err := recover()
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
}()
|
|
||||||
_, err = client.ProcessCommonRequestWithSigner(request, nil)
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_NewClientWithStsRoleNameOnEcs(t *testing.T) {
|
|
||||||
client, err := NewClientWithStsRoleNameOnEcs("regionid", "rolename")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
config := client.GetConfig()
|
|
||||||
assert.NotNil(t, config)
|
|
||||||
err = client.AddAsyncTask(nil)
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_NewClientWithStsRoleArn(t *testing.T) {
|
|
||||||
client, err := NewClientWithStsRoleArn("regionid", "acesskeyid", "accesskeysecret", "rolearn", "rolesessionname")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.NotNil(t, client)
|
|
||||||
assert.Equal(t, true, client.isRunning)
|
|
||||||
task := func() {}
|
|
||||||
client.asyncTaskQueue = make(chan func(), 1)
|
|
||||||
err = client.AddAsyncTask(task)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
client.Shutdown()
|
|
||||||
assert.Equal(t, false, client.isRunning)
|
|
||||||
}
|
|
||||||
|
|
||||||
//func Test_EnableAsync(t *testing.T) {
|
|
||||||
// client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
|
|
||||||
// assert.Nil(t, err)
|
|
||||||
// assert.NotNil(t, client)
|
|
||||||
// assert.Equal(t, true, client.isRunning)
|
|
||||||
// client.EnableAsync(2, 8)
|
|
||||||
// client.Shutdown()
|
|
||||||
// assert.Equal(t, false, client.isRunning)
|
|
||||||
//}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package sdk
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Config(t *testing.T) {
|
|
||||||
config := NewConfig()
|
|
||||||
assert.NotNil(t, config, "NewConfig failed")
|
|
||||||
assert.Equal(t, true, config.AutoRetry, "Default AutoRetry should be true")
|
|
||||||
assert.Equal(t, 3, config.MaxRetryTime, "Default MaxRetryTime should be 3")
|
|
||||||
assert.Equal(t, "", config.UserAgent, "Default UserAgent should be empty")
|
|
||||||
assert.Equal(t, false, config.Debug, "Default AutoRetry should be false")
|
|
||||||
assert.Equal(t, time.Duration(10000000000), config.Timeout, "Default Timeout should be 10000000000")
|
|
||||||
assert.Equal(t, (*http.Transport)(nil), config.HttpTransport, "Default HttpTransport should be nil")
|
|
||||||
assert.Equal(t, false, config.EnableAsync, "Default EnableAsync should be false")
|
|
||||||
assert.Equal(t, 1000, config.MaxTaskQueueSize, "Default MaxTaskQueueSize should be 1000")
|
|
||||||
assert.Equal(t, 5, config.GoRoutinePoolSize, "Default GoRoutinePoolSize should be 5")
|
|
||||||
assert.Equal(t, "HTTP", config.Scheme, "Default Scheme should be HTTP")
|
|
||||||
|
|
||||||
transport := &http.Transport{
|
|
||||||
MaxIdleConns: 10,
|
|
||||||
IdleConnTimeout: 30 * time.Second,
|
|
||||||
DisableCompression: true,
|
|
||||||
}
|
|
||||||
config.
|
|
||||||
WithAutoRetry(false).
|
|
||||||
WithMaxRetryTime(0).
|
|
||||||
WithUserAgent("new user agent").
|
|
||||||
WithDebug(true).
|
|
||||||
WithTimeout(time.Duration(500000)).
|
|
||||||
WithHttpTransport(transport).
|
|
||||||
WithEnableAsync(true).
|
|
||||||
WithMaxTaskQueueSize(1).
|
|
||||||
WithGoRoutinePoolSize(10).
|
|
||||||
WithScheme("HTTPS")
|
|
||||||
|
|
||||||
assert.Equal(t, 0, config.MaxRetryTime)
|
|
||||||
assert.Equal(t, false, config.AutoRetry)
|
|
||||||
assert.Equal(t, "new user agent", config.UserAgent)
|
|
||||||
assert.Equal(t, true, config.Debug)
|
|
||||||
assert.Equal(t, time.Duration(500000), config.Timeout)
|
|
||||||
assert.Equal(t, transport, config.HttpTransport)
|
|
||||||
assert.Equal(t, true, config.EnableAsync)
|
|
||||||
assert.Equal(t, 1, config.MaxTaskQueueSize)
|
|
||||||
assert.Equal(t, 10, config.GoRoutinePoolSize)
|
|
||||||
assert.Equal(t, "HTTPS", config.Scheme)
|
|
||||||
}
|
|
2135
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go
generated
vendored
2135
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go
generated
vendored
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const SignatureDostNotMatchErrorCode = "SignatureDoesNotMatch"
|
const SignatureDostNotMatchErrorCode = "SignatureDoesNotMatch"
|
||||||
const MessagePrefix = "Specified signature is not matched with our calculation. server string to sign is:"
|
const IncompleteSignatureErrorCode = "IncompleteSignature"
|
||||||
|
const MessageContain = "server string to sign is:"
|
||||||
|
|
||||||
var debug utils.Debug
|
var debug utils.Debug
|
||||||
|
|
||||||
|
@ -20,14 +21,15 @@ type SignatureDostNotMatchWrapper struct {
|
||||||
|
|
||||||
func (*SignatureDostNotMatchWrapper) tryWrap(error *ServerError, wrapInfo map[string]string) (ok bool) {
|
func (*SignatureDostNotMatchWrapper) tryWrap(error *ServerError, wrapInfo map[string]string) (ok bool) {
|
||||||
clientStringToSign := wrapInfo["StringToSign"]
|
clientStringToSign := wrapInfo["StringToSign"]
|
||||||
if error.errorCode == SignatureDostNotMatchErrorCode && clientStringToSign != "" {
|
if (error.errorCode == SignatureDostNotMatchErrorCode || error.errorCode == IncompleteSignatureErrorCode) && clientStringToSign != "" {
|
||||||
message := error.message
|
message := error.message
|
||||||
if strings.HasPrefix(message, MessagePrefix) {
|
if strings.Contains(message, MessageContain) {
|
||||||
serverStringToSign := message[len(MessagePrefix):]
|
str := strings.Split(message, MessageContain)
|
||||||
|
serverStringToSign := str[1]
|
||||||
|
|
||||||
if clientStringToSign == serverStringToSign {
|
if clientStringToSign == serverStringToSign {
|
||||||
// user secret is error
|
// user secret is error
|
||||||
error.recommend = "Please check you AccessKeySecret"
|
error.recommend = "InvalidAccessKeySecret: Please check you AccessKeySecret"
|
||||||
} else {
|
} else {
|
||||||
debug("Client StringToSign: %s", clientStringToSign)
|
debug("Client StringToSign: %s", clientStringToSign)
|
||||||
debug("Server StringToSign: %s", serverStringToSign)
|
debug("Server StringToSign: %s", serverStringToSign)
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
||||||
)
|
)
|
||||||
|
@ -72,6 +73,12 @@ type AcsRequest interface {
|
||||||
GetAcceptFormat() string
|
GetAcceptFormat() string
|
||||||
GetLocationServiceCode() string
|
GetLocationServiceCode() string
|
||||||
GetLocationEndpointType() string
|
GetLocationEndpointType() string
|
||||||
|
GetReadTimeout() time.Duration
|
||||||
|
GetConnectTimeout() time.Duration
|
||||||
|
SetReadTimeout(readTimeout time.Duration)
|
||||||
|
SetConnectTimeout(connectTimeout time.Duration)
|
||||||
|
SetHTTPSInsecure(isInsecure bool)
|
||||||
|
GetHTTPSInsecure() *bool
|
||||||
|
|
||||||
GetUserAgent() map[string]string
|
GetUserAgent() map[string]string
|
||||||
|
|
||||||
|
@ -92,11 +99,14 @@ type AcsRequest interface {
|
||||||
|
|
||||||
// base class
|
// base class
|
||||||
type baseRequest struct {
|
type baseRequest struct {
|
||||||
Scheme string
|
Scheme string
|
||||||
Method string
|
Method string
|
||||||
Domain string
|
Domain string
|
||||||
Port string
|
Port string
|
||||||
RegionId string
|
RegionId string
|
||||||
|
ReadTimeout time.Duration
|
||||||
|
ConnectTimeout time.Duration
|
||||||
|
isInsecure *bool
|
||||||
|
|
||||||
userAgent map[string]string
|
userAgent map[string]string
|
||||||
product string
|
product string
|
||||||
|
@ -127,6 +137,30 @@ func (request *baseRequest) GetFormParams() map[string]string {
|
||||||
return request.FormParams
|
return request.FormParams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (request *baseRequest) GetReadTimeout() time.Duration {
|
||||||
|
return request.ReadTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request *baseRequest) GetConnectTimeout() time.Duration {
|
||||||
|
return request.ConnectTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request *baseRequest) SetReadTimeout(readTimeout time.Duration) {
|
||||||
|
request.ReadTimeout = readTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request *baseRequest) SetConnectTimeout(connectTimeout time.Duration) {
|
||||||
|
request.ConnectTimeout = connectTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request *baseRequest) GetHTTPSInsecure() *bool {
|
||||||
|
return request.isInsecure
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request *baseRequest) SetHTTPSInsecure(isInsecure bool) {
|
||||||
|
request.isInsecure = &isInsecure
|
||||||
|
}
|
||||||
|
|
||||||
func (request *baseRequest) GetContent() []byte {
|
func (request *baseRequest) GetContent() []byte {
|
||||||
return request.Content
|
return request.Content
|
||||||
}
|
}
|
||||||
|
@ -294,7 +328,7 @@ func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, pre
|
||||||
for m := 0; m < repeatedFieldValue.Len(); m++ {
|
for m := 0; m < repeatedFieldValue.Len(); m++ {
|
||||||
elementValue := repeatedFieldValue.Index(m)
|
elementValue := repeatedFieldValue.Index(m)
|
||||||
key := prefix + name + "." + strconv.Itoa(m+1)
|
key := prefix + name + "." + strconv.Itoa(m+1)
|
||||||
if elementValue.Type().String() == "string" {
|
if elementValue.Type().Kind().String() == "string" {
|
||||||
value := elementValue.String()
|
value := elementValue.String()
|
||||||
err = addParam(request, fieldPosition, key, value)
|
err = addParam(request, fieldPosition, key, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
148
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request_test.go
generated
vendored
148
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request_test.go
generated
vendored
|
@ -1,148 +0,0 @@
|
||||||
package requests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_AcsRequest(t *testing.T) {
|
|
||||||
r := defaultBaseRequest()
|
|
||||||
assert.NotNil(t, r)
|
|
||||||
|
|
||||||
// query params
|
|
||||||
query := r.GetQueryParams()
|
|
||||||
assert.Equal(t, 0, len(query))
|
|
||||||
r.addQueryParam("key", "value")
|
|
||||||
assert.Equal(t, 1, len(query))
|
|
||||||
assert.Equal(t, "value", query["key"])
|
|
||||||
|
|
||||||
// form params
|
|
||||||
form := r.GetFormParams()
|
|
||||||
assert.Equal(t, 0, len(form))
|
|
||||||
r.addFormParam("key", "value")
|
|
||||||
assert.Equal(t, 1, len(form))
|
|
||||||
assert.Equal(t, "value", form["key"])
|
|
||||||
|
|
||||||
// getter/setter for stringtosign
|
|
||||||
assert.Equal(t, "", r.GetStringToSign())
|
|
||||||
r.SetStringToSign("s2s")
|
|
||||||
assert.Equal(t, "s2s", r.GetStringToSign())
|
|
||||||
|
|
||||||
// content type
|
|
||||||
_, contains := r.GetContentType()
|
|
||||||
assert.False(t, contains)
|
|
||||||
r.SetContentType("application/json")
|
|
||||||
ct, contains := r.GetContentType()
|
|
||||||
assert.Equal(t, "application/json", ct)
|
|
||||||
assert.True(t, contains)
|
|
||||||
|
|
||||||
// default 3 headers & content-type
|
|
||||||
headers := r.GetHeaders()
|
|
||||||
assert.Equal(t, 4, len(headers))
|
|
||||||
r.addHeaderParam("x-key", "x-key-value")
|
|
||||||
assert.Equal(t, 5, len(headers))
|
|
||||||
assert.Equal(t, "x-key-value", headers["x-key"])
|
|
||||||
|
|
||||||
// GetVersion
|
|
||||||
assert.Equal(t, "", r.GetVersion())
|
|
||||||
// GetActionName
|
|
||||||
assert.Equal(t, "", r.GetActionName())
|
|
||||||
|
|
||||||
// GetMethod
|
|
||||||
assert.Equal(t, "GET", r.GetMethod())
|
|
||||||
r.Method = "POST"
|
|
||||||
assert.Equal(t, "POST", r.GetMethod())
|
|
||||||
|
|
||||||
// Domain
|
|
||||||
assert.Equal(t, "", r.GetDomain())
|
|
||||||
r.SetDomain("ecs.aliyuncs.com")
|
|
||||||
assert.Equal(t, "ecs.aliyuncs.com", r.GetDomain())
|
|
||||||
|
|
||||||
// Region
|
|
||||||
assert.Equal(t, "", r.GetRegionId())
|
|
||||||
r.RegionId = "cn-hangzhou"
|
|
||||||
assert.Equal(t, "cn-hangzhou", r.GetRegionId())
|
|
||||||
|
|
||||||
// AcceptFormat
|
|
||||||
assert.Equal(t, "JSON", r.GetAcceptFormat())
|
|
||||||
r.AcceptFormat = "XML"
|
|
||||||
assert.Equal(t, "XML", r.GetAcceptFormat())
|
|
||||||
|
|
||||||
// GetLocationServiceCode
|
|
||||||
assert.Equal(t, "", r.GetLocationServiceCode())
|
|
||||||
|
|
||||||
// GetLocationEndpointType
|
|
||||||
assert.Equal(t, "", r.GetLocationEndpointType())
|
|
||||||
|
|
||||||
// GetProduct
|
|
||||||
assert.Equal(t, "", r.GetProduct())
|
|
||||||
|
|
||||||
// GetScheme
|
|
||||||
assert.Equal(t, "", r.GetScheme())
|
|
||||||
r.SetScheme("HTTPS")
|
|
||||||
assert.Equal(t, "HTTPS", r.GetScheme())
|
|
||||||
|
|
||||||
// GetPort
|
|
||||||
assert.Equal(t, "", r.GetPort())
|
|
||||||
|
|
||||||
// GetUserAgent
|
|
||||||
r.AppendUserAgent("cli", "1.01")
|
|
||||||
assert.Equal(t, "1.01", r.GetUserAgent()["cli"])
|
|
||||||
// Content
|
|
||||||
assert.Equal(t, []byte(nil), r.GetContent())
|
|
||||||
r.SetContent([]byte("The Content"))
|
|
||||||
assert.True(t, bytes.Equal([]byte("The Content"), r.GetContent()))
|
|
||||||
}
|
|
||||||
|
|
||||||
type AcsRequestTest struct {
|
|
||||||
*baseRequest
|
|
||||||
Ontology AcsRequest
|
|
||||||
Query string `position:"Query" name:"Query"`
|
|
||||||
Header string `position:"Header" name:"Header"`
|
|
||||||
Path string `position:"Path" name:"Path"`
|
|
||||||
Body string `position:"Body" name:"Body"`
|
|
||||||
TypeAcs *[]string `position:"type" name:"type" type:"Repeated"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r AcsRequestTest) BuildQueries() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r AcsRequestTest) BuildUrl() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r AcsRequestTest) GetBodyReader() io.Reader {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r AcsRequestTest) GetStyle() string {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r AcsRequestTest) addPathParam(key, value string) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_AcsRequest_InitParams(t *testing.T) {
|
|
||||||
r := &AcsRequestTest{
|
|
||||||
baseRequest: defaultBaseRequest(),
|
|
||||||
Query: "query value",
|
|
||||||
Header: "header value",
|
|
||||||
Path: "path value",
|
|
||||||
Body: "body value",
|
|
||||||
}
|
|
||||||
tmp := []string{r.Query, r.Header}
|
|
||||||
r.TypeAcs = &tmp
|
|
||||||
r.addQueryParam("qkey", "qvalue")
|
|
||||||
InitParams(r)
|
|
||||||
|
|
||||||
queries := r.GetQueryParams()
|
|
||||||
assert.Equal(t, "query value", queries["Query"])
|
|
||||||
headers := r.GetHeaders()
|
|
||||||
assert.Equal(t, "header value", headers["Header"])
|
|
||||||
// TODO: check the body & path
|
|
||||||
}
|
|
82
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request_test.go
generated
vendored
82
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request_test.go
generated
vendored
|
@ -1,82 +0,0 @@
|
||||||
package requests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_NewCommonRequest(t *testing.T) {
|
|
||||||
r := NewCommonRequest()
|
|
||||||
assert.NotNil(t, r)
|
|
||||||
|
|
||||||
assert.Equal(t, "common", r.GetHeaders()["x-sdk-invoke-type"])
|
|
||||||
assert.Equal(t, 0, len(r.PathParams))
|
|
||||||
|
|
||||||
r.addPathParam("name", "value")
|
|
||||||
assert.Equal(t, "value", r.PathParams["name"])
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_CommonRequest_TransToAcsRequest(t *testing.T) {
|
|
||||||
r := NewCommonRequest()
|
|
||||||
assert.NotNil(t, r)
|
|
||||||
r.TransToAcsRequest()
|
|
||||||
|
|
||||||
assert.Equal(t, "RPC", r.GetStyle())
|
|
||||||
|
|
||||||
r2 := NewCommonRequest()
|
|
||||||
assert.NotNil(t, r2)
|
|
||||||
r2.PathPattern = "/users/[user]"
|
|
||||||
r2.TransToAcsRequest()
|
|
||||||
|
|
||||||
assert.Equal(t, "ROA", r2.GetStyle())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_CommonRequest_String(t *testing.T) {
|
|
||||||
r := NewCommonRequest()
|
|
||||||
assert.NotNil(t, r)
|
|
||||||
r.SetDomain("domain")
|
|
||||||
|
|
||||||
expected := `GET /? /1.1
|
|
||||||
Host: domain
|
|
||||||
Accept-Encoding: identity
|
|
||||||
x-sdk-client: golang/1.0.0
|
|
||||||
x-sdk-invoke-type: common
|
|
||||||
|
|
||||||
`
|
|
||||||
assert.Equal(t, expected, r.String())
|
|
||||||
|
|
||||||
r.SetContent([]byte("content"))
|
|
||||||
|
|
||||||
expected = `GET /? /1.1
|
|
||||||
Host: domain
|
|
||||||
Accept-Encoding: identity
|
|
||||||
x-sdk-client: golang/1.0.0
|
|
||||||
x-sdk-invoke-type: common
|
|
||||||
|
|
||||||
content
|
|
||||||
`
|
|
||||||
assert.Equal(t, expected, r.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_CommonRequest_BuildUrl(t *testing.T) {
|
|
||||||
r := NewCommonRequest()
|
|
||||||
assert.NotNil(t, r)
|
|
||||||
r.SetDomain("host")
|
|
||||||
r.SetScheme("http")
|
|
||||||
|
|
||||||
r.TransToAcsRequest()
|
|
||||||
|
|
||||||
assert.Equal(t, "http://host/?", r.BuildUrl())
|
|
||||||
r.Port = "8080"
|
|
||||||
assert.Equal(t, "http://host:8080/?", r.BuildUrl())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_CommonRequest_GetBodyReader(t *testing.T) {
|
|
||||||
r := NewCommonRequest()
|
|
||||||
r.TransToAcsRequest()
|
|
||||||
reader := r.GetBodyReader()
|
|
||||||
b, _ := ioutil.ReadAll(reader)
|
|
||||||
assert.Equal(t, "", string(b))
|
|
||||||
}
|
|
|
@ -134,7 +134,7 @@ func (request *RoaRequest) InitWithApiInfo(product, version, action, uriPattern,
|
||||||
request.pathPattern = uriPattern
|
request.pathPattern = uriPattern
|
||||||
request.locationServiceCode = serviceCode
|
request.locationServiceCode = serviceCode
|
||||||
request.locationEndpointType = endpointType
|
request.locationEndpointType = endpointType
|
||||||
//request.product = product
|
request.product = product
|
||||||
//request.version = version
|
//request.version = version
|
||||||
//request.actionName = action
|
//request.actionName = action
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ func (request *RoaRequest) InitWithApiInfo(product, version, action, uriPattern,
|
||||||
func (request *RoaRequest) initWithCommonRequest(commonRequest *CommonRequest) {
|
func (request *RoaRequest) initWithCommonRequest(commonRequest *CommonRequest) {
|
||||||
request.baseRequest = commonRequest.baseRequest
|
request.baseRequest = commonRequest.baseRequest
|
||||||
request.PathParams = commonRequest.PathParams
|
request.PathParams = commonRequest.PathParams
|
||||||
//request.product = commonRequest.Product
|
request.product = commonRequest.Product
|
||||||
//request.version = commonRequest.Version
|
//request.version = commonRequest.Version
|
||||||
request.Headers["x-acs-version"] = commonRequest.Version
|
request.Headers["x-acs-version"] = commonRequest.Version
|
||||||
//request.actionName = commonRequest.ApiName
|
//request.actionName = commonRequest.ApiName
|
||||||
|
|
116
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request_test.go
generated
vendored
116
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request_test.go
generated
vendored
|
@ -1,116 +0,0 @@
|
||||||
package requests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_RoaRequest(t *testing.T) {
|
|
||||||
r := &RoaRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "/", "serviceCode", "endpointType")
|
|
||||||
assert.NotNil(t, r)
|
|
||||||
|
|
||||||
assert.Equal(t, "GET", r.GetMethod())
|
|
||||||
assert.Equal(t, "ROA", r.GetStyle())
|
|
||||||
// assert.Equal(t, "version", r.GetVersion())
|
|
||||||
// assert.Equal(t, "action", r.GetActionName())
|
|
||||||
assert.Equal(t, "serviceCode", r.GetLocationServiceCode())
|
|
||||||
assert.Equal(t, "endpointType", r.GetLocationEndpointType())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RoaRequest_initWithCommonRequest(t *testing.T) {
|
|
||||||
r := &RoaRequest{}
|
|
||||||
common := NewCommonRequest()
|
|
||||||
r.initWithCommonRequest(common)
|
|
||||||
assert.NotNil(t, r)
|
|
||||||
|
|
||||||
assert.Equal(t, "GET", r.GetMethod())
|
|
||||||
assert.Equal(t, "ROA", r.GetStyle())
|
|
||||||
assert.Equal(t, "common", r.Headers["x-sdk-invoke-type"])
|
|
||||||
// assert.Equal(t, "version", r.GetVersion())
|
|
||||||
// assert.Equal(t, "action", r.GetActionName())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RoaRequest_BuildQueries(t *testing.T) {
|
|
||||||
// url
|
|
||||||
r := &RoaRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "/", "serviceCode", "endpointType")
|
|
||||||
assert.Equal(t, "/", r.BuildQueries())
|
|
||||||
r.addQueryParam("key", "value")
|
|
||||||
assert.Equal(t, "/?key=value", r.BuildQueries())
|
|
||||||
r.addQueryParam("key2", "value2")
|
|
||||||
assert.Equal(t, "/?key=value&key2=value2", r.BuildQueries())
|
|
||||||
// assert.Equal(t, "/?key=https%3A%2F%2Fdomain%2F%3Fq%3Dv", r.BuildQueries())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RoaRequest_BuildUrl(t *testing.T) {
|
|
||||||
r := &RoaRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "/", "serviceCode", "endpointType")
|
|
||||||
r.Domain = "domain.com"
|
|
||||||
r.Scheme = "http"
|
|
||||||
r.Port = "80"
|
|
||||||
assert.Equal(t, "http://domain.com:80/", r.BuildUrl())
|
|
||||||
r.addQueryParam("key", "value")
|
|
||||||
assert.Equal(t, "http://domain.com:80/?key=value", r.BuildUrl())
|
|
||||||
r.addQueryParam("key", "https://domain/?q=v")
|
|
||||||
assert.Equal(t, "http://domain.com:80/?key=https%3A%2F%2Fdomain%2F%3Fq%3Dv", r.BuildUrl())
|
|
||||||
r.addQueryParam("url", "https://domain/?q1=v1&q2=v2")
|
|
||||||
assert.Equal(t, "http://domain.com:80/?key=https%3A%2F%2Fdomain%2F%3Fq%3Dv&url=https%3A%2F%2Fdomain%2F%3Fq1%3Dv1%26q2%3Dv2", r.BuildUrl())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RoaRequest_BuildUrl2(t *testing.T) {
|
|
||||||
r := &RoaRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "/", "serviceCode", "endpointType")
|
|
||||||
r.Domain = "domain.com"
|
|
||||||
r.Scheme = "http"
|
|
||||||
r.Port = "80"
|
|
||||||
assert.Equal(t, "http://domain.com:80/", r.BuildUrl())
|
|
||||||
r.addPathParam("key", "value")
|
|
||||||
assert.Equal(t, "http://domain.com:80/", r.BuildUrl())
|
|
||||||
|
|
||||||
r = &RoaRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "/users/[user]", "serviceCode", "endpointType")
|
|
||||||
r.Domain = "domain.com"
|
|
||||||
r.Scheme = "http"
|
|
||||||
r.Port = "80"
|
|
||||||
r.addPathParam("user", "name")
|
|
||||||
assert.Equal(t, "http://domain.com:80/users/name", r.BuildUrl())
|
|
||||||
r.addQueryParam("key", "value")
|
|
||||||
assert.Equal(t, "http://domain.com:80/users/name?key=value", r.BuildUrl())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RoaRequest_GetBodyReader_Nil(t *testing.T) {
|
|
||||||
r := &RoaRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "/", "serviceCode", "endpointType")
|
|
||||||
|
|
||||||
reader := r.GetBodyReader()
|
|
||||||
assert.Nil(t, reader)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RoaRequest_GetBodyReader_Form(t *testing.T) {
|
|
||||||
r := &RoaRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "/", "serviceCode", "endpointType")
|
|
||||||
|
|
||||||
r.addFormParam("key", "value")
|
|
||||||
reader := r.GetBodyReader()
|
|
||||||
b, _ := ioutil.ReadAll(reader)
|
|
||||||
assert.Equal(t, "key=value", string(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RoaRequest_GetBodyReader_Content(t *testing.T) {
|
|
||||||
r := &RoaRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "/", "serviceCode", "endpointType")
|
|
||||||
|
|
||||||
r.SetContent([]byte("Hello world"))
|
|
||||||
reader := r.GetBodyReader()
|
|
||||||
b, _ := ioutil.ReadAll(reader)
|
|
||||||
assert.Equal(t, "Hello world", string(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
// func Test_RoaRequest_addPathParam(t *testing.T) {
|
|
||||||
// r := &RoaRequest{}
|
|
||||||
// r.InitWithApiInfo("product", "version", "action", "/", "serviceCode", "endpointType")
|
|
||||||
// r.addPathParam("key", "value")
|
|
||||||
// }
|
|
70
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request_test.go
generated
vendored
70
vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request_test.go
generated
vendored
|
@ -1,70 +0,0 @@
|
||||||
package requests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_RpcRequest(t *testing.T) {
|
|
||||||
r := &RpcRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "serviceCode", "endpointType")
|
|
||||||
assert.NotNil(t, r)
|
|
||||||
|
|
||||||
assert.Equal(t, "POST", r.GetMethod())
|
|
||||||
assert.Equal(t, "RPC", r.GetStyle())
|
|
||||||
assert.Equal(t, "product", r.GetProduct())
|
|
||||||
assert.Equal(t, "version", r.GetVersion())
|
|
||||||
assert.Equal(t, "action", r.GetActionName())
|
|
||||||
assert.Equal(t, "serviceCode", r.GetLocationServiceCode())
|
|
||||||
assert.Equal(t, "endpointType", r.GetLocationEndpointType())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RpcRequest_BuildQueries(t *testing.T) {
|
|
||||||
// url
|
|
||||||
r := &RpcRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "serviceCode", "endpointType")
|
|
||||||
assert.Equal(t, "/?", r.BuildQueries())
|
|
||||||
r.addQueryParam("key", "value")
|
|
||||||
assert.Equal(t, "/?key=value", r.BuildQueries())
|
|
||||||
r.addQueryParam("key", "https://domain/?q=v")
|
|
||||||
assert.Equal(t, "/?key=https%3A%2F%2Fdomain%2F%3Fq%3Dv", r.BuildQueries())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RpcRequest_BuildUrl(t *testing.T) {
|
|
||||||
r := &RpcRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "serviceCode", "endpointType")
|
|
||||||
r.Domain = "domain.com"
|
|
||||||
r.Scheme = "http"
|
|
||||||
r.Port = "80"
|
|
||||||
assert.Equal(t, "http://domain.com:80/?", r.BuildUrl())
|
|
||||||
r.addQueryParam("key", "value")
|
|
||||||
assert.Equal(t, "http://domain.com:80/?key=value", r.BuildUrl())
|
|
||||||
r.addQueryParam("key", "https://domain/?q=v")
|
|
||||||
assert.Equal(t, "http://domain.com:80/?key=https%3A%2F%2Fdomain%2F%3Fq%3Dv", r.BuildUrl())
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RpcRequest_GetBodyReader(t *testing.T) {
|
|
||||||
r := &RpcRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "serviceCode", "endpointType")
|
|
||||||
|
|
||||||
reader := r.GetBodyReader()
|
|
||||||
b, _ := ioutil.ReadAll(reader)
|
|
||||||
assert.Equal(t, "", string(b))
|
|
||||||
r.addFormParam("key", "value")
|
|
||||||
reader = r.GetBodyReader()
|
|
||||||
b, _ = ioutil.ReadAll(reader)
|
|
||||||
assert.Equal(t, "key=value", string(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_RpcRequest_addPathParam(t *testing.T) {
|
|
||||||
defer func() { //进行异常捕捉
|
|
||||||
err := recover()
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
assert.Equal(t, "not support", err)
|
|
||||||
}()
|
|
||||||
r := &RpcRequest{}
|
|
||||||
r.InitWithApiInfo("product", "version", "action", "serviceCode", "endpointType")
|
|
||||||
r.addPathParam("key", "value")
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package requests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNewInteger(t *testing.T) {
|
|
||||||
integer := NewInteger(123123)
|
|
||||||
assert.True(t, integer.HasValue())
|
|
||||||
value, err := integer.GetValue()
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, 123123, value)
|
|
||||||
var expected Integer
|
|
||||||
expected = "123123"
|
|
||||||
assert.Equal(t, expected, integer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewInteger64(t *testing.T) {
|
|
||||||
long := NewInteger64(123123123123123123)
|
|
||||||
assert.True(t, long.HasValue())
|
|
||||||
value, err := long.GetValue64()
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, int64(123123123123123123), value)
|
|
||||||
var expected Integer
|
|
||||||
expected = "123123123123123123"
|
|
||||||
assert.Equal(t, expected, long)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewBoolean(t *testing.T) {
|
|
||||||
boolean := NewBoolean(false)
|
|
||||||
assert.True(t, boolean.HasValue())
|
|
||||||
value, err := boolean.GetValue()
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, false, value)
|
|
||||||
var expected Boolean
|
|
||||||
expected = "false"
|
|
||||||
assert.Equal(t, expected, boolean)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewFloat(t *testing.T) {
|
|
||||||
float := NewFloat(123123.123123)
|
|
||||||
assert.True(t, float.HasValue())
|
|
||||||
value, err := float.GetValue()
|
|
||||||
assert.Nil(t, err)
|
|
||||||
assert.Equal(t, 123123.123123, value)
|
|
||||||
var expected Float
|
|
||||||
expected = "123123.123123"
|
|
||||||
assert.Equal(t, expected, float)
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package resource
|
|
||||||
|
|
||||||
func GetTZData(name string) ([]byte, bool) {
|
|
||||||
data, ok := files["zoneinfo/"+name]
|
|
||||||
return data, ok
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -9,7 +9,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxUint = ^uint(0)
|
const maxUint = ^uint(0)
|
||||||
|
@ -22,7 +22,12 @@ var initJson = &sync.Once{}
|
||||||
func initJsonParserOnce() {
|
func initJsonParserOnce() {
|
||||||
initJson.Do(func() {
|
initJson.Do(func() {
|
||||||
registerBetterFuzzyDecoder()
|
registerBetterFuzzyDecoder()
|
||||||
jsonParser = jsoniter.ConfigCompatibleWithStandardLibrary
|
jsonParser = jsoniter.Config{
|
||||||
|
EscapeHTML: true,
|
||||||
|
SortMapKeys: true,
|
||||||
|
ValidateJsonRawMessage: true,
|
||||||
|
CaseSensitive: true,
|
||||||
|
}.Froze()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AcsResponse interface {
|
type AcsResponse interface {
|
||||||
|
@ -35,6 +36,11 @@ type AcsResponse interface {
|
||||||
parseFromHttpResponse(httpResponse *http.Response) error
|
parseFromHttpResponse(httpResponse *http.Response) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var debug utils.Debug
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
debug = utils.Init("sdk")
|
||||||
|
}
|
||||||
// Unmarshal object from http response body to target Response
|
// Unmarshal object from http response body to target Response
|
||||||
func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) {
|
func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) {
|
||||||
err = response.parseFromHttpResponse(httpResponse)
|
err = response.parseFromHttpResponse(httpResponse)
|
||||||
|
@ -109,6 +115,7 @@ func (baseResponse *BaseResponse) parseFromHttpResponse(httpResponse *http.Respo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
debug("%s", string(body))
|
||||||
baseResponse.httpStatus = httpResponse.StatusCode
|
baseResponse.httpStatus = httpResponse.StatusCode
|
||||||
baseResponse.httpHeaders = httpResponse.Header
|
baseResponse.httpHeaders = httpResponse.Header
|
||||||
baseResponse.httpContentBytes = body
|
baseResponse.httpContentBytes = body
|
||||||
|
|
|
@ -26,10 +26,6 @@ import (
|
||||||
"github.com/satori/go.uuid"
|
"github.com/satori/go.uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// if you use go 1.10 or higher, you can hack this util by these to avoid "TimeZone.zip not found" on Windows
|
|
||||||
var LoadLocationFromTZData func(name string, data []byte) (*time.Location, error) = nil
|
|
||||||
var TZData []byte = nil
|
|
||||||
|
|
||||||
func GetUUIDV4() (uuidHex string) {
|
func GetUUIDV4() (uuidHex string) {
|
||||||
uuidV4 := uuid.NewV4()
|
uuidV4 := uuid.NewV4()
|
||||||
uuidHex = hex.EncodeToString(uuidV4.Bytes())
|
uuidHex = hex.EncodeToString(uuidV4.Bytes())
|
||||||
|
@ -44,29 +40,15 @@ func GetMD5Base64(bytes []byte) (base64Value string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGMTLocation() (*time.Location, error) {
|
|
||||||
if LoadLocationFromTZData != nil && TZData != nil {
|
|
||||||
return LoadLocationFromTZData("GMT", TZData)
|
|
||||||
} else {
|
|
||||||
return time.LoadLocation("GMT")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetTimeInFormatISO8601() (timeStr string) {
|
func GetTimeInFormatISO8601() (timeStr string) {
|
||||||
gmt, err := GetGMTLocation()
|
gmt := time.FixedZone("GMT", 0)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return time.Now().In(gmt).Format("2006-01-02T15:04:05Z")
|
return time.Now().In(gmt).Format("2006-01-02T15:04:05Z")
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTimeInFormatRFC2616() (timeStr string) {
|
func GetTimeInFormatRFC2616() (timeStr string) {
|
||||||
gmt, err := GetGMTLocation()
|
gmt := time.FixedZone("GMT", 0)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return time.Now().In(gmt).Format("Mon, 02 Jan 2006 15:04:05 GMT")
|
return time.Now().In(gmt).Format("Mon, 02 Jan 2006 15:04:05 GMT")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright 1999-2017 Alibaba Group Holding Ltd.
|
||||||
|
|
||||||
|
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.
|
1240
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/api.go
generated
vendored
Normal file
1240
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/api.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/error.go
generated
vendored
Normal file
52
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/error.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package tablestore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errMissMustHeader = func(header string) error {
|
||||||
|
return errors.New("[tablestore] miss must header: " + header)
|
||||||
|
}
|
||||||
|
errTableNameTooLong = func(name string) error {
|
||||||
|
return errors.New("[tablestore] table name: \"" + name + "\" too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
errInvalidPartitionType = errors.New("[tablestore] invalid partition key")
|
||||||
|
errMissPrimaryKey = errors.New("[tablestore] missing primary key")
|
||||||
|
errPrimaryKeyTooMuch = errors.New("[tablestore] primary key too much")
|
||||||
|
errMultiDeleteRowsTooMuch = errors.New("[tablestore] multi delete rows too much")
|
||||||
|
errCreateTableNoPrimaryKey = errors.New("[tablestore] create table no primary key")
|
||||||
|
errUnexpectIoEnd = errors.New("[tablestore] unexpect io end")
|
||||||
|
errTag = errors.New("[tablestore] unexpect tag")
|
||||||
|
errNoChecksum = errors.New("[tablestore] expect checksum")
|
||||||
|
errChecksum = errors.New("[tablestore] checksum failed")
|
||||||
|
errInvalidInput = errors.New("[tablestore] invalid input")
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
OTS_CLIENT_UNKNOWN = "OTSClientUnknownError"
|
||||||
|
|
||||||
|
ROW_OPERATION_CONFLICT = "OTSRowOperationConflict"
|
||||||
|
NOT_ENOUGH_CAPACITY_UNIT = "OTSNotEnoughCapacityUnit"
|
||||||
|
TABLE_NOT_READY = "OTSTableNotReady"
|
||||||
|
PARTITION_UNAVAILABLE = "OTSPartitionUnavailable"
|
||||||
|
SERVER_BUSY = "OTSServerBusy"
|
||||||
|
STORAGE_SERVER_BUSY = "OTSStorageServerBusy"
|
||||||
|
QUOTA_EXHAUSTED = "OTSQuotaExhausted"
|
||||||
|
|
||||||
|
STORAGE_TIMEOUT = "OTSTimeout"
|
||||||
|
SERVER_UNAVAILABLE = "OTSServerUnavailable"
|
||||||
|
INTERNAL_SERVER_ERROR = "OTSInternalServerError"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OtsError struct {
|
||||||
|
Code string
|
||||||
|
Message string
|
||||||
|
RequestId string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *OtsError) Error() string {
|
||||||
|
return fmt.Sprintf("%s %s %s", e.Code, e.Message, e.RequestId)
|
||||||
|
}
|
22
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/interface.go
generated
vendored
Normal file
22
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/interface.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package tablestore
|
||||||
|
|
||||||
|
type TableStoreApi interface {
|
||||||
|
CreateTable(request *CreateTableRequest) (*CreateTableResponse, error)
|
||||||
|
ListTable() (*ListTableResponse, error)
|
||||||
|
DeleteTable(request *DeleteTableRequest) (*DeleteTableResponse, error)
|
||||||
|
DescribeTable(request *DescribeTableRequest) (*DescribeTableResponse, error)
|
||||||
|
UpdateTable(request *UpdateTableRequest) (*UpdateTableResponse, error)
|
||||||
|
PutRow(request *PutRowRequest) (*PutRowResponse, error)
|
||||||
|
DeleteRow(request *DeleteRowRequest) (*DeleteRowResponse, error)
|
||||||
|
GetRow(request *GetRowRequest) (*GetRowResponse, error)
|
||||||
|
UpdateRow(request *UpdateRowRequest) (*UpdateRowResponse, error)
|
||||||
|
BatchGetRow(request *BatchGetRowRequest) (*BatchGetRowResponse, error)
|
||||||
|
BatchWriteRow(request *BatchWriteRowRequest) (*BatchWriteRowResponse, error)
|
||||||
|
GetRange(request *GetRangeRequest) (*GetRangeResponse, error)
|
||||||
|
|
||||||
|
// stream related
|
||||||
|
ListStream(request *ListStreamRequest) (*ListStreamResponse, error)
|
||||||
|
DescribeStream(request *DescribeStreamRequest) (*DescribeStreamResponse, error)
|
||||||
|
GetShardIterator(request *GetShardIteratorRequest) (*GetShardIteratorResponse, error)
|
||||||
|
GetStreamRecord(request *GetStreamRecordRequest) (*GetStreamRecordResponse, error)
|
||||||
|
}
|
855
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/model.go
generated
vendored
Normal file
855
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/model.go
generated
vendored
Normal file
|
@ -0,0 +1,855 @@
|
||||||
|
package tablestore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
//"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @class TableStoreClient
|
||||||
|
// The TableStoreClient, which will connect OTS service for authorization, create/list/
|
||||||
|
// delete tables/table groups, to get/put/delete a row.
|
||||||
|
// Note: TableStoreClient is thread-safe.
|
||||||
|
// TableStoreClient的功能包括连接OTS服务进行验证、创建/列出/删除表或表组、插入/获取/
|
||||||
|
// 删除/更新行数据
|
||||||
|
type TableStoreClient struct {
|
||||||
|
endPoint string
|
||||||
|
instanceName string
|
||||||
|
accessKeyId string
|
||||||
|
accessKeySecret string
|
||||||
|
securityToken string
|
||||||
|
|
||||||
|
httpClient IHttpClient
|
||||||
|
config *TableStoreConfig
|
||||||
|
random *rand.Rand
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClientOption func(*TableStoreClient)
|
||||||
|
|
||||||
|
type TableStoreHttpClient struct {
|
||||||
|
httpClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// use this to mock http.client for testing
|
||||||
|
type IHttpClient interface {
|
||||||
|
Do(*http.Request) (*http.Response, error)
|
||||||
|
New(*http.Client)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (httpClient *TableStoreHttpClient) Do(req *http.Request) (*http.Response, error) {
|
||||||
|
return httpClient.httpClient.Do(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (httpClient *TableStoreHttpClient) New(client *http.Client) {
|
||||||
|
httpClient.httpClient = client
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPTimeout struct {
|
||||||
|
ConnectionTimeout time.Duration
|
||||||
|
RequestTimeout time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableStoreConfig struct {
|
||||||
|
RetryTimes uint
|
||||||
|
MaxRetryTime time.Duration
|
||||||
|
HTTPTimeout HTTPTimeout
|
||||||
|
MaxIdleConnections int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultTableStoreConfig() *TableStoreConfig {
|
||||||
|
httpTimeout := &HTTPTimeout{
|
||||||
|
ConnectionTimeout: time.Second * 15,
|
||||||
|
RequestTimeout: time.Second * 30}
|
||||||
|
config := &TableStoreConfig{
|
||||||
|
RetryTimes: 10,
|
||||||
|
HTTPTimeout: *httpTimeout,
|
||||||
|
MaxRetryTime: time.Second * 5,
|
||||||
|
MaxIdleConnections: 2000}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateTableRequest struct {
|
||||||
|
TableMeta *TableMeta
|
||||||
|
TableOption *TableOption
|
||||||
|
ReservedThroughput *ReservedThroughput
|
||||||
|
StreamSpec *StreamSpecification
|
||||||
|
IndexMetas []*IndexMeta
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateIndexRequest struct {
|
||||||
|
MainTableName string
|
||||||
|
IndexMeta *IndexMeta
|
||||||
|
IncludeBaseData bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteIndexRequest struct {
|
||||||
|
MainTableName string
|
||||||
|
IndexName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponseInfo struct {
|
||||||
|
RequestId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateTableResponse struct {
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateIndexResponse struct {
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteIndexResponse struct {
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteTableResponse struct {
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableMeta struct {
|
||||||
|
TableName string
|
||||||
|
SchemaEntry []*PrimaryKeySchema
|
||||||
|
DefinedColumns []*DefinedColumnSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrimaryKeySchema struct {
|
||||||
|
Name *string
|
||||||
|
Type *PrimaryKeyType
|
||||||
|
Option *PrimaryKeyOption
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrimaryKey struct {
|
||||||
|
PrimaryKeys []*PrimaryKeyColumn
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableOption struct {
|
||||||
|
TimeToAlive, MaxVersion int
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReservedThroughput struct {
|
||||||
|
Readcap, Writecap int
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListTableResponse struct {
|
||||||
|
TableNames []string
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteTableRequest struct {
|
||||||
|
TableName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeTableRequest struct {
|
||||||
|
TableName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeTableResponse struct {
|
||||||
|
TableMeta *TableMeta
|
||||||
|
TableOption *TableOption
|
||||||
|
ReservedThroughput *ReservedThroughput
|
||||||
|
StreamDetails *StreamDetails
|
||||||
|
IndexMetas []*IndexMeta
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateTableRequest struct {
|
||||||
|
TableName string
|
||||||
|
TableOption *TableOption
|
||||||
|
ReservedThroughput *ReservedThroughput
|
||||||
|
StreamSpec *StreamSpecification
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateTableResponse struct {
|
||||||
|
TableOption *TableOption
|
||||||
|
ReservedThroughput *ReservedThroughput
|
||||||
|
StreamDetails *StreamDetails
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConsumedCapacityUnit struct {
|
||||||
|
Read int32
|
||||||
|
Write int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type PutRowResponse struct {
|
||||||
|
ConsumedCapacityUnit *ConsumedCapacityUnit
|
||||||
|
PrimaryKey PrimaryKey
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteRowResponse struct {
|
||||||
|
ConsumedCapacityUnit *ConsumedCapacityUnit
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateRowResponse struct {
|
||||||
|
Columns []*AttributeColumn
|
||||||
|
ConsumedCapacityUnit *ConsumedCapacityUnit
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrimaryKeyType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrimaryKeyType_INTEGER PrimaryKeyType = 1
|
||||||
|
PrimaryKeyType_STRING PrimaryKeyType = 2
|
||||||
|
PrimaryKeyType_BINARY PrimaryKeyType = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultRetryInterval = 10
|
||||||
|
MaxRetryInterval = 320
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrimaryKeyOption int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
NONE PrimaryKeyOption = 0
|
||||||
|
AUTO_INCREMENT PrimaryKeyOption = 1
|
||||||
|
MIN PrimaryKeyOption = 2
|
||||||
|
MAX PrimaryKeyOption = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrimaryKeyColumn struct {
|
||||||
|
ColumnName string
|
||||||
|
Value interface{}
|
||||||
|
PrimaryKeyOption PrimaryKeyOption
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *PrimaryKeyColumn) String() string {
|
||||||
|
xs := make([]string, 0)
|
||||||
|
xs = append(xs, fmt.Sprintf("\"Name\": \"%s\"", this.ColumnName))
|
||||||
|
switch this.PrimaryKeyOption {
|
||||||
|
case NONE:
|
||||||
|
xs = append(xs, fmt.Sprintf("\"Value\": \"%s\"", this.Value))
|
||||||
|
case MIN:
|
||||||
|
xs = append(xs, "\"Value\": -inf")
|
||||||
|
case MAX:
|
||||||
|
xs = append(xs, "\"Value\": +inf")
|
||||||
|
case AUTO_INCREMENT:
|
||||||
|
xs = append(xs, "\"Value\": auto-incr")
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("{%s}", strings.Join(xs, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
type AttributeColumn struct {
|
||||||
|
ColumnName string
|
||||||
|
Value interface{}
|
||||||
|
Timestamp int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type TimeRange struct {
|
||||||
|
Start int64
|
||||||
|
End int64
|
||||||
|
Specific int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnToUpdate struct {
|
||||||
|
ColumnName string
|
||||||
|
Type byte
|
||||||
|
Timestamp int64
|
||||||
|
HasType bool
|
||||||
|
HasTimestamp bool
|
||||||
|
IgnoreValue bool
|
||||||
|
Value interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RowExistenceExpectation int
|
||||||
|
|
||||||
|
const (
|
||||||
|
RowExistenceExpectation_IGNORE RowExistenceExpectation = 0
|
||||||
|
RowExistenceExpectation_EXPECT_EXIST RowExistenceExpectation = 1
|
||||||
|
RowExistenceExpectation_EXPECT_NOT_EXIST RowExistenceExpectation = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type ComparatorType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
CT_EQUAL ComparatorType = 1
|
||||||
|
CT_NOT_EQUAL ComparatorType = 2
|
||||||
|
CT_GREATER_THAN ComparatorType = 3
|
||||||
|
CT_GREATER_EQUAL ComparatorType = 4
|
||||||
|
CT_LESS_THAN ComparatorType = 5
|
||||||
|
CT_LESS_EQUAL ComparatorType = 6
|
||||||
|
)
|
||||||
|
|
||||||
|
type LogicalOperator int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
LO_NOT LogicalOperator = 1
|
||||||
|
LO_AND LogicalOperator = 2
|
||||||
|
LO_OR LogicalOperator = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
FT_SINGLE_COLUMN_VALUE FilterType = 1
|
||||||
|
FT_COMPOSITE_COLUMN_VALUE FilterType = 2
|
||||||
|
FT_COLUMN_PAGINATION FilterType = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
type ColumnFilter interface {
|
||||||
|
Serialize() []byte
|
||||||
|
ToFilter() *otsprotocol.Filter
|
||||||
|
}
|
||||||
|
|
||||||
|
type VariantType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
Variant_INTEGER VariantType = 0;
|
||||||
|
Variant_DOUBLE VariantType = 1;
|
||||||
|
//VT_BOOLEAN = 2;
|
||||||
|
Variant_STRING VariantType = 3;
|
||||||
|
)
|
||||||
|
|
||||||
|
type ValueTransferRule struct {
|
||||||
|
Regex string
|
||||||
|
Cast_type VariantType
|
||||||
|
}
|
||||||
|
|
||||||
|
type SingleColumnCondition struct {
|
||||||
|
Comparator *ComparatorType
|
||||||
|
ColumnName *string
|
||||||
|
ColumnValue interface{} //[]byte
|
||||||
|
FilterIfMissing bool
|
||||||
|
LatestVersionOnly bool
|
||||||
|
TransferRule *ValueTransferRule
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReturnType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
ReturnType_RT_NONE ReturnType = 0
|
||||||
|
ReturnType_RT_PK ReturnType = 1
|
||||||
|
ReturnType_RT_AFTER_MODIFY ReturnType = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type PaginationFilter struct {
|
||||||
|
Offset int32
|
||||||
|
Limit int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompositeColumnValueFilter struct {
|
||||||
|
Operator LogicalOperator
|
||||||
|
Filters []ColumnFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccvfilter *CompositeColumnValueFilter) Serialize() []byte {
|
||||||
|
result, _ := proto.Marshal(ccvfilter.ToFilter())
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccvfilter *CompositeColumnValueFilter) ToFilter() *otsprotocol.Filter {
|
||||||
|
compositefilter := NewCompositeFilter(ccvfilter.Filters, ccvfilter.Operator)
|
||||||
|
compositeFilterToBytes, _ := proto.Marshal(compositefilter)
|
||||||
|
filter := new(otsprotocol.Filter)
|
||||||
|
filter.Type = otsprotocol.FilterType_FT_COMPOSITE_COLUMN_VALUE.Enum()
|
||||||
|
filter.Filter = compositeFilterToBytes
|
||||||
|
return filter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccvfilter *CompositeColumnValueFilter) AddFilter(filter ColumnFilter) {
|
||||||
|
ccvfilter.Filters = append(ccvfilter.Filters, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (condition *SingleColumnCondition) ToFilter() *otsprotocol.Filter {
|
||||||
|
singlefilter := NewSingleColumnValueFilter(condition)
|
||||||
|
singleFilterToBytes, _ := proto.Marshal(singlefilter)
|
||||||
|
filter := new(otsprotocol.Filter)
|
||||||
|
filter.Type = otsprotocol.FilterType_FT_SINGLE_COLUMN_VALUE.Enum()
|
||||||
|
filter.Filter = singleFilterToBytes
|
||||||
|
return filter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (condition *SingleColumnCondition) Serialize() []byte {
|
||||||
|
result, _ := proto.Marshal(condition.ToFilter())
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pageFilter *PaginationFilter) ToFilter() *otsprotocol.Filter {
|
||||||
|
compositefilter := NewPaginationFilter(pageFilter)
|
||||||
|
compositeFilterToBytes, _ := proto.Marshal(compositefilter)
|
||||||
|
filter := new(otsprotocol.Filter)
|
||||||
|
filter.Type = otsprotocol.FilterType_FT_COLUMN_PAGINATION.Enum()
|
||||||
|
filter.Filter = compositeFilterToBytes
|
||||||
|
return filter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pageFilter *PaginationFilter) Serialize() []byte {
|
||||||
|
result, _ := proto.Marshal(pageFilter.ToFilter())
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTableOptionWithMaxVersion(maxVersion int) *TableOption {
|
||||||
|
tableOption := new(TableOption)
|
||||||
|
tableOption.TimeToAlive = -1
|
||||||
|
tableOption.MaxVersion = maxVersion
|
||||||
|
return tableOption
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTableOption(timeToAlive int, maxVersion int) *TableOption {
|
||||||
|
tableOption := new(TableOption)
|
||||||
|
tableOption.TimeToAlive = timeToAlive
|
||||||
|
tableOption.MaxVersion = maxVersion
|
||||||
|
return tableOption
|
||||||
|
}
|
||||||
|
|
||||||
|
type RowCondition struct {
|
||||||
|
RowExistenceExpectation RowExistenceExpectation
|
||||||
|
ColumnCondition ColumnFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
type PutRowChange struct {
|
||||||
|
TableName string
|
||||||
|
PrimaryKey *PrimaryKey
|
||||||
|
Columns []AttributeColumn
|
||||||
|
Condition *RowCondition
|
||||||
|
ReturnType ReturnType
|
||||||
|
TransactionId *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type PutRowRequest struct {
|
||||||
|
PutRowChange *PutRowChange
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteRowChange struct {
|
||||||
|
TableName string
|
||||||
|
PrimaryKey *PrimaryKey
|
||||||
|
Condition *RowCondition
|
||||||
|
TransactionId *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteRowRequest struct {
|
||||||
|
DeleteRowChange *DeleteRowChange
|
||||||
|
}
|
||||||
|
|
||||||
|
type SingleRowQueryCriteria struct {
|
||||||
|
ColumnsToGet []string
|
||||||
|
TableName string
|
||||||
|
PrimaryKey *PrimaryKey
|
||||||
|
MaxVersion int32
|
||||||
|
TimeRange *TimeRange
|
||||||
|
Filter ColumnFilter
|
||||||
|
StartColumn *string
|
||||||
|
EndColumn *string
|
||||||
|
TransactionId *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateRowChange struct {
|
||||||
|
TableName string
|
||||||
|
PrimaryKey *PrimaryKey
|
||||||
|
Columns []ColumnToUpdate
|
||||||
|
Condition *RowCondition
|
||||||
|
TransactionId *string
|
||||||
|
ReturnType ReturnType
|
||||||
|
ColumnNamesToReturn []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateRowRequest struct {
|
||||||
|
UpdateRowChange *UpdateRowChange
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rowQueryCriteria *SingleRowQueryCriteria) AddColumnToGet(columnName string) {
|
||||||
|
rowQueryCriteria.ColumnsToGet = append(rowQueryCriteria.ColumnsToGet, columnName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rowQueryCriteria *SingleRowQueryCriteria) SetStartColumn(columnName string) {
|
||||||
|
rowQueryCriteria.StartColumn = &columnName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rowQueryCriteria *SingleRowQueryCriteria) SetEndtColumn(columnName string) {
|
||||||
|
rowQueryCriteria.EndColumn = &columnName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rowQueryCriteria *SingleRowQueryCriteria) getColumnsToGet() []string {
|
||||||
|
return rowQueryCriteria.ColumnsToGet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rowQueryCriteria *MultiRowQueryCriteria) AddColumnToGet(columnName string) {
|
||||||
|
rowQueryCriteria.ColumnsToGet = append(rowQueryCriteria.ColumnsToGet, columnName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rowQueryCriteria *RangeRowQueryCriteria) AddColumnToGet(columnName string) {
|
||||||
|
rowQueryCriteria.ColumnsToGet = append(rowQueryCriteria.ColumnsToGet, columnName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rowQueryCriteria *MultiRowQueryCriteria) AddRow(pk *PrimaryKey) {
|
||||||
|
rowQueryCriteria.PrimaryKey = append(rowQueryCriteria.PrimaryKey, pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetRowRequest struct {
|
||||||
|
SingleRowQueryCriteria *SingleRowQueryCriteria
|
||||||
|
}
|
||||||
|
|
||||||
|
type MultiRowQueryCriteria struct {
|
||||||
|
PrimaryKey []*PrimaryKey
|
||||||
|
ColumnsToGet []string
|
||||||
|
TableName string
|
||||||
|
MaxVersion int
|
||||||
|
TimeRange *TimeRange
|
||||||
|
Filter ColumnFilter
|
||||||
|
StartColumn *string
|
||||||
|
EndColumn *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BatchGetRowRequest struct {
|
||||||
|
MultiRowQueryCriteria []*MultiRowQueryCriteria
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnMap struct {
|
||||||
|
Columns map[string][]*AttributeColumn
|
||||||
|
columnsKey []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetRowResponse struct {
|
||||||
|
PrimaryKey PrimaryKey
|
||||||
|
Columns []*AttributeColumn
|
||||||
|
ConsumedCapacityUnit *ConsumedCapacityUnit
|
||||||
|
columnMap *ColumnMap
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
Code string
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RowResult struct {
|
||||||
|
TableName string
|
||||||
|
IsSucceed bool
|
||||||
|
Error Error
|
||||||
|
PrimaryKey PrimaryKey
|
||||||
|
Columns []*AttributeColumn
|
||||||
|
ConsumedCapacityUnit *ConsumedCapacityUnit
|
||||||
|
Index int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type RowChange interface {
|
||||||
|
Serialize() []byte
|
||||||
|
getOperationType() otsprotocol.OperationType
|
||||||
|
getCondition() *otsprotocol.Condition
|
||||||
|
GetTableName() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BatchGetRowResponse struct {
|
||||||
|
TableToRowsResult map[string][]RowResult
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type BatchWriteRowRequest struct {
|
||||||
|
RowChangesGroupByTable map[string][]RowChange
|
||||||
|
}
|
||||||
|
|
||||||
|
type BatchWriteRowResponse struct {
|
||||||
|
TableToRowsResult map[string][]RowResult
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type Direction int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
FORWARD Direction = 0
|
||||||
|
BACKWARD Direction = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
type RangeRowQueryCriteria struct {
|
||||||
|
TableName string
|
||||||
|
StartPrimaryKey *PrimaryKey
|
||||||
|
EndPrimaryKey *PrimaryKey
|
||||||
|
ColumnsToGet []string
|
||||||
|
MaxVersion int32
|
||||||
|
TimeRange *TimeRange
|
||||||
|
Filter ColumnFilter
|
||||||
|
Direction Direction
|
||||||
|
Limit int32
|
||||||
|
StartColumn *string
|
||||||
|
EndColumn *string
|
||||||
|
TransactionId *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetRangeRequest struct {
|
||||||
|
RangeRowQueryCriteria *RangeRowQueryCriteria
|
||||||
|
}
|
||||||
|
|
||||||
|
type Row struct {
|
||||||
|
PrimaryKey *PrimaryKey
|
||||||
|
Columns []*AttributeColumn
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetRangeResponse struct {
|
||||||
|
Rows []*Row
|
||||||
|
ConsumedCapacityUnit *ConsumedCapacityUnit
|
||||||
|
NextStartPrimaryKey *PrimaryKey
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListStreamRequest struct {
|
||||||
|
TableName *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Stream struct {
|
||||||
|
Id *StreamId
|
||||||
|
TableName *string
|
||||||
|
CreationTime int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListStreamResponse struct {
|
||||||
|
Streams []Stream
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type StreamSpecification struct {
|
||||||
|
EnableStream bool
|
||||||
|
ExpirationTime int32 // must be positive. in hours
|
||||||
|
}
|
||||||
|
|
||||||
|
type StreamDetails struct {
|
||||||
|
EnableStream bool
|
||||||
|
StreamId *StreamId // nil when stream is disabled.
|
||||||
|
ExpirationTime int32 // in hours
|
||||||
|
LastEnableTime int64 // the last time stream is enabled, in usec
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeStreamRequest struct {
|
||||||
|
StreamId *StreamId // required
|
||||||
|
InclusiveStartShardId *ShardId // optional
|
||||||
|
ShardLimit *int32 // optional
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeStreamResponse struct {
|
||||||
|
StreamId *StreamId // required
|
||||||
|
ExpirationTime int32 // in hours
|
||||||
|
TableName *string // required
|
||||||
|
CreationTime int64 // in usec
|
||||||
|
Status StreamStatus // required
|
||||||
|
Shards []*StreamShard
|
||||||
|
NextShardId *ShardId // optional. nil means "no more shards"
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetShardIteratorRequest struct {
|
||||||
|
StreamId *StreamId // required
|
||||||
|
ShardId *ShardId // required
|
||||||
|
Timestamp *int64
|
||||||
|
Token *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetShardIteratorResponse struct {
|
||||||
|
ShardIterator *ShardIterator // required
|
||||||
|
Token *string
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetStreamRecordRequest struct {
|
||||||
|
ShardIterator *ShardIterator // required
|
||||||
|
Limit *int32 // optional. max records which will reside in response
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetStreamRecordResponse struct {
|
||||||
|
Records []*StreamRecord
|
||||||
|
NextShardIterator *ShardIterator // optional. an indicator to be used to read more records in this shard
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComputeSplitPointsBySizeRequest struct {
|
||||||
|
TableName string
|
||||||
|
SplitSize int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComputeSplitPointsBySizeResponse struct {
|
||||||
|
SchemaEntry []*PrimaryKeySchema
|
||||||
|
Splits []*Split
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type Split struct {
|
||||||
|
LowerBound *PrimaryKey
|
||||||
|
UpperBound *PrimaryKey
|
||||||
|
Location string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StreamId string
|
||||||
|
type ShardId string
|
||||||
|
type ShardIterator string
|
||||||
|
type StreamStatus int
|
||||||
|
|
||||||
|
const (
|
||||||
|
SS_Enabling StreamStatus = iota
|
||||||
|
SS_Active
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shards are possibly splitted into two or merged from two.
|
||||||
|
* After splitting, both newly generated shards have the same FatherShard.
|
||||||
|
* After merging, the newly generated shard have both FatherShard and MotherShard.
|
||||||
|
*/
|
||||||
|
type StreamShard struct {
|
||||||
|
SelfShard *ShardId // required
|
||||||
|
FatherShard *ShardId // optional
|
||||||
|
MotherShard *ShardId // optional
|
||||||
|
}
|
||||||
|
|
||||||
|
type StreamRecord struct {
|
||||||
|
Type ActionType
|
||||||
|
Info *RecordSequenceInfo // required
|
||||||
|
PrimaryKey *PrimaryKey // required
|
||||||
|
Columns []*RecordColumn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *StreamRecord) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"{\"Type\":%s, \"PrimaryKey\":%s, \"Info\":%s, \"Columns\":%s}",
|
||||||
|
this.Type,
|
||||||
|
*this.PrimaryKey,
|
||||||
|
this.Info,
|
||||||
|
this.Columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActionType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
AT_Put ActionType = iota
|
||||||
|
AT_Update
|
||||||
|
AT_Delete
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this ActionType) String() string {
|
||||||
|
switch this {
|
||||||
|
case AT_Put:
|
||||||
|
return "\"PutRow\""
|
||||||
|
case AT_Update:
|
||||||
|
return "\"UpdateRow\""
|
||||||
|
case AT_Delete:
|
||||||
|
return "\"DeleteRow\""
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unknown action type: %d", int(this)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RecordSequenceInfo struct {
|
||||||
|
Epoch int32
|
||||||
|
Timestamp int64
|
||||||
|
RowIndex int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *RecordSequenceInfo) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"{\"Epoch\":%d, \"Timestamp\": %d, \"RowIndex\": %d}",
|
||||||
|
this.Epoch,
|
||||||
|
this.Timestamp,
|
||||||
|
this.RowIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
type RecordColumn struct {
|
||||||
|
Type RecordColumnType
|
||||||
|
Name *string // required
|
||||||
|
Value interface{} // optional. present when Type is RCT_Put
|
||||||
|
Timestamp *int64 // optional, in msec. present when Type is RCT_Put or RCT_DeleteOneVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *RecordColumn) String() string {
|
||||||
|
xs := make([]string, 0)
|
||||||
|
xs = append(xs, fmt.Sprintf("\"Name\":%s", strconv.Quote(*this.Name)))
|
||||||
|
switch this.Type {
|
||||||
|
case RCT_DeleteAllVersions:
|
||||||
|
xs = append(xs, "\"Type\":\"DeleteAllVersions\"")
|
||||||
|
case RCT_DeleteOneVersion:
|
||||||
|
xs = append(xs, "\"Type\":\"DeleteOneVersion\"")
|
||||||
|
xs = append(xs, fmt.Sprintf("\"Timestamp\":%d", *this.Timestamp))
|
||||||
|
case RCT_Put:
|
||||||
|
xs = append(xs, "\"Type\":\"Put\"")
|
||||||
|
xs = append(xs, fmt.Sprintf("\"Timestamp\":%d", *this.Timestamp))
|
||||||
|
xs = append(xs, fmt.Sprintf("\"Value\":%s", this.Value))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("{%s}", strings.Join(xs, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
type RecordColumnType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
RCT_Put RecordColumnType = iota
|
||||||
|
RCT_DeleteOneVersion
|
||||||
|
RCT_DeleteAllVersions
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexMeta struct {
|
||||||
|
IndexName string
|
||||||
|
Primarykey []string
|
||||||
|
DefinedColumns []string
|
||||||
|
IndexType IndexType
|
||||||
|
}
|
||||||
|
|
||||||
|
type DefinedColumnSchema struct {
|
||||||
|
Name string
|
||||||
|
ColumnType DefinedColumnType
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
IT_GLOBAL_INDEX IndexType = 1
|
||||||
|
IT_LOCAL_INDEX IndexType = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type DefinedColumnType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
/**
|
||||||
|
* 64位整数。
|
||||||
|
*/
|
||||||
|
DefinedColumn_INTEGER DefinedColumnType = 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 浮点数。
|
||||||
|
*/
|
||||||
|
DefinedColumn_DOUBLE DefinedColumnType = 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 布尔值。
|
||||||
|
*/
|
||||||
|
DefinedColumn_BOOLEAN DefinedColumnType = 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符串。
|
||||||
|
*/
|
||||||
|
DefinedColumn_STRING DefinedColumnType = 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BINARY。
|
||||||
|
*/
|
||||||
|
DefinedColumn_BINARY DefinedColumnType = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
type StartLocalTransactionRequest struct {
|
||||||
|
PrimaryKey *PrimaryKey
|
||||||
|
TableName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StartLocalTransactionResponse struct {
|
||||||
|
TransactionId *string
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommitTransactionRequest struct {
|
||||||
|
TransactionId *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommitTransactionResponse struct {
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type AbortTransactionRequest struct {
|
||||||
|
TransactionId *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AbortTransactionResponse struct {
|
||||||
|
ResponseInfo
|
||||||
|
}
|
124
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/ots_header.go
generated
vendored
Normal file
124
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/ots_header.go
generated
vendored
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
package tablestore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/base64"
|
||||||
|
"hash"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
xOtsDate = "x-ots-date"
|
||||||
|
xOtsApiversion = "x-ots-apiversion"
|
||||||
|
xOtsAccesskeyid = "x-ots-accesskeyid"
|
||||||
|
xOtsContentmd5 = "x-ots-contentmd5"
|
||||||
|
xOtsHeaderStsToken = "x-ots-ststoken"
|
||||||
|
xOtsSignature = "x-ots-signature"
|
||||||
|
xOtsRequestCompressType = "x-ots-request-compress-type"
|
||||||
|
xOtsRequestCompressSize = "x-ots-request-compress-size"
|
||||||
|
xOtsResponseCompressTye = "x-ots-response-compress-type"
|
||||||
|
)
|
||||||
|
|
||||||
|
type otsHeader struct {
|
||||||
|
name string
|
||||||
|
value string
|
||||||
|
must bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type otsHeaders struct {
|
||||||
|
headers []*otsHeader
|
||||||
|
hmacSha1 hash.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func createOtsHeaders(accessKey string) *otsHeaders {
|
||||||
|
h := new(otsHeaders)
|
||||||
|
|
||||||
|
h.headers = []*otsHeader{
|
||||||
|
&otsHeader{name: xOtsDate, must: true},
|
||||||
|
&otsHeader{name: xOtsApiversion, must: true},
|
||||||
|
&otsHeader{name: xOtsAccesskeyid, must: true},
|
||||||
|
&otsHeader{name: xOtsContentmd5, must: true},
|
||||||
|
&otsHeader{name: xOtsInstanceName, must: true},
|
||||||
|
&otsHeader{name: xOtsSignature, must: true},
|
||||||
|
&otsHeader{name: xOtsRequestCompressSize, must: false},
|
||||||
|
&otsHeader{name: xOtsResponseCompressTye, must: false},
|
||||||
|
&otsHeader{name: xOtsRequestCompressType, must: false},
|
||||||
|
&otsHeader{name: xOtsHeaderStsToken, must: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(h)
|
||||||
|
|
||||||
|
h.hmacSha1 = hmac.New(sha1.New, []byte(accessKey))
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *otsHeaders) Len() int {
|
||||||
|
return len(h.headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *otsHeaders) Swap(i, j int) {
|
||||||
|
h.headers[i], h.headers[j] = h.headers[j], h.headers[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *otsHeaders) Less(i, j int) bool {
|
||||||
|
if h.headers[i].name == xOtsSignature {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.headers[j].name == xOtsSignature {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.headers[i].name < h.headers[j].name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *otsHeaders) search(name string) *otsHeader {
|
||||||
|
index := sort.Search(len(h.headers)-1, func(i int) bool {
|
||||||
|
return h.headers[i].name >= name
|
||||||
|
})
|
||||||
|
|
||||||
|
if index >= len(h.headers) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.headers[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *otsHeaders) set(name, value string) {
|
||||||
|
header := h.search(name)
|
||||||
|
if header == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
header.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *otsHeaders) signature(uri, method, accessKey string) (string, error) {
|
||||||
|
for _, header := range h.headers[:len(h.headers)-1] {
|
||||||
|
if header.must && header.value == "" {
|
||||||
|
return "", errMissMustHeader(header.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringToSign = CanonicalURI + '\n' + HTTPRequestMethod + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n'
|
||||||
|
// TODO CanonicalQueryString 为空
|
||||||
|
stringToSign := uri + "\n" + method + "\n" + "\n"
|
||||||
|
|
||||||
|
// 最后一个header 为 xOtsSignature
|
||||||
|
for _, header := range h.headers[:len(h.headers)-1] {
|
||||||
|
if header.value != "" {
|
||||||
|
stringToSign = stringToSign + header.name + ":" + strings.TrimSpace(header.value) + "\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h.hmacSha1.Reset()
|
||||||
|
h.hmacSha1.Write([]byte(stringToSign))
|
||||||
|
|
||||||
|
// fmt.Println("stringToSign:" + stringToSign)
|
||||||
|
sign := base64.StdEncoding.EncodeToString(h.hmacSha1.Sum(nil))
|
||||||
|
h.set(xOtsSignature, sign)
|
||||||
|
// fmt.Println("sign:" + sign)
|
||||||
|
return sign, nil
|
||||||
|
}
|
1
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/build_proto.sh
generated
vendored
Normal file
1
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/build_proto.sh
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
protoc --go_out=. search.proto ots_filter.proto table_store.proto
|
390
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/ots_filter.pb.go
generated
vendored
Normal file
390
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/ots_filter.pb.go
generated
vendored
Normal file
|
@ -0,0 +1,390 @@
|
||||||
|
// Code generated by protoc-gen-go.
|
||||||
|
// source: ots_filter.proto
|
||||||
|
// DO NOT EDIT!
|
||||||
|
|
||||||
|
package otsprotocol
|
||||||
|
|
||||||
|
import proto "github.com/golang/protobuf/proto"
|
||||||
|
import fmt "fmt"
|
||||||
|
import math "math"
|
||||||
|
|
||||||
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
var _ = proto.Marshal
|
||||||
|
var _ = fmt.Errorf
|
||||||
|
var _ = math.Inf
|
||||||
|
|
||||||
|
type VariantType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
VariantType_VT_INTEGER VariantType = 0
|
||||||
|
VariantType_VT_DOUBLE VariantType = 1
|
||||||
|
// VT_BOOLEAN = 2;
|
||||||
|
VariantType_VT_STRING VariantType = 3
|
||||||
|
VariantType_VT_NULL VariantType = 6
|
||||||
|
VariantType_VT_BLOB VariantType = 7
|
||||||
|
)
|
||||||
|
|
||||||
|
var VariantType_name = map[int32]string{
|
||||||
|
0: "VT_INTEGER",
|
||||||
|
1: "VT_DOUBLE",
|
||||||
|
3: "VT_STRING",
|
||||||
|
6: "VT_NULL",
|
||||||
|
7: "VT_BLOB",
|
||||||
|
}
|
||||||
|
var VariantType_value = map[string]int32{
|
||||||
|
"VT_INTEGER": 0,
|
||||||
|
"VT_DOUBLE": 1,
|
||||||
|
"VT_STRING": 3,
|
||||||
|
"VT_NULL": 6,
|
||||||
|
"VT_BLOB": 7,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x VariantType) Enum() *VariantType {
|
||||||
|
p := new(VariantType)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
func (x VariantType) String() string {
|
||||||
|
return proto.EnumName(VariantType_name, int32(x))
|
||||||
|
}
|
||||||
|
func (x *VariantType) UnmarshalJSON(data []byte) error {
|
||||||
|
value, err := proto.UnmarshalJSONEnum(VariantType_value, data, "VariantType")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = VariantType(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (VariantType) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
|
||||||
|
|
||||||
|
type FilterType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
FilterType_FT_SINGLE_COLUMN_VALUE FilterType = 1
|
||||||
|
FilterType_FT_COMPOSITE_COLUMN_VALUE FilterType = 2
|
||||||
|
FilterType_FT_COLUMN_PAGINATION FilterType = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
var FilterType_name = map[int32]string{
|
||||||
|
1: "FT_SINGLE_COLUMN_VALUE",
|
||||||
|
2: "FT_COMPOSITE_COLUMN_VALUE",
|
||||||
|
3: "FT_COLUMN_PAGINATION",
|
||||||
|
}
|
||||||
|
var FilterType_value = map[string]int32{
|
||||||
|
"FT_SINGLE_COLUMN_VALUE": 1,
|
||||||
|
"FT_COMPOSITE_COLUMN_VALUE": 2,
|
||||||
|
"FT_COLUMN_PAGINATION": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x FilterType) Enum() *FilterType {
|
||||||
|
p := new(FilterType)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
func (x FilterType) String() string {
|
||||||
|
return proto.EnumName(FilterType_name, int32(x))
|
||||||
|
}
|
||||||
|
func (x *FilterType) UnmarshalJSON(data []byte) error {
|
||||||
|
value, err := proto.UnmarshalJSONEnum(FilterType_value, data, "FilterType")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = FilterType(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (FilterType) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
|
||||||
|
|
||||||
|
type ComparatorType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
ComparatorType_CT_EQUAL ComparatorType = 1
|
||||||
|
ComparatorType_CT_NOT_EQUAL ComparatorType = 2
|
||||||
|
ComparatorType_CT_GREATER_THAN ComparatorType = 3
|
||||||
|
ComparatorType_CT_GREATER_EQUAL ComparatorType = 4
|
||||||
|
ComparatorType_CT_LESS_THAN ComparatorType = 5
|
||||||
|
ComparatorType_CT_LESS_EQUAL ComparatorType = 6
|
||||||
|
)
|
||||||
|
|
||||||
|
var ComparatorType_name = map[int32]string{
|
||||||
|
1: "CT_EQUAL",
|
||||||
|
2: "CT_NOT_EQUAL",
|
||||||
|
3: "CT_GREATER_THAN",
|
||||||
|
4: "CT_GREATER_EQUAL",
|
||||||
|
5: "CT_LESS_THAN",
|
||||||
|
6: "CT_LESS_EQUAL",
|
||||||
|
}
|
||||||
|
var ComparatorType_value = map[string]int32{
|
||||||
|
"CT_EQUAL": 1,
|
||||||
|
"CT_NOT_EQUAL": 2,
|
||||||
|
"CT_GREATER_THAN": 3,
|
||||||
|
"CT_GREATER_EQUAL": 4,
|
||||||
|
"CT_LESS_THAN": 5,
|
||||||
|
"CT_LESS_EQUAL": 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x ComparatorType) Enum() *ComparatorType {
|
||||||
|
p := new(ComparatorType)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
func (x ComparatorType) String() string {
|
||||||
|
return proto.EnumName(ComparatorType_name, int32(x))
|
||||||
|
}
|
||||||
|
func (x *ComparatorType) UnmarshalJSON(data []byte) error {
|
||||||
|
value, err := proto.UnmarshalJSONEnum(ComparatorType_value, data, "ComparatorType")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = ComparatorType(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (ComparatorType) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{2} }
|
||||||
|
|
||||||
|
type LogicalOperator int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
LogicalOperator_LO_NOT LogicalOperator = 1
|
||||||
|
LogicalOperator_LO_AND LogicalOperator = 2
|
||||||
|
LogicalOperator_LO_OR LogicalOperator = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
var LogicalOperator_name = map[int32]string{
|
||||||
|
1: "LO_NOT",
|
||||||
|
2: "LO_AND",
|
||||||
|
3: "LO_OR",
|
||||||
|
}
|
||||||
|
var LogicalOperator_value = map[string]int32{
|
||||||
|
"LO_NOT": 1,
|
||||||
|
"LO_AND": 2,
|
||||||
|
"LO_OR": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x LogicalOperator) Enum() *LogicalOperator {
|
||||||
|
p := new(LogicalOperator)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
func (x LogicalOperator) String() string {
|
||||||
|
return proto.EnumName(LogicalOperator_name, int32(x))
|
||||||
|
}
|
||||||
|
func (x *LogicalOperator) UnmarshalJSON(data []byte) error {
|
||||||
|
value, err := proto.UnmarshalJSONEnum(LogicalOperator_value, data, "LogicalOperator")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = LogicalOperator(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (LogicalOperator) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{3} }
|
||||||
|
|
||||||
|
type ValueTransferRule struct {
|
||||||
|
Regex *string `protobuf:"bytes,1,req,name=regex" json:"regex,omitempty"`
|
||||||
|
CastType *VariantType `protobuf:"varint,2,opt,name=cast_type,enum=otsprotocol.VariantType" json:"cast_type,omitempty"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ValueTransferRule) Reset() { *m = ValueTransferRule{} }
|
||||||
|
func (m *ValueTransferRule) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*ValueTransferRule) ProtoMessage() {}
|
||||||
|
func (*ValueTransferRule) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
|
||||||
|
|
||||||
|
func (m *ValueTransferRule) GetRegex() string {
|
||||||
|
if m != nil && m.Regex != nil {
|
||||||
|
return *m.Regex
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ValueTransferRule) GetCastType() VariantType {
|
||||||
|
if m != nil && m.CastType != nil {
|
||||||
|
return *m.CastType
|
||||||
|
}
|
||||||
|
return VariantType_VT_INTEGER
|
||||||
|
}
|
||||||
|
|
||||||
|
type SingleColumnValueFilter struct {
|
||||||
|
Comparator *ComparatorType `protobuf:"varint,1,req,name=comparator,enum=otsprotocol.ComparatorType" json:"comparator,omitempty"`
|
||||||
|
ColumnName *string `protobuf:"bytes,2,req,name=column_name" json:"column_name,omitempty"`
|
||||||
|
ColumnValue []byte `protobuf:"bytes,3,req,name=column_value" json:"column_value,omitempty"`
|
||||||
|
FilterIfMissing *bool `protobuf:"varint,4,req,name=filter_if_missing" json:"filter_if_missing,omitempty"`
|
||||||
|
LatestVersionOnly *bool `protobuf:"varint,5,req,name=latest_version_only" json:"latest_version_only,omitempty"`
|
||||||
|
ValueTransRule *ValueTransferRule `protobuf:"bytes,6,opt,name=value_trans_rule" json:"value_trans_rule,omitempty"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SingleColumnValueFilter) Reset() { *m = SingleColumnValueFilter{} }
|
||||||
|
func (m *SingleColumnValueFilter) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*SingleColumnValueFilter) ProtoMessage() {}
|
||||||
|
func (*SingleColumnValueFilter) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
|
||||||
|
|
||||||
|
func (m *SingleColumnValueFilter) GetComparator() ComparatorType {
|
||||||
|
if m != nil && m.Comparator != nil {
|
||||||
|
return *m.Comparator
|
||||||
|
}
|
||||||
|
return ComparatorType_CT_EQUAL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SingleColumnValueFilter) GetColumnName() string {
|
||||||
|
if m != nil && m.ColumnName != nil {
|
||||||
|
return *m.ColumnName
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SingleColumnValueFilter) GetColumnValue() []byte {
|
||||||
|
if m != nil {
|
||||||
|
return m.ColumnValue
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SingleColumnValueFilter) GetFilterIfMissing() bool {
|
||||||
|
if m != nil && m.FilterIfMissing != nil {
|
||||||
|
return *m.FilterIfMissing
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SingleColumnValueFilter) GetLatestVersionOnly() bool {
|
||||||
|
if m != nil && m.LatestVersionOnly != nil {
|
||||||
|
return *m.LatestVersionOnly
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SingleColumnValueFilter) GetValueTransRule() *ValueTransferRule {
|
||||||
|
if m != nil {
|
||||||
|
return m.ValueTransRule
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompositeColumnValueFilter struct {
|
||||||
|
Combinator *LogicalOperator `protobuf:"varint,1,req,name=combinator,enum=otsprotocol.LogicalOperator" json:"combinator,omitempty"`
|
||||||
|
SubFilters []*Filter `protobuf:"bytes,2,rep,name=sub_filters" json:"sub_filters,omitempty"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *CompositeColumnValueFilter) Reset() { *m = CompositeColumnValueFilter{} }
|
||||||
|
func (m *CompositeColumnValueFilter) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*CompositeColumnValueFilter) ProtoMessage() {}
|
||||||
|
func (*CompositeColumnValueFilter) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} }
|
||||||
|
|
||||||
|
func (m *CompositeColumnValueFilter) GetCombinator() LogicalOperator {
|
||||||
|
if m != nil && m.Combinator != nil {
|
||||||
|
return *m.Combinator
|
||||||
|
}
|
||||||
|
return LogicalOperator_LO_NOT
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *CompositeColumnValueFilter) GetSubFilters() []*Filter {
|
||||||
|
if m != nil {
|
||||||
|
return m.SubFilters
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnPaginationFilter struct {
|
||||||
|
Offset *int32 `protobuf:"varint,1,req,name=offset" json:"offset,omitempty"`
|
||||||
|
Limit *int32 `protobuf:"varint,2,req,name=limit" json:"limit,omitempty"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ColumnPaginationFilter) Reset() { *m = ColumnPaginationFilter{} }
|
||||||
|
func (m *ColumnPaginationFilter) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*ColumnPaginationFilter) ProtoMessage() {}
|
||||||
|
func (*ColumnPaginationFilter) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} }
|
||||||
|
|
||||||
|
func (m *ColumnPaginationFilter) GetOffset() int32 {
|
||||||
|
if m != nil && m.Offset != nil {
|
||||||
|
return *m.Offset
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ColumnPaginationFilter) GetLimit() int32 {
|
||||||
|
if m != nil && m.Limit != nil {
|
||||||
|
return *m.Limit
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type Filter struct {
|
||||||
|
Type *FilterType `protobuf:"varint,1,req,name=type,enum=otsprotocol.FilterType" json:"type,omitempty"`
|
||||||
|
Filter []byte `protobuf:"bytes,2,req,name=filter" json:"filter,omitempty"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Filter) Reset() { *m = Filter{} }
|
||||||
|
func (m *Filter) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Filter) ProtoMessage() {}
|
||||||
|
func (*Filter) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} }
|
||||||
|
|
||||||
|
func (m *Filter) GetType() FilterType {
|
||||||
|
if m != nil && m.Type != nil {
|
||||||
|
return *m.Type
|
||||||
|
}
|
||||||
|
return FilterType_FT_SINGLE_COLUMN_VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Filter) GetFilter() []byte {
|
||||||
|
if m != nil {
|
||||||
|
return m.Filter
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterType((*ValueTransferRule)(nil), "otsprotocol.ValueTransferRule")
|
||||||
|
proto.RegisterType((*SingleColumnValueFilter)(nil), "otsprotocol.SingleColumnValueFilter")
|
||||||
|
proto.RegisterType((*CompositeColumnValueFilter)(nil), "otsprotocol.CompositeColumnValueFilter")
|
||||||
|
proto.RegisterType((*ColumnPaginationFilter)(nil), "otsprotocol.ColumnPaginationFilter")
|
||||||
|
proto.RegisterType((*Filter)(nil), "otsprotocol.Filter")
|
||||||
|
proto.RegisterEnum("otsprotocol.VariantType", VariantType_name, VariantType_value)
|
||||||
|
proto.RegisterEnum("otsprotocol.FilterType", FilterType_name, FilterType_value)
|
||||||
|
proto.RegisterEnum("otsprotocol.ComparatorType", ComparatorType_name, ComparatorType_value)
|
||||||
|
proto.RegisterEnum("otsprotocol.LogicalOperator", LogicalOperator_name, LogicalOperator_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { proto.RegisterFile("ots_filter.proto", fileDescriptor1) }
|
||||||
|
|
||||||
|
var fileDescriptor1 = []byte{
|
||||||
|
// 585 bytes of a gzipped FileDescriptorProto
|
||||||
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x92, 0x51, 0x6b, 0xdb, 0x30,
|
||||||
|
0x14, 0x85, 0x67, 0xa7, 0x71, 0x9b, 0xeb, 0x34, 0x55, 0x95, 0xd2, 0xba, 0xed, 0x36, 0x42, 0x60,
|
||||||
|
0x60, 0x32, 0xe8, 0x46, 0x18, 0x6c, 0x6f, 0xc3, 0x75, 0xdd, 0x2c, 0xe0, 0xda, 0x5d, 0xa2, 0xf8,
|
||||||
|
0x55, 0xb8, 0x41, 0x09, 0x02, 0xc7, 0x0a, 0x96, 0x52, 0xda, 0xb7, 0xfd, 0xdb, 0xfd, 0x8d, 0x61,
|
||||||
|
0xd9, 0x1d, 0x69, 0xe8, 0x9b, 0x75, 0xef, 0xd5, 0x77, 0xee, 0xd1, 0x31, 0x20, 0xa1, 0x24, 0x5d,
|
||||||
|
0xf0, 0x4c, 0xb1, 0xe2, 0x6a, 0x5d, 0x08, 0x25, 0xb0, 0x2d, 0x94, 0xd4, 0x5f, 0x73, 0x91, 0xf5,
|
||||||
|
0x63, 0x38, 0x4e, 0xd2, 0x6c, 0xc3, 0x48, 0x91, 0xe6, 0x72, 0xc1, 0x8a, 0xc9, 0x26, 0x63, 0xf8,
|
||||||
|
0x10, 0x9a, 0x05, 0x5b, 0xb2, 0x27, 0xc7, 0xe8, 0x99, 0x6e, 0x0b, 0x7f, 0x86, 0xd6, 0x3c, 0x95,
|
||||||
|
0x8a, 0xaa, 0xe7, 0x35, 0x73, 0xcc, 0x9e, 0xe1, 0x76, 0x86, 0xce, 0xd5, 0x16, 0xe4, 0x2a, 0x49,
|
||||||
|
0x0b, 0x9e, 0xe6, 0x8a, 0x3c, 0xaf, 0x59, 0xff, 0xaf, 0x01, 0x67, 0x53, 0x9e, 0x2f, 0x33, 0xe6,
|
||||||
|
0x8b, 0x6c, 0xb3, 0xca, 0x35, 0xfd, 0x56, 0xeb, 0xe3, 0x2f, 0x00, 0x73, 0xb1, 0x5a, 0xa7, 0x45,
|
||||||
|
0xaa, 0x44, 0xa1, 0xe1, 0x9d, 0xe1, 0xe5, 0x2b, 0x92, 0xff, 0xbf, 0x5d, 0xc2, 0x70, 0x17, 0xec,
|
||||||
|
0xb9, 0xa6, 0xd0, 0x3c, 0x5d, 0x95, 0xda, 0xe5, 0x3a, 0x27, 0xd0, 0xae, 0x8b, 0x8f, 0x25, 0xdb,
|
||||||
|
0x69, 0xf4, 0x4c, 0xb7, 0x8d, 0xcf, 0xe1, 0xb8, 0x72, 0x49, 0xf9, 0x82, 0xae, 0xb8, 0x94, 0x3c,
|
||||||
|
0x5f, 0x3a, 0x7b, 0x3d, 0xd3, 0x3d, 0xc0, 0x97, 0xd0, 0xcd, 0x52, 0xc5, 0xa4, 0xa2, 0x8f, 0xac,
|
||||||
|
0x90, 0x5c, 0xe4, 0x54, 0xe4, 0xd9, 0xb3, 0xd3, 0xd4, 0xcd, 0x1f, 0x80, 0x34, 0x86, 0xaa, 0xf2,
|
||||||
|
0x05, 0x68, 0xb1, 0xc9, 0x98, 0x63, 0xf5, 0x0c, 0xd7, 0x1e, 0x7e, 0xdc, 0xf1, 0xb8, 0xf3, 0x4a,
|
||||||
|
0xfd, 0x27, 0xb8, 0x28, 0xd7, 0x15, 0x92, 0xab, 0x37, 0xbc, 0x7e, 0xd5, 0x5e, 0x1f, 0x78, 0xbe,
|
||||||
|
0xe5, 0xf5, 0xfd, 0x2b, 0x62, 0x28, 0x96, 0x7c, 0x9e, 0x66, 0xf1, 0x9a, 0x69, 0xc3, 0xd8, 0x05,
|
||||||
|
0x5b, 0x6e, 0x1e, 0xea, 0xac, 0xa4, 0x63, 0xf6, 0x1a, 0xae, 0x3d, 0xec, 0xbe, 0xba, 0x52, 0xb1,
|
||||||
|
0xfb, 0xdf, 0xe1, 0xb4, 0x12, 0xbc, 0x4f, 0x97, 0xa5, 0x00, 0x17, 0x79, 0xad, 0xda, 0x01, 0x4b,
|
||||||
|
0x2c, 0x16, 0x92, 0x29, 0xad, 0xd8, 0x2c, 0x93, 0xcc, 0xf8, 0x8a, 0x2b, 0xfd, 0x74, 0xcd, 0xfe,
|
||||||
|
0x4f, 0xb0, 0xea, 0xc1, 0x4f, 0xb0, 0xa7, 0xe3, 0xac, 0x16, 0x3b, 0x7b, 0x43, 0x45, 0x07, 0xd0,
|
||||||
|
0x01, 0xab, 0xda, 0x47, 0x03, 0xda, 0x83, 0x19, 0xd8, 0x5b, 0x61, 0xe3, 0x0e, 0x40, 0x42, 0xe8,
|
||||||
|
0x38, 0x22, 0xc1, 0x28, 0x98, 0xa0, 0x77, 0xf8, 0x10, 0x5a, 0x09, 0xa1, 0x37, 0xf1, 0xec, 0x3a,
|
||||||
|
0x0c, 0x90, 0x51, 0x1f, 0xa7, 0x64, 0x32, 0x8e, 0x46, 0xa8, 0x81, 0x6d, 0xd8, 0x4f, 0x08, 0x8d,
|
||||||
|
0x66, 0x61, 0x88, 0xac, 0xfa, 0x70, 0x1d, 0xc6, 0xd7, 0x68, 0x7f, 0x90, 0x02, 0x6c, 0x89, 0x5e,
|
||||||
|
0xc0, 0xe9, 0x2d, 0xa1, 0xd3, 0x71, 0x34, 0x0a, 0x03, 0xea, 0xc7, 0xe1, 0xec, 0x2e, 0xa2, 0x89,
|
||||||
|
0x17, 0xce, 0x4a, 0xe4, 0x07, 0x38, 0xbf, 0x25, 0xd4, 0x8f, 0xef, 0xee, 0xe3, 0xe9, 0x98, 0xec,
|
||||||
|
0xb4, 0x4d, 0xec, 0xc0, 0x89, 0x6e, 0xeb, 0xe2, 0xbd, 0x37, 0x1a, 0x47, 0x1e, 0x19, 0xc7, 0x11,
|
||||||
|
0x6a, 0x0c, 0xfe, 0x18, 0xd0, 0xd9, 0xf9, 0xbb, 0xda, 0x70, 0xe0, 0x13, 0x1a, 0xfc, 0x9e, 0x79,
|
||||||
|
0x21, 0x32, 0x30, 0x82, 0xb6, 0x4f, 0x68, 0x14, 0xbf, 0x54, 0x4c, 0xdc, 0x85, 0x23, 0x9f, 0xd0,
|
||||||
|
0xd1, 0x24, 0xf0, 0x48, 0x30, 0xa1, 0xe4, 0x97, 0x17, 0xa1, 0x06, 0x3e, 0x01, 0xb4, 0x55, 0xac,
|
||||||
|
0x46, 0xf7, 0xea, 0xcb, 0x61, 0x30, 0x9d, 0x56, 0x73, 0x4d, 0x7c, 0x0c, 0x87, 0x2f, 0x95, 0x6a,
|
||||||
|
0xc8, 0x1a, 0x7c, 0x83, 0xa3, 0xdd, 0xcc, 0x01, 0xac, 0x30, 0x2e, 0x45, 0x91, 0x51, 0x7f, 0x7b,
|
||||||
|
0xd1, 0x0d, 0x32, 0x71, 0x0b, 0x9a, 0x61, 0x4c, 0xe3, 0x09, 0x6a, 0xfc, 0x0b, 0x00, 0x00, 0xff,
|
||||||
|
0xff, 0xb3, 0x10, 0x19, 0xa7, 0xc1, 0x03, 0x00, 0x00,
|
||||||
|
}
|
61
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/ots_filter.proto
generated
vendored
Normal file
61
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/ots_filter.proto
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
package otsprotocol;
|
||||||
|
|
||||||
|
enum VariantType {
|
||||||
|
VT_INTEGER = 0;
|
||||||
|
VT_DOUBLE = 1;
|
||||||
|
//VT_BOOLEAN = 2;
|
||||||
|
VT_STRING = 3;
|
||||||
|
VT_NULL = 6;
|
||||||
|
VT_BLOB = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ValueTransferRule {
|
||||||
|
required string regex = 1;
|
||||||
|
optional VariantType cast_type = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FilterType {
|
||||||
|
FT_SINGLE_COLUMN_VALUE = 1;
|
||||||
|
FT_COMPOSITE_COLUMN_VALUE = 2;
|
||||||
|
FT_COLUMN_PAGINATION = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ComparatorType {
|
||||||
|
CT_EQUAL = 1;
|
||||||
|
CT_NOT_EQUAL = 2;
|
||||||
|
CT_GREATER_THAN = 3;
|
||||||
|
CT_GREATER_EQUAL = 4;
|
||||||
|
CT_LESS_THAN = 5;
|
||||||
|
CT_LESS_EQUAL = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SingleColumnValueFilter {
|
||||||
|
required ComparatorType comparator = 1;
|
||||||
|
required string column_name = 2;
|
||||||
|
required bytes column_value = 3; // Serialized SQLVariant
|
||||||
|
required bool filter_if_missing = 4;
|
||||||
|
required bool latest_version_only = 5;
|
||||||
|
optional ValueTransferRule value_trans_rule = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LogicalOperator {
|
||||||
|
LO_NOT = 1;
|
||||||
|
LO_AND = 2;
|
||||||
|
LO_OR = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CompositeColumnValueFilter {
|
||||||
|
required LogicalOperator combinator = 1;
|
||||||
|
repeated Filter sub_filters = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ColumnPaginationFilter {
|
||||||
|
required int32 offset = 1;
|
||||||
|
required int32 limit = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Filter {
|
||||||
|
required FilterType type = 1;
|
||||||
|
required bytes filter = 2; // Serialized string of filter of the type
|
||||||
|
}
|
1997
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/search.pb.go
generated
vendored
Normal file
1997
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/search.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
323
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/search.proto
generated
vendored
Normal file
323
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/search.proto
generated
vendored
Normal file
|
@ -0,0 +1,323 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
package otsprotocol;
|
||||||
|
|
||||||
|
enum QueryType {
|
||||||
|
MATCH_QUERY = 1;
|
||||||
|
MATCH_PHRASE_QUERY = 2;
|
||||||
|
TERM_QUERY = 3;
|
||||||
|
RANGE_QUERY = 4;
|
||||||
|
PREFIX_QUERY = 5;
|
||||||
|
BOOL_QUERY = 6;
|
||||||
|
CONST_SCORE_QUERY = 7;
|
||||||
|
FUNCTION_SCORE_QUERY = 8;
|
||||||
|
NESTED_QUERY = 9;
|
||||||
|
WILDCARD_QUERY = 10;
|
||||||
|
MATCH_ALL_QUERY = 11;
|
||||||
|
GEO_BOUNDING_BOX_QUERY = 12;
|
||||||
|
GEO_DISTANCE_QUERY = 13;
|
||||||
|
GEO_POLYGON_QUERY = 14;
|
||||||
|
TERMS_QUERY = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum QueryOperator {
|
||||||
|
OR = 1;
|
||||||
|
AND = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MatchQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional string text = 2;
|
||||||
|
optional int32 minimum_should_match = 3;
|
||||||
|
optional QueryOperator operator = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MatchPhraseQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional string text = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MatchAllQuery {
|
||||||
|
}
|
||||||
|
|
||||||
|
message TermQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional bytes term = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TermsQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
repeated bytes terms = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RangeQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional bytes range_from = 2; // variant value
|
||||||
|
optional bytes range_to = 3; // variant value
|
||||||
|
optional bool include_lower = 4;
|
||||||
|
optional bool include_upper = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PrefixQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional string prefix = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WildcardQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional string value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BoolQuery {
|
||||||
|
repeated Query must_queries = 1;
|
||||||
|
repeated Query must_not_queries = 2;
|
||||||
|
repeated Query filter_queries = 3;
|
||||||
|
repeated Query should_queries = 4;
|
||||||
|
optional int32 minimum_should_match = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConstScoreQuery {
|
||||||
|
optional Query filter = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FieldValueFactor {
|
||||||
|
optional string field_name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FunctionScoreQuery {
|
||||||
|
optional Query query = 1;
|
||||||
|
optional FieldValueFactor field_value_factor = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ScoreMode {
|
||||||
|
SCORE_MODE_NONE = 1;
|
||||||
|
SCORE_MODE_AVG = 2;
|
||||||
|
SCORE_MODE_MAX = 3;
|
||||||
|
SCORE_MODE_TOTAL = 4;
|
||||||
|
SCORE_MODE_MIN = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NestedQuery {
|
||||||
|
optional string path = 1;
|
||||||
|
optional Query query = 2;
|
||||||
|
optional ScoreMode score_mode = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GeoBoundingBoxQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional string top_left = 2;
|
||||||
|
optional string bottom_right = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GeoDistanceQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional string center_point = 2;
|
||||||
|
optional double distance = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GeoPolygonQuery {
|
||||||
|
optional string field_name = 1;
|
||||||
|
repeated string points = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Query {
|
||||||
|
optional QueryType type = 1;
|
||||||
|
optional bytes query = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Collapse {
|
||||||
|
optional string field_name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NestedFilter {
|
||||||
|
optional string path = 1;
|
||||||
|
optional Query filter = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SortOrder {
|
||||||
|
SORT_ORDER_ASC = 0;
|
||||||
|
SORT_ORDER_DESC = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SortMode {
|
||||||
|
SORT_MODE_MIN = 0;
|
||||||
|
SORT_MODE_MAX = 1;
|
||||||
|
SORT_MODE_AVG = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ScoreSort {
|
||||||
|
optional SortOrder order = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FieldSort {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional SortOrder order = 2;
|
||||||
|
optional SortMode mode = 3;
|
||||||
|
optional NestedFilter nested_filter = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum GeoDistanceType {
|
||||||
|
GEO_DISTANCE_ARC = 0;
|
||||||
|
GEO_DISTANCE_PLANE = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GeoDistanceSort {
|
||||||
|
optional string field_name = 1;
|
||||||
|
repeated string points = 2;
|
||||||
|
optional SortOrder order = 3;
|
||||||
|
optional SortMode mode = 4;
|
||||||
|
optional GeoDistanceType distance_type = 5;
|
||||||
|
optional NestedFilter nested_filter = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PrimaryKeySort {
|
||||||
|
optional SortOrder order = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Sorter {
|
||||||
|
optional FieldSort field_sort = 1;
|
||||||
|
optional GeoDistanceSort geo_distance_sort = 2;
|
||||||
|
optional ScoreSort score_sort = 3;
|
||||||
|
optional PrimaryKeySort pk_sort = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Sort {
|
||||||
|
repeated Sorter sorter = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SearchQuery {
|
||||||
|
optional int32 offset = 1;
|
||||||
|
optional int32 limit = 2;
|
||||||
|
optional Query query = 4;
|
||||||
|
optional Collapse collapse = 5;
|
||||||
|
optional Sort sort = 6;
|
||||||
|
optional bool getTotalCount = 8;
|
||||||
|
optional bytes token = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ColumnReturnType {
|
||||||
|
RETURN_ALL = 1;
|
||||||
|
RETURN_SPECIFIED = 2;
|
||||||
|
RETURN_NONE = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ColumnsToGet {
|
||||||
|
optional ColumnReturnType return_type = 1;
|
||||||
|
repeated string column_names = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SearchRequest {
|
||||||
|
optional string table_name = 1;
|
||||||
|
optional string index_name = 2;
|
||||||
|
optional ColumnsToGet columns_to_get = 3;
|
||||||
|
optional bytes search_query = 4;
|
||||||
|
repeated bytes routing_values = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response部分:
|
||||||
|
**/
|
||||||
|
|
||||||
|
message SearchResponse {
|
||||||
|
optional int64 total_hits = 1;
|
||||||
|
repeated bytes rows = 2;
|
||||||
|
optional bool is_all_succeeded = 3;
|
||||||
|
optional bytes next_token = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create Search Index */
|
||||||
|
|
||||||
|
enum IndexOptions {
|
||||||
|
DOCS = 1;
|
||||||
|
FREQS = 2;
|
||||||
|
POSITIONS = 3;
|
||||||
|
OFFSETS = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FieldType {
|
||||||
|
LONG = 1;
|
||||||
|
DOUBLE = 2;
|
||||||
|
BOOLEAN = 3;
|
||||||
|
KEYWORD = 4;
|
||||||
|
TEXT = 5;
|
||||||
|
NESTED = 6;
|
||||||
|
GEO_POINT = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FieldSchema {
|
||||||
|
optional string field_name = 1;
|
||||||
|
optional FieldType field_type = 2;
|
||||||
|
optional IndexOptions index_options = 3;
|
||||||
|
optional string analyzer = 4;
|
||||||
|
optional bool index = 5;
|
||||||
|
optional bool doc_values = 6;
|
||||||
|
optional bool store = 7;
|
||||||
|
repeated FieldSchema field_schemas = 8; // only for nested type
|
||||||
|
optional bool is_array = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IndexSchema {
|
||||||
|
repeated FieldSchema field_schemas = 1;
|
||||||
|
optional IndexSetting index_setting = 2;
|
||||||
|
optional Sort index_sort = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IndexSetting {
|
||||||
|
optional int32 number_of_shards = 1;
|
||||||
|
repeated string routing_fields = 2;
|
||||||
|
optional int32 routing_partition_size = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateSearchIndexRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
required string index_name = 2;
|
||||||
|
optional IndexSchema schema = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateSearchIndexResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List Search Index */
|
||||||
|
|
||||||
|
message IndexInfo {
|
||||||
|
optional string table_name = 1;
|
||||||
|
optional string index_name = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListSearchIndexRequest {
|
||||||
|
optional string table_name = 1;
|
||||||
|
}
|
||||||
|
message ListSearchIndexResponse {
|
||||||
|
repeated IndexInfo indices = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete Search Index */
|
||||||
|
|
||||||
|
message DeleteSearchIndexRequest {
|
||||||
|
optional string table_name = 1;
|
||||||
|
optional string index_name = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteSearchIndexResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Describe Search Index */
|
||||||
|
|
||||||
|
enum SyncPhase {
|
||||||
|
FULL = 1;
|
||||||
|
INCR = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SyncStat {
|
||||||
|
optional SyncPhase sync_phase = 1;
|
||||||
|
optional int64 current_sync_timestamp = 2; // 同步进度,参考TunnelService。
|
||||||
|
}
|
||||||
|
|
||||||
|
message DescribeSearchIndexRequest {
|
||||||
|
optional string table_name = 1;
|
||||||
|
optional string index_name = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DescribeSearchIndexResponse {
|
||||||
|
optional IndexSchema schema = 1;
|
||||||
|
optional SyncStat sync_stat = 2;
|
||||||
|
}
|
3141
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/table_store.pb.go
generated
vendored
Normal file
3141
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/table_store.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
616
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/table_store.proto
generated
vendored
Normal file
616
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol/table_store.proto
generated
vendored
Normal file
|
@ -0,0 +1,616 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
package otsprotocol;
|
||||||
|
|
||||||
|
message Error {
|
||||||
|
required string code = 1;
|
||||||
|
optional string message = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PrimaryKeyType {
|
||||||
|
INTEGER = 1;
|
||||||
|
STRING = 2;
|
||||||
|
BINARY = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PrimaryKeyOption {
|
||||||
|
AUTO_INCREMENT = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PrimaryKeySchema {
|
||||||
|
required string name = 1;
|
||||||
|
required PrimaryKeyType type = 2;
|
||||||
|
optional PrimaryKeyOption option = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PartitionRange {
|
||||||
|
required bytes begin = 1; // encoded as SQLVariant
|
||||||
|
required bytes end = 2; // encoded as SQLVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BloomFilterType {
|
||||||
|
NONE = 1;
|
||||||
|
CELL = 2;
|
||||||
|
ROW = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TableOptions {
|
||||||
|
optional int32 time_to_live = 1; // 可以动态更改
|
||||||
|
optional int32 max_versions = 2; // 可以动态更改
|
||||||
|
optional BloomFilterType bloom_filter_type = 3; // 可以动态更改
|
||||||
|
optional int32 block_size = 4; // 可以动态更改
|
||||||
|
optional int64 deviation_cell_version_in_sec = 5; // 可以动态修改
|
||||||
|
}
|
||||||
|
|
||||||
|
message TableMeta {
|
||||||
|
required string table_name = 1;
|
||||||
|
repeated PrimaryKeySchema primary_key = 2;
|
||||||
|
repeated DefinedColumnSchema defined_column = 3;
|
||||||
|
repeated IndexMeta index_meta = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表的状态变更只与用户的操作对应,内部的机器failover等状况不对应表的状态变更。
|
||||||
|
* 有三个考虑:
|
||||||
|
* 一是一般场景下用户只会在做了对表的修改操作后才会去检查表的状态;
|
||||||
|
* 二是内部机器failover导致访问异常到用户能够查看到表的状态变更这两个时刻之间会有一段延迟,无法将表的不可服务状态与用户查看到的表的状态完全匹配上。
|
||||||
|
* 三是内部机器failover后不能说是表的整个状态变更,而应该是partition的状态变更,对应表的状态就是PARTIAL_FAILOVER,这个partial的粒度无法体现,会让用户更加困惑。
|
||||||
|
*/
|
||||||
|
enum TableStatus {
|
||||||
|
ACTIVE = 1; // 表处于可服务状态。
|
||||||
|
INACTIVE = 2; // 用户通过UnloadTable将表禁用。
|
||||||
|
LOADING = 3; // 表正在被创建,partition还未全部加载完毕;或者表刚从INACTIVE状态被Enable。
|
||||||
|
UNLOADING = 4; // 表正在被删除(从delete table到partition完全unload的这段期间)或者表从ACTIVE状态被Unload。
|
||||||
|
UPDATING = 5; // 表正在被更新(table属性变更、预留吞吐量变更)。
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RowExistenceExpectation {
|
||||||
|
IGNORE = 0;
|
||||||
|
EXPECT_EXIST = 1;
|
||||||
|
EXPECT_NOT_EXIST = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Condition {
|
||||||
|
required RowExistenceExpectation row_existence = 1;
|
||||||
|
optional bytes column_condition = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CapacityUnit {
|
||||||
|
optional int32 read = 1;
|
||||||
|
optional int32 write = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReservedThroughputDetails {
|
||||||
|
required CapacityUnit capacity_unit = 1; // 表当前的预留吞吐量的值。
|
||||||
|
required int64 last_increase_time = 2; // 最后一次上调预留吞吐量的时间。
|
||||||
|
optional int64 last_decrease_time = 3; // 最后一次下调预留吞吐量的时间。
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReservedThroughput {
|
||||||
|
required CapacityUnit capacity_unit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConsumedCapacity {
|
||||||
|
required CapacityUnit capacity_unit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StreamSpecification {
|
||||||
|
required bool enable_stream = 1;
|
||||||
|
optional int32 expiration_time = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StreamDetails {
|
||||||
|
required bool enable_stream = 1;
|
||||||
|
optional string stream_id = 2;
|
||||||
|
optional int32 expiration_time = 3;
|
||||||
|
optional int64 last_enable_time = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ############################################# CreateTable ############################################# */
|
||||||
|
/**
|
||||||
|
* table_meta用于存储表中不可更改的schema属性,可以更改的ReservedThroughput和TableOptions独立出来,作为UpdateTable的参数。
|
||||||
|
* 加入GlobalIndex和LocalIndex之后,结构会变为:
|
||||||
|
* message CreateTableRequest {
|
||||||
|
* required TableMeta table_meta = 1;
|
||||||
|
* required ReservedThroughput reserved_throughput = 2;
|
||||||
|
* required TableOptions table_options = 3;
|
||||||
|
* repeated LocalIndex local_indexes = 4; // LocalIndex不再单独包含ReservedThroughput和TableOptions,其与主表共享配置。
|
||||||
|
* repeated GlobalIndex global_indexes = 5; // GlobalIndex内单独包含ReservedThroughput和TableOptions
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
message CreateTableRequest {
|
||||||
|
required TableMeta table_meta = 1;
|
||||||
|
required ReservedThroughput reserved_throughput = 2; // 未放在TableOptions内,原因是UpdateTableResponse中会返回ReservedThroughputDetails,而TableOptions没有类似的返回结构。
|
||||||
|
optional TableOptions table_options = 3;
|
||||||
|
repeated PartitionRange partitions = 4;
|
||||||
|
optional StreamSpecification stream_spec = 5;
|
||||||
|
repeated IndexMeta index_metas = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateTableResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ######################################################################################################### */
|
||||||
|
|
||||||
|
|
||||||
|
/* ############################################# UpdateTable ############################################# */
|
||||||
|
message UpdateTableRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
optional ReservedThroughput reserved_throughput = 2;
|
||||||
|
optional TableOptions table_options = 3;
|
||||||
|
optional StreamSpecification stream_spec = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateTableResponse {
|
||||||
|
required ReservedThroughputDetails reserved_throughput_details = 1;
|
||||||
|
required TableOptions table_options = 2;
|
||||||
|
optional StreamDetails stream_details = 3;
|
||||||
|
}
|
||||||
|
/* ######################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# DescribeTable ############################################# */
|
||||||
|
message DescribeTableRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DescribeTableResponse {
|
||||||
|
required TableMeta table_meta = 1;
|
||||||
|
required ReservedThroughputDetails reserved_throughput_details = 2;
|
||||||
|
required TableOptions table_options = 3;
|
||||||
|
required TableStatus table_status = 4;
|
||||||
|
optional StreamDetails stream_details = 5;
|
||||||
|
repeated bytes shard_splits = 6;
|
||||||
|
repeated IndexMeta index_metas = 8;
|
||||||
|
}
|
||||||
|
/* ########################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# ListTable ############################################# */
|
||||||
|
message ListTableRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前只返回一个简单的名称列表,需要讨论是否有业务场景需要获取除了表名之外的其他信息。
|
||||||
|
* 其他信息可以包含预留吞吐量以及表的状态,这个信息只能是一个粗略的信息,表的详细信息还是需要通过DescribeTable来获取。
|
||||||
|
*/
|
||||||
|
message ListTableResponse {
|
||||||
|
repeated string table_names = 1;
|
||||||
|
}
|
||||||
|
/* ####################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# DeleteTable ############################################# */
|
||||||
|
message DeleteTableRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteTableResponse {
|
||||||
|
}
|
||||||
|
/* ######################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# LoadTable ############################################# */
|
||||||
|
message LoadTableRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LoadTableResponse {
|
||||||
|
}
|
||||||
|
/* ######################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# UnloadTable ############################################# */
|
||||||
|
message UnloadTableRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UnloadTableResponse {
|
||||||
|
|
||||||
|
}
|
||||||
|
/* ########################################################################################################## */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间戳的取值最小值为0,最大值为INT64.MAX
|
||||||
|
* 1. 若要查询一个范围,则指定start_time和end_time
|
||||||
|
* 2. 若要查询一个特定时间戳,则指定specific_time
|
||||||
|
*/
|
||||||
|
message TimeRange {
|
||||||
|
optional int64 start_time = 1;
|
||||||
|
optional int64 end_time = 2;
|
||||||
|
optional int64 specific_time = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ############################################# GetRow ############################################# */
|
||||||
|
|
||||||
|
enum ReturnType {
|
||||||
|
RT_NONE = 0;
|
||||||
|
RT_PK = 1;
|
||||||
|
RT_AFTER_MODIFY = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReturnContent {
|
||||||
|
optional ReturnType return_type = 1;
|
||||||
|
repeated string return_column_names = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. 支持用户指定版本时间戳范围或者特定的版本时间来读取指定版本的列
|
||||||
|
* 2. 目前暂不支持行内的断点
|
||||||
|
*/
|
||||||
|
message GetRowRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
required bytes primary_key = 2; // encoded as InplaceRowChangeSet, but only has primary key
|
||||||
|
repeated string columns_to_get = 3; // 不指定则读出所有的列
|
||||||
|
optional TimeRange time_range = 4;
|
||||||
|
optional int32 max_versions = 5;
|
||||||
|
optional bool cache_blocks = 6 [default = true]; // 本次读出的数据是否进入BlockCache
|
||||||
|
optional bytes filter = 7;
|
||||||
|
optional string start_column = 8;
|
||||||
|
optional string end_column = 9;
|
||||||
|
optional bytes token = 10;
|
||||||
|
optional string transaction_id = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetRowResponse {
|
||||||
|
required ConsumedCapacity consumed = 1;
|
||||||
|
required bytes row = 2; // encoded as InplaceRowChangeSet
|
||||||
|
optional bytes next_token = 3;
|
||||||
|
}
|
||||||
|
/* #################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# UpdateRow ############################################# */
|
||||||
|
message UpdateRowRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
required bytes row_change = 2;
|
||||||
|
required Condition condition = 3;
|
||||||
|
optional ReturnContent return_content = 4;
|
||||||
|
optional string transaction_id = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateRowResponse {
|
||||||
|
required ConsumedCapacity consumed = 1;
|
||||||
|
optional bytes row = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ####################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# PutRow ############################################# */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这里允许用户为每列单独设置timestamp,而不是强制整行统一一个timestamp。
|
||||||
|
* 原因是列都是用统一的结构,该结构本身是带timestamp的,其次强制统一timestamp增强了规范性但是丧失了灵活性,且该规范性没有明显的好处,反而带来了结构的复杂。
|
||||||
|
*/
|
||||||
|
message PutRowRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
required bytes row = 2; // encoded as InplaceRowChangeSet
|
||||||
|
required Condition condition = 3;
|
||||||
|
optional ReturnContent return_content = 4;
|
||||||
|
optional string transaction_id = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PutRowResponse {
|
||||||
|
required ConsumedCapacity consumed = 1;
|
||||||
|
optional bytes row = 2;
|
||||||
|
}
|
||||||
|
/* #################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# DeleteRow ############################################# */
|
||||||
|
/**
|
||||||
|
* OTS只支持删除该行的所有列所有版本,不支持:
|
||||||
|
* 1. 删除所有列的所有小于等于某个版本的所有版本
|
||||||
|
*/
|
||||||
|
message DeleteRowRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
required bytes primary_key = 2; // encoded as InplaceRowChangeSet, but only has primary key
|
||||||
|
required Condition condition = 3;
|
||||||
|
optional ReturnContent return_content = 4;
|
||||||
|
optional string transaction_id = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteRowResponse {
|
||||||
|
required ConsumedCapacity consumed = 1;
|
||||||
|
optional bytes row = 2;
|
||||||
|
}
|
||||||
|
/* ####################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# BatchGetRow ############################################# */
|
||||||
|
/**
|
||||||
|
* HBase支持Batch操作的每行都拥有不同的查询参数,OTS不支持。
|
||||||
|
*/
|
||||||
|
message TableInBatchGetRowRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
repeated bytes primary_key = 2; // encoded as InplaceRowChangeSet, but only has primary key
|
||||||
|
repeated bytes token = 3;
|
||||||
|
repeated string columns_to_get = 4; // 不指定则读出所有的列
|
||||||
|
optional TimeRange time_range = 5;
|
||||||
|
optional int32 max_versions = 6;
|
||||||
|
optional bool cache_blocks = 7 [default = true]; // 本次读出的数据是否进入BlockCache
|
||||||
|
optional bytes filter = 8;
|
||||||
|
optional string start_column = 9;
|
||||||
|
optional string end_column = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BatchGetRowRequest {
|
||||||
|
repeated TableInBatchGetRowRequest tables = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RowInBatchGetRowResponse {
|
||||||
|
required bool is_ok = 1;
|
||||||
|
optional Error error = 2;
|
||||||
|
optional ConsumedCapacity consumed = 3;
|
||||||
|
optional bytes row = 4; // encoded as InplaceRowChangeSet
|
||||||
|
optional bytes next_token = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TableInBatchGetRowResponse {
|
||||||
|
required string table_name = 1;
|
||||||
|
repeated RowInBatchGetRowResponse rows = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BatchGetRowResponse {
|
||||||
|
repeated TableInBatchGetRowResponse tables = 1;
|
||||||
|
}
|
||||||
|
/* ######################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# BatchWriteRow ############################################# */
|
||||||
|
|
||||||
|
enum OperationType {
|
||||||
|
PUT = 1;
|
||||||
|
UPDATE = 2;
|
||||||
|
DELETE = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RowInBatchWriteRowRequest {
|
||||||
|
required OperationType type = 1;
|
||||||
|
required bytes row_change = 2; // encoded as InplaceRowChangeSet
|
||||||
|
required Condition condition = 3;
|
||||||
|
optional ReturnContent return_content = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TableInBatchWriteRowRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
repeated RowInBatchWriteRowRequest rows = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BatchWriteRowRequest {
|
||||||
|
repeated TableInBatchWriteRowRequest tables = 1;
|
||||||
|
optional string transaction_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RowInBatchWriteRowResponse {
|
||||||
|
required bool is_ok = 1;
|
||||||
|
optional Error error = 2;
|
||||||
|
optional ConsumedCapacity consumed = 3;
|
||||||
|
optional bytes row = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TableInBatchWriteRowResponse {
|
||||||
|
required string table_name = 1;
|
||||||
|
repeated RowInBatchWriteRowResponse rows = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BatchWriteRowResponse {
|
||||||
|
repeated TableInBatchWriteRowResponse tables = 1;
|
||||||
|
}
|
||||||
|
/* ########################################################################################################### */
|
||||||
|
|
||||||
|
/* ############################################# GetRange ############################################# */
|
||||||
|
enum Direction {
|
||||||
|
FORWARD = 0;
|
||||||
|
BACKWARD = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HBase支持以下参数:
|
||||||
|
* 1. TimeRange或指定time
|
||||||
|
* 2. Filter(根据列值或列名来过滤)
|
||||||
|
* 我们只支持给同版本的选择条件。
|
||||||
|
*/
|
||||||
|
message GetRangeRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
required Direction direction = 2;
|
||||||
|
repeated string columns_to_get = 3; // 不指定则读出所有的列
|
||||||
|
optional TimeRange time_range = 4;
|
||||||
|
optional int32 max_versions = 5;
|
||||||
|
optional int32 limit = 6;
|
||||||
|
required bytes inclusive_start_primary_key = 7; // encoded as InplaceRowChangeSet, but only has primary key
|
||||||
|
required bytes exclusive_end_primary_key = 8; // encoded as InplaceRowChangeSet, but only has primary key
|
||||||
|
optional bool cache_blocks = 9 [default = true]; // 本次读出的数据是否进入BlockCache
|
||||||
|
optional bytes filter = 10;
|
||||||
|
optional string start_column = 11;
|
||||||
|
optional string end_column = 12;
|
||||||
|
optional bytes token = 13;
|
||||||
|
optional string transaction_id = 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetRangeResponse {
|
||||||
|
required ConsumedCapacity consumed = 1;
|
||||||
|
required bytes rows = 2; // encoded as InplaceRowChangeSet
|
||||||
|
optional bytes next_start_primary_key = 3; // 若为空,则代表数据全部读取完毕. encoded as InplaceRowChangeSet, but only has primary key
|
||||||
|
optional bytes next_token = 4;
|
||||||
|
}
|
||||||
|
/* ###################################################################################################### */
|
||||||
|
/* ############################################# Stream ############################################# */
|
||||||
|
|
||||||
|
message ListStreamRequest {
|
||||||
|
optional string table_name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Stream {
|
||||||
|
required string stream_id = 1;
|
||||||
|
required string table_name = 2;
|
||||||
|
required int64 creation_time = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListStreamResponse {
|
||||||
|
repeated Stream streams = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StreamShard {
|
||||||
|
required string shard_id = 1;
|
||||||
|
optional string parent_id = 2;
|
||||||
|
optional string parent_sibling_id = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum StreamStatus {
|
||||||
|
STREAM_ENABLING = 1;
|
||||||
|
STREAM_ACTIVE = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DescribeStreamRequest {
|
||||||
|
required string stream_id = 1;
|
||||||
|
optional string inclusive_start_shard_id = 2;
|
||||||
|
optional int32 shard_limit = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DescribeStreamResponse {
|
||||||
|
required string stream_id = 1;
|
||||||
|
required int32 expiration_time = 2;
|
||||||
|
required string table_name = 3;
|
||||||
|
required int64 creation_time = 4;
|
||||||
|
required StreamStatus stream_status = 5;
|
||||||
|
repeated StreamShard shards = 6;
|
||||||
|
optional string next_shard_id = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetShardIteratorRequest {
|
||||||
|
required string stream_id = 1;
|
||||||
|
required string shard_id = 2;
|
||||||
|
optional int64 timestamp = 3;
|
||||||
|
optional string token = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetShardIteratorResponse {
|
||||||
|
required string shard_iterator = 1;
|
||||||
|
optional string next_token = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetStreamRecordRequest {
|
||||||
|
required string shard_iterator = 1;
|
||||||
|
optional int32 limit = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ActionType {
|
||||||
|
PUT_ROW = 1;
|
||||||
|
UPDATE_ROW = 2;
|
||||||
|
DELETE_ROW = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetStreamRecordResponse {
|
||||||
|
message StreamRecord {
|
||||||
|
required ActionType action_type = 1;
|
||||||
|
required bytes record = 2;
|
||||||
|
}
|
||||||
|
repeated StreamRecord stream_records = 1;
|
||||||
|
optional string next_shard_iterator = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* +++++ ComputeSplitPointsBySize +++++ */
|
||||||
|
message ComputeSplitPointsBySizeRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
required int64 split_size = 2; // in 100MB
|
||||||
|
}
|
||||||
|
|
||||||
|
message ComputeSplitPointsBySizeResponse {
|
||||||
|
required ConsumedCapacity consumed = 1;
|
||||||
|
repeated PrimaryKeySchema schema = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split points between splits, in the increasing order
|
||||||
|
*
|
||||||
|
* A split is a consecutive range of primary keys,
|
||||||
|
* whose data size is about split_size specified in the request.
|
||||||
|
* The size could be hard to be precise.
|
||||||
|
*
|
||||||
|
* A split point is an array of primary-key column w.r.t. table schema,
|
||||||
|
* which is never longer than that of table schema.
|
||||||
|
* Tailing -inf will be omitted to reduce transmission payloads.
|
||||||
|
*/
|
||||||
|
repeated bytes split_points = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locations where splits lies in.
|
||||||
|
*
|
||||||
|
* By the managed nature of TableStore, these locations are no more than hints.
|
||||||
|
* If a location is not suitable to be seen, an empty string will be placed.
|
||||||
|
*/
|
||||||
|
message SplitLocation {
|
||||||
|
required string location = 1;
|
||||||
|
required sint64 repeat = 2;
|
||||||
|
}
|
||||||
|
repeated SplitLocation locations = 4;
|
||||||
|
}
|
||||||
|
/* -------------------------------------- */
|
||||||
|
|
||||||
|
enum DefinedColumnType {
|
||||||
|
DCT_INTEGER = 1;
|
||||||
|
DCT_DOUBLE = 2;
|
||||||
|
DCT_BOOLEAN = 3;
|
||||||
|
DCT_STRING = 4;
|
||||||
|
// field 5 is reserved for date type, not supported yet
|
||||||
|
// field 6 is reserved for decimal type, not supported yet
|
||||||
|
DCT_BLOB = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DefinedColumnSchema {
|
||||||
|
required string name = 1;
|
||||||
|
required DefinedColumnType type = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum IndexUpdateMode {
|
||||||
|
IUM_ASYNC_INDEX = 0;
|
||||||
|
IUM_SYNC_INDEX = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum IndexType {
|
||||||
|
IT_GLOBAL_INDEX = 0;
|
||||||
|
IT_LOCAL_INDEX = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IndexMeta {
|
||||||
|
required string name = 1;
|
||||||
|
repeated string primary_key = 2;
|
||||||
|
repeated string defined_column = 3;
|
||||||
|
required IndexUpdateMode index_update_mode = 4;
|
||||||
|
required IndexType index_type = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateIndexRequest {
|
||||||
|
required string main_table_name = 1;
|
||||||
|
required IndexMeta index_meta = 2;
|
||||||
|
optional bool include_base_data = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateIndexResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
message DropIndexRequest {
|
||||||
|
required string main_table_name = 1;
|
||||||
|
required string index_name = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DropIndexResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ########################################### LocalTransaction ########################################### */
|
||||||
|
message StartLocalTransactionRequest {
|
||||||
|
required string table_name = 1;
|
||||||
|
required bytes key = 2; // encoded as SQLVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartLocalTransactionResponse {
|
||||||
|
required string transaction_id = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
message CommitTransactionRequest {
|
||||||
|
required string transaction_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CommitTransactionResponse {
|
||||||
|
};
|
||||||
|
|
||||||
|
message AbortTransactionRequest {
|
||||||
|
required string transaction_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AbortTransactionResponse {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ######################################################################################################### */
|
473
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/plain_buffer.go
generated
vendored
Normal file
473
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/plain_buffer.go
generated
vendored
Normal file
|
@ -0,0 +1,473 @@
|
||||||
|
package tablestore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
HEADER = 0x75
|
||||||
|
|
||||||
|
// tag type
|
||||||
|
TAG_ROW_PK = 0x1
|
||||||
|
TAG_ROW_DATA = 0x2
|
||||||
|
TAG_CELL = 0x3
|
||||||
|
TAG_CELL_NAME = 0x4
|
||||||
|
TAG_CELL_VALUE = 0x5
|
||||||
|
TAG_CELL_TYPE = 0x6
|
||||||
|
TAG_CELL_TIMESTAMP = 0x7
|
||||||
|
TAG_DELETE_ROW_MARKER = 0x8
|
||||||
|
TAG_ROW_CHECKSUM = 0x9
|
||||||
|
TAG_CELL_CHECKSUM = 0x0A
|
||||||
|
TAG_EXTENSION = 0x0B
|
||||||
|
TAG_SEQ_INFO = 0x0C
|
||||||
|
TAG_SEQ_INFO_EPOCH = 0x0D
|
||||||
|
TAG_SEQ_INFO_TS = 0x0E
|
||||||
|
TAG_SEQ_INFO_ROW_INDEX = 0x0F
|
||||||
|
|
||||||
|
// cell op type
|
||||||
|
DELETE_ALL_VERSION = 0x1
|
||||||
|
DELETE_ONE_VERSION = 0x3
|
||||||
|
INCREMENT = 0x4;
|
||||||
|
|
||||||
|
// variant type
|
||||||
|
VT_INTEGER = 0x0
|
||||||
|
VT_DOUBLE = 0x1
|
||||||
|
VT_BOOLEAN = 0x2
|
||||||
|
VT_STRING = 0x3
|
||||||
|
|
||||||
|
//public final static byte VT_NULL = 0x6;
|
||||||
|
VT_BLOB = 0x7
|
||||||
|
VT_INF_MIN = 0x9
|
||||||
|
VT_INF_MAX = 0xa
|
||||||
|
VT_AUTO_INCREMENT = 0xb
|
||||||
|
|
||||||
|
LITTLE_ENDIAN_32_SIZE = 4
|
||||||
|
LITTLE_ENDIAN_64_SIZE = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
const spaceSize = 256
|
||||||
|
|
||||||
|
var crc8Table = make([]byte, spaceSize)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
for i := 0; i < spaceSize; i++ {
|
||||||
|
x := byte(i)
|
||||||
|
for j := 8; j > 0; j-- {
|
||||||
|
if (x & 0x80) != 0 {
|
||||||
|
x = (x << 1) ^ 0x07
|
||||||
|
} else {
|
||||||
|
x = (x << 1) ^ 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crc8Table[i] = x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func crc8Byte(crc, in byte) byte {
|
||||||
|
return crc8Table[(crc^in)&0xff]
|
||||||
|
}
|
||||||
|
|
||||||
|
func crc8Int32(crc byte, in int32) byte {
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
crc = crc8Byte(crc, byte((in & 0xff)))
|
||||||
|
in >>= 8
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc
|
||||||
|
}
|
||||||
|
|
||||||
|
func crc8Int64(crc byte, in int64) byte {
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
crc = crc8Byte(crc, byte((in & 0xff)))
|
||||||
|
in >>= 8
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc
|
||||||
|
}
|
||||||
|
|
||||||
|
func crc8Bytes(crc byte, in []byte) byte {
|
||||||
|
for i := 0; i < len(in); i++ {
|
||||||
|
crc = crc8Byte(crc, in[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeRawByte(w io.Writer, value byte) {
|
||||||
|
w.Write([]byte{value})
|
||||||
|
}
|
||||||
|
|
||||||
|
/*func writeRawByteInt8(w io.Writer, value int) {
|
||||||
|
w.Write([]byte{byte(value)})
|
||||||
|
}*/
|
||||||
|
|
||||||
|
func writeRawLittleEndian32(w io.Writer, value int32) {
|
||||||
|
w.Write([]byte{byte((value) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 8) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 16) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 24) & 0xFF)})
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeRawLittleEndian64(w io.Writer, value int64) {
|
||||||
|
w.Write([]byte{byte((value) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 8) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 16) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 24) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 32) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 40) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 48) & 0xFF)})
|
||||||
|
w.Write([]byte{byte((value >> 56) & 0xFF)})
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeDouble(w io.Writer, value float64) {
|
||||||
|
writeRawLittleEndian64(w, int64(math.Float64bits(value)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeBoolean(w io.Writer, value bool) {
|
||||||
|
if value {
|
||||||
|
w.Write([]byte{byte(1)})
|
||||||
|
} else {
|
||||||
|
w.Write([]byte{byte(0)})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeBytes(w io.Writer, value []byte) {
|
||||||
|
w.Write(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeHeader(w io.Writer) {
|
||||||
|
writeRawLittleEndian32(w, HEADER)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeTag(w io.Writer, tag byte) {
|
||||||
|
writeRawByte(w, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeCellName(w io.Writer, name []byte) {
|
||||||
|
writeTag(w, TAG_CELL_NAME)
|
||||||
|
writeRawLittleEndian32(w, int32(len(name)))
|
||||||
|
writeBytes(w, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlainBufferCell struct {
|
||||||
|
cellName []byte
|
||||||
|
cellValue *ColumnValue
|
||||||
|
cellTimestamp int64
|
||||||
|
cellType byte
|
||||||
|
ignoreValue bool
|
||||||
|
hasCellTimestamp bool
|
||||||
|
hasCellType bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cell *PlainBufferCell) writeCell(w io.Writer) {
|
||||||
|
writeTag(w, TAG_CELL)
|
||||||
|
writeCellName(w, cell.cellName)
|
||||||
|
if cell.ignoreValue == false {
|
||||||
|
cell.cellValue.writeCellValue(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cell.hasCellType {
|
||||||
|
writeTag(w, TAG_CELL_TYPE)
|
||||||
|
writeRawByte(w, cell.cellType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cell.hasCellTimestamp {
|
||||||
|
writeTag(w, TAG_CELL_TIMESTAMP)
|
||||||
|
writeRawLittleEndian64(w, cell.cellTimestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
writeTag(w, TAG_CELL_CHECKSUM)
|
||||||
|
writeRawByte(w, cell.getCheckSum(byte(0x0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cell *PlainBufferCell) getCheckSum(crc byte) byte {
|
||||||
|
crc = crc8Bytes(crc, cell.cellName)
|
||||||
|
if cell.ignoreValue == false {
|
||||||
|
crc = cell.cellValue.getCheckSum(crc)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cell.hasCellTimestamp {
|
||||||
|
crc = crc8Int64(crc, cell.cellTimestamp)
|
||||||
|
}
|
||||||
|
if cell.hasCellType {
|
||||||
|
crc = crc8Byte(crc, cell.cellType)
|
||||||
|
}
|
||||||
|
return crc
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlainBufferRow struct {
|
||||||
|
primaryKey []*PlainBufferCell
|
||||||
|
cells []*PlainBufferCell
|
||||||
|
hasDeleteMarker bool
|
||||||
|
extension *RecordSequenceInfo // optional
|
||||||
|
}
|
||||||
|
|
||||||
|
func (row *PlainBufferRow) writeRow(w io.Writer) {
|
||||||
|
/* pk */
|
||||||
|
writeTag(w, TAG_ROW_PK)
|
||||||
|
for _, pk := range row.primaryKey {
|
||||||
|
pk.writeCell(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(row.cells) > 0 {
|
||||||
|
writeTag(w, TAG_ROW_DATA)
|
||||||
|
for _, cell := range row.cells {
|
||||||
|
cell.writeCell(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeTag(w, TAG_ROW_CHECKSUM)
|
||||||
|
writeRawByte(w, row.getCheckSum(byte(0x0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (row *PlainBufferRow) writeRowWithHeader(w io.Writer) {
|
||||||
|
writeHeader(w)
|
||||||
|
row.writeRow(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (row *PlainBufferRow) getCheckSum(crc byte) byte {
|
||||||
|
for _, cell := range row.primaryKey {
|
||||||
|
crcCell := cell.getCheckSum(byte(0x0))
|
||||||
|
crc = crc8Byte(crc, crcCell)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cell := range row.cells {
|
||||||
|
crcCell := cell.getCheckSum(byte(0x0))
|
||||||
|
crc = crc8Byte(crc, crcCell)
|
||||||
|
}
|
||||||
|
|
||||||
|
del := byte(0x0)
|
||||||
|
if row.hasDeleteMarker {
|
||||||
|
del = byte(0x1)
|
||||||
|
}
|
||||||
|
|
||||||
|
crc = crc8Byte(crc, del)
|
||||||
|
|
||||||
|
return crc
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRawByte(r *bytes.Reader) byte {
|
||||||
|
if r.Len() == 0 {
|
||||||
|
panic(errUnexpectIoEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, _ := r.ReadByte()
|
||||||
|
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTag(r *bytes.Reader) int {
|
||||||
|
return int(readRawByte(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRawLittleEndian64(r *bytes.Reader) int64 {
|
||||||
|
if r.Len() < 8 {
|
||||||
|
panic(errUnexpectIoEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var v int64
|
||||||
|
binary.Read(r, binary.LittleEndian, &v)
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRawLittleEndian32(r *bytes.Reader) int32 {
|
||||||
|
if r.Len() < 4 {
|
||||||
|
panic(errUnexpectIoEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var v int32
|
||||||
|
binary.Read(r, binary.LittleEndian, &v)
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func readBoolean(r *bytes.Reader) bool {
|
||||||
|
return readRawByte(r) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func readBytes(r *bytes.Reader, size int32) []byte {
|
||||||
|
if int32(r.Len()) < size {
|
||||||
|
panic(errUnexpectIoEnd)
|
||||||
|
}
|
||||||
|
v := make([]byte, size)
|
||||||
|
r.Read(v)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func readCellValue(r *bytes.Reader) *ColumnValue {
|
||||||
|
value := new(ColumnValue)
|
||||||
|
readRawLittleEndian32(r)
|
||||||
|
tp := readRawByte(r)
|
||||||
|
switch tp {
|
||||||
|
case VT_INTEGER:
|
||||||
|
value.Type = ColumnType_INTEGER
|
||||||
|
value.Value = readRawLittleEndian64(r)
|
||||||
|
case VT_DOUBLE:
|
||||||
|
value.Type = ColumnType_DOUBLE
|
||||||
|
value.Value = math.Float64frombits(uint64(readRawLittleEndian64(r)))
|
||||||
|
case VT_BOOLEAN:
|
||||||
|
value.Type = ColumnType_BOOLEAN
|
||||||
|
value.Value = readBoolean(r)
|
||||||
|
case VT_STRING:
|
||||||
|
value.Type = ColumnType_STRING
|
||||||
|
value.Value = string(readBytes(r, readRawLittleEndian32(r)))
|
||||||
|
case VT_BLOB:
|
||||||
|
value.Type = ColumnType_BINARY
|
||||||
|
value.Value = []byte(readBytes(r, readRawLittleEndian32(r)))
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func readCell(r *bytes.Reader) *PlainBufferCell {
|
||||||
|
cell := new(PlainBufferCell)
|
||||||
|
tag := readTag(r)
|
||||||
|
if tag != TAG_CELL_NAME {
|
||||||
|
panic(errTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.cellName = readBytes(r, readRawLittleEndian32(r))
|
||||||
|
tag = readTag(r)
|
||||||
|
|
||||||
|
if tag == TAG_CELL_VALUE {
|
||||||
|
cell.cellValue = readCellValue(r)
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
if tag == TAG_CELL_TYPE {
|
||||||
|
readRawByte(r)
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == TAG_CELL_TIMESTAMP {
|
||||||
|
cell.cellTimestamp = readRawLittleEndian64(r)
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == TAG_CELL_CHECKSUM {
|
||||||
|
readRawByte(r)
|
||||||
|
} else {
|
||||||
|
panic(errNoChecksum)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRowPk(r *bytes.Reader) []*PlainBufferCell {
|
||||||
|
primaryKeyColumns := make([]*PlainBufferCell, 0, 4)
|
||||||
|
|
||||||
|
tag := readTag(r)
|
||||||
|
for tag == TAG_CELL {
|
||||||
|
primaryKeyColumns = append(primaryKeyColumns, readCell(r))
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Seek(-1, 1)
|
||||||
|
|
||||||
|
return primaryKeyColumns
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRowData(r *bytes.Reader) []*PlainBufferCell {
|
||||||
|
columns := make([]*PlainBufferCell, 0, 10)
|
||||||
|
|
||||||
|
tag := readTag(r)
|
||||||
|
for tag == TAG_CELL {
|
||||||
|
columns = append(columns, readCell(r))
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Seek(-1, 1)
|
||||||
|
|
||||||
|
return columns
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRow(r *bytes.Reader) *PlainBufferRow {
|
||||||
|
row := new(PlainBufferRow)
|
||||||
|
tag := readTag(r)
|
||||||
|
if tag == TAG_ROW_PK {
|
||||||
|
row.primaryKey = readRowPk(r)
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == TAG_ROW_DATA {
|
||||||
|
row.cells = readRowData(r)
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == TAG_DELETE_ROW_MARKER {
|
||||||
|
row.hasDeleteMarker = true
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == TAG_EXTENSION {
|
||||||
|
row.extension = readRowExtension(r)
|
||||||
|
tag = readTag(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == TAG_ROW_CHECKSUM {
|
||||||
|
readRawByte(r)
|
||||||
|
} else {
|
||||||
|
panic(errNoChecksum)
|
||||||
|
}
|
||||||
|
return row
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRowsWithHeader(r *bytes.Reader) (rows []*PlainBufferRow, err error) {
|
||||||
|
defer func() {
|
||||||
|
if err2 := recover(); err2 != nil {
|
||||||
|
if _, ok := err2.(error); ok {
|
||||||
|
err = err2.(error)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// TODO: panic
|
||||||
|
if readRawLittleEndian32(r) != HEADER {
|
||||||
|
return nil, fmt.Errorf("Invalid header from plain buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
rows = make([]*PlainBufferRow, 0, 10)
|
||||||
|
|
||||||
|
for r.Len() > 0 {
|
||||||
|
rows = append(rows, readRow(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readRowExtension(r *bytes.Reader) *RecordSequenceInfo {
|
||||||
|
readRawLittleEndian32(r) // useless
|
||||||
|
tag := readTag(r)
|
||||||
|
if tag != TAG_SEQ_INFO {
|
||||||
|
panic(errTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
readRawLittleEndian32(r) // useless
|
||||||
|
tag = readTag(r)
|
||||||
|
if tag != TAG_SEQ_INFO_EPOCH {
|
||||||
|
panic(errTag)
|
||||||
|
}
|
||||||
|
epoch := readRawLittleEndian32(r)
|
||||||
|
|
||||||
|
tag = readTag(r)
|
||||||
|
if tag != TAG_SEQ_INFO_TS {
|
||||||
|
panic(errTag)
|
||||||
|
}
|
||||||
|
ts := readRawLittleEndian64(r)
|
||||||
|
|
||||||
|
tag = readTag(r)
|
||||||
|
if tag != TAG_SEQ_INFO_ROW_INDEX {
|
||||||
|
panic(errTag)
|
||||||
|
}
|
||||||
|
rowIndex := readRawLittleEndian32(r)
|
||||||
|
|
||||||
|
ext := RecordSequenceInfo{}
|
||||||
|
ext.Epoch = epoch
|
||||||
|
ext.Timestamp = ts
|
||||||
|
ext.RowIndex = rowIndex
|
||||||
|
return &ext
|
||||||
|
}
|
14
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/collapse.go
generated
vendored
Normal file
14
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/collapse.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
|
||||||
|
type Collapse struct {
|
||||||
|
FieldName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Collapse) ProtoBuffer() (*otsprotocol.Collapse, error) {
|
||||||
|
pb := &otsprotocol.Collapse{
|
||||||
|
FieldName: &c.FieldName,
|
||||||
|
}
|
||||||
|
return pb, nil
|
||||||
|
}
|
85
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query.go
generated
vendored
Normal file
85
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query.go
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
|
||||||
|
type QueryType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
QueryType_None QueryType = 0
|
||||||
|
QueryType_MatchQuery QueryType = 1
|
||||||
|
QueryType_MatchPhraseQuery QueryType = 2
|
||||||
|
QueryType_TermQuery QueryType = 3
|
||||||
|
QueryType_RangeQuery QueryType = 4
|
||||||
|
QueryType_PrefixQuery QueryType = 5
|
||||||
|
QueryType_BoolQuery QueryType = 6
|
||||||
|
QueryType_ConstScoreQuery QueryType = 7
|
||||||
|
QueryType_FunctionScoreQuery QueryType = 8
|
||||||
|
QueryType_NestedQuery QueryType = 9
|
||||||
|
QueryType_WildcardQuery QueryType = 10
|
||||||
|
QueryType_MatchAllQuery QueryType = 11
|
||||||
|
QueryType_GeoBoundingBoxQuery QueryType = 12
|
||||||
|
QueryType_GeoDistanceQuery QueryType = 13
|
||||||
|
QueryType_GeoPolygonQuery QueryType = 14
|
||||||
|
QueryType_TermsQuery QueryType = 15
|
||||||
|
)
|
||||||
|
|
||||||
|
func (q QueryType) Enum() *QueryType {
|
||||||
|
newQuery := q
|
||||||
|
return &newQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q QueryType) ToPB() *otsprotocol.QueryType {
|
||||||
|
switch q {
|
||||||
|
case QueryType_None:
|
||||||
|
return nil
|
||||||
|
case QueryType_MatchQuery:
|
||||||
|
return otsprotocol.QueryType_MATCH_QUERY.Enum()
|
||||||
|
case QueryType_MatchPhraseQuery:
|
||||||
|
return otsprotocol.QueryType_MATCH_PHRASE_QUERY.Enum()
|
||||||
|
case QueryType_TermQuery:
|
||||||
|
return otsprotocol.QueryType_TERM_QUERY.Enum()
|
||||||
|
case QueryType_RangeQuery:
|
||||||
|
return otsprotocol.QueryType_RANGE_QUERY.Enum()
|
||||||
|
case QueryType_PrefixQuery:
|
||||||
|
return otsprotocol.QueryType_PREFIX_QUERY.Enum()
|
||||||
|
case QueryType_BoolQuery:
|
||||||
|
return otsprotocol.QueryType_BOOL_QUERY.Enum()
|
||||||
|
case QueryType_ConstScoreQuery:
|
||||||
|
return otsprotocol.QueryType_CONST_SCORE_QUERY.Enum()
|
||||||
|
case QueryType_FunctionScoreQuery:
|
||||||
|
return otsprotocol.QueryType_FUNCTION_SCORE_QUERY.Enum()
|
||||||
|
case QueryType_NestedQuery:
|
||||||
|
return otsprotocol.QueryType_NESTED_QUERY.Enum()
|
||||||
|
case QueryType_WildcardQuery:
|
||||||
|
return otsprotocol.QueryType_WILDCARD_QUERY.Enum()
|
||||||
|
case QueryType_MatchAllQuery:
|
||||||
|
return otsprotocol.QueryType_MATCH_ALL_QUERY.Enum()
|
||||||
|
case QueryType_GeoBoundingBoxQuery:
|
||||||
|
return otsprotocol.QueryType_GEO_BOUNDING_BOX_QUERY.Enum()
|
||||||
|
case QueryType_GeoDistanceQuery:
|
||||||
|
return otsprotocol.QueryType_GEO_DISTANCE_QUERY.Enum()
|
||||||
|
case QueryType_GeoPolygonQuery:
|
||||||
|
return otsprotocol.QueryType_GEO_POLYGON_QUERY.Enum()
|
||||||
|
case QueryType_TermsQuery:
|
||||||
|
return otsprotocol.QueryType_TERMS_QUERY.Enum()
|
||||||
|
default:
|
||||||
|
panic("unexpected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query interface {
|
||||||
|
Type() QueryType
|
||||||
|
Serialize() ([]byte, error)
|
||||||
|
ProtoBuffer() (*otsprotocol.Query, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildPBForQuery(q Query) (*otsprotocol.Query, error) {
|
||||||
|
query := &otsprotocol.Query{}
|
||||||
|
query.Type = q.Type().ToPB()
|
||||||
|
data, err := q.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query.Query = data
|
||||||
|
return query, nil
|
||||||
|
}
|
75
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_bool.go
generated
vendored
Normal file
75
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_bool.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BoolQuery struct {
|
||||||
|
MustQueries []Query
|
||||||
|
MustNotQueries []Query
|
||||||
|
FilterQueries []Query
|
||||||
|
ShouldQueries []Query
|
||||||
|
MinimumShouldMatch *int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *BoolQuery) Type() QueryType {
|
||||||
|
return QueryType_BoolQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *BoolQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.BoolQuery{}
|
||||||
|
if q.MustQueries != nil {
|
||||||
|
pbMustQs := make([]*otsprotocol.Query, 0)
|
||||||
|
for _, mustQ := range q.MustQueries {
|
||||||
|
pbQ, err := mustQ.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbMustQs = append(pbMustQs, pbQ)
|
||||||
|
}
|
||||||
|
query.MustQueries = pbMustQs
|
||||||
|
}
|
||||||
|
if q.MustNotQueries != nil {
|
||||||
|
pbMustNotQs := make([]*otsprotocol.Query, 0)
|
||||||
|
for _, mustNotQ := range q.MustNotQueries {
|
||||||
|
pbQ, err := mustNotQ.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbMustNotQs = append(pbMustNotQs, pbQ)
|
||||||
|
}
|
||||||
|
query.MustNotQueries = pbMustNotQs
|
||||||
|
}
|
||||||
|
if q.FilterQueries != nil {
|
||||||
|
pbFilterQs := make([]*otsprotocol.Query, 0)
|
||||||
|
for _, filterQ := range q.FilterQueries {
|
||||||
|
pbQ, err := filterQ.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbFilterQs = append(pbFilterQs, pbQ)
|
||||||
|
}
|
||||||
|
query.FilterQueries = pbFilterQs
|
||||||
|
}
|
||||||
|
if q.ShouldQueries != nil {
|
||||||
|
pbShouldQs := make([]*otsprotocol.Query, 0)
|
||||||
|
for _, shouldQ := range q.ShouldQueries {
|
||||||
|
pbQ, err := shouldQ.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbShouldQs = append(pbShouldQs, pbQ)
|
||||||
|
}
|
||||||
|
query.ShouldQueries = pbShouldQs
|
||||||
|
}
|
||||||
|
if (q.MinimumShouldMatch != nil) {
|
||||||
|
query.MinimumShouldMatch = q.MinimumShouldMatch
|
||||||
|
}
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *BoolQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
29
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_const_score.go
generated
vendored
Normal file
29
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_const_score.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConstScoreQuery struct {
|
||||||
|
Filter Query
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *ConstScoreQuery) Type() QueryType {
|
||||||
|
return QueryType_ConstScoreQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *ConstScoreQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.ConstScoreQuery{}
|
||||||
|
pbQ, err := q.Filter.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query.Filter = pbQ
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *ConstScoreQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
49
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_function_score.go
generated
vendored
Normal file
49
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_function_score.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FieldValueFactor struct {
|
||||||
|
FieldName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FieldValueFactor) ProtoBuffer() (*otsprotocol.FieldValueFactor, error) {
|
||||||
|
pb := &otsprotocol.FieldValueFactor{}
|
||||||
|
pb.FieldName = &f.FieldName
|
||||||
|
return pb, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type FunctionScoreQuery struct {
|
||||||
|
Query Query
|
||||||
|
FieldValueFactor *FieldValueFactor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *FunctionScoreQuery) Type() QueryType {
|
||||||
|
return QueryType_FunctionScoreQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *FunctionScoreQuery) Serialize() ([]byte, error) {
|
||||||
|
if q.Query == nil || q.FieldValueFactor == nil {
|
||||||
|
return nil, errors.New("FunctionScoreQuery: Query or FieldValueFactor is nil")
|
||||||
|
}
|
||||||
|
query := &otsprotocol.FunctionScoreQuery{}
|
||||||
|
pbQ, err := q.Query.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query.Query = pbQ
|
||||||
|
pbF, err := q.FieldValueFactor.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query.FieldValueFactor = pbF
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *FunctionScoreQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
29
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_geo_bounding_box.go
generated
vendored
Normal file
29
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_geo_bounding_box.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GeoBoundingBoxQuery struct {
|
||||||
|
FieldName string
|
||||||
|
TopLeft string
|
||||||
|
BottomRight string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoBoundingBoxQuery) Type() QueryType {
|
||||||
|
return QueryType_GeoBoundingBoxQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoBoundingBoxQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.GeoBoundingBoxQuery{}
|
||||||
|
query.FieldName = &q.FieldName
|
||||||
|
query.TopLeft = &q.TopLeft
|
||||||
|
query.BottomRight = &q.BottomRight
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoBoundingBoxQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
29
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_geo_distance.go
generated
vendored
Normal file
29
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_geo_distance.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GeoDistanceQuery struct {
|
||||||
|
FieldName string
|
||||||
|
CenterPoint string
|
||||||
|
DistanceInMeter float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoDistanceQuery) Type() QueryType {
|
||||||
|
return QueryType_GeoDistanceQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoDistanceQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.GeoDistanceQuery{}
|
||||||
|
query.FieldName = &q.FieldName
|
||||||
|
query.CenterPoint = &q.CenterPoint
|
||||||
|
query.Distance = &q.DistanceInMeter
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoDistanceQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_geo_polygon.go
generated
vendored
Normal file
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_geo_polygon.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GeoPolygonQuery struct {
|
||||||
|
FieldName string
|
||||||
|
Points []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoPolygonQuery) Type() QueryType {
|
||||||
|
return QueryType_GeoPolygonQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoPolygonQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.GeoPolygonQuery{}
|
||||||
|
query.FieldName = &q.FieldName
|
||||||
|
query.Points = q.Points
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *GeoPolygonQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
68
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_match.go
generated
vendored
Normal file
68
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_match.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type QueryOperator int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
QueryOperator_OR QueryOperator = 0
|
||||||
|
QueryOperator_AND QueryOperator = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x QueryOperator) Enum() *QueryOperator {
|
||||||
|
p := new(QueryOperator)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *QueryOperator) ProtoBuffer() (*otsprotocol.QueryOperator, error) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, errors.New("query operator is nil")
|
||||||
|
}
|
||||||
|
if *o == QueryOperator_OR {
|
||||||
|
return otsprotocol.QueryOperator_OR.Enum(), nil
|
||||||
|
} else if *o == QueryOperator_AND {
|
||||||
|
return otsprotocol.QueryOperator_AND.Enum(), nil
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("unknown query operator: " + fmt.Sprintf("%#v", *o))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type MatchQuery struct {
|
||||||
|
FieldName string
|
||||||
|
Text string
|
||||||
|
MinimumShouldMatch *int32
|
||||||
|
Operator *QueryOperator
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchQuery) Type() QueryType {
|
||||||
|
return QueryType_MatchQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.MatchQuery{}
|
||||||
|
query.FieldName = &q.FieldName
|
||||||
|
query.Text = &q.Text
|
||||||
|
if q.MinimumShouldMatch != nil {
|
||||||
|
query.MinimumShouldMatch = q.MinimumShouldMatch
|
||||||
|
}
|
||||||
|
if q.Operator != nil {
|
||||||
|
pbOperator, err := q.Operator.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query.Operator = pbOperator
|
||||||
|
}
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_match_phrase.go
generated
vendored
Normal file
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_match_phrase.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MatchPhraseQuery struct {
|
||||||
|
FieldName string
|
||||||
|
Text string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchPhraseQuery) Type() QueryType {
|
||||||
|
return QueryType_MatchPhraseQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchPhraseQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.MatchPhraseQuery{}
|
||||||
|
query.FieldName = &q.FieldName
|
||||||
|
query.Text = &q.Text
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchPhraseQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
23
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_matchall.go
generated
vendored
Normal file
23
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_matchall.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MatchAllQuery struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchAllQuery) Type() QueryType {
|
||||||
|
return QueryType_MatchAllQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchAllQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.MatchAllQuery{}
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *MatchAllQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
54
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_nested.go
generated
vendored
Normal file
54
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_nested.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ScoreModeType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ScoreMode_None ScoreModeType = 1
|
||||||
|
ScoreMode_Avg ScoreModeType = 2
|
||||||
|
ScoreMode_Max ScoreModeType = 3
|
||||||
|
ScoreMode_Total ScoreModeType = 4
|
||||||
|
ScoreMode_Min ScoreModeType = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
type NestedQuery struct {
|
||||||
|
Path string
|
||||||
|
Query Query
|
||||||
|
ScoreMode ScoreModeType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *NestedQuery) Type() QueryType {
|
||||||
|
return QueryType_NestedQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *NestedQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.NestedQuery{}
|
||||||
|
pbQ, err := q.Query.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query.Query = pbQ
|
||||||
|
query.Path = &q.Path
|
||||||
|
switch q.ScoreMode {
|
||||||
|
case ScoreMode_None:
|
||||||
|
query.ScoreMode = otsprotocol.ScoreMode_SCORE_MODE_NONE.Enum()
|
||||||
|
case ScoreMode_Avg:
|
||||||
|
query.ScoreMode = otsprotocol.ScoreMode_SCORE_MODE_AVG.Enum()
|
||||||
|
case ScoreMode_Max:
|
||||||
|
query.ScoreMode = otsprotocol.ScoreMode_SCORE_MODE_MAX.Enum()
|
||||||
|
case ScoreMode_Min:
|
||||||
|
query.ScoreMode = otsprotocol.ScoreMode_SCORE_MODE_MIN.Enum()
|
||||||
|
case ScoreMode_Total:
|
||||||
|
query.ScoreMode = otsprotocol.ScoreMode_SCORE_MODE_TOTAL.Enum()
|
||||||
|
}
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *NestedQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_prefix.go
generated
vendored
Normal file
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_prefix.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrefixQuery struct {
|
||||||
|
FieldName string
|
||||||
|
Prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *PrefixQuery) Type() QueryType {
|
||||||
|
return QueryType_PrefixQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *PrefixQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.PrefixQuery{}
|
||||||
|
query.FieldName = &q.FieldName
|
||||||
|
query.Prefix = &q.Prefix
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *PrefixQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
75
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_range.go
generated
vendored
Normal file
75
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_range.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RangeQuery struct {
|
||||||
|
FieldName string
|
||||||
|
From interface{}
|
||||||
|
To interface{}
|
||||||
|
IncludeLower bool
|
||||||
|
IncludeUpper bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) GT(value interface{}) {
|
||||||
|
q.from(value, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) GTE(value interface{}) {
|
||||||
|
q.from(value, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) LT(value interface{}) {
|
||||||
|
q.to(value, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) LTE(value interface{}) {
|
||||||
|
q.to(value, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) from(value interface{}, includeLower bool) {
|
||||||
|
q.From = value
|
||||||
|
q.IncludeLower = includeLower
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) to(value interface{}, includeUpper bool) {
|
||||||
|
q.To = value
|
||||||
|
q.IncludeUpper = includeUpper
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) Type() QueryType {
|
||||||
|
return QueryType_RangeQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) Serialize() ([]byte, error) {
|
||||||
|
if q.FieldName == "" {
|
||||||
|
return nil, errors.New("RangeQuery: fieldName not set.")
|
||||||
|
}
|
||||||
|
query := &otsprotocol.RangeQuery{}
|
||||||
|
query.FieldName = &q.FieldName
|
||||||
|
if q.From != nil {
|
||||||
|
vFrom, err := ToVariantValue(q.From)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query.RangeFrom = ([]byte)(vFrom)
|
||||||
|
}
|
||||||
|
if q.To != nil {
|
||||||
|
vTo, err := ToVariantValue(q.To)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
query.RangeTo = ([]byte)(vTo)
|
||||||
|
}
|
||||||
|
query.IncludeLower = &q.IncludeLower
|
||||||
|
query.IncludeUpper = &q.IncludeUpper
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *RangeQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
31
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_term.go
generated
vendored
Normal file
31
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_term.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TermQuery struct {
|
||||||
|
FieldName string
|
||||||
|
Term interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *TermQuery) Type() QueryType {
|
||||||
|
return QueryType_TermQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *TermQuery) Serialize() ([]byte, error) {
|
||||||
|
term := &otsprotocol.TermQuery{}
|
||||||
|
term.FieldName = &q.FieldName
|
||||||
|
vt, err := ToVariantValue(q.Term)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
term.Term = []byte(vt)
|
||||||
|
data, err := proto.Marshal(term)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *TermQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
35
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_terms.go
generated
vendored
Normal file
35
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_terms.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TermsQuery struct {
|
||||||
|
FieldName string
|
||||||
|
Terms []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *TermsQuery) Type() QueryType {
|
||||||
|
return QueryType_TermsQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *TermsQuery) Serialize() ([]byte, error) {
|
||||||
|
term := &otsprotocol.TermsQuery{}
|
||||||
|
term.FieldName = &q.FieldName
|
||||||
|
term.Terms = make([][]byte, 0)
|
||||||
|
|
||||||
|
for _, value := range q.Terms {
|
||||||
|
vt, err := ToVariantValue(value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
term.Terms = append(term.Terms, []byte(vt))
|
||||||
|
}
|
||||||
|
data, err := proto.Marshal(term)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *TermsQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_wildcard.go
generated
vendored
Normal file
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/query_wildcard.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WildcardQuery struct {
|
||||||
|
FieldName string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *WildcardQuery) Type() QueryType {
|
||||||
|
return QueryType_WildcardQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *WildcardQuery) Serialize() ([]byte, error) {
|
||||||
|
query := &otsprotocol.WildcardQuery{}
|
||||||
|
query.FieldName = &q.FieldName
|
||||||
|
query.Value = &q.Value
|
||||||
|
data, err := proto.Marshal(query)
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *WildcardQuery) ProtoBuffer() (*otsprotocol.Query, error) {
|
||||||
|
return BuildPBForQuery(q)
|
||||||
|
}
|
101
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/search_query.go
generated
vendored
Normal file
101
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/search_query.go
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SearchQuery interface {
|
||||||
|
Serialize() ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type searchQuery struct {
|
||||||
|
Offset int32
|
||||||
|
Limit int32
|
||||||
|
Query Query
|
||||||
|
Collapse *Collapse
|
||||||
|
Sort *Sort
|
||||||
|
GetTotalCount bool
|
||||||
|
Token []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSearchQuery() *searchQuery {
|
||||||
|
return &searchQuery{
|
||||||
|
Offset: -1,
|
||||||
|
Limit: -1,
|
||||||
|
GetTotalCount: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *searchQuery) SetOffset(offset int32) *searchQuery {
|
||||||
|
s.Offset = offset
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *searchQuery) SetLimit(limit int32) *searchQuery {
|
||||||
|
s.Limit = limit
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *searchQuery) SetQuery(query Query) *searchQuery {
|
||||||
|
s.Query = query
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *searchQuery) SetCollapse(collapse *Collapse) *searchQuery {
|
||||||
|
s.Collapse = collapse
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *searchQuery) SetSort(sort *Sort) *searchQuery {
|
||||||
|
s.Sort = sort
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *searchQuery) SetGetTotalCount(getTotalCount bool) *searchQuery {
|
||||||
|
s.GetTotalCount = getTotalCount
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *searchQuery) SetToken(token []byte) *searchQuery {
|
||||||
|
s.Token = token
|
||||||
|
s.Sort = nil
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *searchQuery) Serialize() ([]byte, error) {
|
||||||
|
search_query := &otsprotocol.SearchQuery{}
|
||||||
|
if s.Offset >= 0 {
|
||||||
|
search_query.Offset = &s.Offset
|
||||||
|
}
|
||||||
|
if s.Limit >= 0 {
|
||||||
|
search_query.Limit = &s.Limit
|
||||||
|
}
|
||||||
|
if s.Query != nil {
|
||||||
|
pbQuery, err := s.Query.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
search_query.Query = pbQuery
|
||||||
|
}
|
||||||
|
if s.Collapse != nil {
|
||||||
|
pbCollapse, err := s.Collapse.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
search_query.Collapse = pbCollapse
|
||||||
|
}
|
||||||
|
if s.Sort != nil {
|
||||||
|
pbSort, err := s.Sort.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
search_query.Sort = pbSort
|
||||||
|
}
|
||||||
|
search_query.GetTotalCount = &s.GetTotalCount
|
||||||
|
if s.Token != nil && len(s.Token) > 0 {
|
||||||
|
search_query.Token = s.Token
|
||||||
|
}
|
||||||
|
data, err := proto.Marshal(search_query)
|
||||||
|
return data, err
|
||||||
|
}
|
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort.go
generated
vendored
Normal file
27
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Sorter interface {
|
||||||
|
ProtoBuffer() (*otsprotocol.Sorter, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Sort struct {
|
||||||
|
Sorters []Sorter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sort) ProtoBuffer() (*otsprotocol.Sort, error) {
|
||||||
|
pbSort := &otsprotocol.Sort{}
|
||||||
|
pbSortors := make([]*otsprotocol.Sorter, 0)
|
||||||
|
for _, fs := range s.Sorters {
|
||||||
|
pbFs, err := fs.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbSortors = append(pbSortors, pbFs)
|
||||||
|
}
|
||||||
|
pbSort.Sorter = pbSortors
|
||||||
|
return pbSort, nil
|
||||||
|
}
|
67
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_field.go
generated
vendored
Normal file
67
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_field.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
|
||||||
|
type NestedFilter struct {
|
||||||
|
Path string
|
||||||
|
Filter Query
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *NestedFilter) ProtoBuffer() (*otsprotocol.NestedFilter, error) {
|
||||||
|
pbF := &otsprotocol.NestedFilter{
|
||||||
|
Path: &f.Path,
|
||||||
|
}
|
||||||
|
pbQ, err := f.Filter.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbF.Filter = pbQ
|
||||||
|
return pbF, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldSort struct {
|
||||||
|
FieldName string
|
||||||
|
Order *SortOrder
|
||||||
|
Mode *SortMode
|
||||||
|
NestedFilter *NestedFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFieldSort(fieldName string, order SortOrder) *FieldSort {
|
||||||
|
return &FieldSort{
|
||||||
|
FieldName: fieldName,
|
||||||
|
Order: order.Enum(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FieldSort) ProtoBuffer() (*otsprotocol.Sorter, error) {
|
||||||
|
pbFieldSort := &otsprotocol.FieldSort{
|
||||||
|
FieldName: &s.FieldName,
|
||||||
|
}
|
||||||
|
if s.Order != nil {
|
||||||
|
pbOrder, err := s.Order.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbFieldSort.Order = pbOrder
|
||||||
|
}
|
||||||
|
if s.Mode != nil {
|
||||||
|
pbMode, err := s.Mode.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if pbMode != nil {
|
||||||
|
pbFieldSort.Mode = pbMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if s.NestedFilter != nil {
|
||||||
|
pbFilter, err := s.NestedFilter.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbFieldSort.NestedFilter = pbFilter
|
||||||
|
}
|
||||||
|
pbSorter := &otsprotocol.Sorter{
|
||||||
|
FieldSort: pbFieldSort,
|
||||||
|
}
|
||||||
|
return pbSorter, nil
|
||||||
|
}
|
77
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_geo_distance.go
generated
vendored
Normal file
77
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_geo_distance.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GeoDistanceType int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
GeoDistanceType_ARC GeoDistanceType = 0
|
||||||
|
GeoDistanceType_PLANE GeoDistanceType = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t *GeoDistanceType) ProtoBuffer() (*otsprotocol.GeoDistanceType, error) {
|
||||||
|
if t == nil {
|
||||||
|
return nil, errors.New("type is nil")
|
||||||
|
}
|
||||||
|
if *t == GeoDistanceType_ARC {
|
||||||
|
return otsprotocol.GeoDistanceType_GEO_DISTANCE_ARC.Enum(), nil
|
||||||
|
} else if *t == GeoDistanceType_PLANE {
|
||||||
|
return otsprotocol.GeoDistanceType_GEO_DISTANCE_PLANE.Enum(), nil
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("unknown distance type: " + fmt.Sprintf("%#v", *t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type GeoDistanceSort struct {
|
||||||
|
FieldName string
|
||||||
|
Points []string
|
||||||
|
Order *SortOrder
|
||||||
|
Mode *SortMode
|
||||||
|
GeoDistanceType *GeoDistanceType
|
||||||
|
NestedFilter *NestedFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GeoDistanceSort) ProtoBuffer() (*otsprotocol.Sorter, error) {
|
||||||
|
pbGeoDistanceSort := &otsprotocol.GeoDistanceSort{
|
||||||
|
FieldName: &s.FieldName,
|
||||||
|
Points: s.Points,
|
||||||
|
}
|
||||||
|
if s.Order != nil {
|
||||||
|
pbOrder, err := s.Order.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbGeoDistanceSort.Order = pbOrder
|
||||||
|
}
|
||||||
|
if s.Mode != nil {
|
||||||
|
pbMode, err := s.Mode.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if pbMode != nil {
|
||||||
|
pbGeoDistanceSort.Mode = pbMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if s.GeoDistanceType != nil {
|
||||||
|
pbGeoDisType, err := s.GeoDistanceType.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbGeoDistanceSort.DistanceType = pbGeoDisType
|
||||||
|
}
|
||||||
|
if s.NestedFilter != nil {
|
||||||
|
pbFilter, err := s.NestedFilter.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbGeoDistanceSort.NestedFilter = pbFilter
|
||||||
|
}
|
||||||
|
pbSorter := &otsprotocol.Sorter{
|
||||||
|
GeoDistanceSort: pbGeoDistanceSort,
|
||||||
|
}
|
||||||
|
return pbSorter, nil
|
||||||
|
}
|
36
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_mode.go
generated
vendored
Normal file
36
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_mode.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SortMode int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
SortMode_Min SortMode = 0
|
||||||
|
SortMode_Max SortMode = 1
|
||||||
|
SortMode_Avg SortMode = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x SortMode) Enum() *SortMode {
|
||||||
|
p := new(SortMode)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SortMode) ProtoBuffer() (*otsprotocol.SortMode, error) {
|
||||||
|
if m == nil {
|
||||||
|
return nil, errors.New("sort mode is nil")
|
||||||
|
}
|
||||||
|
if *m == SortMode_Min {
|
||||||
|
return otsprotocol.SortMode_SORT_MODE_MIN.Enum(), nil
|
||||||
|
} else if *m == SortMode_Max {
|
||||||
|
return otsprotocol.SortMode_SORT_MODE_MAX.Enum(), nil
|
||||||
|
} else if *m == SortMode_Avg {
|
||||||
|
return otsprotocol.SortMode_SORT_MODE_AVG.Enum(), nil
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("unknown sort mode: " + fmt.Sprintf("%#v", *m))
|
||||||
|
}
|
||||||
|
}
|
47
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_order.go
generated
vendored
Normal file
47
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_order.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SortOrder int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
SortOrder_ASC SortOrder = 0
|
||||||
|
SortOrder_DESC SortOrder = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x SortOrder) Enum() *SortOrder {
|
||||||
|
p := new(SortOrder)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *SortOrder) ProtoBuffer() (*otsprotocol.SortOrder, error) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, errors.New("sort order is nil")
|
||||||
|
}
|
||||||
|
if *o == SortOrder_ASC {
|
||||||
|
return otsprotocol.SortOrder_SORT_ORDER_ASC.Enum(), nil
|
||||||
|
} else if *o == SortOrder_DESC {
|
||||||
|
return otsprotocol.SortOrder_SORT_ORDER_DESC.Enum(), nil
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("unknown sort order: " + fmt.Sprintf("%#v", *o))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseSortOrder(order *otsprotocol.SortOrder) *SortOrder {
|
||||||
|
if order == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if *order == otsprotocol.SortOrder_SORT_ORDER_ASC {
|
||||||
|
return SortOrder_ASC.Enum()
|
||||||
|
} else if *order == otsprotocol.SortOrder_SORT_ORDER_DESC {
|
||||||
|
return SortOrder_DESC.Enum()
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
28
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_primary_key.go
generated
vendored
Normal file
28
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_primary_key.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
|
||||||
|
type PrimaryKeySort struct {
|
||||||
|
Order *SortOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPrimaryKeySort() *PrimaryKeySort {
|
||||||
|
return &PrimaryKeySort{
|
||||||
|
Order: SortOrder_ASC.Enum(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PrimaryKeySort) ProtoBuffer() (*otsprotocol.Sorter, error) {
|
||||||
|
pbPrimaryKeySort := &otsprotocol.PrimaryKeySort{}
|
||||||
|
if s.Order != nil {
|
||||||
|
pbOrder, err := s.Order.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbPrimaryKeySort.Order = pbOrder
|
||||||
|
}
|
||||||
|
pbSorter := &otsprotocol.Sorter{
|
||||||
|
PkSort: pbPrimaryKeySort,
|
||||||
|
}
|
||||||
|
return pbSorter, nil
|
||||||
|
}
|
28
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_score.go
generated
vendored
Normal file
28
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/sort_score.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
|
||||||
|
type ScoreSort struct {
|
||||||
|
Order *SortOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewScoreSort() *ScoreSort {
|
||||||
|
return &ScoreSort{
|
||||||
|
Order: SortOrder_DESC.Enum(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ScoreSort) ProtoBuffer() (*otsprotocol.Sorter, error) {
|
||||||
|
pbScoreSort := &otsprotocol.ScoreSort{}
|
||||||
|
if s.Order != nil {
|
||||||
|
pbOrder, err := s.Order.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pbScoreSort.Order = pbOrder
|
||||||
|
}
|
||||||
|
pbSorter := &otsprotocol.Sorter{
|
||||||
|
ScoreSort: pbScoreSort,
|
||||||
|
}
|
||||||
|
return pbSorter, nil
|
||||||
|
}
|
74
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/variant_types.go
generated
vendored
Normal file
74
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search/variant_types.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VariantValue []byte
|
||||||
|
type VariantType byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
// variant type
|
||||||
|
VT_INTEGER VariantType = 0x0
|
||||||
|
VT_DOUBLE VariantType = 0x1
|
||||||
|
VT_BOOLEAN VariantType = 0x2
|
||||||
|
VT_STRING VariantType = 0x3
|
||||||
|
)
|
||||||
|
|
||||||
|
func ToVariantValue(value interface{}) (VariantValue, error) {
|
||||||
|
t := reflect.TypeOf(value)
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return VTString(value.(string)), nil
|
||||||
|
case reflect.Int:
|
||||||
|
return VTInteger(int64(value.(int))), nil
|
||||||
|
case reflect.Int64:
|
||||||
|
return VTInteger(value.(int64)), nil
|
||||||
|
case reflect.Float64:
|
||||||
|
return VTDouble(value.(float64)), nil
|
||||||
|
case reflect.Bool:
|
||||||
|
return VTBoolean(value.(bool)), nil
|
||||||
|
default:
|
||||||
|
return nil, errors.New("interface{} type must be string/int64/float64.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *VariantValue) GetType() VariantType {
|
||||||
|
return VariantType(([]byte)(*v)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func VTInteger(v int64) VariantValue {
|
||||||
|
buf := make([]byte, 9)
|
||||||
|
buf[0] = byte(VT_INTEGER)
|
||||||
|
binary.LittleEndian.PutUint64(buf[1:9], uint64(v))
|
||||||
|
return (VariantValue)(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func VTDouble(v float64) VariantValue {
|
||||||
|
buf := make([]byte, 9)
|
||||||
|
buf[0] = byte(VT_DOUBLE)
|
||||||
|
binary.LittleEndian.PutUint64(buf[1:9], math.Float64bits(v))
|
||||||
|
return (VariantValue)(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func VTString(v string) VariantValue {
|
||||||
|
buf := make([]byte, 5+len(v))
|
||||||
|
buf[0] = byte(VT_STRING)
|
||||||
|
binary.LittleEndian.PutUint32(buf[1:5], uint32(len(v)))
|
||||||
|
copy(buf[5:], v)
|
||||||
|
return (VariantValue)(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func VTBoolean(b bool) VariantValue {
|
||||||
|
buf := make([]byte, 2)
|
||||||
|
buf[0] = byte(VT_BOOLEAN)
|
||||||
|
if b {
|
||||||
|
buf[1] = 1
|
||||||
|
} else {
|
||||||
|
buf[1] = 0
|
||||||
|
}
|
||||||
|
return (VariantValue)(buf)
|
||||||
|
}
|
136
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search_api.go
generated
vendored
Normal file
136
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search_api.go
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
package tablestore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (tableStoreClient *TableStoreClient) CreateSearchIndex(request *CreateSearchIndexRequest) (*CreateSearchIndexResponse, error) {
|
||||||
|
req := new(otsprotocol.CreateSearchIndexRequest)
|
||||||
|
req.TableName = proto.String(request.TableName)
|
||||||
|
req.IndexName = proto.String(request.IndexName)
|
||||||
|
var err error
|
||||||
|
req.Schema, err = convertToPbSchema(request.IndexSchema)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp := new(otsprotocol.CreateSearchIndexRequest)
|
||||||
|
response := &CreateSearchIndexResponse{}
|
||||||
|
if err := tableStoreClient.doRequestWithRetry(createSearchIndexUri, req, resp, &response.ResponseInfo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tableStoreClient *TableStoreClient) DeleteSearchIndex(request *DeleteSearchIndexRequest) (*DeleteSearchIndexResponse, error) {
|
||||||
|
req := new(otsprotocol.DeleteSearchIndexRequest)
|
||||||
|
req.TableName = proto.String(request.TableName)
|
||||||
|
req.IndexName = proto.String(request.IndexName)
|
||||||
|
|
||||||
|
resp := new(otsprotocol.DeleteSearchIndexResponse)
|
||||||
|
response := &DeleteSearchIndexResponse{}
|
||||||
|
if err := tableStoreClient.doRequestWithRetry(deleteSearchIndexUri, req, resp, &response.ResponseInfo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tableStoreClient *TableStoreClient) ListSearchIndex(request *ListSearchIndexRequest) (*ListSearchIndexResponse, error) {
|
||||||
|
req := new(otsprotocol.ListSearchIndexRequest)
|
||||||
|
req.TableName = proto.String(request.TableName)
|
||||||
|
|
||||||
|
resp := new(otsprotocol.ListSearchIndexResponse)
|
||||||
|
response := &ListSearchIndexResponse{}
|
||||||
|
if err := tableStoreClient.doRequestWithRetry(listSearchIndexUri, req, resp, &response.ResponseInfo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
indexs := make([]*IndexInfo, 0)
|
||||||
|
for _, info := range resp.Indices {
|
||||||
|
indexs = append(indexs, &IndexInfo{
|
||||||
|
TableName: *info.TableName,
|
||||||
|
IndexName: *info.IndexName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
response.IndexInfo = indexs
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tableStoreClient *TableStoreClient) DescribeSearchIndex(request *DescribeSearchIndexRequest) (*DescribeSearchIndexResponse, error) {
|
||||||
|
req := new(otsprotocol.DescribeSearchIndexRequest)
|
||||||
|
req.TableName = proto.String(request.TableName)
|
||||||
|
req.IndexName = proto.String(request.IndexName)
|
||||||
|
|
||||||
|
resp := new(otsprotocol.DescribeSearchIndexResponse)
|
||||||
|
response := &DescribeSearchIndexResponse{}
|
||||||
|
if err := tableStoreClient.doRequestWithRetry(describeSearchIndexUri, req, resp, &response.ResponseInfo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
schema, err := parseFromPbSchema(resp.Schema)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
response.Schema = schema
|
||||||
|
if resp.SyncStat != nil {
|
||||||
|
response.SyncStat = &SyncStat{
|
||||||
|
CurrentSyncTimestamp: resp.SyncStat.CurrentSyncTimestamp,
|
||||||
|
}
|
||||||
|
syncPhase := resp.SyncStat.SyncPhase
|
||||||
|
if syncPhase == nil {
|
||||||
|
return nil, errors.New("missing [SyncPhase] in DescribeSearchIndexResponse")
|
||||||
|
} else if *syncPhase == otsprotocol.SyncPhase_FULL {
|
||||||
|
response.SyncStat.SyncPhase = SyncPhase_FULL
|
||||||
|
} else if *syncPhase == otsprotocol.SyncPhase_INCR {
|
||||||
|
response.SyncStat.SyncPhase = SyncPhase_INCR
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(fmt.Sprintf("unknown SyncPhase: %v", syncPhase))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tableStoreClient *TableStoreClient) Search(request *SearchRequest) (*SearchResponse, error) {
|
||||||
|
req, err := request.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp := new(otsprotocol.SearchResponse)
|
||||||
|
response := &SearchResponse{}
|
||||||
|
if err := tableStoreClient.doRequestWithRetry(searchUri, req, resp, &response.ResponseInfo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
response.TotalCount = *resp.TotalHits
|
||||||
|
|
||||||
|
rows := make([]*PlainBufferRow, 0)
|
||||||
|
for _, buf := range resp.Rows {
|
||||||
|
row, err := readRowsWithHeader(bytes.NewReader(buf))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows = append(rows, row[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, row := range rows {
|
||||||
|
currentRow := &Row{}
|
||||||
|
currentPk := new(PrimaryKey)
|
||||||
|
for _, pk := range row.primaryKey {
|
||||||
|
pkColumn := &PrimaryKeyColumn{ColumnName: string(pk.cellName), Value: pk.cellValue.Value}
|
||||||
|
currentPk.PrimaryKeys = append(currentPk.PrimaryKeys, pkColumn)
|
||||||
|
}
|
||||||
|
currentRow.PrimaryKey = currentPk
|
||||||
|
for _, cell := range row.cells {
|
||||||
|
dataColumn := &AttributeColumn{ColumnName: string(cell.cellName), Value: cell.cellValue.Value, Timestamp: cell.cellTimestamp}
|
||||||
|
currentRow.Columns = append(currentRow.Columns, dataColumn)
|
||||||
|
}
|
||||||
|
response.Rows = append(response.Rows, currentRow)
|
||||||
|
}
|
||||||
|
|
||||||
|
response.IsAllSuccess = *resp.IsAllSucceeded
|
||||||
|
if resp.NextToken != nil && len(resp.NextToken) > 0 {
|
||||||
|
response.NextToken = resp.NextToken
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
327
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search_model.go
generated
vendored
Normal file
327
vendor/github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search_model.go
generated
vendored
Normal file
|
@ -0,0 +1,327 @@
|
||||||
|
package tablestore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/otsprotocol"
|
||||||
|
"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore/search"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ColumnsToGet struct {
|
||||||
|
Columns []string
|
||||||
|
ReturnAll bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type SearchRequest struct {
|
||||||
|
TableName string
|
||||||
|
IndexName string
|
||||||
|
SearchQuery search.SearchQuery
|
||||||
|
ColumnsToGet *ColumnsToGet
|
||||||
|
RoutingValues []*PrimaryKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SearchRequest) SetTableName(tableName string) *SearchRequest {
|
||||||
|
r.TableName = tableName
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SearchRequest) SetIndexName(indexName string) *SearchRequest {
|
||||||
|
r.IndexName = indexName
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SearchRequest) SetSearchQuery(searchQuery search.SearchQuery) *SearchRequest {
|
||||||
|
r.SearchQuery = searchQuery
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SearchRequest) SetColumnsToGet(columnToGet *ColumnsToGet) *SearchRequest {
|
||||||
|
r.ColumnsToGet = columnToGet
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SearchRequest) SetRoutingValues(routingValues []*PrimaryKey) *SearchRequest {
|
||||||
|
r.RoutingValues = routingValues
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SearchRequest) AddRoutingValue(routingValue *PrimaryKey) *SearchRequest {
|
||||||
|
r.RoutingValues = append(r.RoutingValues, routingValue)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SearchRequest) ProtoBuffer() (*otsprotocol.SearchRequest, error) {
|
||||||
|
req := &otsprotocol.SearchRequest{}
|
||||||
|
req.TableName = &r.TableName
|
||||||
|
req.IndexName = &r.IndexName
|
||||||
|
query, err := r.SearchQuery.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.SearchQuery = query
|
||||||
|
pbColumns := &otsprotocol.ColumnsToGet{}
|
||||||
|
pbColumns.ReturnType = otsprotocol.ColumnReturnType_RETURN_NONE.Enum()
|
||||||
|
if r.ColumnsToGet != nil {
|
||||||
|
if r.ColumnsToGet.ReturnAll {
|
||||||
|
pbColumns.ReturnType = otsprotocol.ColumnReturnType_RETURN_ALL.Enum()
|
||||||
|
} else if len(r.ColumnsToGet.Columns) > 0 {
|
||||||
|
pbColumns.ReturnType = otsprotocol.ColumnReturnType_RETURN_SPECIFIED.Enum()
|
||||||
|
pbColumns.ColumnNames = r.ColumnsToGet.Columns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.ColumnsToGet = pbColumns
|
||||||
|
if r.RoutingValues != nil {
|
||||||
|
for _, routingValue := range r.RoutingValues {
|
||||||
|
req.RoutingValues = append(req.RoutingValues, routingValue.Build(false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return req, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type SearchResponse struct {
|
||||||
|
TotalCount int64
|
||||||
|
Rows []*Row
|
||||||
|
IsAllSuccess bool
|
||||||
|
NextToken []byte
|
||||||
|
ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertFieldSchemaToPBFieldSchema(fieldSchemas []*FieldSchema) []*otsprotocol.FieldSchema {
|
||||||
|
var schemas []*otsprotocol.FieldSchema
|
||||||
|
for _, value := range fieldSchemas {
|
||||||
|
field := new(otsprotocol.FieldSchema)
|
||||||
|
|
||||||
|
field.FieldName = proto.String(*value.FieldName)
|
||||||
|
field.FieldType = otsprotocol.FieldType(int32(value.FieldType)).Enum()
|
||||||
|
|
||||||
|
if value.Index != nil {
|
||||||
|
field.Index = proto.Bool(*value.Index)
|
||||||
|
} else if value.FieldType != FieldType_NESTED {
|
||||||
|
field.Index = proto.Bool(true)
|
||||||
|
}
|
||||||
|
if value.IndexOptions != nil {
|
||||||
|
field.IndexOptions = otsprotocol.IndexOptions(int32(*value.IndexOptions)).Enum()
|
||||||
|
}
|
||||||
|
if value.Analyzer != nil {
|
||||||
|
field.Analyzer = proto.String(string(*value.Analyzer))
|
||||||
|
}
|
||||||
|
if value.EnableSortAndAgg != nil {
|
||||||
|
field.DocValues = proto.Bool(*value.EnableSortAndAgg)
|
||||||
|
}
|
||||||
|
if value.Store != nil {
|
||||||
|
field.Store = proto.Bool(*value.Store)
|
||||||
|
} else if value.FieldType != FieldType_NESTED {
|
||||||
|
if *field.FieldType == otsprotocol.FieldType_TEXT {
|
||||||
|
field.Store = proto.Bool(false)
|
||||||
|
} else {
|
||||||
|
field.Store = proto.Bool(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if value.IsArray != nil {
|
||||||
|
field.IsArray = proto.Bool(*value.IsArray)
|
||||||
|
}
|
||||||
|
if value.FieldType == FieldType_NESTED {
|
||||||
|
field.FieldSchemas = convertFieldSchemaToPBFieldSchema(value.FieldSchemas)
|
||||||
|
}
|
||||||
|
|
||||||
|
schemas = append(schemas, field)
|
||||||
|
}
|
||||||
|
|
||||||
|
return schemas
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToPbSchema(schema *IndexSchema) (*otsprotocol.IndexSchema, error) {
|
||||||
|
indexSchema := new(otsprotocol.IndexSchema)
|
||||||
|
indexSchema.FieldSchemas = convertFieldSchemaToPBFieldSchema(schema.FieldSchemas)
|
||||||
|
indexSchema.IndexSetting = new(otsprotocol.IndexSetting)
|
||||||
|
var defaultNumberOfShards int32 = 1
|
||||||
|
indexSchema.IndexSetting.NumberOfShards = &defaultNumberOfShards
|
||||||
|
if schema.IndexSetting != nil {
|
||||||
|
indexSchema.IndexSetting.RoutingFields = schema.IndexSetting.RoutingFields
|
||||||
|
}
|
||||||
|
if schema.IndexSort != nil {
|
||||||
|
pbSort, err := schema.IndexSort.ProtoBuffer()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
indexSchema.IndexSort = pbSort
|
||||||
|
}
|
||||||
|
return indexSchema, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseFieldSchemaFromPb(pbFieldSchemas []*otsprotocol.FieldSchema) []*FieldSchema {
|
||||||
|
var schemas []*FieldSchema
|
||||||
|
for _, value := range pbFieldSchemas {
|
||||||
|
field := new(FieldSchema)
|
||||||
|
field.FieldName = value.FieldName
|
||||||
|
field.FieldType = FieldType(*value.FieldType)
|
||||||
|
field.Index = value.Index
|
||||||
|
if value.IndexOptions != nil {
|
||||||
|
indexOption := IndexOptions(*value.IndexOptions)
|
||||||
|
field.IndexOptions = &indexOption
|
||||||
|
}
|
||||||
|
field.Analyzer = (*Analyzer)(value.Analyzer)
|
||||||
|
field.EnableSortAndAgg = value.DocValues
|
||||||
|
field.Store = value.Store
|
||||||
|
field.IsArray = value.IsArray
|
||||||
|
if field.FieldType == FieldType_NESTED {
|
||||||
|
field.FieldSchemas = parseFieldSchemaFromPb(value.FieldSchemas)
|
||||||
|
}
|
||||||
|
schemas = append(schemas, field)
|
||||||
|
}
|
||||||
|
return schemas
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseIndexSortFromPb(pbIndexSort *otsprotocol.Sort) (*search.Sort, error) {
|
||||||
|
indexSort := &search.Sort{
|
||||||
|
Sorters: make([]search.Sorter, 0),
|
||||||
|
}
|
||||||
|
for _, sorter := range pbIndexSort.GetSorter() {
|
||||||
|
if sorter.GetFieldSort() != nil {
|
||||||
|
fieldSort := &search.FieldSort{
|
||||||
|
FieldName: *sorter.GetFieldSort().FieldName,
|
||||||
|
Order: search.ParseSortOrder(sorter.GetFieldSort().Order),
|
||||||
|
}
|
||||||
|
indexSort.Sorters = append(indexSort.Sorters, fieldSort)
|
||||||
|
} else if sorter.GetPkSort() != nil {
|
||||||
|
pkSort := &search.PrimaryKeySort{
|
||||||
|
Order: search.ParseSortOrder(sorter.GetPkSort().Order),
|
||||||
|
}
|
||||||
|
indexSort.Sorters = append(indexSort.Sorters, pkSort)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("unknown index sort type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return indexSort, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseFromPbSchema(pbSchema *otsprotocol.IndexSchema) (*IndexSchema, error) {
|
||||||
|
schema := &IndexSchema{
|
||||||
|
IndexSetting: &IndexSetting{
|
||||||
|
RoutingFields: pbSchema.IndexSetting.RoutingFields,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
schema.FieldSchemas = parseFieldSchemaFromPb(pbSchema.GetFieldSchemas())
|
||||||
|
indexSort, err := parseIndexSortFromPb(pbSchema.GetIndexSort())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
schema.IndexSort = indexSort
|
||||||
|
return schema, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexSchema struct {
|
||||||
|
IndexSetting *IndexSetting
|
||||||
|
FieldSchemas []*FieldSchema
|
||||||
|
IndexSort *search.Sort
|
||||||
|
}
|
||||||
|
|
||||||
|
type FieldType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
FieldType_LONG FieldType = 1
|
||||||
|
FieldType_DOUBLE FieldType = 2
|
||||||
|
FieldType_BOOLEAN FieldType = 3
|
||||||
|
FieldType_KEYWORD FieldType = 4
|
||||||
|
FieldType_TEXT FieldType = 5
|
||||||
|
FieldType_NESTED FieldType = 6
|
||||||
|
FieldType_GEO_POINT FieldType = 7
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexOptions int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
IndexOptions_DOCS IndexOptions = 1
|
||||||
|
IndexOptions_FREQS IndexOptions = 2
|
||||||
|
IndexOptions_POSITIONS IndexOptions = 3
|
||||||
|
IndexOptions_OFFSETS IndexOptions = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
type Analyzer string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Analyzer_SingleWord Analyzer = "single_word"
|
||||||
|
Analyzer_MaxWord Analyzer = "max_word"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FieldSchema struct {
|
||||||
|
FieldName *string
|
||||||
|
FieldType FieldType
|
||||||
|
Index *bool
|
||||||
|
IndexOptions *IndexOptions
|
||||||
|
Analyzer *Analyzer
|
||||||
|
EnableSortAndAgg *bool
|
||||||
|
Store *bool
|
||||||
|
IsArray *bool
|
||||||
|
FieldSchemas []*FieldSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FieldSchema) String() string {
|
||||||
|
out, err := json.Marshal(fs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return string(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexSetting struct {
|
||||||
|
RoutingFields []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateSearchIndexRequest struct {
|
||||||
|
TableName string
|
||||||
|
IndexName string
|
||||||
|
IndexSchema *IndexSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateSearchIndexResponse struct {
|
||||||
|
ResponseInfo ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeSearchIndexRequest struct {
|
||||||
|
TableName string
|
||||||
|
IndexName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SyncPhase int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
SyncPhase_FULL SyncPhase = 1
|
||||||
|
SyncPhase_INCR SyncPhase = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type SyncStat struct {
|
||||||
|
SyncPhase SyncPhase
|
||||||
|
CurrentSyncTimestamp *int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeSearchIndexResponse struct {
|
||||||
|
Schema *IndexSchema
|
||||||
|
SyncStat *SyncStat
|
||||||
|
ResponseInfo ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListSearchIndexRequest struct {
|
||||||
|
TableName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexInfo struct {
|
||||||
|
TableName string
|
||||||
|
IndexName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListSearchIndexResponse struct {
|
||||||
|
IndexInfo []*IndexInfo
|
||||||
|
ResponseInfo ResponseInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteSearchIndexRequest struct {
|
||||||
|
TableName string
|
||||||
|
IndexName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteSearchIndexResponse struct {
|
||||||
|
ResponseInfo ResponseInfo
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue