diff --git a/.security-profile-branches.json b/.security-profile-branches.json deleted file mode 100644 index ba9674882..000000000 --- a/.security-profile-branches.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "project": "Amplify - APIC Agent SDK", - "repo_url": "https://github.com/Axway/agent-sdk", - "security_guide": "https://docs.axway.com/bundle/axway_resources/page/amplify_api_management_platform_security_white_paper.html", - "requirements": { - "fortify": false, - "irius-risk": false, - "pentest": false, - "twistlock": false, - "blackduck": true, - "third-party-policy-violation": false, - "appspider": false, - "insightvm": false - }, - "suppressions": [ - ] - } diff --git a/.security-profile-latest.json b/.security-profile-latest.json deleted file mode 100644 index ba9674882..000000000 --- a/.security-profile-latest.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "project": "Amplify - APIC Agent SDK", - "repo_url": "https://github.com/Axway/agent-sdk", - "security_guide": "https://docs.axway.com/bundle/axway_resources/page/amplify_api_management_platform_security_white_paper.html", - "requirements": { - "fortify": false, - "irius-risk": false, - "pentest": false, - "twistlock": false, - "blackduck": true, - "third-party-policy-violation": false, - "appspider": false, - "insightvm": false - }, - "suppressions": [ - ] - } diff --git a/go.sum b/go.sum index 774d803dd..ca2bf59c0 100644 --- a/go.sum +++ b/go.sum @@ -429,8 +429,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -468,8 +466,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -508,8 +504,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -579,12 +573,8 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= -golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548= golang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c h1:6a8FdnNk6bTXBjR4AGKFgUKuo+7GnR3FX5L7CbveeZc= golang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c/go.mod h1:TpUTTEp9frx7rTdLpC9gFG9kdI7zVLFTFFlqaH2Cncw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -596,8 +586,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -653,8 +641,6 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/agent/events/eventlistener.go b/pkg/agent/events/eventlistener.go index 4f44f100c..12bef629a 100644 --- a/pkg/agent/events/eventlistener.go +++ b/pkg/agent/events/eventlistener.go @@ -28,7 +28,7 @@ type APIClient interface { // EventListener holds the various caches to save events into as they get written to the source channel. type EventListener struct { ctx context.Context - cancel context.CancelFunc + cancel context.CancelCauseFunc client APIClient handlers []handler.Handler logger log.FieldLogger @@ -37,10 +37,10 @@ type EventListener struct { } // NewListenerFunc type for creating a new listener -type NewListenerFunc func(ctx context.Context, cancel context.CancelFunc, source chan *proto.Event, client APIClient, sequenceManager SequenceProvider, cbs ...handler.Handler) *EventListener +type NewListenerFunc func(ctx context.Context, cancel context.CancelCauseFunc, source chan *proto.Event, client APIClient, sequenceManager SequenceProvider, cbs ...handler.Handler) *EventListener // NewEventListener creates a new EventListener to process events based on the provided Handlers. -func NewEventListener(ctx context.Context, cancel context.CancelFunc, source chan *proto.Event, client APIClient, sequenceManager SequenceProvider, cbs ...handler.Handler) *EventListener { +func NewEventListener(ctx context.Context, cancel context.CancelCauseFunc, source chan *proto.Event, client APIClient, sequenceManager SequenceProvider, cbs ...handler.Handler) *EventListener { logger := log.NewFieldLogger(). WithComponent("EventListener"). WithPackage("sdk.agent.events") @@ -59,7 +59,7 @@ func NewEventListener(ctx context.Context, cancel context.CancelFunc, source cha // Stop stops the listener func (em *EventListener) Stop() { if em != nil { - em.cancel() + em.cancel(nil) } } @@ -92,10 +92,10 @@ func (em *EventListener) start() (done bool, err error) { } if err := em.handleEvent(event); err != nil { - em.logger.WithError(err).Error("stream event listener error") + em.logger.WithError(err).Error("stream event listener error handling event") } case <-em.ctx.Done(): - em.logger.Trace("stream event listener has been gracefully stopped") + em.logger.Trace("stream event listener context is done") done = true err = nil break diff --git a/pkg/agent/events/eventlistener_test.go b/pkg/agent/events/eventlistener_test.go index 8965cfa99..bf23e7822 100644 --- a/pkg/agent/events/eventlistener_test.go +++ b/pkg/agent/events/eventlistener_test.go @@ -59,7 +59,7 @@ func TestEventListener_start(t *testing.T) { sequenceManager := NewSequenceProvider(cacheManager, "testWatch") for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) listener := NewEventListener(ctx, cancel, tc.events, tc.client, sequenceManager, tc.handler) errCh := make(chan error) @@ -100,14 +100,14 @@ func TestEventListener_Listen(t *testing.T) { cacheManager := agentcache.NewAgentCacheManager(&config.CentralConfiguration{}, false) sequenceManager := NewSequenceProvider(cacheManager, "testWatch") events := make(chan *proto.Event) - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) listener := NewEventListener(ctx, cancel, events, &mockAPIClient{}, sequenceManager, &mockHandler{}) listener.Listen() listener.Stop() err := ctx.Err() assert.NotNil(t, err) - ctx, cancel = context.WithCancel(context.Background()) + ctx, cancel = context.WithCancelCause(context.Background()) listener = NewEventListener(ctx, cancel, events, &mockAPIClient{}, sequenceManager, &mockHandler{}) listener.Listen() close(events) @@ -173,7 +173,7 @@ func TestEventListener_handleEvent(t *testing.T) { }, } - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) listener := NewEventListener(ctx, cancel, make(chan *proto.Event), tc.client, sequenceManager, tc.handler) err := listener.handleEvent(event) diff --git a/pkg/agent/events/requestqueue.go b/pkg/agent/events/requestqueue.go index 902111ada..ef5dc0215 100644 --- a/pkg/agent/events/requestqueue.go +++ b/pkg/agent/events/requestqueue.go @@ -20,7 +20,7 @@ type RequestQueue interface { // requestQueue type requestQueue struct { ctx context.Context - cancel context.CancelFunc + cancel context.CancelCauseFunc logger log.FieldLogger requestCh chan *proto.Request receiveCh chan *proto.Request @@ -28,10 +28,10 @@ type requestQueue struct { } // NewRequestQueueFunc type for creating a new request queue -type NewRequestQueueFunc func(ctx context.Context, cancel context.CancelFunc, requestCh chan *proto.Request) RequestQueue +type NewRequestQueueFunc func(ctx context.Context, cancel context.CancelCauseFunc, requestCh chan *proto.Request) RequestQueue // NewRequestQueue creates a new queue for the requests to be sent for watch subscription -func NewRequestQueue(ctx context.Context, cancel context.CancelFunc, requestCh chan *proto.Request) RequestQueue { +func NewRequestQueue(ctx context.Context, cancel context.CancelCauseFunc, requestCh chan *proto.Request) RequestQueue { logger := log.NewFieldLogger(). WithComponent("requestQueue"). WithPackage("sdk.agent.events") @@ -52,7 +52,7 @@ func (q *requestQueue) Stop() { } defer q.isActive.Store(false) - q.cancel() + q.cancel(nil) close(q.receiveCh) } @@ -66,8 +66,12 @@ func (q *requestQueue) Write(request *proto.Request) error { } q.logger.WithField("requestType", request.RequestType).Trace("received stream request") - q.receiveCh <- request - return nil + select { + case q.receiveCh <- request: + return nil + case <-q.ctx.Done(): + return q.ctx.Err() + } } func (q *requestQueue) Start() { diff --git a/pkg/agent/events/requestqueue_test.go b/pkg/agent/events/requestqueue_test.go index e122ea652..1997b9c78 100644 --- a/pkg/agent/events/requestqueue_test.go +++ b/pkg/agent/events/requestqueue_test.go @@ -29,7 +29,7 @@ func TestRequestQueue(t *testing.T) { for _, tc := range cases { requestCh := make(chan *proto.Request, 1) t.Run(tc.name, func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) q := NewRequestQueue(ctx, cancel, requestCh) var receivedReq *proto.Request wg := sync.WaitGroup{} diff --git a/pkg/agent/poller/client.go b/pkg/agent/poller/client.go index 049cbae76..d23410238 100644 --- a/pkg/agent/poller/client.go +++ b/pkg/agent/poller/client.go @@ -65,9 +65,9 @@ func NewPollClient( // Start the polling client func (p *PollClient) Start() error { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - eventCh, eventErrorCh := make(chan *proto.Event), make(chan error) + ctx, cancel := context.WithCancelCause(context.Background()) + defer cancel(nil) + eventCh := make(chan *proto.Event) p.mutex.Lock() @@ -76,7 +76,7 @@ func (p *PollClient) Start() error { p.poller = p.newPollManager(p.interval, withOnStop(p.onClientStop), withHarvester(p.harvesterConfig), WithContext(ctx, cancel)) p.mutex.Unlock() p.listener.Listen() - p.poller.RegisterWatch(eventCh, eventErrorCh) + p.poller.RegisterWatch(eventCh) if p.onStreamConnection != nil { p.onStreamConnection() @@ -86,12 +86,11 @@ func (p *PollClient) Start() error { p.initialized = true p.mutex.Unlock() - select { - case err := <-eventErrorCh: - return err - case <-ctx.Done(): - return fmt.Errorf("poll client context has been closed") + <-ctx.Done() + if cause := context.Cause(ctx); cause != nil { + return cause } + return fmt.Errorf("poll client context has been closed") } // Status returns an error if the poller is not running diff --git a/pkg/agent/poller/options.go b/pkg/agent/poller/options.go index cb0f939ed..07ecdb3c3 100644 --- a/pkg/agent/poller/options.go +++ b/pkg/agent/poller/options.go @@ -53,7 +53,7 @@ func withOnStop(cb onClientStopCb) executorOpt { } } -func WithContext(ctx context.Context, cancel context.CancelFunc) executorOpt { +func WithContext(ctx context.Context, cancel context.CancelCauseFunc) executorOpt { return func(m *pollExecutor) { m.ctx = ctx m.cancel = cancel diff --git a/pkg/agent/poller/poller.go b/pkg/agent/poller/poller.go index 44f43b835..a6642f99a 100644 --- a/pkg/agent/poller/poller.go +++ b/pkg/agent/poller/poller.go @@ -14,7 +14,7 @@ import ( type pollExecutor struct { ctx context.Context - cancel context.CancelFunc + cancel context.CancelCauseFunc harvester harvester.Harvest sequence events.SequenceProvider topicSelfLink string @@ -33,7 +33,7 @@ func newPollExecutor(interval time.Duration, options ...executorOpt) *pollExecut WithComponent("pollExecutor"). WithPackage("sdk.agent.poller") - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) pm := &pollExecutor{ logger: logger, timer: time.NewTimer(interval), @@ -50,32 +50,28 @@ func newPollExecutor(interval time.Duration, options ...executorOpt) *pollExecut } // RegisterWatch registers a watch topic for polling events and publishing events on a channel -func (m *pollExecutor) RegisterWatch(eventChan chan *proto.Event, errChan chan error) { +func (m *pollExecutor) RegisterWatch(eventChan chan *proto.Event) { m.logger.Trace("register watch topic for polling and publishing events") if m.harvester == nil { - go func() { - m.Stop() - errChan <- fmt.Errorf("harvester is not configured for the polling client") - }() + err := fmt.Errorf("harvester is not configured for the polling client") + m.cancel(err) + m.Stop() return } if m.sequence.GetSequence() < 0 { m.onHarvesterErr() - go func() { - m.Stop() - errChan <- fmt.Errorf("do not have a sequence id, stopping poller") - }() + err := fmt.Errorf("do not have a sequence id, stopping poller") + m.cancel(err) + m.Stop() return } if err := m.harvester.EventCatchUp(m.ctx, m.topicSelfLink, eventChan); err != nil { m.logger.WithError(err).Error("harvester returned an error when syncing events") m.onHarvesterErr() - go func() { - m.Stop() - errChan <- err - }() + m.cancel(err) + m.Stop() return } @@ -84,9 +80,10 @@ func (m *pollExecutor) RegisterWatch(eventChan chan *proto.Event, errChan chan e m.lock.Unlock() go func() { - err := m.sync(m.topicSelfLink, eventChan) + if err := m.sync(m.topicSelfLink, eventChan); err != nil { + m.cancel(err) + } m.Stop() - errChan <- err }() } @@ -142,7 +139,7 @@ func (m *pollExecutor) onHarvesterErr() { // Stop stops the poller func (m *pollExecutor) Stop() { m.timer.Stop() - m.cancel() + m.cancel(nil) m.lock.Lock() defer m.lock.Unlock() diff --git a/pkg/agent/poller/poller_test.go b/pkg/agent/poller/poller_test.go index 303559d3e..d958ce722 100644 --- a/pkg/agent/poller/poller_test.go +++ b/pkg/agent/poller/poller_test.go @@ -1,6 +1,7 @@ package poller import ( + "context" "fmt" "testing" @@ -26,13 +27,13 @@ func TestPollerRegisterWatch(t *testing.T) { hClient: mockH, })) - eventCh, errCh := make(chan *proto.Event), make(chan error) + eventCh := make(chan *proto.Event) h := &mockHarvester{ eventCh: eventCh, } poller.harvester = h - poller.RegisterWatch(eventCh, errCh) + poller.RegisterWatch(eventCh) evt := <-h.eventCh assert.NotNil(t, evt) @@ -50,15 +51,16 @@ func TestPollerRegisterWatchError(t *testing.T) { hClient: mockH, })) - eventCh, errCh := make(chan *proto.Event), make(chan error) + eventCh := make(chan *proto.Event) poller.harvester = &mockHarvester{ err: fmt.Errorf("harvester error"), } - poller.RegisterWatch(eventCh, errCh) + poller.RegisterWatch(eventCh) - err := <-errCh - assert.NotNil(t, err) + <-poller.ctx.Done() + assert.NotNil(t, poller.ctx.Err()) + assert.Equal(t, "harvester error", context.Cause(poller.ctx).Error()) } func TestPollClientOptions(t *testing.T) { diff --git a/pkg/agent/stream/client.go b/pkg/agent/stream/client.go index 5210a3ad9..b9ca3c327 100644 --- a/pkg/agent/stream/client.go +++ b/pkg/agent/stream/client.go @@ -54,7 +54,7 @@ type StreamerClient struct { onEventSyncError func() isInitialized atomic.Bool isRunning atomic.Bool - cancel context.CancelFunc + cancel context.CancelCauseFunc } // NewStreamerClient creates a StreamerClient @@ -89,6 +89,7 @@ func NewStreamerClient( logger: logger, environmentURL: cfg.GetEnvironmentURL(), } + s.isInitialized.Store(false) for _, opt := range options { opt(s) @@ -146,11 +147,11 @@ func (s *StreamerClient) Start() error { s.isRunning.Store(true) defer s.isRunning.Store(false) - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) s.cancel = cancel - defer cancel() - eventCh, requestCh, eventErrorCh := make(chan *proto.Event), make(chan *proto.Request, 1), make(chan error) + defer cancel(nil) + eventCh, requestCh := make(chan *proto.Event), make(chan *proto.Request, 1) s.listener = s.newListener(ctx, cancel, eventCh, s.apiClient, s.sequence, s.handlers...) defer s.listener.Stop() @@ -165,31 +166,30 @@ func (s *StreamerClient) Start() error { defer manager.CloseConn() s.manager = manager - s.isInitialized.Store(false) s.listener.Listen() - s.requestQueue.Start() - _, err = s.manager.RegisterWatch(s.topicSelfLink, eventCh, eventErrorCh) + _, err = s.manager.RegisterWatch(s.topicSelfLink, eventCh) if s.onStreamConnection != nil { s.onStreamConnection() } - s.isInitialized.Store(true) if err != nil { return err } + s.requestQueue.Start() + s.isInitialized.Store(true) + defer s.isInitialized.Store(false) - select { - case err := <-eventErrorCh: - return err - case <-ctx.Done(): - return fmt.Errorf("stream client context has been closed") + <-ctx.Done() + if cause := context.Cause(ctx); cause != nil { + return cause } + return fmt.Errorf("stream client context has been closed") } // Status returns the health status func (s *StreamerClient) Status() error { if !s.isInitialized.Load() { - return nil + return fmt.Errorf("stream client is not yet initialized") } if s.manager == nil || s.listener == nil || s.requestQueue == nil { @@ -205,7 +205,7 @@ func (s *StreamerClient) Status() error { // Stop stops the StreamerClient func (s *StreamerClient) Stop() { if s.cancel != nil { - s.cancel() + s.cancel(nil) } } diff --git a/pkg/agent/stream/client_test.go b/pkg/agent/stream/client_test.go index da02139f0..519a9aefb 100644 --- a/pkg/agent/stream/client_test.go +++ b/pkg/agent/stream/client_test.go @@ -3,6 +3,7 @@ package stream import ( "context" "testing" + "time" agentcache "github.com/Axway/agent-sdk/pkg/agent/cache" "github.com/Axway/agent-sdk/pkg/agent/events" @@ -63,7 +64,7 @@ func TestNewStreamer(t *testing.T) { return manager, nil } - assert.Nil(t, streamer.Status()) + assert.NotNil(t, streamer.Status()) errCh := make(chan error) go func() { @@ -72,14 +73,14 @@ func TestNewStreamer(t *testing.T) { }() <-manager.readyCh - + assert.Equal(t, hc.OK, hc.RunChecks()) // should stop the listener and write nil to the listener's error channel streamer.listener.Stop() err = <-errCh assert.NotNil(t, err) - assert.Equal(t, hc.OK, hc.RunChecks()) + assert.Equal(t, hc.FAIL, hc.RunChecks()) streamer.manager = nil streamer.listener = nil @@ -90,7 +91,8 @@ func TestNewStreamer(t *testing.T) { <-manager.readyCh - assert.Nil(t, streamer.Status()) + // wait for isInitialized to be set after requestQueue.Start() + assert.Eventually(t, func() bool { return streamer.Status() == nil }, time.Second, 10*time.Millisecond) stop(t, streamer, errCh) manager.status = false @@ -169,14 +171,14 @@ func TestStatusUpdates(t *testing.T) { } requestQueue := &mockRequestQueue{active: tc.queueActive} - streamer.newRequestQueue = func(ctx context.Context, cancel context.CancelFunc, requestCh chan *proto.Request) events.RequestQueue { + streamer.newRequestQueue = func(ctx context.Context, cancel context.CancelCauseFunc, requestCh chan *proto.Request) events.RequestQueue { return requestQueue } streamer.newManager = func(cfg *wm.Config, opts ...wm.Option) (wm.Manager, error) { return manager, nil } - assert.Nil(t, streamer.Status()) + assert.NotNil(t, streamer.Status()) errCh := make(chan error) go func() { err := streamer.Start() @@ -222,7 +224,7 @@ type mockManager struct { readyCh chan struct{} } -func (m *mockManager) RegisterWatch(_ string, _ chan *proto.Event, _ chan error) (string, error) { +func (m *mockManager) RegisterWatch(_ string, _ chan *proto.Event) (string, error) { if m.readyCh != nil { m.readyCh <- struct{}{} } diff --git a/pkg/agent/stream/options.go b/pkg/agent/stream/options.go index b48f36061..012992b05 100644 --- a/pkg/agent/stream/options.go +++ b/pkg/agent/stream/options.go @@ -53,7 +53,7 @@ func WithEventSyncError(cb func()) StreamerOpt { func WithOnStreamConnection() StreamerOpt { return func(pc *StreamerClient) { pc.onStreamConnection = func() { - hc.RegisterHealthcheck(util.AmplifyCentral, util.CentralHealthCheckEndpoint, pc.Healthcheck) + hc.RegisterOrUpdateHealthcheck(util.AmplifyCentral, util.CentralHealthCheckEndpoint, pc.Healthcheck) } } } diff --git a/pkg/amplify/agent/correlation/correlation.pb.go b/pkg/amplify/agent/correlation/correlation.pb.go index d459855da..cf14bed5a 100644 --- a/pkg/amplify/agent/correlation/correlation.pb.go +++ b/pkg/amplify/agent/correlation/correlation.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v4.24.4 +// protoc-gen-go v1.36.10 +// protoc v6.31.1 // source: correlation/correlation.proto package correlation @@ -13,6 +13,7 @@ import ( timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -24,10 +25,7 @@ const ( // Request - represents the API request properties type Request struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // HTTP request method Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` // The request protocol scheme @@ -49,16 +47,16 @@ type Request struct { // The value of X-Forwarded-For request header ForwardedFor string `protobuf:"bytes,10,opt,name=forwarded_for,json=forwardedFor,proto3" json:"forwarded_for,omitempty"` // The map of request headers - Headers map[string]string `protobuf:"bytes,11,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Headers map[string]string `protobuf:"bytes,11,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Request) Reset() { *x = Request{} - if protoimpl.UnsafeEnabled { - mi := &file_correlation_correlation_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_correlation_correlation_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Request) String() string { @@ -69,7 +67,7 @@ func (*Request) ProtoMessage() {} func (x *Request) ProtoReflect() protoreflect.Message { mi := &file_correlation_correlation_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -163,23 +161,20 @@ func (x *Request) GetHeaders() map[string]string { // Response - represents the API response properties type Response struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The HTTP response code ResponseCode uint32 `protobuf:"varint,1,opt,name=response_code,json=responseCode,proto3" json:"response_code,omitempty"` // The map of response headers - Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Response) Reset() { *x = Response{} - if protoimpl.UnsafeEnabled { - mi := &file_correlation_correlation_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_correlation_correlation_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Response) String() string { @@ -190,7 +185,7 @@ func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { mi := &file_correlation_correlation_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -221,10 +216,7 @@ func (x *Response) GetHeaders() map[string]string { // TransactionContext - represents the API traffic transaction context type TransactionContext struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The request/transaction identifier TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` // The source address on which the request from the user was received @@ -239,22 +231,22 @@ type TransactionContext struct { RouteName string `protobuf:"bytes,6,opt,name=routeName,proto3" json:"routeName,omitempty"` // The map of additional metadata associated to the traffic // for specific dataplane gateway - Metadata map[string]*structpb.Value `protobuf:"bytes,7,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Metadata map[string]*structpb.Value `protobuf:"bytes,7,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // The response properties associated with the API transaction Request *Request `protobuf:"bytes,8,opt,name=request,proto3" json:"request,omitempty"` // The response properties associated with the API transaction Response *Response `protobuf:"bytes,9,opt,name=response,proto3" json:"response,omitempty"` // The time request was received by the dataplane gateway - StartTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + StartTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *TransactionContext) Reset() { *x = TransactionContext{} - if protoimpl.UnsafeEnabled { - mi := &file_correlation_correlation_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_correlation_correlation_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *TransactionContext) String() string { @@ -265,7 +257,7 @@ func (*TransactionContext) ProtoMessage() {} func (x *TransactionContext) ProtoReflect() protoreflect.Message { mi := &file_correlation_correlation_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -353,10 +345,7 @@ func (x *TransactionContext) GetStartTime() *timestamppb.Timestamp { // ResourceContext - holds the properties that correlates the transaction with // Amplify API resources. type ResourceContext struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The dataplane gateway specific identifier used for correlating // the API service resource ApiId string `protobuf:"bytes,1,opt,name=api_id,json=apiId,proto3" json:"api_id,omitempty"` @@ -368,16 +357,16 @@ type ResourceContext struct { Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` // The dataplane gateway specific identifier used for correlating // the Amplify marketplace subscription/application - ConsumerId string `protobuf:"bytes,4,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` + ConsumerId string `protobuf:"bytes,4,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ResourceContext) Reset() { *x = ResourceContext{} - if protoimpl.UnsafeEnabled { - mi := &file_correlation_correlation_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_correlation_correlation_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ResourceContext) String() string { @@ -388,7 +377,7 @@ func (*ResourceContext) ProtoMessage() {} func (x *ResourceContext) ProtoReflect() protoreflect.Message { mi := &file_correlation_correlation_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -433,122 +422,65 @@ func (x *ResourceContext) GetConsumerId() string { var File_correlation_correlation_proto protoreflect.FileDescriptor -var file_correlation_correlation_proto_rawDesc = []byte{ - 0x0a, 0x1d, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, - 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x19, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, - 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb8, 0x03, 0x0a, 0x07, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x18, - 0x0a, 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72, 0x77, - 0x61, 0x72, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x12, 0x49, 0x0a, - 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, - 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, - 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb7, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, - 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe5, - 0x04, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, - 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x12, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x57, - 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x3b, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3c, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, - 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, - 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, - 0x65, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x79, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x69, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x69, 0x49, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, - 0x64, 0x32, 0x87, 0x01, 0x0a, 0x12, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x71, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x2d, - 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, - 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x1a, 0x2a, 0x2e, - 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6f, - 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x00, 0x42, 0x1f, 0x5a, 0x1d, 0x70, - 0x6b, 0x67, 0x2f, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} +const file_correlation_correlation_proto_rawDesc = "" + + "\n" + + "\x1dcorrelation/correlation.proto\x12\x19amplify.agent.correlation\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb8\x03\n" + + "\aRequest\x12\x16\n" + + "\x06method\x18\x01 \x01(\tR\x06method\x12\x1a\n" + + "\bprotocol\x18\x02 \x01(\tR\bprotocol\x12)\n" + + "\x10protocol_version\x18\x03 \x01(\tR\x0fprotocolVersion\x12\x1c\n" + + "\tauthority\x18\x04 \x01(\tR\tauthority\x12\x12\n" + + "\x04port\x18\x05 \x01(\rR\x04port\x12\x12\n" + + "\x04path\x18\x06 \x01(\tR\x04path\x12#\n" + + "\roriginal_path\x18\a \x01(\tR\foriginalPath\x12\x1d\n" + + "\n" + + "user_agent\x18\b \x01(\tR\tuserAgent\x12\x18\n" + + "\areferer\x18\t \x01(\tR\areferer\x12#\n" + + "\rforwarded_for\x18\n" + + " \x01(\tR\fforwardedFor\x12I\n" + + "\aheaders\x18\v \x03(\v2/.amplify.agent.correlation.Request.HeadersEntryR\aheaders\x1a:\n" + + "\fHeadersEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xb7\x01\n" + + "\bResponse\x12#\n" + + "\rresponse_code\x18\x01 \x01(\rR\fresponseCode\x12J\n" + + "\aheaders\x18\x02 \x03(\v20.amplify.agent.correlation.Response.HeadersEntryR\aheaders\x1a:\n" + + "\fHeadersEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xe5\x04\n" + + "\x12TransactionContext\x12%\n" + + "\x0etransaction_id\x18\x01 \x01(\tR\rtransactionId\x12$\n" + + "\roriginAddress\x18\x02 \x01(\tR\roriginAddress\x12 \n" + + "\voriginAlias\x18\x03 \x01(\tR\voriginAlias\x12.\n" + + "\x12destinationAddress\x18\x04 \x01(\tR\x12destinationAddress\x12*\n" + + "\x10destinationAlias\x18\x05 \x01(\tR\x10destinationAlias\x12\x1c\n" + + "\trouteName\x18\x06 \x01(\tR\trouteName\x12W\n" + + "\bmetadata\x18\a \x03(\v2;.amplify.agent.correlation.TransactionContext.MetadataEntryR\bmetadata\x12<\n" + + "\arequest\x18\b \x01(\v2\".amplify.agent.correlation.RequestR\arequest\x12?\n" + + "\bresponse\x18\t \x01(\v2#.amplify.agent.correlation.ResponseR\bresponse\x129\n" + + "\n" + + "start_time\x18\n" + + " \x01(\v2\x1a.google.protobuf.TimestampR\tstartTime\x1aS\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12,\n" + + "\x05value\x18\x02 \x01(\v2\x16.google.protobuf.ValueR\x05value:\x028\x01\"y\n" + + "\x0fResourceContext\x12\x15\n" + + "\x06api_id\x18\x01 \x01(\tR\x05apiId\x12\x14\n" + + "\x05stage\x18\x02 \x01(\tR\x05stage\x12\x18\n" + + "\aversion\x18\x03 \x01(\tR\aversion\x12\x1f\n" + + "\vconsumer_id\x18\x04 \x01(\tR\n" + + "consumerId2\x87\x01\n" + + "\x12CorrelationService\x12q\n" + + "\x12GetResourceContext\x12-.amplify.agent.correlation.TransactionContext\x1a*.amplify.agent.correlation.ResourceContext\"\x00B\x1fZ\x1dpkg/amplify/agent/correlationb\x06proto3" var ( file_correlation_correlation_proto_rawDescOnce sync.Once - file_correlation_correlation_proto_rawDescData = file_correlation_correlation_proto_rawDesc + file_correlation_correlation_proto_rawDescData []byte ) func file_correlation_correlation_proto_rawDescGZIP() []byte { file_correlation_correlation_proto_rawDescOnce.Do(func() { - file_correlation_correlation_proto_rawDescData = protoimpl.X.CompressGZIP(file_correlation_correlation_proto_rawDescData) + file_correlation_correlation_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_correlation_correlation_proto_rawDesc), len(file_correlation_correlation_proto_rawDesc))) }) return file_correlation_correlation_proto_rawDescData } @@ -587,61 +519,11 @@ func file_correlation_correlation_proto_init() { if File_correlation_correlation_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_correlation_correlation_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*Request); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_correlation_correlation_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*Response); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_correlation_correlation_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*TransactionContext); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_correlation_correlation_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*ResourceContext); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_correlation_correlation_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_correlation_correlation_proto_rawDesc), len(file_correlation_correlation_proto_rawDesc)), NumEnums: 0, NumMessages: 7, NumExtensions: 0, @@ -652,7 +534,6 @@ func file_correlation_correlation_proto_init() { MessageInfos: file_correlation_correlation_proto_msgTypes, }.Build() File_correlation_correlation_proto = out.File - file_correlation_correlation_proto_rawDesc = nil file_correlation_correlation_proto_goTypes = nil file_correlation_correlation_proto_depIdxs = nil } diff --git a/pkg/amplify/agent/correlation/correlation_grpc.pb.go b/pkg/amplify/agent/correlation/correlation_grpc.pb.go index c16c82e65..bfcd52089 100644 --- a/pkg/amplify/agent/correlation/correlation_grpc.pb.go +++ b/pkg/amplify/agent/correlation/correlation_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 -// - protoc v4.24.4 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.31.1 // source: correlation/correlation.proto package correlation @@ -15,8 +15,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( CorrelationService_GetResourceContext_FullMethodName = "/amplify.agent.correlation.CorrelationService/GetResourceContext" @@ -51,7 +51,7 @@ func (c *correlationServiceClient) GetResourceContext(ctx context.Context, in *T // CorrelationServiceServer is the server API for CorrelationService service. // All implementations must embed UnimplementedCorrelationServiceServer -// for forward compatibility +// for forward compatibility. // // Correlation service returns the resource context related to API transaction type CorrelationServiceServer interface { @@ -59,14 +59,18 @@ type CorrelationServiceServer interface { mustEmbedUnimplementedCorrelationServiceServer() } -// UnimplementedCorrelationServiceServer must be embedded to have forward compatible implementations. -type UnimplementedCorrelationServiceServer struct { -} +// UnimplementedCorrelationServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedCorrelationServiceServer struct{} func (UnimplementedCorrelationServiceServer) GetResourceContext(context.Context, *TransactionContext) (*ResourceContext, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetResourceContext not implemented") + return nil, status.Error(codes.Unimplemented, "method GetResourceContext not implemented") } func (UnimplementedCorrelationServiceServer) mustEmbedUnimplementedCorrelationServiceServer() {} +func (UnimplementedCorrelationServiceServer) testEmbeddedByValue() {} // UnsafeCorrelationServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to CorrelationServiceServer will @@ -76,6 +80,13 @@ type UnsafeCorrelationServiceServer interface { } func RegisterCorrelationServiceServer(s grpc.ServiceRegistrar, srv CorrelationServiceServer) { + // If the following call panics, it indicates UnimplementedCorrelationServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&CorrelationService_ServiceDesc, srv) } diff --git a/pkg/amplify/agent/customunits/customunits.pb.go b/pkg/amplify/agent/customunits/customunits.pb.go index 93769aa25..5d2e3a311 100644 --- a/pkg/amplify/agent/customunits/customunits.pb.go +++ b/pkg/amplify/agent/customunits/customunits.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v4.24.4 +// protoc-gen-go v1.36.10 +// protoc v6.31.1 // source: customunits/customunits.proto package customunits @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -180,25 +181,22 @@ func (QuotaIntervalType) EnumDescriptor() ([]byte, []int) { } type APIServiceLookup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // the type that the agent will look to match against in the resource Type APIServiceLookupType `protobuf:"varint,1,opt,name=type,proto3,enum=amplify.agent.customunits.APIServiceLookupType" json:"type,omitempty"` // Only required when Custom is the type CustomAttribute string `protobuf:"bytes,2,opt,name=customAttribute,proto3" json:"customAttribute,omitempty"` // the value of the attribute the agent will look for in the resource - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *APIServiceLookup) Reset() { *x = APIServiceLookup{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *APIServiceLookup) String() string { @@ -209,7 +207,7 @@ func (*APIServiceLookup) ProtoMessage() {} func (x *APIServiceLookup) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -246,25 +244,22 @@ func (x *APIServiceLookup) GetValue() string { } type AppLookup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // the type that the agent will look to match against in the resource Type AppLookupType `protobuf:"varint,1,opt,name=type,proto3,enum=amplify.agent.customunits.AppLookupType" json:"type,omitempty"` // Only required when Custom is the type CustomAttribute string `protobuf:"bytes,2,opt,name=customAttribute,proto3" json:"customAttribute,omitempty"` // the value of the attribute the agent will look for in the resource - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AppLookup) Reset() { *x = AppLookup{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AppLookup) String() string { @@ -275,7 +270,7 @@ func (*AppLookup) ProtoMessage() {} func (x *AppLookup) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -312,21 +307,18 @@ func (x *AppLookup) GetValue() string { } type UnitLookup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // the logical name of the plan unit the agent will look for in the resource - UnitName string `protobuf:"bytes,1,opt,name=unitName,proto3" json:"unitName,omitempty"` + UnitName string `protobuf:"bytes,1,opt,name=unitName,proto3" json:"unitName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *UnitLookup) Reset() { *x = UnitLookup{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UnitLookup) String() string { @@ -337,7 +329,7 @@ func (*UnitLookup) ProtoMessage() {} func (x *UnitLookup) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -361,23 +353,20 @@ func (x *UnitLookup) GetUnitName() string { // this message will be received continually type MetricReport struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` + ApiService *APIServiceLookup `protobuf:"bytes,2,opt,name=apiService,proto3" json:"apiService,omitempty"` + ManagedApp *AppLookup `protobuf:"bytes,3,opt,name=managedApp,proto3" json:"managedApp,omitempty"` + PlanUnit *UnitLookup `protobuf:"bytes,4,opt,name=planUnit,proto3" json:"planUnit,omitempty"` unknownFields protoimpl.UnknownFields - - Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` - ApiService *APIServiceLookup `protobuf:"bytes,2,opt,name=apiService,proto3" json:"apiService,omitempty"` - ManagedApp *AppLookup `protobuf:"bytes,3,opt,name=managedApp,proto3" json:"managedApp,omitempty"` - PlanUnit *UnitLookup `protobuf:"bytes,4,opt,name=planUnit,proto3" json:"planUnit,omitempty"` + sizeCache protoimpl.SizeCache } func (x *MetricReport) Reset() { *x = MetricReport{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MetricReport) String() string { @@ -388,7 +377,7 @@ func (*MetricReport) ProtoMessage() {} func (x *MetricReport) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -433,18 +422,16 @@ func (x *MetricReport) GetPlanUnit() *UnitLookup { // message to start the connection to the custom metric reporting service type MetricServiceInit struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *MetricServiceInit) Reset() { *x = MetricServiceInit{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MetricServiceInit) String() string { @@ -455,7 +442,7 @@ func (*MetricServiceInit) ProtoMessage() {} func (x *MetricServiceInit) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -471,22 +458,19 @@ func (*MetricServiceInit) Descriptor() ([]byte, []int) { } type Quota struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` + Unit string `protobuf:"bytes,2,opt,name=unit,proto3" json:"unit,omitempty"` + Interval QuotaIntervalType `protobuf:"varint,3,opt,name=interval,proto3,enum=amplify.agent.customunits.QuotaIntervalType" json:"interval,omitempty"` unknownFields protoimpl.UnknownFields - - Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` - Unit string `protobuf:"bytes,2,opt,name=unit,proto3" json:"unit,omitempty"` - Interval QuotaIntervalType `protobuf:"varint,3,opt,name=interval,proto3,enum=amplify.agent.customunits.QuotaIntervalType" json:"interval,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Quota) Reset() { *x = Quota{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Quota) String() string { @@ -497,7 +481,7 @@ func (*Quota) ProtoMessage() {} func (x *Quota) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -534,23 +518,20 @@ func (x *Quota) GetInterval() QuotaIntervalType { } type APIInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ServiceDetails map[string]string `protobuf:"bytes,1,rep,name=ServiceDetails,proto3" json:"ServiceDetails,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // x-agent-details from the API Service - ServiceName string `protobuf:"bytes,2,opt,name=ServiceName,proto3" json:"ServiceName,omitempty"` - ServiceID string `protobuf:"bytes,3,opt,name=ServiceID,proto3" json:"ServiceID,omitempty"` - ExternalAPIID string `protobuf:"bytes,4,opt,name=ExternalAPIID,proto3" json:"ExternalAPIID,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + ServiceDetails map[string]string `protobuf:"bytes,1,rep,name=ServiceDetails,proto3" json:"ServiceDetails,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // x-agent-details from the API Service + ServiceName string `protobuf:"bytes,2,opt,name=ServiceName,proto3" json:"ServiceName,omitempty"` + ServiceID string `protobuf:"bytes,3,opt,name=ServiceID,proto3" json:"ServiceID,omitempty"` + ExternalAPIID string `protobuf:"bytes,4,opt,name=ExternalAPIID,proto3" json:"ExternalAPIID,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *APIInfo) Reset() { *x = APIInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *APIInfo) String() string { @@ -561,7 +542,7 @@ func (*APIInfo) ProtoMessage() {} func (x *APIInfo) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -605,23 +586,20 @@ func (x *APIInfo) GetExternalAPIID() string { } type AppInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + AppDetails map[string]string `protobuf:"bytes,1,rep,name=AppDetails,proto3" json:"AppDetails,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // x-agent-details from the Managed App + AppName string `protobuf:"bytes,2,opt,name=AppName,proto3" json:"AppName,omitempty"` + AppID string `protobuf:"bytes,3,opt,name=AppID,proto3" json:"AppID,omitempty"` + ExternalAppID string `protobuf:"bytes,4,opt,name=ExternalAppID,proto3" json:"ExternalAppID,omitempty"` unknownFields protoimpl.UnknownFields - - AppDetails map[string]string `protobuf:"bytes,1,rep,name=AppDetails,proto3" json:"AppDetails,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // x-agent-details from the Managed App - AppName string `protobuf:"bytes,2,opt,name=AppName,proto3" json:"AppName,omitempty"` - AppID string `protobuf:"bytes,3,opt,name=AppID,proto3" json:"AppID,omitempty"` - ExternalAppID string `protobuf:"bytes,4,opt,name=ExternalAppID,proto3" json:"ExternalAppID,omitempty"` + sizeCache protoimpl.SizeCache } func (x *AppInfo) Reset() { *x = AppInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AppInfo) String() string { @@ -632,7 +610,7 @@ func (*AppInfo) ProtoMessage() {} func (x *AppInfo) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -677,22 +655,19 @@ func (x *AppInfo) GetExternalAppID() string { // message to send to the metric service for enforcing a quota type QuotaInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ApiInfo *APIInfo `protobuf:"bytes,1,opt,name=apiInfo,proto3" json:"apiInfo,omitempty"` + AppInfo *AppInfo `protobuf:"bytes,2,opt,name=appInfo,proto3" json:"appInfo,omitempty"` + Quota *Quota `protobuf:"bytes,3,opt,name=quota,proto3" json:"quota,omitempty"` // custom quota information unknownFields protoimpl.UnknownFields - - ApiInfo *APIInfo `protobuf:"bytes,1,opt,name=apiInfo,proto3" json:"apiInfo,omitempty"` - AppInfo *AppInfo `protobuf:"bytes,2,opt,name=appInfo,proto3" json:"appInfo,omitempty"` - Quota *Quota `protobuf:"bytes,3,opt,name=quota,proto3" json:"quota,omitempty"` // custom quota information + sizeCache protoimpl.SizeCache } func (x *QuotaInfo) Reset() { *x = QuotaInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *QuotaInfo) String() string { @@ -703,7 +678,7 @@ func (*QuotaInfo) ProtoMessage() {} func (x *QuotaInfo) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -741,20 +716,17 @@ func (x *QuotaInfo) GetQuota() *Quota { // response received for the quota enforcement rpc type QuotaEnforcementResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` unknownFields protoimpl.UnknownFields - - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + sizeCache protoimpl.SizeCache } func (x *QuotaEnforcementResponse) Reset() { *x = QuotaEnforcementResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_customunits_customunits_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_customunits_customunits_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *QuotaEnforcementResponse) String() string { @@ -765,7 +737,7 @@ func (*QuotaEnforcementResponse) ProtoMessage() {} func (x *QuotaEnforcementResponse) ProtoReflect() protoreflect.Message { mi := &file_customunits_customunits_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -789,155 +761,87 @@ func (x *QuotaEnforcementResponse) GetError() string { var File_customunits_customunits_proto protoreflect.FileDescriptor -var file_customunits_customunits_proto_rawDesc = []byte{ - 0x0a, 0x1d, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2f, 0x63, 0x75, - 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x19, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, - 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x10, 0x41, - 0x50, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x12, - 0x43, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, - 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, - 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, - 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x22, 0x89, 0x01, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x4c, 0x6f, 0x6f, 0x6b, - 0x75, 0x70, 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x28, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x41, 0x70, 0x70, - 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, - 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x28, 0x0a, 0x0a, 0x55, 0x6e, 0x69, 0x74, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x12, 0x1a, - 0x0a, 0x08, 0x75, 0x6e, 0x69, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x75, 0x6e, 0x69, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xfa, 0x01, 0x0a, 0x0c, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x4b, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, - 0x73, 0x2e, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x6f, 0x6b, - 0x75, 0x70, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, - 0x0a, 0x0a, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x41, 0x70, 0x70, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x41, - 0x70, 0x70, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x0a, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x64, 0x41, 0x70, 0x70, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x6e, 0x55, 0x6e, 0x69, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, - 0x74, 0x73, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x08, 0x70, - 0x6c, 0x61, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x22, 0x13, 0x0a, 0x11, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x22, 0x7b, 0x0a, 0x05, - 0x51, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, - 0x6e, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, - 0x48, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x2c, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x51, 0x75, - 0x6f, 0x74, 0x61, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x92, 0x02, 0x0a, 0x07, 0x41, 0x50, - 0x49, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x5e, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, - 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, - 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x41, 0x50, 0x49, 0x49, 0x6e, 0x66, - 0x6f, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x49, 0x44, 0x12, 0x24, 0x0a, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x41, 0x50, 0x49, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x45, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x50, 0x49, 0x49, 0x44, 0x1a, 0x41, 0x0a, 0x13, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf2, - 0x01, 0x0a, 0x07, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x52, 0x0a, 0x0a, 0x41, 0x70, - 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, - 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, - 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x49, 0x6e, - 0x66, 0x6f, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x0a, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x41, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x41, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x70, 0x70, 0x49, - 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x41, 0x70, 0x70, 0x49, 0x44, 0x12, 0x24, - 0x0a, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x49, 0x44, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, - 0x70, 0x70, 0x49, 0x44, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, - 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0xbf, 0x01, 0x0a, 0x09, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x3c, 0x0a, 0x07, 0x61, 0x70, 0x69, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x41, - 0x50, 0x49, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x61, 0x70, 0x69, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x3c, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x41, 0x70, 0x70, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x61, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x36, 0x0a, - 0x05, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, - 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, - 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x05, - 0x71, 0x75, 0x6f, 0x74, 0x61, 0x22, 0x30, 0x0a, 0x18, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x45, 0x6e, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x65, 0x0a, 0x14, 0x41, 0x50, 0x49, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1a, 0x0a, 0x16, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x50, 0x49, 0x49, 0x44, 0x10, 0x03, 0x2a, 0x5d, - 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x13, 0x0a, 0x0f, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x41, 0x70, 0x70, 0x4c, 0x6f, 0x6f, 0x6b, - 0x75, 0x70, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x41, - 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x64, 0x41, 0x70, 0x70, 0x49, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x49, 0x44, 0x10, 0x03, 0x2a, 0x7e, 0x0a, - 0x11, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, - 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x41, 0x6e, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x10, - 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x6f, 0x6e, - 0x74, 0x68, 0x6c, 0x79, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, - 0x61, 0x6c, 0x57, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x10, 0x04, 0x32, 0x86, 0x01, - 0x0a, 0x16, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, - 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x0f, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x2c, 0x2e, 0x61, 0x6d, - 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, - 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x1a, 0x27, 0x2e, 0x61, 0x6d, 0x70, 0x6c, - 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x22, 0x00, 0x30, 0x01, 0x32, 0x87, 0x01, 0x0a, 0x10, 0x51, 0x75, 0x6f, 0x74, 0x61, - 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x73, 0x0a, 0x14, 0x51, - 0x75, 0x6f, 0x74, 0x61, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x2e, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, - 0x51, 0x75, 0x6f, 0x74, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x33, 0x2e, 0x61, 0x6d, 0x70, 0x6c, - 0x69, 0x66, 0x79, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x75, 0x6e, 0x69, 0x74, 0x73, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x45, 0x6e, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x42, 0x1f, 0x5a, 0x1d, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x66, 0x79, 0x2f, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x74, - 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +const file_customunits_customunits_proto_rawDesc = "" + + "\n" + + "\x1dcustomunits/customunits.proto\x12\x19amplify.agent.customunits\"\x97\x01\n" + + "\x10APIServiceLookup\x12C\n" + + "\x04type\x18\x01 \x01(\x0e2/.amplify.agent.customunits.APIServiceLookupTypeR\x04type\x12(\n" + + "\x0fcustomAttribute\x18\x02 \x01(\tR\x0fcustomAttribute\x12\x14\n" + + "\x05value\x18\x03 \x01(\tR\x05value\"\x89\x01\n" + + "\tAppLookup\x12<\n" + + "\x04type\x18\x01 \x01(\x0e2(.amplify.agent.customunits.AppLookupTypeR\x04type\x12(\n" + + "\x0fcustomAttribute\x18\x02 \x01(\tR\x0fcustomAttribute\x12\x14\n" + + "\x05value\x18\x03 \x01(\tR\x05value\"(\n" + + "\n" + + "UnitLookup\x12\x1a\n" + + "\bunitName\x18\x01 \x01(\tR\bunitName\"\xfa\x01\n" + + "\fMetricReport\x12\x14\n" + + "\x05count\x18\x01 \x01(\x03R\x05count\x12K\n" + + "\n" + + "apiService\x18\x02 \x01(\v2+.amplify.agent.customunits.APIServiceLookupR\n" + + "apiService\x12D\n" + + "\n" + + "managedApp\x18\x03 \x01(\v2$.amplify.agent.customunits.AppLookupR\n" + + "managedApp\x12A\n" + + "\bplanUnit\x18\x04 \x01(\v2%.amplify.agent.customunits.UnitLookupR\bplanUnit\"\x13\n" + + "\x11MetricServiceInit\"{\n" + + "\x05Quota\x12\x14\n" + + "\x05count\x18\x01 \x01(\x03R\x05count\x12\x12\n" + + "\x04unit\x18\x02 \x01(\tR\x04unit\x12H\n" + + "\binterval\x18\x03 \x01(\x0e2,.amplify.agent.customunits.QuotaIntervalTypeR\binterval\"\x92\x02\n" + + "\aAPIInfo\x12^\n" + + "\x0eServiceDetails\x18\x01 \x03(\v26.amplify.agent.customunits.APIInfo.ServiceDetailsEntryR\x0eServiceDetails\x12 \n" + + "\vServiceName\x18\x02 \x01(\tR\vServiceName\x12\x1c\n" + + "\tServiceID\x18\x03 \x01(\tR\tServiceID\x12$\n" + + "\rExternalAPIID\x18\x04 \x01(\tR\rExternalAPIID\x1aA\n" + + "\x13ServiceDetailsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xf2\x01\n" + + "\aAppInfo\x12R\n" + + "\n" + + "AppDetails\x18\x01 \x03(\v22.amplify.agent.customunits.AppInfo.AppDetailsEntryR\n" + + "AppDetails\x12\x18\n" + + "\aAppName\x18\x02 \x01(\tR\aAppName\x12\x14\n" + + "\x05AppID\x18\x03 \x01(\tR\x05AppID\x12$\n" + + "\rExternalAppID\x18\x04 \x01(\tR\rExternalAppID\x1a=\n" + + "\x0fAppDetailsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xbf\x01\n" + + "\tQuotaInfo\x12<\n" + + "\aapiInfo\x18\x01 \x01(\v2\".amplify.agent.customunits.APIInfoR\aapiInfo\x12<\n" + + "\aappInfo\x18\x02 \x01(\v2\".amplify.agent.customunits.AppInfoR\aappInfo\x126\n" + + "\x05quota\x18\x03 \x01(\v2 .amplify.agent.customunits.QuotaR\x05quota\"0\n" + + "\x18QuotaEnforcementResponse\x12\x14\n" + + "\x05error\x18\x01 \x01(\tR\x05error*e\n" + + "\x14APIServiceLookupType\x12\x1a\n" + + "\x16CustomAPIServiceLookup\x10\x00\x12\x0f\n" + + "\vServiceName\x10\x01\x12\r\n" + + "\tServiceID\x10\x02\x12\x11\n" + + "\rExternalAPIID\x10\x03*]\n" + + "\rAppLookupType\x12\x13\n" + + "\x0fCustomAppLookup\x10\x00\x12\x12\n" + + "\x0eManagedAppName\x10\x01\x12\x10\n" + + "\fManagedAppID\x10\x02\x12\x11\n" + + "\rExternalAppID\x10\x03*~\n" + + "\x11QuotaIntervalType\x12\x17\n" + + "\x13IntervalUnspecified\x10\x00\x12\x14\n" + + "\x10IntervalAnnually\x10\x01\x12\x13\n" + + "\x0fIntervalMonthly\x10\x02\x12\x12\n" + + "\x0eIntervalWeekly\x10\x03\x12\x11\n" + + "\rIntervalDaily\x10\x042\x86\x01\n" + + "\x16MetricReportingService\x12l\n" + + "\x0fMetricReporting\x12,.amplify.agent.customunits.MetricServiceInit\x1a'.amplify.agent.customunits.MetricReport\"\x000\x012\x87\x01\n" + + "\x10QuotaEnforcement\x12s\n" + + "\x14QuotaEnforcementInfo\x12$.amplify.agent.customunits.QuotaInfo\x1a3.amplify.agent.customunits.QuotaEnforcementResponse\"\x00B\x1fZ\x1dpkg/amplify/agent/customunitsb\x06proto3" var ( file_customunits_customunits_proto_rawDescOnce sync.Once - file_customunits_customunits_proto_rawDescData = file_customunits_customunits_proto_rawDesc + file_customunits_customunits_proto_rawDescData []byte ) func file_customunits_customunits_proto_rawDescGZIP() []byte { file_customunits_customunits_proto_rawDescOnce.Do(func() { - file_customunits_customunits_proto_rawDescData = protoimpl.X.CompressGZIP(file_customunits_customunits_proto_rawDescData) + file_customunits_customunits_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_customunits_customunits_proto_rawDesc), len(file_customunits_customunits_proto_rawDesc))) }) return file_customunits_customunits_proto_rawDescData } @@ -989,133 +893,11 @@ func file_customunits_customunits_proto_init() { if File_customunits_customunits_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_customunits_customunits_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*APIServiceLookup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*AppLookup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*UnitLookup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*MetricReport); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*MetricServiceInit); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*Quota); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*APIInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*AppInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*QuotaInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_customunits_customunits_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*QuotaEnforcementResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_customunits_customunits_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_customunits_customunits_proto_rawDesc), len(file_customunits_customunits_proto_rawDesc)), NumEnums: 3, NumMessages: 12, NumExtensions: 0, @@ -1127,7 +909,6 @@ func file_customunits_customunits_proto_init() { MessageInfos: file_customunits_customunits_proto_msgTypes, }.Build() File_customunits_customunits_proto = out.File - file_customunits_customunits_proto_rawDesc = nil file_customunits_customunits_proto_goTypes = nil file_customunits_customunits_proto_depIdxs = nil } diff --git a/pkg/amplify/agent/customunits/customunits_grpc.pb.go b/pkg/amplify/agent/customunits/customunits_grpc.pb.go index 3e725b8dc..955a4ce2c 100644 --- a/pkg/amplify/agent/customunits/customunits_grpc.pb.go +++ b/pkg/amplify/agent/customunits/customunits_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 -// - protoc v4.24.4 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.31.1 // source: customunits/customunits.proto package customunits @@ -15,8 +15,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( MetricReportingService_MetricReporting_FullMethodName = "/amplify.agent.customunits.MetricReportingService/MetricReporting" @@ -27,7 +27,7 @@ const ( // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type MetricReportingServiceClient interface { // The agent will initiate the connection to the service and the service can then begin to send metric data for the SDK to handle - MetricReporting(ctx context.Context, in *MetricServiceInit, opts ...grpc.CallOption) (MetricReportingService_MetricReportingClient, error) + MetricReporting(ctx context.Context, in *MetricServiceInit, opts ...grpc.CallOption) (grpc.ServerStreamingClient[MetricReport], error) } type metricReportingServiceClient struct { @@ -38,13 +38,13 @@ func NewMetricReportingServiceClient(cc grpc.ClientConnInterface) MetricReportin return &metricReportingServiceClient{cc} } -func (c *metricReportingServiceClient) MetricReporting(ctx context.Context, in *MetricServiceInit, opts ...grpc.CallOption) (MetricReportingService_MetricReportingClient, error) { +func (c *metricReportingServiceClient) MetricReporting(ctx context.Context, in *MetricServiceInit, opts ...grpc.CallOption) (grpc.ServerStreamingClient[MetricReport], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &MetricReportingService_ServiceDesc.Streams[0], MetricReportingService_MetricReporting_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &metricReportingServiceMetricReportingClient{ClientStream: stream} + x := &grpc.GenericClientStream[MetricServiceInit, MetricReport]{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -54,41 +54,31 @@ func (c *metricReportingServiceClient) MetricReporting(ctx context.Context, in * return x, nil } -type MetricReportingService_MetricReportingClient interface { - Recv() (*MetricReport, error) - grpc.ClientStream -} - -type metricReportingServiceMetricReportingClient struct { - grpc.ClientStream -} - -func (x *metricReportingServiceMetricReportingClient) Recv() (*MetricReport, error) { - m := new(MetricReport) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type MetricReportingService_MetricReportingClient = grpc.ServerStreamingClient[MetricReport] // MetricReportingServiceServer is the server API for MetricReportingService service. // All implementations must embed UnimplementedMetricReportingServiceServer -// for forward compatibility +// for forward compatibility. type MetricReportingServiceServer interface { // The agent will initiate the connection to the service and the service can then begin to send metric data for the SDK to handle - MetricReporting(*MetricServiceInit, MetricReportingService_MetricReportingServer) error + MetricReporting(*MetricServiceInit, grpc.ServerStreamingServer[MetricReport]) error mustEmbedUnimplementedMetricReportingServiceServer() } -// UnimplementedMetricReportingServiceServer must be embedded to have forward compatible implementations. -type UnimplementedMetricReportingServiceServer struct { -} +// UnimplementedMetricReportingServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedMetricReportingServiceServer struct{} -func (UnimplementedMetricReportingServiceServer) MetricReporting(*MetricServiceInit, MetricReportingService_MetricReportingServer) error { - return status.Errorf(codes.Unimplemented, "method MetricReporting not implemented") +func (UnimplementedMetricReportingServiceServer) MetricReporting(*MetricServiceInit, grpc.ServerStreamingServer[MetricReport]) error { + return status.Error(codes.Unimplemented, "method MetricReporting not implemented") } func (UnimplementedMetricReportingServiceServer) mustEmbedUnimplementedMetricReportingServiceServer() { } +func (UnimplementedMetricReportingServiceServer) testEmbeddedByValue() {} // UnsafeMetricReportingServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to MetricReportingServiceServer will @@ -98,6 +88,13 @@ type UnsafeMetricReportingServiceServer interface { } func RegisterMetricReportingServiceServer(s grpc.ServiceRegistrar, srv MetricReportingServiceServer) { + // If the following call panics, it indicates UnimplementedMetricReportingServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&MetricReportingService_ServiceDesc, srv) } @@ -106,21 +103,11 @@ func _MetricReportingService_MetricReporting_Handler(srv interface{}, stream grp if err := stream.RecvMsg(m); err != nil { return err } - return srv.(MetricReportingServiceServer).MetricReporting(m, &metricReportingServiceMetricReportingServer{ServerStream: stream}) + return srv.(MetricReportingServiceServer).MetricReporting(m, &grpc.GenericServerStream[MetricServiceInit, MetricReport]{ServerStream: stream}) } -type MetricReportingService_MetricReportingServer interface { - Send(*MetricReport) error - grpc.ServerStream -} - -type metricReportingServiceMetricReportingServer struct { - grpc.ServerStream -} - -func (x *metricReportingServiceMetricReportingServer) Send(m *MetricReport) error { - return x.ServerStream.SendMsg(m) -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type MetricReportingService_MetricReportingServer = grpc.ServerStreamingServer[MetricReport] // MetricReportingService_ServiceDesc is the grpc.ServiceDesc for MetricReportingService service. // It's only intended for direct use with grpc.RegisterService, @@ -171,21 +158,25 @@ func (c *quotaEnforcementClient) QuotaEnforcementInfo(ctx context.Context, in *Q // QuotaEnforcementServer is the server API for QuotaEnforcement service. // All implementations must embed UnimplementedQuotaEnforcementServer -// for forward compatibility +// for forward compatibility. type QuotaEnforcementServer interface { // The discovery agent will reach out, if configured, to allow the external service to provision any quota enforcement or access it may need to QuotaEnforcementInfo(context.Context, *QuotaInfo) (*QuotaEnforcementResponse, error) mustEmbedUnimplementedQuotaEnforcementServer() } -// UnimplementedQuotaEnforcementServer must be embedded to have forward compatible implementations. -type UnimplementedQuotaEnforcementServer struct { -} +// UnimplementedQuotaEnforcementServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedQuotaEnforcementServer struct{} func (UnimplementedQuotaEnforcementServer) QuotaEnforcementInfo(context.Context, *QuotaInfo) (*QuotaEnforcementResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QuotaEnforcementInfo not implemented") + return nil, status.Error(codes.Unimplemented, "method QuotaEnforcementInfo not implemented") } func (UnimplementedQuotaEnforcementServer) mustEmbedUnimplementedQuotaEnforcementServer() {} +func (UnimplementedQuotaEnforcementServer) testEmbeddedByValue() {} // UnsafeQuotaEnforcementServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to QuotaEnforcementServer will @@ -195,6 +186,13 @@ type UnsafeQuotaEnforcementServer interface { } func RegisterQuotaEnforcementServer(s grpc.ServiceRegistrar, srv QuotaEnforcementServer) { + // If the following call panics, it indicates UnimplementedQuotaEnforcementServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&QuotaEnforcement_ServiceDesc, srv) } diff --git a/pkg/apic/apiserver/models/management/v1alpha1/model_dataplane_spec_aws_agent_core.go b/pkg/apic/apiserver/models/management/v1alpha1/model_dataplane_spec_aws_agent_core.go index ec13401c7..610605be1 100644 --- a/pkg/apic/apiserver/models/management/v1alpha1/model_dataplane_spec_aws_agent_core.go +++ b/pkg/apic/apiserver/models/management/v1alpha1/model_dataplane_spec_aws_agent_core.go @@ -11,8 +11,6 @@ package management // DataplaneSpecAwsAgentCore Configuration specific to the agentcore-gateway mode. type DataplaneSpecAwsAgentCore struct { - // Number of items per page when listing agentcore resources. - PageSize int32 `json:"pageSize,omitempty"` // Log group prefix for agentcore-gateway vendored logs. LogGroupPrefix string `json:"logGroupPrefix,omitempty"` // If true, IAM authentication is enabled for agentcore-gateway requests. diff --git a/pkg/apic/apiservice_test.go b/pkg/apic/apiservice_test.go index 8bdc0c76f..9bb2c3b6b 100644 --- a/pkg/apic/apiservice_test.go +++ b/pkg/apic/apiservice_test.go @@ -350,29 +350,128 @@ func Test_PublishServiceError(t *testing.T) { func Test_processRevision(t *testing.T) { client, httpClient := GetTestServiceClient() - // tests for updating existing revision - httpClient.SetResponses([]api.MockResponse{ - { - FileName: "./testdata/servicerevision.json", // for call to update the serviceRevision - RespCode: http.StatusOK, + testCases := map[string]struct { + skip bool + httpResponses []api.MockResponse + serviceBody ServiceBody + expectedRevName string + }{ + "publish new revision": { + httpResponses: []api.MockResponse{ + { + FileName: "./testdata/servicerevision.json", // for call to update the serviceRevision + RespCode: http.StatusOK, + }, + { + FileName: "./testdata/servicerevision.json", // for call to update the serviceRevision x-agent-details + RespCode: http.StatusOK, + }, + { + FileName: "./testdata/servicerevision.json", // for call to update the serviceRevision + RespCode: http.StatusOK, + }, + { + FileName: "./testdata/servicerevision.json", // for call to update the serviceRevision x-agent-details + RespCode: http.StatusOK, + }, + }, + serviceBody: ServiceBody{ + APIName: "daleapi", + Documentation: []byte("\"docs\""), + Image: "abcde", + ImageContentType: "image/jpeg", + ResourceType: Oas2, + RestAPIID: "12345", + }, + expectedRevName: "daleapi", }, - { - FileName: "./testdata/servicerevision.json", // for call to update the serviceRevision x-agent-details - RespCode: http.StatusOK, + "skip publish when no changes": { + httpResponses: []api.MockResponse{ + { + RespData: `[{"name": "daleapi","tags": ["tag1","tag2"]}]`, + RespCode: http.StatusOK, + }, + }, + serviceBody: ServiceBody{ + APIName: "daleapi", + Documentation: []byte("\"docs\""), + Image: "abcde", + ImageContentType: "image/jpeg", + ResourceType: Oas2, + RestAPIID: "12345", + specHash: "abc123", + specHashes: map[string]interface{}{ + "abc123": "daleapi", + }, + serviceContext: serviceContext{ + serviceAction: updateAPI, + }, + }, + expectedRevName: "daleapi", }, - { - FileName: "./testdata/servicerevision.json", // for call to update the serviceRevision - RespCode: http.StatusOK, + "skip publish when previous revision found": { + httpResponses: []api.MockResponse{ + { + RespData: `[{"name": "daleapi","tags": ["tag1","tag2"]},{"name": "daleapi-1","tags": ["tag1","tag2"]}]`, + RespCode: http.StatusOK, + }, + }, + serviceBody: ServiceBody{ + APIName: "daleapi", + Documentation: []byte("\"docs\""), + Image: "abcde", + ImageContentType: "image/jpeg", + ResourceType: Oas2, + RestAPIID: "12345", + specHash: "abc123", + specHashes: map[string]interface{}{ + "abc123": "daleapi-1", + }, + serviceContext: serviceContext{ + serviceAction: updateAPI, + }, + }, + expectedRevName: "daleapi-1", }, - { - FileName: "./testdata/servicerevision.json", // for call to update the serviceRevision x-agent-details - RespCode: http.StatusOK, + "find revision match using original spec hash": { + httpResponses: []api.MockResponse{ + { + RespData: `[{"name": "daleapi","tags": ["tag1","tag2"]},{"name": "daleapi-1","tags": ["tag1","tag2"]}]`, + RespCode: http.StatusOK, + }, + }, + serviceBody: ServiceBody{ + APIName: "daleapi", + Documentation: []byte("\"docs\""), + Image: "abcde", + ImageContentType: "image/jpeg", + ResourceType: Oas2, + RestAPIID: "12345", + specHash: "abc1234", + originalSpecHash: "abc123", + specHashes: map[string]interface{}{ + "abc123": "daleapi-1", + }, + serviceContext: serviceContext{ + serviceAction: updateAPI, + }, + }, + expectedRevName: "daleapi-1", }, - }) - cloneServiceBody := serviceBody - // Normal Revision - client.processRevision(&cloneServiceBody) - assert.NotEqual(t, "", cloneServiceBody.serviceContext.revisionName) + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + if tc.skip { + return + } + // tests for updating existing revision + httpClient.SetResponses(tc.httpResponses) + + client.processRevision(&tc.serviceBody) + assert.NotEqual(t, "", tc.serviceBody.serviceContext.revisionName) + assert.Equal(t, tc.expectedRevName, tc.serviceBody.serviceContext.revisionName) + }) + } } func TestDeleteServiceByAPIID(t *testing.T) { diff --git a/pkg/apic/apiserviceinstance.go b/pkg/apic/apiserviceinstance.go index 6e7993be2..85a264c5f 100644 --- a/pkg/apic/apiserviceinstance.go +++ b/pkg/apic/apiserviceinstance.go @@ -43,6 +43,8 @@ func (c *ServiceClient) checkCredentialRequestDefinitions(serviceBody *ServiceBo for _, crd := range crds { if def, err := c.caches.GetCredentialRequestDefinitionByName(crd); err == nil && def != nil { knownCRDs = append(knownCRDs, crd) + } else { + log.Warnf("credential request definition %s for API %s not found in cache, skipping", crd, serviceBody.APIName) } } } else { diff --git a/pkg/apic/apiservicerevision.go b/pkg/apic/apiservicerevision.go index e6af85c26..235ca4c9d 100644 --- a/pkg/apic/apiservicerevision.go +++ b/pkg/apic/apiservicerevision.go @@ -7,9 +7,7 @@ import ( "errors" "fmt" "net/http" - "reflect" "regexp" - "sort" "strconv" "strings" "text/template" @@ -165,7 +163,15 @@ func (c *ServiceClient) getRevisionsIfUpdating(serviceBody *ServiceBody) ([]*man // checkAndUpdateExistingRevision checks if a revision with the same hash exists and updates tags if needed func (c *ServiceClient) checkAndUpdateExistingRevision(serviceBody *ServiceBody, apiServiceRevisions []*management.APIServiceRevision) (bool, error) { + // attempt to use the stripped spec hash revName, found := serviceBody.specHashes[serviceBody.specHash] + if !found && serviceBody.originalSpecHash != "" { + // check if the original spec hash matches an existing revision, + // this is to cover the case where the spec content has not changed since the last publish, + // but the hash has changed due to non-content related changes (e.g. stripping servers) + revName, found = serviceBody.specHashes[serviceBody.originalSpecHash] + } + if !found { return false, nil } @@ -205,24 +211,13 @@ func (c *ServiceClient) checkAndUpdateExistingRevision(serviceBody *ServiceBody, // different, return the updated tags func (c *ServiceClient) getUpdatedTagKeys(serviceBodyTags map[string]interface{}, revisionTags []string) []string { // Extract values from map and convert to []string - var mapValues []string - for _, v := range serviceBodyTags { - if strVal, ok := v.(string); ok { - mapValues = append(mapValues, strVal) - } - } - - // Sort both slices to allow unordered comparison - sort.Strings(mapValues) - sort.Strings(revisionTags) + tags := mapToTagsArray(serviceBodyTags, c.cfg.GetTagsToPublish()) // Compare - if reflect.DeepEqual(mapValues, revisionTags) { + if util.StringSlicesEqualUnordered(tags, revisionTags) { return []string{} // return empty string slice if equal } - // If not equal, return the keys from serviceBodyTags - tags := mapToTagsArray(serviceBodyTags, c.cfg.GetTagsToPublish()) return tags } diff --git a/pkg/apic/client.go b/pkg/apic/client.go index 3507d38ce..0066fb07b 100644 --- a/pkg/apic/client.go +++ b/pkg/apic/client.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "net/http" - "slices" "strconv" "strings" "sync" @@ -662,6 +661,8 @@ func (c *ServiceClient) ExecuteAPIWithHeader(method, url string, query map[strin return response.Body, nil case response.Code == http.StatusUnauthorized: return nil, ErrAuthentication + case response.Code == http.StatusConflict: + return nil, ErrConflict default: responseErr := readResponseErrors(response.Code, response.Body) return nil, errors.Wrap(ErrRequestQuery, responseErr) @@ -868,7 +869,7 @@ func (c *ServiceClient) updateSpecORCreateResourceInstance(data *apiv1.ResourceI method = coreapi.PUT // check if either hash, tags or title have changed and mark for update - equalTags := slices.Equal(existingRI.GetTags(), data.GetTags()) + equalTags := util.StringSlicesEqualUnordered(existingRI.GetTags(), data.GetTags()) oldHash, _ := util.GetAgentDetailsValue(existingRI, defs.AttrSpecHash) newHash, _ := util.GetAgentDetailsValue(data, defs.AttrSpecHash) if oldHash == newHash && existingRI.Title == data.Title && equalTags { @@ -915,14 +916,25 @@ func (c *ServiceClient) updateSpecORCreateResourceInstance(data *apiv1.ResourceI return nil, err } - response, err := c.ExecuteAPI(method, url, nil, reqBytes) - if err != nil { + respBytes, err := c.ExecuteAPIWithHeader(method, url, nil, reqBytes, nil) + switch { + case err == ErrConflict && method == coreapi.POST: + // Resource exists on server but not in cache; fetch and cache it. + log.Warnf("resource %s %s already exists on the server but was not in the local cache, fetching existing resource", data.Kind, data.Name) + fetchedRI, fetchErr := c.GetResource(data.GetSelfLink()) + if fetchErr != nil { + return nil, fetchErr + } + c.addResourceToCache(fetchedRI) + newRI = fetchedRI + case err != nil: return nil, err } - err = json.Unmarshal(response, newRI) - if err != nil { - return nil, err + if newRI.Name == "" { + if err = json.Unmarshal(respBytes, newRI); err != nil { + return nil, err + } } } else { newRI = existingRI diff --git a/pkg/apic/client_test.go b/pkg/apic/client_test.go index c99c2118e..03b901e4f 100644 --- a/pkg/apic/client_test.go +++ b/pkg/apic/client_test.go @@ -232,95 +232,109 @@ func TestCreateSubResource(t *testing.T) { } func TestUpdateSpecORCreateResourceInstance(t *testing.T) { - tests := []struct { - name string + tests := map[string]struct { gvk apiv1.GroupVersionKind + resourceName string oldHash string newHash string + skipCache bool apiResponses []api.MockResponse expectedAttrVal string expectErr bool + expectCached bool }{ - { - name: "should error with bad response from api call", + "should error with bad response from api call": { gvk: management.AccessRequestDefinitionGVK(), oldHash: "1234", newHash: "1235", apiResponses: []api.MockResponse{ - { - RespCode: http.StatusUnauthorized, - }, + {RespCode: http.StatusUnauthorized}, }, - expectedAttrVal: "existing", - expectErr: true, + expectErr: true, }, - { - name: "should not update ARD as hash is unchanged", + "should not update ARD as hash is unchanged": { gvk: management.AccessRequestDefinitionGVK(), oldHash: "1234", newHash: "1234", apiResponses: []api.MockResponse{}, expectedAttrVal: "existing", - expectErr: false, }, - { - name: "should not update CRD as hash is unchanged", + "should not update CRD as hash is unchanged": { gvk: management.CredentialRequestDefinitionGVK(), oldHash: "1234", newHash: "1234", apiResponses: []api.MockResponse{}, expectedAttrVal: "existing", - expectErr: false, }, - { - name: "should update ARD as hash has changed", + "should update ARD as hash has changed": { gvk: management.AccessRequestDefinitionGVK(), oldHash: "1234", newHash: "5234", apiResponses: []api.MockResponse{ - { - FileName: "./testdata/apiservice.json", - RespCode: http.StatusOK, - }, - { - FileName: "./testdata/apiservice.json", - RespCode: http.StatusOK, - }, + {FileName: "./testdata/apiservice.json", RespCode: http.StatusOK}, + {FileName: "./testdata/apiservice.json", RespCode: http.StatusOK}, }, - expectErr: false, }, - { - name: "should update CRD as hash has changed", + "should update CRD as hash has changed": { gvk: management.CredentialRequestDefinitionGVK(), oldHash: "1234", newHash: "5234", apiResponses: []api.MockResponse{ - { - FileName: "./testdata/apiservice.json", - RespCode: http.StatusOK, - }, - { - FileName: "./testdata/apiservice.json", - RespCode: http.StatusOK, - }, + {FileName: "./testdata/apiservice.json", RespCode: http.StatusOK}, + {FileName: "./testdata/apiservice.json", RespCode: http.StatusOK}, }, - expectErr: false, + }, + "should recover from 409 conflict by fetching existing resource": { + gvk: management.CredentialRequestDefinitionGVK(), + resourceName: "oauth-secret", + oldHash: "1234", + newHash: "1234", + skipCache: true, + apiResponses: []api.MockResponse{ + {RespCode: http.StatusConflict}, + {FileName: "./testdata/credentialrequestdefinition.json", RespCode: http.StatusOK}, + {FileName: "./testdata/credentialrequestdefinition.json", RespCode: http.StatusOK}, + }, + expectCached: true, + }, + "should return error when 409 recovery GET fails": { + gvk: management.CredentialRequestDefinitionGVK(), + resourceName: "oauth-secret", + oldHash: "1234", + newHash: "1234", + skipCache: true, + apiResponses: []api.MockResponse{ + {RespCode: http.StatusConflict}, + {RespCode: http.StatusInternalServerError}, + }, + expectErr: true, }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { + + for name, tt := range tests { + t.Run(name, func(t *testing.T) { svcClient, mockHTTPClient := GetTestServiceClient() cfg := GetTestServiceClientCentralConfiguration(svcClient) cfg.Environment = "mockenv" cfg.PlatformURL = "http://foo.bar:4080" - // There should be one request for each sub resource of the ResourceInstance mockHTTPClient.SetResponses(tt.apiResponses) + resName := tt.resourceName + if resName == "" { + resName = name + } + res := apiv1.ResourceInstance{ ResourceMeta: apiv1.ResourceMeta{ - Name: tt.name, + Name: resName, GroupVersionKind: tt.gvk, + Metadata: apiv1.Metadata{ + Scope: apiv1.MetadataScope{ + Kind: management.EnvironmentGVK().Kind, + Name: "mockenv", + }, + }, SubResources: map[string]interface{}{ defs.XAgentDetails: map[string]interface{}{ defs.AttrSpecHash: tt.oldHash, @@ -331,12 +345,13 @@ func TestUpdateSpecORCreateResourceInstance(t *testing.T) { Spec: map[string]interface{}{}, } - // setup the cachedResources - switch tt.gvk.Kind { - case management.AccessRequestDefinitionGVK().Kind: - svcClient.caches.AddAccessRequestDefinition(&res) - case management.CredentialRequestDefinitionGVK().Kind: - svcClient.caches.AddCredentialRequestDefinition(&res) + if !tt.skipCache { + switch tt.gvk.Kind { + case management.AccessRequestDefinitionGVK().Kind: + svcClient.caches.AddAccessRequestDefinition(&res) + case management.CredentialRequestDefinitionGVK().Kind: + svcClient.caches.AddCredentialRequestDefinition(&res) + } } newRes := res @@ -346,11 +361,23 @@ func TestUpdateSpecORCreateResourceInstance(t *testing.T) { ri, err := svcClient.updateSpecORCreateResourceInstance(&newRes) if tt.expectErr { assert.NotNil(t, err) - } else { - assert.Nil(t, err) + return + } + + assert.Nil(t, err) + assert.NotNil(t, ri) + + if tt.expectedAttrVal != "" { assert.Equal(t, tt.expectedAttrVal, ri.Attributes["existing"]) } + if tt.expectCached { + cached, cacheErr := svcClient.caches.GetCredentialRequestDefinitionByName(ri.Name) + assert.Nil(t, cacheErr) + assert.NotNil(t, cached) + // Verify the cached entry is the fetched resource, not the original local one. + assert.Equal(t, ri.Metadata.ID, cached.Metadata.ID) + } }) } } diff --git a/pkg/apic/errors.go b/pkg/apic/errors.go index 33c6725f5..dd45fae60 100644 --- a/pkg/apic/errors.go +++ b/pkg/apic/errors.go @@ -11,6 +11,7 @@ var ( ErrRequestQuery = errors.New(1120, "error making a request to Amplify") ErrAuthenticationCall = errors.New(1130, "error getting authentication token. Check Amplify Central auth configuration (CENTRAL_AUTH_*) and network configuration for agent on docs.axway.com") ErrAuthentication = errors.New(1131, "authentication token was not valid. Check Amplify Central auth configuration (CENTRAL_AUTH_*)") + ErrConflict = errors.New(1132, "conflict: resource already exists on Amplify Central") ) // Errors hit when calling different Amplify APIs diff --git a/pkg/apic/servicebody.go b/pkg/apic/servicebody.go index 4e9bebf43..fa398b5bb 100644 --- a/pkg/apic/servicebody.go +++ b/pkg/apic/servicebody.go @@ -14,59 +14,61 @@ type APIKeyInfo struct { // ServiceBody - details about a service to create type ServiceBody struct { - NameToPush string - APIName string - RestAPIID string - PrimaryKey string - URL string - Stage string - StageDescriptor string - StageDisplayName string - Description string - Version string - AuthPolicy string - authPolicies []string - apiKeyInfo []APIKeyInfo - scopes map[string]string - SpecDefinition []byte - Documentation []byte - Tags map[string]interface{} - Image string - ImageContentType string - CreatedBy string - ResourceContentType string - ResourceType string - SubscriptionName string - APIUpdateSeverity string - State string - Status string - ServiceAttributes map[string]string - RevisionAttributes map[string]string - InstanceAttributes map[string]string - ServiceAgentDetails map[string]interface{} - InstanceAgentDetails map[string]interface{} - RevisionAgentDetails map[string]interface{} - serviceContext serviceContext - Endpoints []EndpointDefinition - UnstructuredProps *UnstructuredProperties - TeamName string - teamID string - credentialRequestPolicies []string - ardName string - uniqueARD bool - ignoreSpecBasesCreds bool - stripOASExtensions bool - specHash string - specVersion string - accessRequestDefinition *management.AccessRequestDefinition - specHashes map[string]interface{} // map of hash values to revision names - requestDefinitionsAllowed bool // used to validate if the instance can have request definitions or not. Use case example - v7 unpublished, remove request definitions - dataplaneType DataplaneType - isDesignDataplane bool - referencedServiceName string - referencedInstanceName string - logger log.FieldLogger - instanceLifecycle *management.ApiServiceInstanceLifecycle + NameToPush string + APIName string + RestAPIID string + PrimaryKey string + URL string + Stage string + StageDescriptor string + StageDisplayName string + Description string + Version string + AuthPolicy string + authPolicies []string + apiKeyInfo []APIKeyInfo + scopes map[string]string + SpecDefinition []byte + Documentation []byte + Tags map[string]interface{} + Image string + ImageContentType string + CreatedBy string + ResourceContentType string + ResourceType string + SubscriptionName string + APIUpdateSeverity string + State string + Status string + ServiceAttributes map[string]string + RevisionAttributes map[string]string + InstanceAttributes map[string]string + ServiceAgentDetails map[string]interface{} + InstanceAgentDetails map[string]interface{} + RevisionAgentDetails map[string]interface{} + serviceContext serviceContext + Endpoints []EndpointDefinition + UnstructuredProps *UnstructuredProperties + TeamName string + teamID string + credentialRequestPolicies []string + ardName string + uniqueARD bool + ignoreSpecBasesCreds bool + stripOASExtensions bool + stripOASServersBeforePublish bool + specHash string + specVersion string + accessRequestDefinition *management.AccessRequestDefinition + specHashes map[string]interface{} // map of hash values to revision names + requestDefinitionsAllowed bool // used to validate if the instance can have request definitions or not. Use case example - v7 unpublished, remove request definitions + dataplaneType DataplaneType + isDesignDataplane bool + referencedServiceName string + referencedInstanceName string + logger log.FieldLogger + instanceLifecycle *management.ApiServiceInstanceLifecycle + originalSpecHash string } // SetAccessRequestDefinitionName - set the name of the access request definition for this service body diff --git a/pkg/apic/servicebuilder.go b/pkg/apic/servicebuilder.go index 52d1abd81..c4bca3a8b 100644 --- a/pkg/apic/servicebuilder.go +++ b/pkg/apic/servicebuilder.go @@ -56,6 +56,7 @@ type ServiceBuilder interface { SetAccessRequestDefinitionName(accessRequestDefName string, isUnique bool) ServiceBuilder SetIgnoreSpecBasedCreds(ignore bool) ServiceBuilder SetStripOASExtensions(strip bool) ServiceBuilder + SetStripOASServersBeforePublish() ServiceBuilder SetUnstructuredType(assetType string) ServiceBuilder SetUnstructuredContentType(contentType string) ServiceBuilder @@ -379,6 +380,14 @@ func (b *serviceBodyBuilder) Build() (ServiceBody, error) { val.StripExtensions() } + if b.serviceBody.stripOASServersBeforePublish { + b.serviceBody.originalSpecHash = b.serviceBody.specHash + val.stripEndpoints() + b.serviceBody.SpecDefinition = val.GetSpecBytes() + newHash, _ := util.ComputeHash(val.GetSpecBytes()) + b.serviceBody.specHash = fmt.Sprintf("%v", newHash) + } + // only set ard name based on spec if not already set, use first auth we find if b.serviceBody.ardName != "" { return b.serviceBody, nil @@ -426,6 +435,11 @@ func (b *serviceBodyBuilder) SetIgnoreSpecBasedCreds(ignore bool) ServiceBuilder return b } +func (b *serviceBodyBuilder) SetStripOASServersBeforePublish() ServiceBuilder { + b.serviceBody.stripOASServersBeforePublish = true + return b +} + func (b *serviceBodyBuilder) SetStripOASExtensions(strip bool) ServiceBuilder { b.serviceBody.stripOASExtensions = strip return b diff --git a/pkg/apic/servicebuilder_test.go b/pkg/apic/servicebuilder_test.go index 93a081cde..6b73ea9f1 100644 --- a/pkg/apic/servicebuilder_test.go +++ b/pkg/apic/servicebuilder_test.go @@ -84,6 +84,7 @@ func TestServiceBodySetters(t *testing.T) { SetReferenceInstanceName("refInstance", "refEnv"). SetIgnoreSpecBasedCreds(true). SetStripOASExtensions(true). + SetStripOASServersBeforePublish(). SetInstanceLifecycle("stage", "active", ""). SetServiceEndpoints(ep) @@ -136,6 +137,7 @@ func TestServiceBodySetters(t *testing.T) { assert.Equal(t, "refEnv/refInstance", sb.GetReferenceInstanceName()) assert.Equal(t, true, sb.ignoreSpecBasesCreds) assert.Equal(t, true, sb.stripOASExtensions) + assert.Equal(t, true, sb.stripOASServersBeforePublish) instanceLifecycle := sb.GetInstanceLifeCycle() assert.NotNil(t, instanceLifecycle) assert.Equal(t, "stage", instanceLifecycle.Stage) @@ -222,7 +224,7 @@ func TestServiceBodyBuilderWithLargeSpec(t *testing.T) { "status": "active", } - sb, err = serviceBuilder. + serviceBuilder = serviceBuilder. SetDescription("A sample Petstore server based on OpenAPI 3.0"). SetAPIName("petstore"). SetAuthPolicy("pass-through"). @@ -230,8 +232,9 @@ func TestServiceBodyBuilderWithLargeSpec(t *testing.T) { SetState(PublishedState). SetServiceEndpoints(endpoints). SetTags(tags). - SetTeamName("pet-team"). - Build() + SetTeamName("pet-team") + + sb, err = serviceBuilder.Build() // Assertions assert.Nil(t, err) @@ -246,9 +249,17 @@ func TestServiceBodyBuilderWithLargeSpec(t *testing.T) { assert.Equal(t, endpoints, sb.Endpoints) assert.Equal(t, tags, sb.Tags) assert.NotEmpty(t, sb.SpecDefinition) + assert.Empty(t, sb.originalSpecHash) assert.Equal(t, Oas3, sb.ResourceType) // Verify spec size constraints assert.Less(t, len(sb.SpecDefinition), len(specBytes), "processed spec should be smaller than original") assert.Less(t, len(sb.SpecDefinition), tenMB, "spec should be under 10MB limit") + + sb, err = serviceBuilder. + SetStripOASServersBeforePublish(). + Build() + assert.Nil(t, err) + assert.NotNil(t, sb) + assert.NotEqual(t, sb.originalSpecHash, sb.specHash) } diff --git a/pkg/apic/specoas2processor.go b/pkg/apic/specoas2processor.go index 753d3d421..6e8553672 100644 --- a/pkg/apic/specoas2processor.go +++ b/pkg/apic/specoas2processor.go @@ -78,6 +78,13 @@ func (p *oas2SpecProcessor) GetEndpoints() ([]EndpointDefinition, error) { return endPoints, nil } +func (p *oas2SpecProcessor) stripEndpoints() { + // strip the endpoints from the spec, these will be added based on the API Service EndpointDefinitions + p.spec.BasePath = "" + p.spec.Host = "" + p.spec.Schemes = []string{} +} + func (p *oas2SpecProcessor) ParseAuthInfo() { authPolicies := []string{} keyInfo := []APIKeyInfo{} diff --git a/pkg/apic/specoas3processor.go b/pkg/apic/specoas3processor.go index f1dbd536d..a93b361f9 100644 --- a/pkg/apic/specoas3processor.go +++ b/pkg/apic/specoas3processor.go @@ -280,6 +280,11 @@ func (p *oas3SpecProcessor) StripExtensions() { } } +func (p *oas3SpecProcessor) stripEndpoints() { + // strip the endpoints from the spec, these will be added based on the API Service EndpointDefinitions + p.spec.Servers = []*openapi3.Server{} +} + func (p *oas3SpecProcessor) GetSpecBytes() []byte { s, _ := json.Marshal(p.spec) return s diff --git a/pkg/apic/specparser.go b/pkg/apic/specparser.go index 053d60c30..38e265538 100644 --- a/pkg/apic/specparser.go +++ b/pkg/apic/specparser.go @@ -57,6 +57,7 @@ type OasSpecProcessor interface { GetSpecBytes() []byte GetResourceType() string GetVersion() string + stripEndpoints() } // SpecResourceParser - diff --git a/pkg/apic/testdata/credentialrequestdefinition.json b/pkg/apic/testdata/credentialrequestdefinition.json new file mode 100644 index 000000000..3b446b8a1 --- /dev/null +++ b/pkg/apic/testdata/credentialrequestdefinition.json @@ -0,0 +1,16 @@ +{ + "group": "management", + "apiVersion": "v1alpha1", + "kind": "CredentialRequestDefinition", + "name": "oauth-secret", + "title": "OAuth Secret", + "metadata": { + "id": "crd-409-test-id", + "scope": { + "kind": "Environment", + "name": "mockenv" + } + }, + "attributes": {}, + "spec": {} +} diff --git a/pkg/jobs/channeljob.go b/pkg/jobs/channeljob.go index 7d282f77c..cbc2b6af4 100644 --- a/pkg/jobs/channeljob.go +++ b/pkg/jobs/channeljob.go @@ -43,7 +43,7 @@ func (b *channelJob) handleExecution() { b.setError(b.job.Execute()) if b.getError() != nil { b.setExecutionError() - b.baseJob.logger.Error(b.err.Load()) + b.baseJob.logger.Error(b.getError()) b.stop() // stop the job on error b.incrementConsecutiveFails() return diff --git a/pkg/jobs/intervaljob.go b/pkg/jobs/intervaljob.go index b98542728..3cd8a938e 100644 --- a/pkg/jobs/intervaljob.go +++ b/pkg/jobs/intervaljob.go @@ -86,13 +86,17 @@ func (b *intervalJob) stop() { return } b.stopLog() + b.setIsStopped(true) if b.IsReady() { b.logger.Tracef("writing to %s stop channel", b.GetName()) - b.stopChan <- true - b.logger.Tracef("wrote to %s stop channel", b.GetName()) + select { + case b.stopChan <- true: + b.logger.Tracef("wrote to %s stop channel", b.GetName()) + default: + b.logger.Tracef("stop channel for %s already has a pending signal", b.GetName()) + } b.UnsetIsReady() } else { b.stopReadyIfWaiting(0) } - b.setIsStopped(true) } diff --git a/pkg/jobs/jobs.go b/pkg/jobs/jobs.go index 5005c4eb4..67b82a51c 100644 --- a/pkg/jobs/jobs.go +++ b/pkg/jobs/jobs.go @@ -20,7 +20,7 @@ func UpdateDurations(retryInterval time.Duration, executionTimeout time.Duration durationsMutex.Lock() defer durationsMutex.Unlock() executionTimeLimit = executionTimeout - globalPool.setBackoff(newBackoffTimeout(retryInterval, 10*time.Minute, 2)) + globalPool.backoff.Store(newBackoffTimeout(retryInterval, 10*time.Minute, 2)) statusCheckInterval = retryInterval } diff --git a/pkg/jobs/pool.go b/pkg/jobs/pool.go index 83738d3bf..fa90f966b 100644 --- a/pkg/jobs/pool.go +++ b/pkg/jobs/pool.go @@ -3,6 +3,7 @@ package jobs import ( "context" "sync" + "sync/atomic" "time" "github.com/Axway/agent-sdk/pkg/util/log" @@ -10,24 +11,20 @@ import ( // Pool - represents a pool of jobs that are related in such a way that when one is not running none of them should be type Pool struct { + logger log.FieldLogger jobs map[string]JobExecution // All jobs that are in this pool cronJobs map[string]JobExecution // Jobs that run continuously, not just ran once detachedCronJobs map[string]JobExecution // Jobs that run continuously, not just ran once, detached from all others - poolStatus PoolStatus // Holds the current status of the pool of jobs - failedJob string // Holds the ID of the job that is the reason for a non-running status + poolStatus atomic.Value // Holds the current status of the pool of jobs + failedJob atomic.Value // Holds the ID of the job that is the reason for a non-running status jobsMapLock sync.Mutex cronJobsMapLock sync.Mutex detachedCronJobsMapLock sync.Mutex - poolStatusLock sync.Mutex - backoffLock sync.Mutex - failedJobLock sync.Mutex failJobChan chan string stopJobsChan chan bool - backoff *backoff - logger log.FieldLogger + backoff atomic.Pointer[backoff] startStopLock sync.Mutex - isStartStopping bool - isStartStopLock sync.Mutex + isStartStopping atomic.Bool } func newPool() *Pool { @@ -39,33 +36,23 @@ func newPool() *Pool { jobs: make(map[string]JobExecution), cronJobs: make(map[string]JobExecution), detachedCronJobs: make(map[string]JobExecution), - failedJob: "", + poolStatus: atomic.Value{}, + failedJob: atomic.Value{}, startStopLock: sync.Mutex{}, - isStartStopLock: sync.Mutex{}, + isStartStopping: atomic.Bool{}, failJobChan: make(chan string, 1), stopJobsChan: make(chan bool, 1), - backoff: newBackoffTimeout(defaultRetryInterval, 10*time.Minute, 2), + backoff: atomic.Pointer[backoff]{}, logger: logger, } - newPool.SetStatus(PoolStatusInitializing) + newPool.backoff.Store(newBackoffTimeout(defaultRetryInterval, 10*time.Minute, 2)) + newPool.failedJob.Store("") + newPool.isStartStopping.Store(false) + newPool.poolStatus.Store(PoolStatusInitializing) return &newPool } -// getBackoff - get the job backoff -func (p *Pool) getBackoff() *backoff { - p.backoffLock.Lock() - defer p.backoffLock.Unlock() - return p.backoff -} - -// setBackoff - set the job backoff -func (p *Pool) setBackoff(backoff *backoff) { - p.backoffLock.Lock() - defer p.backoffLock.Unlock() - p.backoff = backoff -} - // recordJob - Adds a job to the jobs map func (p *Pool) recordJob(job JobExecution) string { p.jobsMapLock.Lock() @@ -284,18 +271,6 @@ func (p *Pool) JobUnlock(id string) { p.jobs[id].Unlock() } -func (p *Pool) getFailedJob() string { - p.failedJobLock.Lock() - defer p.failedJobLock.Unlock() - return p.failedJob -} - -func (p *Pool) setFailedJob(job string) { - p.failedJobLock.Lock() - defer p.failedJobLock.Unlock() - p.failedJob = job -} - // GetJobStatus - Returns the Status of the Job based on the id func (p *Pool) GetJobStatus(id string) string { return p.jobs[id].GetStatus().String() @@ -303,16 +278,12 @@ func (p *Pool) GetJobStatus(id string) string { // GetStatus - returns the status of the pool of jobs func (p *Pool) GetStatus() string { - p.poolStatusLock.Lock() - defer p.poolStatusLock.Unlock() - return p.poolStatus.String() + return p.poolStatus.Load().(PoolStatus).String() } // SetStatus - Sets the status of the pool of jobs func (p *Pool) SetStatus(status PoolStatus) { - p.poolStatusLock.Lock() - defer p.poolStatusLock.Unlock() - p.poolStatus = status + p.poolStatus.Store(status) } // waits with timeout for the specified status in all cron jobs @@ -345,18 +316,6 @@ func (p *Pool) waitStartStop(jobStatus JobStatus) bool { } } -func (p *Pool) setIsStartStop(isStartStop bool) { - p.isStartStopLock.Lock() - defer p.isStartStopLock.Unlock() - p.isStartStopping = isStartStop -} - -func (p *Pool) getIsStartStop() bool { - p.isStartStopLock.Lock() - defer p.isStartStopLock.Unlock() - return p.isStartStopping -} - // startAll - starts all jobs defined in the cronJobs map, used by watchJobs // // other jobs are single run and never restarted @@ -424,7 +383,7 @@ func (p *Pool) jobChecker() { } } - if !p.getIsStartStop() { + if !p.isStartStopping.Load() { if failedJob != "" { p.failJobChan <- failedJob } else { @@ -433,7 +392,7 @@ func (p *Pool) jobChecker() { } }() case failedJob := <-p.failJobChan: - p.setFailedJob(failedJob) // this is the job for the current fail loop + p.failedJob.Store(failedJob) // this is the job for the current fail loop p.stopJobsChan <- true p.SetStatus(PoolStatusStopped) } @@ -444,8 +403,8 @@ func (p *Pool) stopPool() { p.startStopLock.Lock() defer p.startStopLock.Unlock() - p.setIsStartStop(true) - defer p.setIsStartStop(false) + p.isStartStopping.Store(true) + defer p.isStartStopping.Store(false) p.stopAll() } @@ -454,38 +413,38 @@ func (p *Pool) startPool() { defer p.startStopLock.Unlock() if p.GetStatus() == PoolStatusStopped.String() { - p.setIsStartStop(true) - defer p.setIsStartStop(false) + p.isStartStopping.Store(true) + defer p.isStartStopping.Store(false) // attempt to restart all jobs if p.startAll() { - p.getBackoff().reset() + p.backoff.Load().reset() } else { - p.getBackoff().increaseTimeout() + p.backoff.Load().increaseTimeout() } - p.setFailedJob("") + p.failedJob.Store("") } } // watchJobs - the main loop of a pool of jobs, constantly checks for status of jobs and acts accordingly func (p *Pool) watchJobs() { p.SetStatus(PoolStatusRunning) - ticker := time.NewTicker(p.getBackoff().getCurrentTimeout()) + ticker := time.NewTicker(p.backoff.Load().getCurrentTimeout()) defer ticker.Stop() for { select { case <-p.stopJobsChan: - if job, found := p.getCronJob(p.getFailedJob()); found { + if job, found := p.getCronJob(p.failedJob.Load().(string)); found { p.logger. - WithField("job-name", job.GetName()). - WithField("failed-job", p.getFailedJob()). + WithField("jobName", job.GetName()). + WithField("failedJob", p.failedJob.Load().(string)). Debug("Job failed, stop all jobs") } p.stopPool() case <-ticker.C: p.startPool() - ticker = time.NewTicker(p.getBackoff().getCurrentTimeout()) + ticker = time.NewTicker(p.backoff.Load().getCurrentTimeout()) p.logger. - WithField("interval", p.getBackoff().getCurrentTimeout()). + WithField("interval", p.backoff.Load().getCurrentTimeout()). Trace("setting next job restart backoff interval") } } diff --git a/pkg/jobs/pool_test.go b/pkg/jobs/pool_test.go index f53af086c..6b9a6a07d 100644 --- a/pkg/jobs/pool_test.go +++ b/pkg/jobs/pool_test.go @@ -17,7 +17,7 @@ func setStatusCheckInterval(interval time.Duration) { func TestPoolCoordination(t *testing.T) { testPool := newPool() // create a new pool for this test to not interfere with other tests - testPool.setBackoff(newBackoffTimeout(time.Millisecond, time.Millisecond, 1)) + testPool.backoff.Store(newBackoffTimeout(time.Millisecond, time.Millisecond, 1)) setStatusCheckInterval(time.Millisecond) failJob := &intervalJobImpl{ name: "FailedIntervalJob", diff --git a/pkg/traceability/sampling/sample.go b/pkg/traceability/sampling/sample.go index 277a946fd..505fb7b9d 100644 --- a/pkg/traceability/sampling/sample.go +++ b/pkg/traceability/sampling/sample.go @@ -138,10 +138,14 @@ func (s *sample) sampleEndpointAndOnlyErrors(apiID string) (bool, bool) { return true, s.endpointsSampling.endpointsInfo[apiID] // endpoint found, return onlyErrors } -func (s *sample) resetEndpointSampling() { +func (s *sample) hasRemainingEndpoints() bool { s.endpointsSampling.endpointsLock.Lock() defer s.endpointsSampling.endpointsLock.Unlock() - if len(s.endpointsSampling.endpointsInfo) > 0 { + return len(s.endpointsSampling.endpointsInfo) > 0 +} + +func (s *sample) resetEndpointSampling() { + if s.hasRemainingEndpoints() { return } s.endpointsSampling.enabled.Store(false) diff --git a/pkg/util/healthcheck/definitions.go b/pkg/util/healthcheck/definitions.go index de98b003f..4f00bec6f 100644 --- a/pkg/util/healthcheck/definitions.go +++ b/pkg/util/healthcheck/definitions.go @@ -14,6 +14,7 @@ type healthChecker struct { Status StatusLevel `json:"status"` StatusDetail string `json:"-"` Checks map[string]*statusCheck `json:"statusChecks"` + checksMu sync.RWMutex `json:"-"` registered bool statusServer *Server `json:"-"` } diff --git a/pkg/util/healthcheck/healthcheck_test.go b/pkg/util/healthcheck/healthcheck_test.go index f6d3573a0..8101ddaa0 100644 --- a/pkg/util/healthcheck/healthcheck_test.go +++ b/pkg/util/healthcheck/healthcheck_test.go @@ -220,7 +220,7 @@ func TestHTTPRequests(t *testing.T) { //########################## GetHealthcheckOutput ################################ // Marshall the previous response to the same marshall indented expected from GetHealthcheckOutput - indentResult, _ := json.MarshalIndent(result, "", " ") + indentResult, _ := json.MarshalIndent(&result, "", " ") output, err := GetHealthcheckOutput(server.URL) assert.Nil(t, err) diff --git a/pkg/util/healthcheck/healthchecker.go b/pkg/util/healthcheck/healthchecker.go index 8ce2315bb..6f592c04c 100644 --- a/pkg/util/healthcheck/healthchecker.go +++ b/pkg/util/healthcheck/healthchecker.go @@ -54,10 +54,30 @@ func SetNameAndVersion(name, version string) { // RegisterHealthcheck - register a new dependency with this service func RegisterHealthcheck(name, endpoint string, check CheckStatus) (string, error) { + globalHealthChecker.checksMu.Lock() + defer globalHealthChecker.checksMu.Unlock() + if _, ok := globalHealthChecker.Checks[endpoint]; ok { return "", fmt.Errorf("a check with the endpoint of %s already exists", endpoint) } + return registerHealthcheck(name, endpoint, check) +} + +// RegisterOrUpdateHealthcheck - updates or registers the checker +func RegisterOrUpdateHealthcheck(name, endpoint string, check CheckStatus) (string, error) { + globalHealthChecker.checksMu.Lock() + defer globalHealthChecker.checksMu.Unlock() + + if existing, ok := globalHealthChecker.Checks[endpoint]; ok { + existing.checker = check + return existing.ID, nil + } + + return registerHealthcheck(name, endpoint, check) +} + +func registerHealthcheck(name, endpoint string, check CheckStatus) (string, error) { newID, _ := uuid.NewUUID() newChecker := &statusCheck{ Name: name, @@ -97,7 +117,9 @@ func GetStatusConfig() corecfg.StatusConfig { // GetStatus - returns the current status for specified service func GetStatus(endpoint string) StatusLevel { + globalHealthChecker.checksMu.RLock() statusCheck, ok := globalHealthChecker.Checks[endpoint] + globalHealthChecker.checksMu.RUnlock() if !ok { logger.Debugf("health check endpoint for %s not found in global health checker. Returning %s status", endpoint, FAIL) return FAIL @@ -114,8 +136,15 @@ func GetStatus(endpoint string) StatusLevel { // RunChecks - loop through all func RunChecks() StatusLevel { - status := Status{Result: OK} + globalHealthChecker.checksMu.RLock() + checks := make([]*statusCheck, 0, len(globalHealthChecker.Checks)) for _, check := range globalHealthChecker.Checks { + checks = append(checks, check) + } + globalHealthChecker.checksMu.RUnlock() + + status := Status{Result: OK} + for _, check := range checks { check.executeCheck() if check.Status.Result == FAIL && status.Result == OK { status = *check.Status @@ -171,9 +200,11 @@ func (s *Server) registerHandler(path string, handler func(http.ResponseWriter, func (s *Server) HandleRequests() { if !globalHealthChecker.registered { s.registerHandler("/status", statusHandler) + globalHealthChecker.checksMu.RLock() for _, statusChecks := range globalHealthChecker.Checks { s.registerHandler(fmt.Sprintf("/status/%s", statusChecks.Endpoint), checkHandler) } + globalHealthChecker.checksMu.RUnlock() globalHealthChecker.registered = true } @@ -243,7 +274,7 @@ func GetHealthcheckOutput(url string) (string, error) { // Close the response body and the server resp.Body.Close() - output, err := json.MarshalIndent(statusResp, "", " ") + output, err := json.MarshalIndent(&statusResp, "", " ") if err != nil { return "", fmt.Errorf("error formatting the Status Check into Indented JSON") } @@ -285,7 +316,9 @@ func checkHandler(w http.ResponseWriter, r *http.Request) { // Get the check object endpoint := path[1] + globalHealthChecker.checksMu.RLock() thisCheck, ok := globalHealthChecker.Checks[endpoint] + globalHealthChecker.checksMu.RUnlock() if !ok { logger.Errorf("Check with endpoint of %s is not known", endpoint) w.WriteHeader(http.StatusInternalServerError) @@ -299,7 +332,7 @@ func checkHandler(w http.ResponseWriter, r *http.Request) { } // Return data - data, _ := json.Marshal(globalHealthChecker.Checks[endpoint].Status) + data, _ := json.Marshal(thisCheck.Status) io.WriteString(w, string(data)) } diff --git a/pkg/util/util.go b/pkg/util/util.go index 60d223318..60fa3b01f 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -595,3 +595,21 @@ func IsInArray[K comparable](arr []K, val K) bool { } return false } + +func StringSlicesEqualUnordered(a, b []string) bool { + if len(a) != len(b) { + return false + } + + counts := make(map[string]int) + for _, item := range a { + counts[item]++ + } + for _, item := range b { + counts[item]-- + if counts[item] < 0 { + return false + } + } + return true +} diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index ad5d7984a..62664aab5 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -511,3 +511,12 @@ func TestGCMEcryptor(t *testing.T) { }) } } + +func TestStringSlicesEqualUnordered(t *testing.T) { + slice1 := []string{"foo", "bar"} + slice2 := []string{"bar", "foo"} + slice3 := []string{"foo", "baz"} + + assert.True(t, StringSlicesEqualUnordered(slice1, slice2)) + assert.False(t, StringSlicesEqualUnordered(slice1, slice3)) +} diff --git a/pkg/watchmanager/README.md b/pkg/watchmanager/README.md index 2e9bbc8e9..4180da71e 100644 --- a/pkg/watchmanager/README.md +++ b/pkg/watchmanager/README.md @@ -112,18 +112,18 @@ func New(cfg *Config, opts ...Option) (Manager, error) The method create a new watch manager client and returns the following interface to allow implementation to manage the gRPC stream ```golang type Manager interface { - RegisterWatch(topicSelfLink string, eventChan chan *proto.Event, errChan chan error) (string, error) + RegisterWatch(topicSelfLink string, eventChan chan *proto.Event) (string, error) CloseWatch(id string) error CloseConn() Status() bool } ``` -The client can call the *RegisterWatch* method with the topic self link and a set of channels to receive events and errors. +The client can call the *RegisterWatch* method with the topic self link and an event channel. When the client initiates the subscription request, it calls the sequence getter if configured to get the last known sequence identifier of the resource event that the implementation received. On successful subscription request, the client places an API call to Amplify Central watch service to fetch the events that were missed while the gRPC watch stream connection was not active. -When the client receives an event from the gRPC stream (or fetched by API call) it hands over the events to the implementation by writing them to the event channel configured while registering the watch subscription. In case the client receives any error on gRPC stream connection, the error is written to an error channel configured while registering the watch subscription. +When the client receives an event from the gRPC stream (or fetched by API call) it hands over the events to the implementation by writing them to the event channel configured while registering the watch subscription. In case the client receives any error on gRPC stream connection, the watch context is canceled. Below is the structure of the event that is received by the Amplify Central watch service(refer [./proto/watch.pb.go](./proto/watch.pb.go) for more detail) ```golang @@ -222,14 +222,16 @@ func startWatch(tenantID string, host string, port uint32, topicSelfLink string, } /** - * 4. Create channels to receive event and error + * 4. Create context and channel to receive events */ - eventChannel, errCh := make(chan *proto.Event), make(chan error) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + eventChannel := make(chan *proto.Event) /** * 5. Register the watch subscription */ - subscriptionID, err := wm.RegisterWatch(topicSelfLink, eventChannel, errCh) + subscriptionID, err := wm.RegisterWatch(topicSelfLink, eventChannel) if err != nil { log.Error(err) return @@ -238,13 +240,12 @@ func startWatch(tenantID string, host string, port uint32, topicSelfLink string, log.Infof("watch subscription (%s) registered successfully", subscriptionID) /** - * 6. Start to process event and error received on channel + * 6. Start to process events until context is canceled */ for { select { - case err = <-errCh: - log.Error(err) - wm.CloseWatch(subscriptionID) + case <-ctx.Done(): + log.Error("watch stream closed") return case event := <-eventChannel: bts, _ := json.MarshalIndent(event, "", " ") diff --git a/pkg/watchmanager/client.go b/pkg/watchmanager/client.go index 3961c7c28..eef314a3a 100644 --- a/pkg/watchmanager/client.go +++ b/pkg/watchmanager/client.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "sync" + "sync/atomic" "time" "google.golang.org/grpc" @@ -20,8 +21,7 @@ const ( type clientConfig struct { ctx context.Context - cancel context.CancelFunc - errors chan error + cancel context.CancelCauseFunc events chan *proto.Event tokenGetter TokenGetter topicSelfLink string @@ -31,10 +31,9 @@ type clientConfig struct { type watchClient struct { cfg clientConfig getTokenExpirationTime getTokenExpFunc - isRunning bool + isRunning atomic.Bool stream proto.Watch_SubscribeClient timer *time.Timer - mutex sync.Mutex } // newWatchClientFunc func signature to create a watch client @@ -47,23 +46,22 @@ func newWatchClient(cc grpc.ClientConnInterface, clientCfg clientConfig, newClie // If no context is provided, create a new one if clientCfg.ctx == nil { - clientCfg.ctx, clientCfg.cancel = context.WithCancel(context.Background()) + clientCfg.ctx, clientCfg.cancel = context.WithCancelCause(context.Background()) } stream, err := svcClient.Subscribe(clientCfg.ctx) if err != nil { - clientCfg.cancel() + clientCfg.cancel(err) return nil, err } client := &watchClient{ cfg: clientCfg, getTokenExpirationTime: getTokenExpirationTime, - isRunning: true, stream: stream, timer: time.NewTimer(initDuration), } - + client.isRunning.Store(true) return client, nil } @@ -84,8 +82,15 @@ func (c *watchClient) recv() error { if err != nil { return err } - c.cfg.events <- event - return nil + + select { + case c.cfg.events <- event: + return nil + case <-c.cfg.ctx.Done(): + return c.cfg.ctx.Err() + case <-c.stream.Context().Done(): + return c.stream.Context().Err() + } } // processRequest sends a message to the client when the timer expires, and handles when the stream is closed. @@ -105,7 +110,7 @@ func (c *watchClient) processRequest() error { return err } - return lock.wait() + return lock.wait(c.cfg.ctx, initDuration) } func (c *watchClient) initialRequest() error { @@ -120,9 +125,6 @@ func (c *watchClient) requestLoop(rl *initialRequestLock) { for { select { - case <-c.cfg.ctx.Done(): - c.handleError(c.cfg.ctx.Err()) - return case <-c.stream.Context().Done(): c.handleError(c.stream.Context().Err()) return @@ -158,27 +160,42 @@ func (c *watchClient) createTokenRefreshRequest() error { } req := createWatchRequest(c.cfg.topicSelfLink, token) - // write the token request to the channel - c.cfg.requests <- req + if err = c.enqueueRequest(req); err != nil { + return err + } c.timer.Reset(exp) return nil } -// handleError stop the running timer, send to the error channel, and close the open stream. -func (c *watchClient) handleError(err error) { - c.mutex.Lock() - defer c.mutex.Unlock() +func (c *watchClient) enqueueRequest(req *proto.Request) error { + select { + case c.cfg.requests <- req: + return nil + case <-c.cfg.ctx.Done(): + return c.cfg.ctx.Err() + case <-c.stream.Context().Done(): + return c.stream.Context().Err() + } +} - if c.isRunning { - c.isRunning = false +// shouldCancelContext checks if the context should be canceled. Returns true only once per client lifecycle. +func (c *watchClient) shouldCancelContext() bool { + if c.isRunning.CompareAndSwap(true, false) { c.timer.Stop() - if c.cfg.ctx.Err() != nil { - return + if c.cfg.ctx.Err() == nil { + return true } - c.cfg.errors <- err - c.cfg.cancel() } + return false +} + +// handleError stops the running timer and cancels the stream context +func (c *watchClient) handleError(err error) { + if !c.shouldCancelContext() { + return + } + c.cfg.cancel(err) } func createWatchRequest(watchTopicSelfLink, token string) *proto.Request { @@ -219,32 +236,36 @@ func getTokenExpirationTime(token string) (time.Duration, error) { } type initialRequestLock struct { - waitDone bool - lock sync.Mutex - wg sync.WaitGroup - err error + once sync.Once + ready chan struct{} + lock sync.Mutex + err error } func createInitialRequestLock() *initialRequestLock { - l := &initialRequestLock{ - wg: sync.WaitGroup{}, + return &initialRequestLock{ + ready: make(chan struct{}), } - l.wg.Add(1) - return l } func (l *initialRequestLock) done(err error) { - l.setError(err) - - if !l.waitDone { - l.wg.Done() - l.waitDone = true - } + l.once.Do(func() { + l.setError(err) + close(l.ready) + }) } -func (l *initialRequestLock) wait() error { - l.wg.Wait() - return l.getError() +func (l *initialRequestLock) wait(ctx context.Context, timeout time.Duration) error { + timer := time.NewTimer(timeout) + defer timer.Stop() + select { + case <-l.ready: + return l.getError() + case <-ctx.Done(): + return ctx.Err() + case <-timer.C: + return fmt.Errorf("timed out waiting for initial watch request after %s", timeout) + } } func (l *initialRequestLock) setError(err error) { diff --git a/pkg/watchmanager/client_test.go b/pkg/watchmanager/client_test.go index fb5a82cd2..a11aecd65 100644 --- a/pkg/watchmanager/client_test.go +++ b/pkg/watchmanager/client_test.go @@ -13,9 +13,11 @@ import ( func Test_watchClient_recv(t *testing.T) { tests := []struct { - name string - hasErr bool - err error + name string + hasErr bool + err error + cancelCtx bool // cancel context after starting recv + streamCtxDone bool // override stream ctx to pre-cancelled after creation }{ { name: "should call recv and return nil", @@ -27,17 +29,38 @@ func Test_watchClient_recv(t *testing.T) { hasErr: true, err: fmt.Errorf("error"), }, + { + name: "should return ctx error when context is cancelled", + hasErr: true, + cancelCtx: true, + }, + { + name: "should return stream ctx error when stream context is cancelled", + hasErr: true, + streamCtxDone: true, + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { + ctx, cancel := context.WithCancelCause(context.Background()) + defer cancel(nil) + cfg := clientConfig{ + ctx: ctx, + cancel: cancel, events: make(chan *proto.Event), - errors: make(chan error), } + + streamCtx := context.Background() + if tc.cancelCtx { + streamCtx = ctx + } + stream := &mockStream{ - event: &proto.Event{}, - err: tc.err, + event: &proto.Event{}, + err: tc.err, + context: streamCtx, } conn := &mockConn{ stream: stream, @@ -47,19 +70,27 @@ func Test_watchClient_recv(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, c) - errCh := make(chan error) + if tc.streamCtxDone { + doneCtx, doneCancel := context.WithCancel(context.Background()) + doneCancel() + stream.context = doneCtx + } + + errCh := make(chan error, 1) go func() { - err := c.recv() - errCh <- err + errCh <- c.recv() }() + if tc.cancelCtx { + cancel(nil) + } + if !tc.hasErr { event := <-cfg.events assert.NotNil(t, event) - assert.Nil(t, err) } else { - err = <-errCh - assert.NotNil(t, err) + recvErr := <-errCh + assert.NotNil(t, recvErr) } }) } @@ -112,7 +143,6 @@ func Test_watchClient_send(t *testing.T) { cfg := clientConfig{ events: make(chan *proto.Event), - errors: make(chan error), tokenGetter: getter.GetToken, requests: make(chan *proto.Request, 1), } @@ -160,14 +190,13 @@ func Test_watchClient_send(t *testing.T) { } } -// Should write an error to the error channel when calling processEvents +// Should cancel context when processEvents encounters an error func Test_watchClient_processEvents(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) cfg := clientConfig{ ctx: ctx, cancel: cancel, events: make(chan *proto.Event), - errors: make(chan error), } stream := &mockStream{ event: &proto.Event{}, @@ -183,8 +212,15 @@ func Test_watchClient_processEvents(t *testing.T) { go c.processEvents() - err = <-cfg.errors - assert.NotNil(t, err) + select { + case <-ctx.Done(): + assert.NotNil(t, ctx.Err()) + cause := context.Cause(ctx) + assert.NotNil(t, cause) + assert.Equal(t, "err", cause.Error()) + case <-time.After(time.Second): + t.Fatal("expected context to be cancelled on processEvents error") + } } // Stream should be cancelled and an error received over the context @@ -192,12 +228,11 @@ func Test_watchClient_processRequest(t *testing.T) { getter := &mockTokenGetter{ err: nil, } - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) cfg := clientConfig{ ctx: ctx, cancel: cancel, events: make(chan *proto.Event), - errors: make(chan error), tokenGetter: getter.GetToken, } stream := &mockStream{ @@ -215,18 +250,45 @@ func Test_watchClient_processRequest(t *testing.T) { go c.processRequest() - cancel() + cancel(nil) err = ctx.Err() assert.NotNil(t, err) } +func Test_watchClient_handleError_withCancelContext(t *testing.T) { + ctx, cancel := context.WithCancelCause(context.Background()) + defer cancel(nil) + + cfg := clientConfig{ + ctx: ctx, + cancel: cancel, + events: make(chan *proto.Event), + } + stream := &mockStream{ + event: &proto.Event{}, + context: context.Background(), + } + + c, err := newWatchClient(&mockConn{stream: stream}, cfg, newMockWatchClient(stream, nil)) + assert.Nil(t, err) + assert.NotNil(t, c) + + c.handleError(fmt.Errorf("watch stream failed")) + + select { + case <-ctx.Done(): + assert.NotNil(t, ctx.Err()) + case <-time.After(time.Second): + t.Fatal("expected watch client to cancel context on error") + } +} + // Should return an error when calling newWatchClient func Test_newWatchClient(t *testing.T) { getter := &mockTokenGetter{} cfg := clientConfig{ events: make(chan *proto.Event), - errors: make(chan error), tokenGetter: getter.GetToken, } stream := &mockStream{ @@ -243,9 +305,251 @@ func Test_newWatchClient(t *testing.T) { } func Test_getTokenExpirationTime(t *testing.T) { - futureTokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjk5OTk5OTk5OTksImlzcyI6InRlc3QifQ.XaPiwTklPiU3Ke7byMlSWNfVN7WwkNkmKorNzpM5b9o" - _, err := getTokenExpirationTime(futureTokenString) + tests := []struct { + name string + token string + hasErr bool + }{ + { + name: "should parse a valid future token", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjk5OTk5OTk5OTksImlzcyI6InRlc3QifQ.XaPiwTklPiU3Ke7byMlSWNfVN7WwkNkmKorNzpM5b9o", + hasErr: false, + }, + { + name: "should fail on an expired token", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjF9.signature", + hasErr: true, + }, + { + name: "should fail on an invalid token", + token: "not.a.jwt", + hasErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + _, err := getTokenExpirationTime(tc.token) + if tc.hasErr { + assert.NotNil(t, err) + } else { + assert.Nil(t, err) + } + }) + } +} + +func Test_initialRequestLock_wait_timeout(t *testing.T) { + tests := []struct { + name string + timeout time.Duration + }{ + { + name: "should return timeout error after waiting", + timeout: 10 * time.Millisecond, + }, + { + name: "should return timeout error when context is not cancelled but wait exceeds timeout", + timeout: 10 * time.Millisecond, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + lock := createInitialRequestLock() + ctx := context.Background() + err := lock.wait(ctx, tc.timeout) + assert.NotNil(t, err) + }) + } +} + +func Test_watchClient_enqueueRequest(t *testing.T) { + tests := []struct { + name string + cancelCtx bool // pre-cancel context before enqueue + streamCtxDone bool // override stream ctx to pre-cancelled after creation + }{ + { + name: "should return ctx error when context is already cancelled", + cancelCtx: true, + }, + { + name: "should return stream ctx error when stream context is cancelled", + streamCtxDone: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctx, cancel := context.WithCancelCause(context.Background()) + defer cancel(nil) + + cfg := clientConfig{ + ctx: ctx, + cancel: cancel, + events: make(chan *proto.Event), + requests: make(chan *proto.Request), // unbuffered, no reader + } + stream := &mockStream{context: context.Background()} + c, err := newWatchClient(&mockConn{stream: stream}, cfg, newMockWatchClient(stream, nil)) + assert.Nil(t, err) + + if tc.cancelCtx { + cancel(nil) + c.cfg.ctx = ctx + } + + if tc.streamCtxDone { + doneCtx, doneCancel := context.WithCancel(context.Background()) + doneCancel() + stream.context = doneCtx + } + + err = c.enqueueRequest(&proto.Request{}) + assert.NotNil(t, err) + }) + } +} + +// createTokenRefreshRequest should return error when enqueue fails (ctx cancelled) +func Test_watchClient_createTokenRefreshRequest_enqueueError(t *testing.T) { + ctx, cancel := context.WithCancelCause(context.Background()) + cancel(nil) + getter := &mockTokenGetter{} + cfg := clientConfig{ + ctx: ctx, + cancel: cancel, + events: make(chan *proto.Event), + tokenGetter: getter.GetToken, + requests: make(chan *proto.Request), // unbuffered, no reader + } + stream := &mockStream{context: context.Background()} + c, err := newWatchClient(&mockConn{stream: stream}, cfg, newMockWatchClient(stream, nil)) assert.Nil(t, err) + c.cfg.ctx = ctx + c.getTokenExpirationTime = mockGetTokenExp + + err = c.createTokenRefreshRequest() + assert.NotNil(t, err) +} + +func Test_watchClient_requestLoop(t *testing.T) { + tests := []struct { + name string + makeTokenGetter func() func() (string, error) // factory so each run gets fresh state; nil means use default + streamErr error + streamCtxDone bool // override stream ctx with a new context cancelled after loop starts + fireTimer bool // reset timer to fire immediately after loop starts + sendRequest bool // send a request into cfg.requests after loop starts + checkRequest bool // assert a request was enqueued (used with fireTimer) + expectLockReady bool // wait for lock.ready (loop exit) + expectLockErr bool // assert lock carries an error after exit + }{ + { + name: "should handle token refresh when timer fires", + fireTimer: true, + checkRequest: true, + }, + { + name: "should exit when token refresh fails after timer fires", + makeTokenGetter: func() func() (string, error) { + callCount := 0 + return func() (string, error) { + callCount++ + if callCount > 1 { + return "", fmt.Errorf("token error after timer") + } + return "testToken", nil + } + }, + fireTimer: true, + expectLockReady: true, + }, + { + name: "should exit when Send fails", + streamErr: fmt.Errorf("send error"), + sendRequest: true, + expectLockReady: true, + expectLockErr: true, + }, + { + name: "should stop when stream context is done", + streamCtxDone: true, + expectLockReady: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + ctx, cancel := context.WithCancelCause(context.Background()) + defer cancel(nil) + + tokenGetter := func() (string, error) { return "testToken", nil } + if tc.makeTokenGetter != nil { + tokenGetter = tc.makeTokenGetter() + } + + cfg := clientConfig{ + ctx: ctx, + cancel: cancel, + events: make(chan *proto.Event), + tokenGetter: tokenGetter, + requests: make(chan *proto.Request, 1), + } + stream := &mockStream{ + event: &proto.Event{}, + err: tc.streamErr, + context: ctx, + } + c, err := newWatchClient(&mockConn{stream: stream}, cfg, newMockWatchClient(stream, nil)) + assert.Nil(t, err) + c.getTokenExpirationTime = mockGetTokenExp + + // For streamCtxDone, override stream context before starting the loop so + // requestLoop picks it up, then cancel it after starting to trigger exit. + var cancelStream context.CancelFunc + if tc.streamCtxDone { + var streamDoneCtx context.Context + streamDoneCtx, cancelStream = context.WithCancel(context.Background()) + stream.context = streamDoneCtx + } + + lock := createInitialRequestLock() + go c.requestLoop(lock) + + if cancelStream != nil { + cancelStream() + } + if tc.fireTimer { + c.timer.Reset(1 * time.Millisecond) + } + if tc.sendRequest { + cfg.requests <- &proto.Request{} + } + + if tc.checkRequest { + time.Sleep(50 * time.Millisecond) + select { + case req := <-cfg.requests: + assert.NotNil(t, req) + default: + // request may already have been consumed; that's fine too + } + } + + if tc.expectLockReady { + select { + case <-lock.ready: + case <-time.After(2 * time.Second): + t.Fatal("requestLoop did not exit in time") + } + if tc.expectLockErr { + assert.NotNil(t, lock.getError()) + } + } + }) + } } type mockTokenGetter struct { diff --git a/pkg/watchmanager/manager.go b/pkg/watchmanager/manager.go index 3f6fad0f0..1db9a63b9 100644 --- a/pkg/watchmanager/manager.go +++ b/pkg/watchmanager/manager.go @@ -19,7 +19,7 @@ type NewManagerFunc func(cfg *Config, opts ...Option) (Manager, error) // Manager - Interface to manage watch connections type Manager interface { - RegisterWatch(topic string, eventChan chan *proto.Event, errChan chan error) (string, error) + RegisterWatch(topic string, eventChan chan *proto.Event) (string, error) CloseWatch(id string) error CloseConn() Status() bool @@ -135,13 +135,17 @@ func (m *watchManager) eventCatchUp(link string, events chan *proto.Event) error } // RegisterWatch - Registers a subscription with watch service using topic -func (m *watchManager) RegisterWatch(link string, events chan *proto.Event, errors chan error) (string, error) { +func (m *watchManager) RegisterWatch(link string, events chan *proto.Event) (string, error) { + subscriptionID, _ := uuid.NewUUID() + subID := subscriptionID.String() + logger := m.logger.WithField("watchId", subID).WithField("watchTopic", link) + logger.Info("registering watch client") + client, err := newWatchClient( m.connection, clientConfig{ ctx: m.options.ctx, cancel: m.options.cancel, - errors: errors, events: events, tokenGetter: m.cfg.TokenGetter, topicSelfLink: link, @@ -150,37 +154,35 @@ func (m *watchManager) RegisterWatch(link string, events chan *proto.Event, erro m.newWatchClientFunc, ) if err != nil { - return "", err + logger.WithError(err).Error("failed to create watch stream client") + return subID, err } - subscriptionID, _ := uuid.NewUUID() - subID := subscriptionID.String() - if m.options.sequence != nil && m.options.sequence.GetSequence() < 0 { err := fmt.Errorf("do not have a sequence id, stopping watch manager") - m.logger.Error(err.Error()) - m.CloseWatch(subID) + logger.WithError(err). + Error("cannot register watch due to invalid sequence") m.onHarvesterErr() return subID, err } + logger.Debug("starting watch catch-up sync") if err := m.eventCatchUp(link, events); err != nil { - m.logger.WithError(err).Error("failed to sync events from harvester") - m.CloseWatch(subID) + logger.WithError(err).Error("failed to sync events from harvester") m.onHarvesterErr() return subID, err } + logger.Debug("watch catch-up sync complete, proceeding to register watch client") if err := client.processRequest(); err != nil { - m.CloseWatch(subID) + logger.WithError(err). + Error("failed to send initial watch subscribe request") return subID, err } + logger.Debug("watch subscription request sent, starting watch event receiver") go client.processEvents() m.addClient(subID, client) - m.logger. - WithField("id", subID). - WithField("watchtopic", link). - Info("registered watch client") + logger.Info("registered watch client") return subID, nil } @@ -192,9 +194,8 @@ func (m *watchManager) CloseWatch(id string) error { return err } - m.logger.WithField("watchID", id).Info("closing connection for subscription") - client.cfg.cancel() - m.deleteClients([]string{id}) + m.logger.WithField("watchId", id).Info("closing connection for subscription") + client.cfg.cancel(nil) return nil } @@ -213,22 +214,18 @@ func (m *watchManager) CloseConn() { // Status returns a boolean to indicate if the clients connected to central are active. func (m *watchManager) Status() bool { clients := m.getClients() - ok := true if len(clients) == 0 { - ok = false + return false } - clientsToRemove := make([]string, 0) - for k, c := range clients { - if c != nil && !c.isRunning { + for _, c := range clients { + if c != nil && !c.isRunning.Load() { m.logger.Debug("watch client is not running") - ok = false - clientsToRemove = append(clientsToRemove, k) + return false } } - m.deleteClients(clientsToRemove) - return ok && m.connection.GetState() == connectivity.Ready + return m.connection.GetState() == connectivity.Ready } func (m *watchManager) onHarvesterErr() { @@ -242,7 +239,7 @@ func (m *watchManager) addClient(id string, client *watchClient) { m.mutex.Lock() defer m.mutex.Unlock() m.clientMap[id] = client - m.logger.WithField("watchID", id).Trace("added client to watch manager") + m.logger.WithField("watchId", id).Trace("added client to watch manager") } func (m *watchManager) getClient(id string) (*watchClient, error) { @@ -273,5 +270,6 @@ func (m *watchManager) deleteClients(ids []string) { for _, id := range ids { delete(m.clientMap, id) + m.logger.WithField("watchId", id).Trace("removed client from watch manager") } } diff --git a/pkg/watchmanager/manager_test.go b/pkg/watchmanager/manager_test.go index 57cb83edf..236a12cb7 100644 --- a/pkg/watchmanager/manager_test.go +++ b/pkg/watchmanager/manager_test.go @@ -22,35 +22,80 @@ func getMockToken() (string, error) { return token, err } -// test register watch func TestWatchManager_RegisterWatch(t *testing.T) { - cfg := &Config{ - Host: "localhost", - Port: 8080, - TenantID: "tenantID", - TokenGetter: getMockToken, + tests := []struct { + name string + tokenGetter func() (string, error) + withHarvester bool + sequenceID int64 + subscribeErr error + hasErr bool + checkCloseConn bool // assert clientMap is cleaned up after CloseConn + }{ + { + name: "success with harvester", + withHarvester: true, + sequenceID: 1, + hasErr: false, + checkCloseConn: true, + }, + { + name: "new client error returns error", + subscribeErr: fmt.Errorf("subscribe error"), + hasErr: true, + }, + { + name: "process request error returns error", + tokenGetter: func() (string, error) { + return "", fmt.Errorf("token error") + }, + hasErr: true, + }, } - sequence := &testSequenceProvider{} - sequence.SetSequence(1) - wm, err := New(cfg, WithHarvester(&hClient{}, sequence)) - assert.Nil(t, err) - assert.NotNil(t, wm) - manager := wm.(*watchManager) - stream := &mockStream{ - context: context.Background(), - } - manager.newWatchClientFunc = newMockWatchClient(stream, nil) + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + tokenGetter := getMockToken + if tc.tokenGetter != nil { + tokenGetter = tc.tokenGetter + } + cfg := &Config{ + Host: "localhost", + Port: 8080, + TenantID: "tenantID", + TokenGetter: tokenGetter, + } - events, errors := make(chan *proto.Event), make(chan error) - _, err = manager.RegisterWatch("/watch/topic", events, errors) - assert.Nil(t, err) + opts := []Option{} + if tc.withHarvester { + sequence := &testSequenceProvider{} + sequence.SetSequence(tc.sequenceID) + opts = append(opts, WithHarvester(&hClient{}, sequence)) + } - assert.Equal(t, len(manager.clientMap), 1) + wm, err := New(cfg, opts...) + assert.Nil(t, err) + assert.NotNil(t, wm) - manager.CloseConn() + manager := wm.(*watchManager) + stream := &mockStream{context: context.Background()} + manager.newWatchClientFunc = newMockWatchClient(stream, tc.subscribeErr) - assert.Equal(t, len(manager.clientMap), 0) + events := make(chan *proto.Event) + _, err = manager.RegisterWatch("/watch/topic", events) + if tc.hasErr { + assert.NotNil(t, err) + assert.Equal(t, 0, len(manager.clientMap)) + } else { + assert.Nil(t, err) + assert.Equal(t, 1, len(manager.clientMap)) + if tc.checkCloseConn { + manager.CloseConn() + assert.Equal(t, 0, len(manager.clientMap)) + } + } + }) + } } func TestWatchManager_OnError(t *testing.T) { @@ -81,8 +126,8 @@ func TestWatchManager_OnError(t *testing.T) { } manager.newWatchClientFunc = newMockWatchClient(stream, nil) - events, errors := make(chan *proto.Event), make(chan error) - _, err = manager.RegisterWatch("/watch/topic", events, errors) + events := make(chan *proto.Event) + _, err = manager.RegisterWatch("/watch/topic", events) assert.NotNil(t, err) // expect that the callback func for a harvester error was called @@ -119,8 +164,8 @@ func TestWatchManager_zeroSequenceID(t *testing.T) { } manager.newWatchClientFunc = newMockWatchClient(stream, nil) - events, errors := make(chan *proto.Event), make(chan error) - _, err = manager.RegisterWatch("/watch/topic", events, errors) + events := make(chan *proto.Event) + _, err = manager.RegisterWatch("/watch/topic", events) assert.NotNil(t, err) // expect that the callback func for a harvester error was called @@ -156,6 +201,210 @@ func TestConfig(t *testing.T) { assert.Nil(t, err) } +func TestWatchManager_Status(t *testing.T) { + tests := []struct { + name string + registerWatch bool // register a watch client before calling Status + stopClient bool // mark the registered client as not running before calling Status + expectedStatus bool + }{ + { + name: "no clients returns false", + registerWatch: false, + expectedStatus: false, + }, + { + name: "running client does not panic", + registerWatch: true, + // Status depends on grpc connectivity; just assert it does not panic + }, + { + name: "stopped client returns false", + registerWatch: true, + stopClient: true, + expectedStatus: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + cfg := &Config{ + Host: "localhost", + Port: 8080, + TenantID: "tenantID", + TokenGetter: getMockToken, + } + wm, err := New(cfg) + assert.Nil(t, err) + + if tc.registerWatch { + manager := wm.(*watchManager) + stream := &mockStream{context: context.Background()} + manager.newWatchClientFunc = newMockWatchClient(stream, nil) + + events := make(chan *proto.Event) + id, regErr := manager.RegisterWatch("/watch/topic", events) + assert.Nil(t, regErr) + + if tc.stopClient { + client, _ := manager.getClient(id) + client.isRunning.Store(false) + assert.False(t, wm.Status()) + } else { + _ = wm.Status() + } + } else { + assert.Equal(t, tc.expectedStatus, wm.Status()) + } + }) + } +} + +func TestWatchManager_CloseWatch(t *testing.T) { + tests := []struct { + name string + registerWatch bool + invalidID bool + hasErr bool + }{ + { + name: "success", + registerWatch: true, + hasErr: false, + }, + { + name: "invalid ID returns error", + invalidID: true, + hasErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + cfg := &Config{ + Host: "localhost", + Port: 8080, + TenantID: "tenantID", + TokenGetter: getMockToken, + } + wm, err := New(cfg) + assert.Nil(t, err) + + id := "nonexistent-id" + if tc.registerWatch { + manager := wm.(*watchManager) + stream := &mockStream{context: context.Background()} + manager.newWatchClientFunc = newMockWatchClient(stream, nil) + + events := make(chan *proto.Event) + id, err = manager.RegisterWatch("/watch/topic", events) + assert.Nil(t, err) + } + + err = wm.CloseWatch(id) + if tc.hasErr { + assert.NotNil(t, err) + } else { + assert.Nil(t, err) + } + }) + } +} + +func TestWatchManager_nilConfig(t *testing.T) { + var cfg *Config + _, err := New(cfg) + assert.NotNil(t, err) +} + + +func TestWatchManager_getDialer(t *testing.T) { + tests := []struct { + name string + opts []Option + hasErr bool + }{ + { + name: "with proxy", + opts: []Option{WithProxy("http://myproxy:8080")}, + hasErr: false, + }, + { + name: "with single entry address", + opts: []Option{WithSingleEntryAddr("single-entry:443")}, + hasErr: false, + }, + { + name: "invalid proxy returns error", + opts: []Option{WithProxy("://bad-proxy")}, + hasErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + cfg := &Config{ + Host: "localhost", + Port: 8080, + TenantID: "tenantID", + TokenGetter: getMockToken, + } + wm, err := New(cfg, tc.opts...) + if tc.hasErr { + assert.NotNil(t, err) + } else { + assert.Nil(t, err) + assert.NotNil(t, wm) + } + }) + } +} + +func TestWatchManager_negativeSequenceID(t *testing.T) { + cfg := &Config{ + Host: "localhost", + Port: 8080, + TenantID: "tenantID", + TokenGetter: getMockToken, + } + sequence := &testSequenceProvider{} + sequence.SetSequence(-1) + cbChan := make(chan struct{}, 1) + cb := func() { cbChan <- struct{}{} } + wm, err := New(cfg, WithHarvester(&hClient{}, sequence), WithEventSyncError(cb)) + assert.Nil(t, err) + + manager := wm.(*watchManager) + stream := &mockStream{context: context.Background()} + manager.newWatchClientFunc = newMockWatchClient(stream, nil) + + events := make(chan *proto.Event) + _, err = manager.RegisterWatch("/watch/topic", events) + assert.NotNil(t, err) + + select { + case <-cbChan: + case <-time.After(time.Second): + t.Fatal("onEventSyncError not called") + } + assert.Equal(t, 0, len(manager.clientMap)) +} + + +func TestWatchManager_onHarvesterErr_nilCallback(t *testing.T) { + cfg := &Config{ + Host: "localhost", + Port: 8080, + TenantID: "tenantID", + TokenGetter: getMockToken, + } + wm, err := New(cfg) + assert.Nil(t, err) + manager := wm.(*watchManager) + // should not panic when onEventSyncError is nil + assert.NotPanics(t, func() { manager.onHarvesterErr() }) +} + type hClient struct { err error } diff --git a/pkg/watchmanager/options.go b/pkg/watchmanager/options.go index be430ee80..2073eb26c 100644 --- a/pkg/watchmanager/options.go +++ b/pkg/watchmanager/options.go @@ -44,7 +44,7 @@ type keepAliveOption struct { // watchOptions options to use when creating a stream type watchOptions struct { ctx context.Context - cancel context.CancelFunc + cancel context.CancelCauseFunc tlsCfg *tls.Config proxyURL string singleEntryAddr string @@ -59,7 +59,7 @@ type watchOptions struct { // newWatchOptions returns the default watchOptions func newWatchOptions() *watchOptions { // Default context and cancel function - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) return &watchOptions{ ctx: ctx, @@ -131,7 +131,7 @@ func WithRequestChannel(requestCh chan *proto.Request) Option { }) } -func WithContext(ctx context.Context, cancel context.CancelFunc) Option { +func WithContext(ctx context.Context, cancel context.CancelCauseFunc) Option { return funcOption(func(o *watchOptions) { o.ctx = ctx o.cancel = cancel diff --git a/pkg/watchmanager/options_test.go b/pkg/watchmanager/options_test.go index 729ad74fc..4a0390d59 100644 --- a/pkg/watchmanager/options_test.go +++ b/pkg/watchmanager/options_test.go @@ -26,6 +26,9 @@ func TestWatchOptions(t *testing.T) { entry := logrus.NewEntry(logrus.New()) seq := &testSequenceProvider{} seq.SetSequence(1) + ch := make(chan *proto.Request, 1) + ctx, cancel := context.WithCancelCause(context.Background()) + defer cancel(nil) opts := []Option{ WithTLSConfig(nil), WithKeepAlive(1*time.Second, 1*time.Second), @@ -33,6 +36,8 @@ func TestWatchOptions(t *testing.T) { WithHarvester(&mockHarvester{}, seq), WithProxy("http://proxy"), WithSingleEntryAddr("single-entry"), + WithRequestChannel(ch), + WithContext(ctx, cancel), } options := newWatchOptions() @@ -48,6 +53,8 @@ func TestWatchOptions(t *testing.T) { assert.NotNil(t, options.sequence) assert.Equal(t, "http://proxy", options.proxyURL) assert.Equal(t, "single-entry", options.singleEntryAddr) + assert.Equal(t, ch, options.requestCh) + assert.Equal(t, ctx, options.ctx) } type mockHarvester struct{} diff --git a/pkg/watchmanager/proto/apicentral.pb.go b/pkg/watchmanager/proto/apicentral.pb.go index 57080b995..0eb46bbe0 100644 --- a/pkg/watchmanager/proto/apicentral.pb.go +++ b/pkg/watchmanager/proto/apicentral.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v4.24.4 +// protoc-gen-go v1.36.10 +// protoc v6.31.1 // source: apicentral.proto package proto @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -111,10 +112,7 @@ func (Reference_Type) EnumDescriptor() ([]byte, []int) { // API Server generic resource structure. type ResourceInstance struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Defines the group from which the resource belongs to. The server infers this from the endpoint the client submits the request to. Group string `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` // Resource kind @@ -122,17 +120,17 @@ type ResourceInstance struct { // Name of the resource Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` // Metadata. - Metadata *Metadata `protobuf:"bytes,5,opt,name=metadata,proto3" json:"metadata,omitempty"` - Attributes map[string]string `protobuf:"bytes,6,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Metadata *Metadata `protobuf:"bytes,5,opt,name=metadata,proto3" json:"metadata,omitempty"` + Attributes map[string]string `protobuf:"bytes,6,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ResourceInstance) Reset() { *x = ResourceInstance{} - if protoimpl.UnsafeEnabled { - mi := &file_apicentral_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_apicentral_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ResourceInstance) String() string { @@ -143,7 +141,7 @@ func (*ResourceInstance) ProtoMessage() {} func (x *ResourceInstance) ProtoReflect() protoreflect.Message { mi := &file_apicentral_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -195,10 +193,7 @@ func (x *ResourceInstance) GetAttributes() map[string]string { // Metadata that all server resources have. Data is generated by the server. type Metadata struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Internal id of the resource. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The scope where this resource was defined. @@ -206,16 +201,16 @@ type Metadata struct { // The URL representing this resource object. SelfLink string `protobuf:"bytes,6,opt,name=selfLink,proto3" json:"selfLink,omitempty"` // resource references - References []*Reference `protobuf:"bytes,7,rep,name=references,proto3" json:"references,omitempty"` + References []*Reference `protobuf:"bytes,7,rep,name=references,proto3" json:"references,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Metadata) Reset() { *x = Metadata{} - if protoimpl.UnsafeEnabled { - mi := &file_apicentral_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_apicentral_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Metadata) String() string { @@ -226,7 +221,7 @@ func (*Metadata) ProtoMessage() {} func (x *Metadata) ProtoReflect() protoreflect.Message { mi := &file_apicentral_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -271,23 +266,20 @@ func (x *Metadata) GetReferences() []*Reference { // Owner of the resource. type Owner struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Id of the owner of the resource. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The type of the owner. Defaults to team if not present. - Type Owner_Type `protobuf:"varint,2,opt,name=type,proto3,enum=central.events.v1.datamodel.Owner_Type" json:"type,omitempty"` + Type Owner_Type `protobuf:"varint,2,opt,name=type,proto3,enum=central.events.v1.datamodel.Owner_Type" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Owner) Reset() { *x = Owner{} - if protoimpl.UnsafeEnabled { - mi := &file_apicentral_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_apicentral_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Owner) String() string { @@ -298,7 +290,7 @@ func (*Owner) ProtoMessage() {} func (x *Owner) ProtoReflect() protoreflect.Message { mi := &file_apicentral_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -329,10 +321,7 @@ func (x *Owner) GetType() Owner_Type { // Reference resource type Reference struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Unique id generated by the server. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The kind of the referenced resource. @@ -346,16 +335,16 @@ type Reference struct { // The URL representing the referenced resource. SelfLink string `protobuf:"bytes,6,opt,name=selfLink,proto3" json:"selfLink,omitempty"` // Defines the type of the reference: * soft - spec property that has this reference will get nulled out if the referenced resource gets removed. * hard - dictates that the current resource will get removed when the referenced resource gets removed. - Type Reference_Type `protobuf:"varint,7,opt,name=type,proto3,enum=central.events.v1.datamodel.Reference_Type" json:"type,omitempty"` + Type Reference_Type `protobuf:"varint,7,opt,name=type,proto3,enum=central.events.v1.datamodel.Reference_Type" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Reference) Reset() { *x = Reference{} - if protoimpl.UnsafeEnabled { - mi := &file_apicentral_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_apicentral_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Reference) String() string { @@ -366,7 +355,7 @@ func (*Reference) ProtoMessage() {} func (x *Reference) ProtoReflect() protoreflect.Message { mi := &file_apicentral_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -431,10 +420,7 @@ func (x *Reference) GetType() Reference_Type { } type Metadata_ScopeKind struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Internal id of the scope resource where the resource is defined. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The kind of the scope resource where the resource is defined. @@ -442,16 +428,16 @@ type Metadata_ScopeKind struct { // The name of the scope where the resource is defined. Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // The URL to access the scope resource. - SelfLink string `protobuf:"bytes,4,opt,name=selfLink,proto3" json:"selfLink,omitempty"` + SelfLink string `protobuf:"bytes,4,opt,name=selfLink,proto3" json:"selfLink,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Metadata_ScopeKind) Reset() { *x = Metadata_ScopeKind{} - if protoimpl.UnsafeEnabled { - mi := &file_apicentral_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_apicentral_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Metadata_ScopeKind) String() string { @@ -462,7 +448,7 @@ func (*Metadata_ScopeKind) ProtoMessage() {} func (x *Metadata_ScopeKind) ProtoReflect() protoreflect.Message { mi := &file_apicentral_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -507,83 +493,57 @@ func (x *Metadata_ScopeKind) GetSelfLink() string { var File_apicentral_proto protoreflect.FileDescriptor -var file_apicentral_proto_rawDesc = []byte{ - 0x0a, 0x10, 0x61, 0x70, 0x69, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x1b, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x22, - 0xb1, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x6d, 0x6f, 0x64, - 0x65, 0x6c, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x5d, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x63, 0x65, 0x6e, 0x74, - 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x64, 0x61, - 0x74, 0x61, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0xa6, 0x02, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x45, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2f, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x69, 0x6e, 0x64, - 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x66, 0x4c, - 0x69, 0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x66, 0x4c, - 0x69, 0x6e, 0x6b, 0x12, 0x46, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, - 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x64, 0x61, 0x74, 0x61, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, - 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x5f, 0x0a, 0x09, 0x53, - 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x69, 0x6e, 0x6b, 0x22, 0x66, 0x0a, 0x05, - 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x6d, 0x6f, 0x64, 0x65, - 0x6c, 0x2e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x10, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x45, - 0x41, 0x4d, 0x10, 0x00, 0x22, 0xf8, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x63, - 0x6f, 0x70, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, - 0x63, 0x6f, 0x70, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x63, 0x6f, 0x70, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x6f, - 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x69, - 0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x69, - 0x6e, 0x6b, 0x12, 0x3f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x2b, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x22, 0x1a, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x53, - 0x4f, 0x46, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x41, 0x52, 0x44, 0x10, 0x01, 0x42, - 0x18, 0x5a, 0x16, 0x70, 0x6b, 0x67, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} +const file_apicentral_proto_rawDesc = "" + + "\n" + + "\x10apicentral.proto\x12\x1bcentral.events.v1.datamodel\"\xb1\x02\n" + + "\x10ResourceInstance\x12\x14\n" + + "\x05group\x18\x01 \x01(\tR\x05group\x12\x12\n" + + "\x04kind\x18\x02 \x01(\tR\x04kind\x12\x12\n" + + "\x04name\x18\x04 \x01(\tR\x04name\x12A\n" + + "\bmetadata\x18\x05 \x01(\v2%.central.events.v1.datamodel.MetadataR\bmetadata\x12]\n" + + "\n" + + "attributes\x18\x06 \x03(\v2=.central.events.v1.datamodel.ResourceInstance.AttributesEntryR\n" + + "attributes\x1a=\n" + + "\x0fAttributesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xa6\x02\n" + + "\bMetadata\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12E\n" + + "\x05scope\x18\x02 \x01(\v2/.central.events.v1.datamodel.Metadata.ScopeKindR\x05scope\x12\x1a\n" + + "\bselfLink\x18\x06 \x01(\tR\bselfLink\x12F\n" + + "\n" + + "references\x18\a \x03(\v2&.central.events.v1.datamodel.ReferenceR\n" + + "references\x1a_\n" + + "\tScopeKind\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04kind\x18\x02 \x01(\tR\x04kind\x12\x12\n" + + "\x04name\x18\x03 \x01(\tR\x04name\x12\x1a\n" + + "\bselfLink\x18\x04 \x01(\tR\bselfLink\"f\n" + + "\x05Owner\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12;\n" + + "\x04type\x18\x02 \x01(\x0e2'.central.events.v1.datamodel.Owner.TypeR\x04type\"\x10\n" + + "\x04Type\x12\b\n" + + "\x04TEAM\x10\x00\"\xf8\x01\n" + + "\tReference\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04kind\x18\x02 \x01(\tR\x04kind\x12\x12\n" + + "\x04name\x18\x03 \x01(\tR\x04name\x12\x1c\n" + + "\tscopeKind\x18\x04 \x01(\tR\tscopeKind\x12\x1c\n" + + "\tscopeName\x18\x05 \x01(\tR\tscopeName\x12\x1a\n" + + "\bselfLink\x18\x06 \x01(\tR\bselfLink\x12?\n" + + "\x04type\x18\a \x01(\x0e2+.central.events.v1.datamodel.Reference.TypeR\x04type\"\x1a\n" + + "\x04Type\x12\b\n" + + "\x04SOFT\x10\x00\x12\b\n" + + "\x04HARD\x10\x01B\x18Z\x16pkg/watchmanager/protob\x06proto3" var ( file_apicentral_proto_rawDescOnce sync.Once - file_apicentral_proto_rawDescData = file_apicentral_proto_rawDesc + file_apicentral_proto_rawDescData []byte ) func file_apicentral_proto_rawDescGZIP() []byte { file_apicentral_proto_rawDescOnce.Do(func() { - file_apicentral_proto_rawDescData = protoimpl.X.CompressGZIP(file_apicentral_proto_rawDescData) + file_apicentral_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_apicentral_proto_rawDesc), len(file_apicentral_proto_rawDesc))) }) return file_apicentral_proto_rawDescData } @@ -619,73 +579,11 @@ func file_apicentral_proto_init() { if File_apicentral_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_apicentral_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*ResourceInstance); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_apicentral_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*Metadata); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_apicentral_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*Owner); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_apicentral_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*Reference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_apicentral_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*Metadata_ScopeKind); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_apicentral_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_apicentral_proto_rawDesc), len(file_apicentral_proto_rawDesc)), NumEnums: 2, NumMessages: 6, NumExtensions: 0, @@ -697,7 +595,6 @@ func file_apicentral_proto_init() { MessageInfos: file_apicentral_proto_msgTypes, }.Build() File_apicentral_proto = out.File - file_apicentral_proto_rawDesc = nil file_apicentral_proto_goTypes = nil file_apicentral_proto_depIdxs = nil } diff --git a/pkg/watchmanager/proto/watch.pb.go b/pkg/watchmanager/proto/watch.pb.go index 2e50a0a0a..c772f0bef 100644 --- a/pkg/watchmanager/proto/watch.pb.go +++ b/pkg/watchmanager/proto/watch.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v4.24.4 +// protoc-gen-go v1.36.10 +// protoc v6.31.1 // source: watch.proto package proto @@ -12,6 +12,7 @@ import ( anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -119,25 +120,75 @@ func (x Event_Type) Number() protoreflect.EnumNumber { // Deprecated: Use Event_Type.Descriptor instead. func (Event_Type) EnumDescriptor() ([]byte, []int) { - return file_watch_proto_rawDescGZIP(), []int{2, 0} + return file_watch_proto_rawDescGZIP(), []int{3, 0} +} + +type AgentContext struct { + state protoimpl.MessageState `protogen:"open.v1"` + EnvironmentName string `protobuf:"bytes,2,opt,name=environmentName,proto3" json:"environmentName,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agentName,proto3" json:"agentName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentContext) Reset() { + *x = AgentContext{} + mi := &file_watch_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentContext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentContext) ProtoMessage() {} + +func (x *AgentContext) ProtoReflect() protoreflect.Message { + mi := &file_watch_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentContext.ProtoReflect.Descriptor instead. +func (*AgentContext) Descriptor() ([]byte, []int) { + return file_watch_proto_rawDescGZIP(), []int{0} +} + +func (x *AgentContext) GetEnvironmentName() string { + if x != nil { + return x.EnvironmentName + } + return "" +} + +func (x *AgentContext) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" } type AgentStatus struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + State string `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Context *AgentContext `protobuf:"bytes,3,opt,name=context,proto3,oneof" json:"context,omitempty"` unknownFields protoimpl.UnknownFields - - State string `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + sizeCache protoimpl.SizeCache } func (x *AgentStatus) Reset() { *x = AgentStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_watch_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_watch_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AgentStatus) String() string { @@ -147,8 +198,8 @@ func (x *AgentStatus) String() string { func (*AgentStatus) ProtoMessage() {} func (x *AgentStatus) ProtoReflect() protoreflect.Message { - mi := &file_watch_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_watch_proto_msgTypes[1] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -160,7 +211,7 @@ func (x *AgentStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentStatus.ProtoReflect.Descriptor instead. func (*AgentStatus) Descriptor() ([]byte, []int) { - return file_watch_proto_rawDescGZIP(), []int{0} + return file_watch_proto_rawDescGZIP(), []int{1} } func (x *AgentStatus) GetState() string { @@ -177,24 +228,28 @@ func (x *AgentStatus) GetMessage() string { return "" } +func (x *AgentStatus) GetContext() *AgentContext { + if x != nil { + return x.Context + } + return nil +} + type Request struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SelfLink string `protobuf:"bytes,1,opt,name=selfLink,proto3" json:"selfLink,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + RequestType *RequestType `protobuf:"varint,3,opt,name=requestType,proto3,enum=central.events.v1.RequestType,oneof" json:"requestType,omitempty"` + AgentStatus *AgentStatus `protobuf:"bytes,4,opt,name=agentStatus,proto3" json:"agentStatus,omitempty"` unknownFields protoimpl.UnknownFields - - SelfLink string `protobuf:"bytes,1,opt,name=selfLink,proto3" json:"selfLink,omitempty"` - Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` - RequestType *RequestType `protobuf:"varint,3,opt,name=requestType,proto3,enum=central.events.v1.RequestType,oneof" json:"requestType,omitempty"` - AgentStatus *AgentStatus `protobuf:"bytes,4,opt,name=agentStatus,proto3" json:"agentStatus,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Request) Reset() { *x = Request{} - if protoimpl.UnsafeEnabled { - mi := &file_watch_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_watch_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Request) String() string { @@ -204,8 +259,8 @@ func (x *Request) String() string { func (*Request) ProtoMessage() {} func (x *Request) ProtoReflect() protoreflect.Message { - mi := &file_watch_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_watch_proto_msgTypes[2] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -217,7 +272,7 @@ func (x *Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Request.ProtoReflect.Descriptor instead. func (*Request) Descriptor() ([]byte, []int) { - return file_watch_proto_rawDescGZIP(), []int{1} + return file_watch_proto_rawDescGZIP(), []int{2} } func (x *Request) GetSelfLink() string { @@ -249,28 +304,25 @@ func (x *Request) GetAgentStatus() *AgentStatus { } type Event struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Time string `protobuf:"bytes,2,opt,name=time,proto3" json:"time,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Product string `protobuf:"bytes,4,opt,name=product,proto3" json:"product,omitempty"` + CorrelationId string `protobuf:"bytes,5,opt,name=correlationId,proto3" json:"correlationId,omitempty"` + Organization *Organization `protobuf:"bytes,6,opt,name=organization,proto3" json:"organization,omitempty"` + Type Event_Type `protobuf:"varint,7,opt,name=type,proto3,enum=central.events.v1.Event_Type" json:"type,omitempty"` + Payload *ResourceInstance `protobuf:"bytes,8,opt,name=payload,proto3" json:"payload,omitempty"` + Metadata *EventMeta `protobuf:"bytes,9,opt,name=metadata,proto3" json:"metadata,omitempty"` unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Time string `protobuf:"bytes,2,opt,name=time,proto3" json:"time,omitempty"` - Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` - Product string `protobuf:"bytes,4,opt,name=product,proto3" json:"product,omitempty"` - CorrelationId string `protobuf:"bytes,5,opt,name=correlationId,proto3" json:"correlationId,omitempty"` - Organization *Organization `protobuf:"bytes,6,opt,name=organization,proto3" json:"organization,omitempty"` - Type Event_Type `protobuf:"varint,7,opt,name=type,proto3,enum=central.events.v1.Event_Type" json:"type,omitempty"` - Payload *ResourceInstance `protobuf:"bytes,8,opt,name=payload,proto3" json:"payload,omitempty"` - Metadata *EventMeta `protobuf:"bytes,9,opt,name=metadata,proto3" json:"metadata,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Event) Reset() { *x = Event{} - if protoimpl.UnsafeEnabled { - mi := &file_watch_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_watch_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Event) String() string { @@ -280,8 +332,8 @@ func (x *Event) String() string { func (*Event) ProtoMessage() {} func (x *Event) ProtoReflect() protoreflect.Message { - mi := &file_watch_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_watch_proto_msgTypes[3] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -293,7 +345,7 @@ func (x *Event) ProtoReflect() protoreflect.Message { // Deprecated: Use Event.ProtoReflect.Descriptor instead. func (*Event) Descriptor() ([]byte, []int) { - return file_watch_proto_rawDescGZIP(), []int{2} + return file_watch_proto_rawDescGZIP(), []int{3} } func (x *Event) GetId() string { @@ -360,24 +412,21 @@ func (x *Event) GetMetadata() *EventMeta { } type EventMeta struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - WatchTopicID string `protobuf:"bytes,1,opt,name=watchTopicID,proto3" json:"watchTopicID,omitempty"` - WatchTopicSelfLink string `protobuf:"bytes,2,opt,name=watchTopicSelfLink,proto3" json:"watchTopicSelfLink,omitempty"` - SequenceID int64 `protobuf:"varint,3,opt,name=sequenceID,proto3" json:"sequenceID,omitempty"` - Subresource string `protobuf:"bytes,4,opt,name=subresource,proto3" json:"subresource,omitempty"` - ActionDetails *anypb.Any `protobuf:"bytes,5,opt,name=actionDetails,proto3,oneof" json:"actionDetails,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + WatchTopicID string `protobuf:"bytes,1,opt,name=watchTopicID,proto3" json:"watchTopicID,omitempty"` + WatchTopicSelfLink string `protobuf:"bytes,2,opt,name=watchTopicSelfLink,proto3" json:"watchTopicSelfLink,omitempty"` + SequenceID int64 `protobuf:"varint,3,opt,name=sequenceID,proto3" json:"sequenceID,omitempty"` + Subresource string `protobuf:"bytes,4,opt,name=subresource,proto3" json:"subresource,omitempty"` + ActionDetails *anypb.Any `protobuf:"bytes,5,opt,name=actionDetails,proto3,oneof" json:"actionDetails,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *EventMeta) Reset() { *x = EventMeta{} - if protoimpl.UnsafeEnabled { - mi := &file_watch_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_watch_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EventMeta) String() string { @@ -387,8 +436,8 @@ func (x *EventMeta) String() string { func (*EventMeta) ProtoMessage() {} func (x *EventMeta) ProtoReflect() protoreflect.Message { - mi := &file_watch_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_watch_proto_msgTypes[4] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -400,7 +449,7 @@ func (x *EventMeta) ProtoReflect() protoreflect.Message { // Deprecated: Use EventMeta.ProtoReflect.Descriptor instead. func (*EventMeta) Descriptor() ([]byte, []int) { - return file_watch_proto_rawDescGZIP(), []int{3} + return file_watch_proto_rawDescGZIP(), []int{4} } func (x *EventMeta) GetWatchTopicID() string { @@ -439,20 +488,17 @@ func (x *EventMeta) GetActionDetails() *anypb.Any { } type Organization struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Organization) Reset() { *x = Organization{} - if protoimpl.UnsafeEnabled { - mi := &file_watch_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_watch_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Organization) String() string { @@ -462,8 +508,8 @@ func (x *Organization) String() string { func (*Organization) ProtoMessage() {} func (x *Organization) ProtoReflect() protoreflect.Message { - mi := &file_watch_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_watch_proto_msgTypes[5] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -475,7 +521,7 @@ func (x *Organization) ProtoReflect() protoreflect.Message { // Deprecated: Use Organization.ProtoReflect.Descriptor instead. func (*Organization) Descriptor() ([]byte, []int) { - return file_watch_proto_rawDescGZIP(), []int{4} + return file_watch_proto_rawDescGZIP(), []int{5} } func (x *Organization) GetId() string { @@ -487,129 +533,99 @@ func (x *Organization) GetId() string { var File_watch_proto protoreflect.FileDescriptor -var file_watch_proto_rawDesc = []byte{ - 0x0a, 0x0b, 0x77, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x63, - 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, - 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x10, 0x61, 0x70, 0x69, - 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, - 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xd4, 0x01, 0x0a, - 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x66, - 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x66, - 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x45, 0x0a, 0x0b, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1e, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, - 0x00, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, - 0x01, 0x12, 0x40, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, - 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x22, 0xda, 0x03, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x70, - 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, - 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, - 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x43, 0x0a, 0x0c, 0x6f, - 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x31, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, - 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x47, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x6d, 0x6f, 0x64, - 0x65, 0x6c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x38, 0x0a, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x58, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, - 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, - 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x55, 0x42, 0x52, 0x45, 0x53, 0x4f, - 0x55, 0x52, 0x43, 0x45, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x11, 0x0a, - 0x0d, 0x54, 0x52, 0x49, 0x47, 0x47, 0x45, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, - 0x22, 0xf4, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x22, - 0x0a, 0x0c, 0x77, 0x61, 0x74, 0x63, 0x68, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x49, 0x44, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x74, 0x63, 0x68, 0x54, 0x6f, 0x70, 0x69, 0x63, - 0x49, 0x44, 0x12, 0x2e, 0x0a, 0x12, 0x77, 0x61, 0x74, 0x63, 0x68, 0x54, 0x6f, 0x70, 0x69, 0x63, - 0x53, 0x65, 0x6c, 0x66, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, - 0x77, 0x61, 0x74, 0x63, 0x68, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x53, 0x65, 0x6c, 0x66, 0x4c, 0x69, - 0x6e, 0x6b, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x44, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x75, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x75, 0x62, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, - 0x79, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, - 0x6c, 0x73, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x1e, 0x0a, 0x0c, 0x4f, 0x72, 0x67, 0x61, 0x6e, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x2a, 0x32, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x5f, - 0x52, 0x45, 0x46, 0x52, 0x45, 0x53, 0x48, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x47, 0x45, - 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x01, 0x32, 0x50, 0x0a, 0x05, 0x77, - 0x61, 0x74, 0x63, 0x68, 0x12, 0x47, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x12, 0x1a, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, - 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x18, 0x5a, - 0x16, 0x70, 0x6b, 0x67, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +const file_watch_proto_rawDesc = "" + + "\n" + + "\vwatch.proto\x12\x11central.events.v1\x1a\x19google/protobuf/any.proto\x1a\x10apicentral.proto\"V\n" + + "\fAgentContext\x12(\n" + + "\x0fenvironmentName\x18\x02 \x01(\tR\x0fenvironmentName\x12\x1c\n" + + "\tagentName\x18\x03 \x01(\tR\tagentName\"\x89\x01\n" + + "\vAgentStatus\x12\x14\n" + + "\x05state\x18\x01 \x01(\tR\x05state\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12>\n" + + "\acontext\x18\x03 \x01(\v2\x1f.central.events.v1.AgentContextH\x00R\acontext\x88\x01\x01B\n" + + "\n" + + "\b_context\"\xd4\x01\n" + + "\aRequest\x12\x1a\n" + + "\bselfLink\x18\x01 \x01(\tR\bselfLink\x12\x14\n" + + "\x05token\x18\x02 \x01(\tR\x05token\x12E\n" + + "\vrequestType\x18\x03 \x01(\x0e2\x1e.central.events.v1.RequestTypeH\x00R\vrequestType\x88\x01\x01\x12@\n" + + "\vagentStatus\x18\x04 \x01(\v2\x1e.central.events.v1.AgentStatusR\vagentStatusB\x0e\n" + + "\f_requestType\"\xda\x03\n" + + "\x05Event\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04time\x18\x02 \x01(\tR\x04time\x12\x18\n" + + "\aversion\x18\x03 \x01(\tR\aversion\x12\x18\n" + + "\aproduct\x18\x04 \x01(\tR\aproduct\x12$\n" + + "\rcorrelationId\x18\x05 \x01(\tR\rcorrelationId\x12C\n" + + "\forganization\x18\x06 \x01(\v2\x1f.central.events.v1.OrganizationR\forganization\x121\n" + + "\x04type\x18\a \x01(\x0e2\x1d.central.events.v1.Event.TypeR\x04type\x12G\n" + + "\apayload\x18\b \x01(\v2-.central.events.v1.datamodel.ResourceInstanceR\apayload\x128\n" + + "\bmetadata\x18\t \x01(\v2\x1c.central.events.v1.EventMetaR\bmetadata\"X\n" + + "\x04Type\x12\v\n" + + "\aCREATED\x10\x00\x12\v\n" + + "\aUPDATED\x10\x01\x12\v\n" + + "\aDELETED\x10\x02\x12\x16\n" + + "\x12SUBRESOURCEUPDATED\x10\x03\x12\x11\n" + + "\rTRIGGERACTION\x10\x04\"\xf4\x01\n" + + "\tEventMeta\x12\"\n" + + "\fwatchTopicID\x18\x01 \x01(\tR\fwatchTopicID\x12.\n" + + "\x12watchTopicSelfLink\x18\x02 \x01(\tR\x12watchTopicSelfLink\x12\x1e\n" + + "\n" + + "sequenceID\x18\x03 \x01(\x03R\n" + + "sequenceID\x12 \n" + + "\vsubresource\x18\x04 \x01(\tR\vsubresource\x12?\n" + + "\ractionDetails\x18\x05 \x01(\v2\x14.google.protobuf.AnyH\x00R\ractionDetails\x88\x01\x01B\x10\n" + + "\x0e_actionDetails\"\x1e\n" + + "\fOrganization\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id*2\n" + + "\vRequestType\x12\x11\n" + + "\rTOKEN_REFRESH\x10\x00\x12\x10\n" + + "\fAGENT_STATUS\x10\x012P\n" + + "\x05watch\x12G\n" + + "\tsubscribe\x12\x1a.central.events.v1.Request\x1a\x18.central.events.v1.Event\"\x00(\x010\x01B\x18Z\x16pkg/watchmanager/protob\x06proto3" var ( file_watch_proto_rawDescOnce sync.Once - file_watch_proto_rawDescData = file_watch_proto_rawDesc + file_watch_proto_rawDescData []byte ) func file_watch_proto_rawDescGZIP() []byte { file_watch_proto_rawDescOnce.Do(func() { - file_watch_proto_rawDescData = protoimpl.X.CompressGZIP(file_watch_proto_rawDescData) + file_watch_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_watch_proto_rawDesc), len(file_watch_proto_rawDesc))) }) return file_watch_proto_rawDescData } var file_watch_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_watch_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_watch_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_watch_proto_goTypes = []any{ (RequestType)(0), // 0: central.events.v1.RequestType (Event_Type)(0), // 1: central.events.v1.Event.Type - (*AgentStatus)(nil), // 2: central.events.v1.AgentStatus - (*Request)(nil), // 3: central.events.v1.Request - (*Event)(nil), // 4: central.events.v1.Event - (*EventMeta)(nil), // 5: central.events.v1.EventMeta - (*Organization)(nil), // 6: central.events.v1.Organization - (*ResourceInstance)(nil), // 7: central.events.v1.datamodel.ResourceInstance - (*anypb.Any)(nil), // 8: google.protobuf.Any + (*AgentContext)(nil), // 2: central.events.v1.AgentContext + (*AgentStatus)(nil), // 3: central.events.v1.AgentStatus + (*Request)(nil), // 4: central.events.v1.Request + (*Event)(nil), // 5: central.events.v1.Event + (*EventMeta)(nil), // 6: central.events.v1.EventMeta + (*Organization)(nil), // 7: central.events.v1.Organization + (*ResourceInstance)(nil), // 8: central.events.v1.datamodel.ResourceInstance + (*anypb.Any)(nil), // 9: google.protobuf.Any } var file_watch_proto_depIdxs = []int32{ - 0, // 0: central.events.v1.Request.requestType:type_name -> central.events.v1.RequestType - 2, // 1: central.events.v1.Request.agentStatus:type_name -> central.events.v1.AgentStatus - 6, // 2: central.events.v1.Event.organization:type_name -> central.events.v1.Organization - 1, // 3: central.events.v1.Event.type:type_name -> central.events.v1.Event.Type - 7, // 4: central.events.v1.Event.payload:type_name -> central.events.v1.datamodel.ResourceInstance - 5, // 5: central.events.v1.Event.metadata:type_name -> central.events.v1.EventMeta - 8, // 6: central.events.v1.EventMeta.actionDetails:type_name -> google.protobuf.Any - 3, // 7: central.events.v1.watch.subscribe:input_type -> central.events.v1.Request - 4, // 8: central.events.v1.watch.subscribe:output_type -> central.events.v1.Event - 8, // [8:9] is the sub-list for method output_type - 7, // [7:8] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 2, // 0: central.events.v1.AgentStatus.context:type_name -> central.events.v1.AgentContext + 0, // 1: central.events.v1.Request.requestType:type_name -> central.events.v1.RequestType + 3, // 2: central.events.v1.Request.agentStatus:type_name -> central.events.v1.AgentStatus + 7, // 3: central.events.v1.Event.organization:type_name -> central.events.v1.Organization + 1, // 4: central.events.v1.Event.type:type_name -> central.events.v1.Event.Type + 8, // 5: central.events.v1.Event.payload:type_name -> central.events.v1.datamodel.ResourceInstance + 6, // 6: central.events.v1.Event.metadata:type_name -> central.events.v1.EventMeta + 9, // 7: central.events.v1.EventMeta.actionDetails:type_name -> google.protobuf.Any + 4, // 8: central.events.v1.watch.subscribe:input_type -> central.events.v1.Request + 5, // 9: central.events.v1.watch.subscribe:output_type -> central.events.v1.Event + 9, // [9:10] is the sub-list for method output_type + 8, // [8:9] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_watch_proto_init() } @@ -618,77 +634,16 @@ func file_watch_proto_init() { return } file_apicentral_proto_init() - if !protoimpl.UnsafeEnabled { - file_watch_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*AgentStatus); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_watch_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*Request); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_watch_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*Event); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_watch_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*EventMeta); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_watch_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*Organization); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } file_watch_proto_msgTypes[1].OneofWrappers = []any{} - file_watch_proto_msgTypes[3].OneofWrappers = []any{} + file_watch_proto_msgTypes[2].OneofWrappers = []any{} + file_watch_proto_msgTypes[4].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_watch_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_watch_proto_rawDesc), len(file_watch_proto_rawDesc)), NumEnums: 2, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, @@ -698,7 +653,6 @@ func file_watch_proto_init() { MessageInfos: file_watch_proto_msgTypes, }.Build() File_watch_proto = out.File - file_watch_proto_rawDesc = nil file_watch_proto_goTypes = nil file_watch_proto_depIdxs = nil } diff --git a/pkg/watchmanager/proto/watch_grpc.pb.go b/pkg/watchmanager/proto/watch_grpc.pb.go index ef38d2a29..8da1ae75f 100644 --- a/pkg/watchmanager/proto/watch_grpc.pb.go +++ b/pkg/watchmanager/proto/watch_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 -// - protoc v4.24.4 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v6.31.1 // source: watch.proto package proto @@ -15,8 +15,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Watch_Subscribe_FullMethodName = "/central.events.v1.watch/subscribe" @@ -26,7 +26,7 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type WatchClient interface { - Subscribe(ctx context.Context, opts ...grpc.CallOption) (Watch_SubscribeClient, error) + Subscribe(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[Request, Event], error) } type watchClient struct { @@ -37,54 +37,39 @@ func NewWatchClient(cc grpc.ClientConnInterface) WatchClient { return &watchClient{cc} } -func (c *watchClient) Subscribe(ctx context.Context, opts ...grpc.CallOption) (Watch_SubscribeClient, error) { +func (c *watchClient) Subscribe(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[Request, Event], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &Watch_ServiceDesc.Streams[0], Watch_Subscribe_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &watchSubscribeClient{ClientStream: stream} + x := &grpc.GenericClientStream[Request, Event]{ClientStream: stream} return x, nil } -type Watch_SubscribeClient interface { - Send(*Request) error - Recv() (*Event, error) - grpc.ClientStream -} - -type watchSubscribeClient struct { - grpc.ClientStream -} - -func (x *watchSubscribeClient) Send(m *Request) error { - return x.ClientStream.SendMsg(m) -} - -func (x *watchSubscribeClient) Recv() (*Event, error) { - m := new(Event) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Watch_SubscribeClient = grpc.BidiStreamingClient[Request, Event] // WatchServer is the server API for Watch service. // All implementations must embed UnimplementedWatchServer -// for forward compatibility +// for forward compatibility. type WatchServer interface { - Subscribe(Watch_SubscribeServer) error + Subscribe(grpc.BidiStreamingServer[Request, Event]) error mustEmbedUnimplementedWatchServer() } -// UnimplementedWatchServer must be embedded to have forward compatible implementations. -type UnimplementedWatchServer struct { -} +// UnimplementedWatchServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedWatchServer struct{} -func (UnimplementedWatchServer) Subscribe(Watch_SubscribeServer) error { - return status.Errorf(codes.Unimplemented, "method Subscribe not implemented") +func (UnimplementedWatchServer) Subscribe(grpc.BidiStreamingServer[Request, Event]) error { + return status.Error(codes.Unimplemented, "method Subscribe not implemented") } func (UnimplementedWatchServer) mustEmbedUnimplementedWatchServer() {} +func (UnimplementedWatchServer) testEmbeddedByValue() {} // UnsafeWatchServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to WatchServer will @@ -94,34 +79,22 @@ type UnsafeWatchServer interface { } func RegisterWatchServer(s grpc.ServiceRegistrar, srv WatchServer) { + // If the following call panics, it indicates UnimplementedWatchServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Watch_ServiceDesc, srv) } func _Watch_Subscribe_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(WatchServer).Subscribe(&watchSubscribeServer{ServerStream: stream}) -} - -type Watch_SubscribeServer interface { - Send(*Event) error - Recv() (*Request, error) - grpc.ServerStream -} - -type watchSubscribeServer struct { - grpc.ServerStream + return srv.(WatchServer).Subscribe(&grpc.GenericServerStream[Request, Event]{ServerStream: stream}) } -func (x *watchSubscribeServer) Send(m *Event) error { - return x.ServerStream.SendMsg(m) -} - -func (x *watchSubscribeServer) Recv() (*Request, error) { - m := new(Request) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Watch_SubscribeServer = grpc.BidiStreamingServer[Request, Event] // Watch_ServiceDesc is the grpc.ServiceDesc for Watch service. // It's only intended for direct use with grpc.RegisterService, diff --git a/pkg/watchmanager/rpcauth_test.go b/pkg/watchmanager/rpcauth_test.go index 6baa37875..a329d2ebe 100644 --- a/pkg/watchmanager/rpcauth_test.go +++ b/pkg/watchmanager/rpcauth_test.go @@ -2,18 +2,47 @@ package watchmanager import ( "context" + "fmt" "testing" "github.com/stretchr/testify/assert" ) func Test_rpcAuth(t *testing.T) { - cred := newRPCAuth("123", getToken) - - headers, err := cred.GetRequestMetadata(context.Background()) - assert.Nil(t, err) - assert.Equal(t, headers["x-axway-tenant-id"], "123") - assert.Equal(t, headers["authorization"], "Bearer abc") + testCases := []struct { + name string + tenantID string + tokenFunc func() (string, error) + expectError bool + }{ + { + name: "valid token", + tenantID: "123", + tokenFunc: getToken, + expectError: false, + }, + { + name: "token function error", + tenantID: "123", + tokenFunc: func() (string, error) { return "", fmt.Errorf("token error") }, + expectError: true, + }, + } + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + cred := newRPCAuth(test.tenantID, test.tokenFunc) + headers, err := cred.GetRequestMetadata(context.Background()) + if test.expectError { + assert.NotNil(t, err) + assert.Nil(t, headers) + } else { + assert.Nil(t, err) + assert.Equal(t, "Bearer abc", headers["authorization"]) + assert.Equal(t, "123", headers["x-axway-tenant-id"]) + } + assert.False(t, cred.RequireTransportSecurity()) + }) + } } func getToken() (string, error) { diff --git a/proto/watch.proto b/proto/watch.proto index 1f5cfa66a..af1f5daf8 100644 --- a/proto/watch.proto +++ b/proto/watch.proto @@ -17,9 +17,15 @@ enum RequestType { AGENT_STATUS = 1; } +message AgentContext { + string environmentName = 2; + string agentName = 3; +} + message AgentStatus { string state = 1; string message = 2; + optional AgentContext context = 3; } message Request { diff --git a/samples/watchclient/pkg/client/client.go b/samples/watchclient/pkg/client/client.go index ae9d54139..31a1adf4a 100644 --- a/samples/watchclient/pkg/client/client.go +++ b/samples/watchclient/pkg/client/client.go @@ -23,6 +23,8 @@ type WatchClient struct { config *Config logger logrus.FieldLogger wm wm.Manager + ctx context.Context + cancel context.CancelCauseFunc } type sequenceManager struct { @@ -135,6 +137,9 @@ func NewWatchClient(config *Config, logger logrus.FieldLogger) (*WatchClient, er watchOptions = append(watchOptions, wm.WithHarvester(hClient, sm)) } + ctx, cancel := context.WithCancelCause(context.Background()) + watchOptions = append(watchOptions, wm.WithContext(ctx, cancel)) + cfg := &wm.Config{ Host: ccfg.GRPCCfg.Host, Port: uint32(ccfg.GRPCCfg.Port), @@ -152,6 +157,8 @@ func NewWatchClient(config *Config, logger logrus.FieldLogger) (*WatchClient, er config: config, logger: entry, wm: w, + ctx: ctx, + cancel: cancel, }, nil } @@ -160,21 +167,25 @@ func (w WatchClient) Watch() { log := w.logger log.Info("starting to watch events") - eventChannel, errCh := make(chan *proto.Event), make(chan error) - subscriptionID, err := w.wm.RegisterWatch(w.config.TopicSelfLink, eventChannel, errCh) + eventChannel := make(chan *proto.Event) + subscriptionID, err := w.wm.RegisterWatch(w.config.TopicSelfLink, eventChannel) if err != nil { log.Error(err) return } + defer w.cancel(nil) log = log.WithField("subscriptionID", subscriptionID) log.Infof("watch registered successfully") for { select { - case err = <-errCh: - log.Error(err) - w.wm.CloseWatch(subscriptionID) + case <-w.ctx.Done(): + if cause := context.Cause(w.ctx); cause != nil { + log.WithError(cause).Error("watch stream closed with error") + } else { + log.Error("watch stream closed") + } return case event := <-eventChannel: log.