proto-gen-rpc-glue: support QueryMeta and QueryOptions (#12637)

This commit is contained in:
R.B. Boyer 2022-03-28 13:12:51 -05:00 committed by GitHub
parent 7ddeab2e50
commit 484e1da6da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 777 additions and 77 deletions

View file

@ -1 +1 @@
./e2e/source.rpcglue.pb.go
e2e/*.rpcglue.pb.go

View file

@ -0,0 +1,57 @@
package structs
import (
"time"
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/duration"
"github.com/golang/protobuf/ptypes/timestamp"
)
type QueryOptions struct {
// NOTE: fields omitted from upstream if not necessary for compilation check
MinQueryIndex uint64
MaxQueryTime time.Duration
}
func (q QueryOptions) HasTimedOut(start time.Time, rpcHoldTimeout, maxQueryTime, defaultQueryTime time.Duration) (bool, error) {
// NOTE: body was omitted from upstream; we only need the signature to verify it compiles
return false, nil
}
type RPCInfo interface {
// NOTE: methods omitted from upstream if not necessary for compilation check
}
type QueryBackend int
const (
QueryBackendBlocking QueryBackend = iota
QueryBackendStreaming
)
func DurationToProto(d time.Duration) *duration.Duration {
return ptypes.DurationProto(d)
}
func DurationFromProto(d *duration.Duration) time.Duration {
ret, _ := ptypes.Duration(d)
return ret
}
func TimeFromProto(s *timestamp.Timestamp) time.Time {
ret, _ := ptypes.Timestamp(s)
return ret
}
func TimeToProto(s time.Time) *timestamp.Timestamp {
ret, _ := ptypes.TimestampProto(s)
return ret
}
// IsZeroProtoTime returns true if the time is the minimum protobuf timestamp
// (the Unix epoch).
func IsZeroProtoTime(t *timestamp.Timestamp) bool {
return t.Seconds == 0 && t.Nanos == 0
}

View file

@ -0,0 +1,178 @@
package pbcommon
import (
"time"
"github.com/hashicorp/consul/agent/structs"
)
// IsRead is always true for QueryOption
func (q *QueryOptions) IsRead() bool {
return true
}
// AllowStaleRead returns whether a stale read should be allowed
func (q *QueryOptions) AllowStaleRead() bool {
return q.AllowStale
}
func (q *QueryOptions) TokenSecret() string {
return q.Token
}
func (q *QueryOptions) SetTokenSecret(s string) {
q.Token = s
}
// SetToken is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetToken(token string) {
q.Token = token
}
// SetMinQueryIndex is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetMinQueryIndex(minQueryIndex uint64) {
q.MinQueryIndex = minQueryIndex
}
// SetMaxQueryTime is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetMaxQueryTime(maxQueryTime time.Duration) {
q.MaxQueryTime = structs.DurationToProto(maxQueryTime)
}
// SetAllowStale is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetAllowStale(allowStale bool) {
q.AllowStale = allowStale
}
// SetRequireConsistent is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetRequireConsistent(requireConsistent bool) {
q.RequireConsistent = requireConsistent
}
// SetUseCache is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetUseCache(useCache bool) {
q.UseCache = useCache
}
// SetMaxStaleDuration is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetMaxStaleDuration(maxStaleDuration time.Duration) {
q.MaxStaleDuration = structs.DurationToProto(maxStaleDuration)
}
// SetMaxAge is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetMaxAge(maxAge time.Duration) {
q.MaxAge = structs.DurationToProto(maxAge)
}
// SetMustRevalidate is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetMustRevalidate(mustRevalidate bool) {
q.MustRevalidate = mustRevalidate
}
// SetStaleIfError is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetStaleIfError(staleIfError time.Duration) {
q.StaleIfError = structs.DurationToProto(staleIfError)
}
func (q QueryOptions) HasTimedOut(start time.Time, rpcHoldTimeout, maxQueryTime, defaultQueryTime time.Duration) (bool, error) {
maxTime := structs.DurationFromProto(q.MaxQueryTime)
o := structs.QueryOptions{
MaxQueryTime: maxTime,
MinQueryIndex: q.MinQueryIndex,
}
return o.HasTimedOut(start, rpcHoldTimeout, maxQueryTime, defaultQueryTime)
}
// SetFilter is needed to implement the structs.QueryOptionsCompat interface
func (q *QueryOptions) SetFilter(filter string) {
q.Filter = filter
}
// WriteRequest only applies to writes, always false
//
// IsRead implements structs.RPCInfo
func (w WriteRequest) IsRead() bool {
return false
}
// SetTokenSecret implements structs.RPCInfo
func (w WriteRequest) TokenSecret() string {
return w.Token
}
// SetTokenSecret implements structs.RPCInfo
func (w *WriteRequest) SetTokenSecret(s string) {
w.Token = s
}
// AllowStaleRead returns whether a stale read should be allowed
//
// AllowStaleRead implements structs.RPCInfo
func (w WriteRequest) AllowStaleRead() bool {
return false
}
// HasTimedOut implements structs.RPCInfo
func (w WriteRequest) HasTimedOut(start time.Time, rpcHoldTimeout, _, _ time.Duration) (bool, error) {
return time.Since(start) > rpcHoldTimeout, nil
}
// IsRead implements structs.RPCInfo
func (r *ReadRequest) IsRead() bool {
return true
}
// AllowStaleRead implements structs.RPCInfo
func (r *ReadRequest) AllowStaleRead() bool {
// TODO(partitions): plumb this?
return false
}
// TokenSecret implements structs.RPCInfo
func (r *ReadRequest) TokenSecret() string {
return r.Token
}
// SetTokenSecret implements structs.RPCInfo
func (r *ReadRequest) SetTokenSecret(token string) {
r.Token = token
}
// HasTimedOut implements structs.RPCInfo
func (r *ReadRequest) HasTimedOut(start time.Time, rpcHoldTimeout, maxQueryTime, defaultQueryTime time.Duration) (bool, error) {
return time.Since(start) > rpcHoldTimeout, nil
}
// RequestDatacenter implements structs.RPCInfo
func (td TargetDatacenter) RequestDatacenter() string {
return td.Datacenter
}
// SetLastContact is needed to implement the structs.QueryMetaCompat interface
func (q *QueryMeta) SetLastContact(lastContact time.Duration) {
q.LastContact = structs.DurationToProto(lastContact)
}
// SetKnownLeader is needed to implement the structs.QueryMetaCompat interface
func (q *QueryMeta) SetKnownLeader(knownLeader bool) {
q.KnownLeader = knownLeader
}
// SetIndex is needed to implement the structs.QueryMetaCompat interface
func (q *QueryMeta) SetIndex(index uint64) {
q.Index = index
}
// SetConsistencyLevel is needed to implement the structs.QueryMetaCompat interface
func (q *QueryMeta) SetConsistencyLevel(consistencyLevel string) {
q.ConsistencyLevel = consistencyLevel
}
func (q *QueryMeta) GetBackend() structs.QueryBackend {
return structs.QueryBackend(0)
}
// SetResultsFilteredByACLs is needed to implement the structs.QueryMetaCompat interface
func (q *QueryMeta) SetResultsFilteredByACLs(v bool) {
q.ResultsFilteredByACLs = v
}

View file

@ -19,6 +19,19 @@ type ExampleReadRequest struct {
TargetDatacenter *pbcommon.TargetDatacenter
}
// @consul-rpc-glue: QueryOptions,TargetDatacenter
type ExampleQueryOptions struct {
Value string
QueryOptions *pbcommon.QueryOptions
TargetDatacenter *pbcommon.TargetDatacenter
}
// @consul-rpc-glue: QueryMeta
type ExampleQueryMeta struct {
Value string
QueryMeta *pbcommon.QueryMeta
}
// @consul-rpc-glue: WriteRequest=AltWriteRequest
type AltExampleWriteRequest struct {
Value int
@ -30,3 +43,14 @@ type AltExampleReadRequest struct {
Value int
AltReadRequest *pbcommon.ReadRequest
}
// @consul-rpc-glue: QueryOptions=AltQueryOptions
type AltExampleQueryOptions struct {
Value string
AltQueryOptions *pbcommon.QueryOptions
}
// @consul-rpc-glue: QueryMeta=AltQueryMeta
type AltExampleQueryMeta struct {
AltQueryMeta *pbcommon.QueryMeta
}

View file

@ -7,12 +7,19 @@ package e2e
import (
"time"
"github.com/hashicorp/consul/agent/structs"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ structs.RPCInfo
// AllowStaleRead implements structs.RPCInfo
func (msg *ExampleWriteRequest) AllowStaleRead() bool {
return false
}
// HasTimedOut implements structs.RPCInfo
func (msg *ExampleWriteRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.WriteRequest == nil {
return false, nil
@ -20,14 +27,18 @@ func (msg *ExampleWriteRequest) HasTimedOut(start time.Time, rpcHoldTimeout time
return msg.WriteRequest.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// IsRead implements structs.RPCInfo
func (msg *ExampleWriteRequest) IsRead() bool {
return false
}
// SetTokenSecret implements structs.RPCInfo
func (msg *ExampleWriteRequest) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.WriteRequest.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *ExampleWriteRequest) TokenSecret() string {
if msg == nil || msg.WriteRequest == nil {
return ""
@ -35,6 +46,7 @@ func (msg *ExampleWriteRequest) TokenSecret() string {
return msg.WriteRequest.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *ExampleWriteRequest) Token() string {
if msg.WriteRequest == nil {
return ""
@ -42,6 +54,7 @@ func (msg *ExampleWriteRequest) Token() string {
return msg.WriteRequest.Token
}
// RequestDatacenter implements structs.RPCInfo
func (msg *ExampleWriteRequest) RequestDatacenter() string {
if msg == nil || msg.TargetDatacenter == nil {
return ""
@ -49,14 +62,18 @@ func (msg *ExampleWriteRequest) RequestDatacenter() string {
return msg.TargetDatacenter.GetDatacenter()
}
// IsRead implements structs.RPCInfo
func (msg *ExampleReadRequest) IsRead() bool {
return true
}
// AllowStaleRead implements structs.RPCInfo
func (msg *ExampleReadRequest) AllowStaleRead() bool {
// TODO: initialize if nil
return msg.ReadRequest.AllowStaleRead()
}
// HasTimedOut implements structs.RPCInfo
func (msg *ExampleReadRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.ReadRequest == nil {
return false, nil
@ -64,10 +81,13 @@ func (msg *ExampleReadRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.
return msg.ReadRequest.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// SetTokenSecret implements structs.RPCInfo
func (msg *ExampleReadRequest) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.ReadRequest.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *ExampleReadRequest) TokenSecret() string {
if msg == nil || msg.ReadRequest == nil {
return ""
@ -75,6 +95,7 @@ func (msg *ExampleReadRequest) TokenSecret() string {
return msg.ReadRequest.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *ExampleReadRequest) Token() string {
if msg.ReadRequest == nil {
return ""
@ -82,6 +103,7 @@ func (msg *ExampleReadRequest) Token() string {
return msg.ReadRequest.Token
}
// RequestDatacenter implements structs.RPCInfo
func (msg *ExampleReadRequest) RequestDatacenter() string {
if msg == nil || msg.TargetDatacenter == nil {
return ""
@ -89,10 +111,135 @@ func (msg *ExampleReadRequest) RequestDatacenter() string {
return msg.TargetDatacenter.GetDatacenter()
}
// RequestDatacenter implements structs.RPCInfo
func (msg *ExampleQueryOptions) RequestDatacenter() string {
if msg == nil || msg.TargetDatacenter == nil {
return ""
}
return msg.TargetDatacenter.GetDatacenter()
}
// IsRead implements structs.RPCInfo
func (msg *ExampleQueryOptions) IsRead() bool {
return true
}
// AllowStaleRead implements structs.RPCInfo
func (msg *ExampleQueryOptions) AllowStaleRead() bool {
return msg.QueryOptions.AllowStaleRead()
}
// HasTimedOut implements structs.RPCInfo
func (msg *ExampleQueryOptions) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.QueryOptions == nil {
return false, nil
}
return msg.QueryOptions.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// SetTokenSecret implements structs.RPCInfo
func (msg *ExampleQueryOptions) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.QueryOptions.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *ExampleQueryOptions) TokenSecret() string {
if msg == nil || msg.QueryOptions == nil {
return ""
}
return msg.QueryOptions.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *ExampleQueryOptions) Token() string {
if msg.QueryOptions == nil {
return ""
}
return msg.QueryOptions.Token
}
// GetToken is required to implement blockingQueryOptions
func (msg *ExampleQueryOptions) GetToken() string {
if msg == nil || msg.QueryOptions == nil {
return ""
}
return msg.QueryOptions.GetToken()
}
// GetMinQueryIndex is required to implement blockingQueryOptions
func (msg *ExampleQueryOptions) GetMinQueryIndex() uint64 {
if msg == nil || msg.QueryOptions == nil {
return 0
}
return msg.QueryOptions.GetMinQueryIndex()
}
// GetMaxQueryTime is required to implement blockingQueryOptions
func (msg *ExampleQueryOptions) GetMaxQueryTime() (time.Duration, error) {
if msg == nil || msg.QueryOptions == nil {
return 0, nil
}
return structs.DurationFromProto(msg.QueryOptions.GetMaxQueryTime()), nil
}
// GetRequireConsistent is required to implement blockingQueryOptions
func (msg *ExampleQueryOptions) GetRequireConsistent() bool {
if msg == nil || msg.QueryOptions == nil {
return false
}
return msg.QueryOptions.RequireConsistent
}
// SetLastContact is required to implement blockingQueryResponseMeta
func (msg *ExampleQueryMeta) SetLastContact(d time.Duration) {
if msg == nil || msg.QueryMeta == nil {
return
}
msg.QueryMeta.SetLastContact(d)
}
// SetKnownLeader is required to implement blockingQueryResponseMeta
func (msg *ExampleQueryMeta) SetKnownLeader(b bool) {
if msg == nil || msg.QueryMeta == nil {
return
}
msg.QueryMeta.SetKnownLeader(b)
}
// GetIndex is required to implement blockingQueryResponseMeta
func (msg *ExampleQueryMeta) GetIndex() uint64 {
if msg == nil || msg.QueryMeta == nil {
return 0
}
return msg.QueryMeta.GetIndex()
}
// SetIndex is required to implement blockingQueryResponseMeta
func (msg *ExampleQueryMeta) SetIndex(i uint64) {
if msg == nil || msg.QueryMeta == nil {
return
}
msg.QueryMeta.SetIndex(i)
}
// SetResultsFilteredByACLs is required to implement blockingQueryResponseMeta
func (msg *ExampleQueryMeta) SetResultsFilteredByACLs(b bool) {
if msg == nil || msg.QueryMeta == nil {
return
}
msg.QueryMeta.SetResultsFilteredByACLs(b)
}
// AllowStaleRead implements structs.RPCInfo
func (msg *AltExampleWriteRequest) AllowStaleRead() bool {
return false
}
// HasTimedOut implements structs.RPCInfo
func (msg *AltExampleWriteRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.AltWriteRequest == nil {
return false, nil
@ -100,14 +247,18 @@ func (msg *AltExampleWriteRequest) HasTimedOut(start time.Time, rpcHoldTimeout t
return msg.AltWriteRequest.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// IsRead implements structs.RPCInfo
func (msg *AltExampleWriteRequest) IsRead() bool {
return false
}
// SetTokenSecret implements structs.RPCInfo
func (msg *AltExampleWriteRequest) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.AltWriteRequest.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *AltExampleWriteRequest) TokenSecret() string {
if msg == nil || msg.AltWriteRequest == nil {
return ""
@ -115,6 +266,7 @@ func (msg *AltExampleWriteRequest) TokenSecret() string {
return msg.AltWriteRequest.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *AltExampleWriteRequest) Token() string {
if msg.AltWriteRequest == nil {
return ""
@ -122,14 +274,18 @@ func (msg *AltExampleWriteRequest) Token() string {
return msg.AltWriteRequest.Token
}
// IsRead implements structs.RPCInfo
func (msg *AltExampleReadRequest) IsRead() bool {
return true
}
// AllowStaleRead implements structs.RPCInfo
func (msg *AltExampleReadRequest) AllowStaleRead() bool {
// TODO: initialize if nil
return msg.AltReadRequest.AllowStaleRead()
}
// HasTimedOut implements structs.RPCInfo
func (msg *AltExampleReadRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.AltReadRequest == nil {
return false, nil
@ -137,10 +293,13 @@ func (msg *AltExampleReadRequest) HasTimedOut(start time.Time, rpcHoldTimeout ti
return msg.AltReadRequest.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// SetTokenSecret implements structs.RPCInfo
func (msg *AltExampleReadRequest) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.AltReadRequest.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *AltExampleReadRequest) TokenSecret() string {
if msg == nil || msg.AltReadRequest == nil {
return ""
@ -148,9 +307,125 @@ func (msg *AltExampleReadRequest) TokenSecret() string {
return msg.AltReadRequest.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *AltExampleReadRequest) Token() string {
if msg.AltReadRequest == nil {
return ""
}
return msg.AltReadRequest.Token
}
// IsRead implements structs.RPCInfo
func (msg *AltExampleQueryOptions) IsRead() bool {
return true
}
// AllowStaleRead implements structs.RPCInfo
func (msg *AltExampleQueryOptions) AllowStaleRead() bool {
return msg.AltQueryOptions.AllowStaleRead()
}
// HasTimedOut implements structs.RPCInfo
func (msg *AltExampleQueryOptions) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.AltQueryOptions == nil {
return false, nil
}
return msg.AltQueryOptions.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// SetTokenSecret implements structs.RPCInfo
func (msg *AltExampleQueryOptions) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.AltQueryOptions.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *AltExampleQueryOptions) TokenSecret() string {
if msg == nil || msg.AltQueryOptions == nil {
return ""
}
return msg.AltQueryOptions.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *AltExampleQueryOptions) Token() string {
if msg.AltQueryOptions == nil {
return ""
}
return msg.AltQueryOptions.Token
}
// GetToken is required to implement blockingQueryOptions
func (msg *AltExampleQueryOptions) GetToken() string {
if msg == nil || msg.AltQueryOptions == nil {
return ""
}
return msg.AltQueryOptions.GetToken()
}
// GetMinQueryIndex is required to implement blockingQueryOptions
func (msg *AltExampleQueryOptions) GetMinQueryIndex() uint64 {
if msg == nil || msg.AltQueryOptions == nil {
return 0
}
return msg.AltQueryOptions.GetMinQueryIndex()
}
// GetMaxQueryTime is required to implement blockingQueryOptions
func (msg *AltExampleQueryOptions) GetMaxQueryTime() (time.Duration, error) {
if msg == nil || msg.AltQueryOptions == nil {
return 0, nil
}
return structs.DurationFromProto(msg.AltQueryOptions.GetMaxQueryTime()), nil
}
// GetRequireConsistent is required to implement blockingQueryOptions
func (msg *AltExampleQueryOptions) GetRequireConsistent() bool {
if msg == nil || msg.AltQueryOptions == nil {
return false
}
return msg.AltQueryOptions.RequireConsistent
}
// SetLastContact is required to implement blockingQueryResponseMeta
func (msg *AltExampleQueryMeta) SetLastContact(d time.Duration) {
if msg == nil || msg.AltQueryMeta == nil {
return
}
msg.AltQueryMeta.SetLastContact(d)
}
// SetKnownLeader is required to implement blockingQueryResponseMeta
func (msg *AltExampleQueryMeta) SetKnownLeader(b bool) {
if msg == nil || msg.AltQueryMeta == nil {
return
}
msg.AltQueryMeta.SetKnownLeader(b)
}
// GetIndex is required to implement blockingQueryResponseMeta
func (msg *AltExampleQueryMeta) GetIndex() uint64 {
if msg == nil || msg.AltQueryMeta == nil {
return 0
}
return msg.AltQueryMeta.GetIndex()
}
// SetIndex is required to implement blockingQueryResponseMeta
func (msg *AltExampleQueryMeta) SetIndex(i uint64) {
if msg == nil || msg.AltQueryMeta == nil {
return
}
msg.AltQueryMeta.SetIndex(i)
}
// SetResultsFilteredByACLs is required to implement blockingQueryResponseMeta
func (msg *AltExampleQueryMeta) SetResultsFilteredByACLs(b bool) {
if msg == nil || msg.AltQueryMeta == nil {
return
}
msg.AltQueryMeta.SetResultsFilteredByACLs(b)
}

View file

@ -96,6 +96,12 @@ func processFile(path string) error {
if ann.TargetDatacenter != "" {
log.Printf(" TargetDatacenter from %s", ann.TargetDatacenter)
}
if ann.QueryOptions != "" {
log.Printf(" QueryOptions from %s", ann.QueryOptions)
}
if ann.QueryMeta != "" {
log.Printf(" QueryMeta from %s", ann.QueryMeta)
}
}
}
@ -114,91 +120,29 @@ func processFile(path string) error {
buf.WriteString(`
import (
"time"
"github.com/hashicorp/consul/agent/structs"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ structs.RPCInfo
`)
for _, typ := range v.Types {
if typ.Annotation.WriteRequest != "" {
buf.WriteString(fmt.Sprintf(`
func (msg *%[1]s) AllowStaleRead() bool {
return false
}
func (msg *%[1]s) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.%[2]s == nil {
return false, nil
}
return msg.%[2]s.HasTimedOut(start, rpcHoldTimeout, a, b)
}
func (msg *%[1]s) IsRead() bool {
return false
}
func (msg *%[1]s) SetTokenSecret(s string) {
msg.%[2]s.SetTokenSecret(s)
}
func (msg *%[1]s) TokenSecret() string {
if msg == nil || msg.%[2]s == nil {
return ""
}
return msg.%[2]s.TokenSecret()
}
func (msg *%[1]s) Token() string {
if msg.%[2]s == nil {
return ""
}
return msg.%[2]s.Token
}
`, typ.Name, typ.Annotation.WriteRequest))
buf.WriteString(fmt.Sprintf(tmplWriteRequest, typ.Name, typ.Annotation.WriteRequest))
}
if typ.Annotation.ReadRequest != "" {
buf.WriteString(fmt.Sprintf(`
func (msg *%[1]s) IsRead() bool {
return true
}
func (msg *%[1]s) AllowStaleRead() bool {
return msg.%[2]s.AllowStaleRead()
}
func (msg *%[1]s) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.%[2]s == nil {
return false, nil
}
return msg.%[2]s.HasTimedOut(start, rpcHoldTimeout, a, b)
}
func (msg *%[1]s) SetTokenSecret(s string) {
msg.%[2]s.SetTokenSecret(s)
}
func (msg *%[1]s) TokenSecret() string {
if msg == nil || msg.%[2]s == nil {
return ""
}
return msg.%[2]s.TokenSecret()
}
func (msg *%[1]s) Token() string {
if msg.%[2]s == nil {
return ""
}
return msg.%[2]s.Token
}
`, typ.Name, typ.Annotation.ReadRequest))
buf.WriteString(fmt.Sprintf(tmplReadRequest, typ.Name, typ.Annotation.ReadRequest))
}
if typ.Annotation.TargetDatacenter != "" {
buf.WriteString(fmt.Sprintf(`
func (msg *%[1]s) RequestDatacenter() string {
if msg == nil || msg.%[2]s == nil {
return ""
buf.WriteString(fmt.Sprintf(tmplTargetDatacenter, typ.Name, typ.Annotation.TargetDatacenter))
}
return msg.%[2]s.GetDatacenter()
}
`, typ.Name, typ.Annotation.TargetDatacenter))
if typ.Annotation.QueryOptions != "" {
buf.WriteString(fmt.Sprintf(tmplQueryOptions, typ.Name, typ.Annotation.QueryOptions))
}
if typ.Annotation.QueryMeta != "" {
buf.WriteString(fmt.Sprintf(tmplQueryMeta, typ.Name, typ.Annotation.QueryMeta))
}
}
@ -296,6 +240,8 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor {
}
type Annotation struct {
QueryMeta string
QueryOptions string
ReadRequest string
WriteRequest string
TargetDatacenter string
@ -332,6 +278,16 @@ func getAnnotation(doc []*ast.Comment) (Annotation, error) {
case strings.HasPrefix(part, "TargetDatacenter="):
ann.TargetDatacenter = strings.TrimPrefix(part, "TargetDatacenter=")
case part == "QueryOptions":
ann.QueryOptions = "QueryOptions"
case strings.HasPrefix(part, "QueryOptions="):
ann.QueryOptions = strings.TrimPrefix(part, "QueryOptions=")
case part == "QueryMeta":
ann.QueryMeta = "QueryMeta"
case strings.HasPrefix(part, "QueryMeta="):
ann.QueryMeta = strings.TrimPrefix(part, "QueryMeta=")
default:
return Annotation{}, fmt.Errorf("unexpected annotation part: %s", part)
}
@ -373,3 +329,213 @@ func getRawBuildTags(file *ast.File) []string {
return out
}
const tmplWriteRequest = `
// AllowStaleRead implements structs.RPCInfo
func (msg *%[1]s) AllowStaleRead() bool {
return false
}
// HasTimedOut implements structs.RPCInfo
func (msg *%[1]s) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.%[2]s == nil {
return false, nil
}
return msg.%[2]s.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// IsRead implements structs.RPCInfo
func (msg *%[1]s) IsRead() bool {
return false
}
// SetTokenSecret implements structs.RPCInfo
func (msg *%[1]s) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.%[2]s.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *%[1]s) TokenSecret() string {
if msg == nil || msg.%[2]s == nil {
return ""
}
return msg.%[2]s.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *%[1]s) Token() string {
if msg.%[2]s == nil {
return ""
}
return msg.%[2]s.Token
}
`
const tmplReadRequest = `
// IsRead implements structs.RPCInfo
func (msg *%[1]s) IsRead() bool {
return true
}
// AllowStaleRead implements structs.RPCInfo
func (msg *%[1]s) AllowStaleRead() bool {
// TODO: initialize if nil
return msg.%[2]s.AllowStaleRead()
}
// HasTimedOut implements structs.RPCInfo
func (msg *%[1]s) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.%[2]s == nil {
return false, nil
}
return msg.%[2]s.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// SetTokenSecret implements structs.RPCInfo
func (msg *%[1]s) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.%[2]s.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *%[1]s) TokenSecret() string {
if msg == nil || msg.%[2]s == nil {
return ""
}
return msg.%[2]s.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *%[1]s) Token() string {
if msg.%[2]s == nil {
return ""
}
return msg.%[2]s.Token
}
`
const tmplTargetDatacenter = `
// RequestDatacenter implements structs.RPCInfo
func (msg *%[1]s) RequestDatacenter() string {
if msg == nil || msg.%[2]s == nil {
return ""
}
return msg.%[2]s.GetDatacenter()
}
`
const tmplQueryOptions = `
// IsRead implements structs.RPCInfo
func (msg *%[1]s) IsRead() bool {
return true
}
// AllowStaleRead implements structs.RPCInfo
func (msg *%[1]s) AllowStaleRead() bool {
return msg.%[2]s.AllowStaleRead()
}
// HasTimedOut implements structs.RPCInfo
func (msg *%[1]s) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
if msg == nil || msg.%[2]s == nil {
return false, nil
}
return msg.%[2]s.HasTimedOut(start, rpcHoldTimeout, a, b)
}
// SetTokenSecret implements structs.RPCInfo
func (msg *%[1]s) SetTokenSecret(s string) {
// TODO: initialize if nil
msg.%[2]s.SetTokenSecret(s)
}
// TokenSecret implements structs.RPCInfo
func (msg *%[1]s) TokenSecret() string {
if msg == nil || msg.%[2]s == nil {
return ""
}
return msg.%[2]s.TokenSecret()
}
// Token implements structs.RPCInfo
func (msg *%[1]s) Token() string {
if msg.%[2]s == nil {
return ""
}
return msg.%[2]s.Token
}
// GetToken is required to implement blockingQueryOptions
func (msg *%[1]s) GetToken() string {
if msg == nil || msg.%[2]s == nil {
return ""
}
return msg.%[2]s.GetToken()
}
// GetMinQueryIndex is required to implement blockingQueryOptions
func (msg *%[1]s) GetMinQueryIndex() uint64 {
if msg == nil || msg.%[2]s == nil {
return 0
}
return msg.%[2]s.GetMinQueryIndex()
}
// GetMaxQueryTime is required to implement blockingQueryOptions
func (msg *%[1]s) GetMaxQueryTime() (time.Duration, error) {
if msg == nil || msg.%[2]s == nil {
return 0, nil
}
return structs.DurationFromProto(msg.%[2]s.GetMaxQueryTime()), nil
}
// GetRequireConsistent is required to implement blockingQueryOptions
func (msg *%[1]s) GetRequireConsistent() bool {
if msg == nil || msg.%[2]s == nil {
return false
}
return msg.%[2]s.RequireConsistent
}
`
const tmplQueryMeta = `
// SetLastContact is required to implement blockingQueryResponseMeta
func (msg *%[1]s) SetLastContact(d time.Duration) {
if msg == nil || msg.%[2]s == nil {
return
}
msg.%[2]s.SetLastContact(d)
}
// SetKnownLeader is required to implement blockingQueryResponseMeta
func (msg *%[1]s) SetKnownLeader(b bool) {
if msg == nil || msg.%[2]s == nil {
return
}
msg.%[2]s.SetKnownLeader(b)
}
// GetIndex is required to implement blockingQueryResponseMeta
func (msg *%[1]s) GetIndex() uint64 {
if msg == nil || msg.%[2]s == nil {
return 0
}
return msg.%[2]s.GetIndex()
}
// SetIndex is required to implement blockingQueryResponseMeta
func (msg *%[1]s) SetIndex(i uint64) {
if msg == nil || msg.%[2]s == nil {
return
}
msg.%[2]s.SetIndex(i)
}
// SetResultsFilteredByACLs is required to implement blockingQueryResponseMeta
func (msg *%[1]s) SetResultsFilteredByACLs(b bool) {
if msg == nil || msg.%[2]s == nil {
return
}
msg.%[2]s.SetResultsFilteredByACLs(b)
}
`