Skip to content

Commit

Permalink
Add RefreshWithMetricsOnly
Browse files Browse the repository at this point in the history
Allows for a Refresh API call to be made with only metrics, no config.
To be used by the charmrevisonupdater worker for sending data on models
without an installed application.
  • Loading branch information
hmlanigan committed Oct 8, 2021
1 parent 8712c9a commit b4432b0
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
7 changes: 7 additions & 0 deletions charmhub/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,13 @@ func (c *Client) RefreshWithRequestMetrics(ctx context.Context, config RefreshCo
return c.refreshClient.RefreshWithRequestMetrics(ctx, config, metrics)
}

// RefreshWithMetricsOnly defines a client making a refresh API call with no
// action, whose purpose is to send metrics data for models without current
// units. E.G. the controller model.
func (c *Client) RefreshWithMetricsOnly(ctx context.Context, metrics map[charmmetrics.MetricKey]map[charmmetrics.MetricKey]string) error {
return c.refreshClient.RefreshWithMetricsOnly(ctx, metrics)
}

// Download defines a client for downloading charms directly.
func (c *Client) Download(ctx context.Context, resourceURL *url.URL, archivePath string, options ...DownloadOption) error {
return c.downloadClient.Download(ctx, resourceURL, archivePath, options...)
Expand Down
34 changes: 32 additions & 2 deletions charmhub/refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,37 @@ func (c *RefreshClient) RefreshWithRequestMetrics(ctx context.Context, config Re
if err != nil {
return nil, errors.Trace(err)
}
m, err := contextMetrics(metrics)
if err != nil {
return nil, errors.Trace(err)
}
req.Metrics = m
return c.refresh(ctx, config.Ensure, req, headers)
}

// RefreshWithMetricsOnly is to provide metrics without context or actions. Used
// as part of the charm revision updater facade.
func (c *RefreshClient) RefreshWithMetricsOnly(ctx context.Context, metrics map[charmmetrics.MetricKey]map[charmmetrics.MetricKey]string) error {
c.logger.Tracef("RefreshWithMetricsOnly(%+v)", metrics)
m, err := contextMetrics(metrics)
if err != nil {
return errors.Trace(err)
}
req := transport.RefreshRequest{
Context: []transport.RefreshRequestContext{},
Actions: []transport.RefreshRequestAction{},
Metrics: m,
}
headers := make(map[string][]string)

// No need to ensure data which is not expected.
ensure := func(responses []transport.RefreshResponse) error { return nil }

_, err = c.refresh(ctx, ensure, req, headers)
return err
}

func contextMetrics(metrics map[charmmetrics.MetricKey]map[charmmetrics.MetricKey]string) (transport.RequestMetrics, error) {
m := make(transport.RequestMetrics, 0)
for k, v := range metrics {
// verify top level "model" and "controller" keys
Expand All @@ -127,8 +158,7 @@ func (c *RefreshClient) RefreshWithRequestMetrics(ctx context.Context, config Re
}
m[k.String()] = ctxM
}
req.Metrics = m
return c.refresh(ctx, config.Ensure, req, headers)
return m, nil
}

func (c *RefreshClient) refresh(ctx context.Context, ensure func(responses []transport.RefreshResponse) error, req transport.RefreshRequest, headers Headers) ([]transport.RefreshResponse, error) {
Expand Down
37 changes: 37 additions & 0 deletions charmhub/refresh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,43 @@ func (s *RefreshSuite) TestRefreshMetadata(c *gc.C) {
})
}

func (s *RefreshSuite) TestRefreshWithMetricsOnly(c *gc.C) {
ctrl := gomock.NewController(c)
defer ctrl.Finish()

baseURL := MustParseURL(c, "http://api.foo.bar")

path := path.MakePath(baseURL)
id := ""
body := transport.RefreshRequest{
Context: []transport.RefreshRequestContext{},
Actions: []transport.RefreshRequestAction{},
Metrics: map[string]map[string]string{
"controller": {"uuid": "controller-uuid"},
"model": {"units": "3", "controller": "controller-uuid", "uuid": "model-uuid"},
},
}

restClient := NewMockRESTClient(ctrl)
s.expectPost(c, restClient, path, id, body)

metrics := map[charmmetrics.MetricKey]map[charmmetrics.MetricKey]string{
charmmetrics.Controller: {

charmmetrics.UUID: "controller-uuid",
},
charmmetrics.Model: {
charmmetrics.NumUnits: "3",
charmmetrics.Controller: "controller-uuid",
charmmetrics.UUID: "model-uuid",
},
}

client := NewRefreshClient(path, restClient, &FakeLogger{})
err := client.RefreshWithMetricsOnly(context.TODO(), metrics)
c.Assert(err, jc.ErrorIsNil)
}

func (s *RefreshSuite) RefreshWithRequestMetrics(c *gc.C) {
ctrl := gomock.NewController(c)
defer ctrl.Finish()
Expand Down

0 comments on commit b4432b0

Please sign in to comment.