diff --git a/internal/tools/proto-gen-rpc-glue/.gitignore b/internal/tools/proto-gen-rpc-glue/.gitignore index 14130d475..343d68c1c 100644 --- a/internal/tools/proto-gen-rpc-glue/.gitignore +++ b/internal/tools/proto-gen-rpc-glue/.gitignore @@ -1 +1 @@ -./e2e/source.rpcglue.pb.go +e2e/*.rpcglue.pb.go diff --git a/internal/tools/proto-gen-rpc-glue/e2e/consul/agent/structs/structs.go b/internal/tools/proto-gen-rpc-glue/e2e/consul/agent/structs/structs.go new file mode 100644 index 000000000..4d7741398 --- /dev/null +++ b/internal/tools/proto-gen-rpc-glue/e2e/consul/agent/structs/structs.go @@ -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 +} diff --git a/internal/tools/proto-gen-rpc-glue/e2e/consul/proto/pbcommon/common.go b/internal/tools/proto-gen-rpc-glue/e2e/consul/proto/pbcommon/common.go new file mode 100644 index 000000000..f8211604d --- /dev/null +++ b/internal/tools/proto-gen-rpc-glue/e2e/consul/proto/pbcommon/common.go @@ -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 +} diff --git a/internal/tools/proto-gen-rpc-glue/e2e/source.pb.go b/internal/tools/proto-gen-rpc-glue/e2e/source.pb.go index ed47e1d09..43ace7a84 100644 --- a/internal/tools/proto-gen-rpc-glue/e2e/source.pb.go +++ b/internal/tools/proto-gen-rpc-glue/e2e/source.pb.go @@ -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 +} diff --git a/internal/tools/proto-gen-rpc-glue/e2e/source.rpcglue.pb.go.golden b/internal/tools/proto-gen-rpc-glue/e2e/source.rpcglue.pb.go.golden index 7f87f5477..a035aab7a 100644 --- a/internal/tools/proto-gen-rpc-glue/e2e/source.rpcglue.pb.go.golden +++ b/internal/tools/proto-gen-rpc-glue/e2e/source.rpcglue.pb.go.golden @@ -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) +} diff --git a/internal/tools/proto-gen-rpc-glue/main.go b/internal/tools/proto-gen-rpc-glue/main.go index dd4956912..0618b35b2 100644 --- a/internal/tools/proto-gen-rpc-glue/main.go +++ b/internal/tools/proto-gen-rpc-glue/main.go @@ -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 "" - } - return msg.%[2]s.GetDatacenter() -} -`, typ.Name, typ.Annotation.TargetDatacenter)) + buf.WriteString(fmt.Sprintf(tmplTargetDatacenter, 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) +} +`