Merge pull request #22917 from mattermost/MM-51907-route-true-up-telemetry-to-cws

MM-51907 - Route True-Up Review Telemetry to CWS
This commit is contained in:
Conor Macpherson
2023-04-17 15:47:21 -04:00
committed by GitHub
8 changed files with 77 additions and 16 deletions

View File

@@ -8803,3 +8803,17 @@ func (c *Client4) GetWorkTemplatesByCategory(category string) ([]*WorkTemplate,
err = json.NewDecoder(r.Body).Decode(&templates)
return templates, BuildResponse(r), err
}
func (c *Client4) SubmitTrueUpReview(req map[string]any) (*Response, error) {
reqBytes, err := json.Marshal(req)
if err != nil {
return nil, NewAppError("SubmitTrueUpReview", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
r, err := c.DoAPIPostBytes(c.licenseRoute()+"/review", reqBytes)
if err != nil {
return BuildResponse(r), nil
}
defer closeBody(r)
return BuildResponse(r), nil
}

View File

@@ -11,8 +11,8 @@ import (
"net/http"
timePkg "time"
"github.com/mattermost/mattermost-server/v6/server/channels/einterfaces"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/server/channels/einterfaces"
)
type apiTimerLayer struct {

View File

@@ -11,8 +11,8 @@ import (
"net/http"
timePkg "time"
"github.com/mattermost/mattermost-server/v6/server/channels/einterfaces"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/server/channels/einterfaces"
)
type hooksTimerLayer struct {

View File

@@ -351,18 +351,21 @@ func requestTrueUpReview(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
// Do not send true-up review data if the user has already requested one for the quarter.
// And only send a true-up review via as a one-time telemetry request if telemetry is disabled.
// True-up is only enabled when telemetry is disabled.
// When telemetry is enabled, we already have all the data necessary for true-up reviews to be completed.
telemetryEnabled := c.App.Config().LogSettings.EnableDiagnostics
if telemetryEnabled != nil && !*telemetryEnabled {
// Send telemetry data
c.App.Srv().GetTelemetryService().SendTelemetry(model.TrueUpReviewTelemetryName, profileMap)
// Update the review status to reflect the completion.
status.Completed = true
c.App.Srv().Store().TrueUpReview().Update(status)
err = c.App.Cloud().SubmitTrueUpReview(c.AppContext.Session().UserId, profileMap)
if err != nil {
c.Err = model.NewAppError("requestTrueUpReview", "api.license.true_up_review.failed_to_submit", nil, err.Error(), http.StatusInternalServerError)
return
}
}
// Update the review status to reflect the completion.
status.Completed = true
c.App.Srv().Store().TrueUpReview().Update(status)
// Encode to string rather than byte[] otherwise json.Marshal will encode it further.
encodedData := b64.StdEncoding.EncodeToString(profileMapJson)
responseContent := struct {
@@ -370,6 +373,7 @@ func requestTrueUpReview(c *Context, w http.ResponseWriter, r *http.Request) {
}{Content: encodedData}
response, _ := json.Marshal(responseContent)
w.WriteHeader(http.StatusOK)
w.Write(response)
}

View File

@@ -478,18 +478,33 @@ func TestRequestRenewalLink(t *testing.T) {
}
func TestRequestTrueUpReview(t *testing.T) {
th := Setup(t)
defer th.TearDown()
th.App.Srv().SetLicense(model.NewTestLicense())
t.Run("returns status 200 when telemetry data sent", func(t *testing.T) {
resp, err := th.SystemAdminClient.DoAPIPost("/license/review", "")
th := Setup(t).InitBasic()
defer th.TearDown()
th.App.Srv().SetLicense(model.NewTestLicense())
th.Client.Login(th.SystemAdminUser.Email, th.SystemAdminUser.Password)
cloud := mocks.CloudInterface{}
cloud.Mock.On("SubmitTrueUpReview", mock.Anything, mock.Anything).Return(nil)
cloudImpl := th.App.Srv().Cloud
defer func() {
th.App.Srv().Cloud = cloudImpl
}()
th.App.Srv().Cloud = &cloud
var reviewProfile map[string]any
resp, err := th.Client.SubmitTrueUpReview(reviewProfile)
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("returns 501 when ran by cloud user", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
th.App.Srv().SetLicense(model.NewTestLicense())
th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
resp, err := th.SystemAdminClient.DoAPIPost("/license/review", "")
@@ -500,12 +515,19 @@ func TestRequestTrueUpReview(t *testing.T) {
})
t.Run("returns 403 when user does not have permissions", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
th.App.Srv().SetLicense(model.NewTestLicense())
resp, err := th.Client.DoAPIPost("/license/review", "")
require.Error(t, err)
require.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("returns 400 when license is nil", func(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
th.App.Srv().SetLicense(nil)
resp, err := th.SystemAdminClient.DoAPIPost("/license/review", "")

View File

@@ -48,4 +48,7 @@ type CloudInterface interface {
SelfServeDeleteWorkspace(userID string, deletionRequest *model.WorkspaceDeletionRequest) error
SubscribeToNewsletter(userID string, req *model.SubscribeNewsletterRequest) error
// Used only for when a customer has telemetry disabled. In this scenario, true up review telemetry will be submitted via CWS.
SubmitTrueUpReview(userID string, trueUpReviewProfile map[string]any) error
}

View File

@@ -594,6 +594,20 @@ func (_m *CloudInterface) SelfServeDeleteWorkspace(userID string, deletionReques
return r0
}
// SubmitTrueUpReview provides a mock function with given fields: userID, trueUpReviewProfile
func (_m *CloudInterface) SubmitTrueUpReview(userID string, trueUpReviewProfile map[string]interface{}) error {
ret := _m.Called(userID, trueUpReviewProfile)
var r0 error
if rf, ok := ret.Get(0).(func(string, map[string]interface{}) error); ok {
r0 = rf(userID, trueUpReviewProfile)
} else {
r0 = ret.Error(0)
}
return r0
}
// SubscribeToNewsletter provides a mock function with given fields: userID, req
func (_m *CloudInterface) SubscribeToNewsletter(userID string, req *model.SubscribeNewsletterRequest) error {
ret := _m.Called(userID, req)

View File

@@ -2089,6 +2089,10 @@
"id": "api.license.true_up_review.create_error",
"translation": "Could not create true up status record"
},
{
"id": "api.license.true_up_review.failed_to_submit",
"translation": "Failed to submit true up review profile to CWS."
},
{
"id": "api.license.true_up_review.get_status_error",
"translation": "Could not get true up status records"