Skip to content

Commit

Permalink
[scd] minimal implementation for the dss report handler (#1012)
Browse files Browse the repository at this point in the history
* [scd] minimal implementation for the dss report handler

* PR comments
  • Loading branch information
Shastick authored Mar 21, 2024
1 parent 123a501 commit 621c04a
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 24 deletions.
7 changes: 4 additions & 3 deletions cmds/core-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,10 @@ func createSCDServer(ctx context.Context, logger *zap.Logger) (*scd.Server, erro
scdCron.Start()

return &scd.Server{
Store: scdStore,
Timeout: *timeout,
EnableHTTP: *enableHTTP,
Store: scdStore,
DSSReportHandler: &scd.JSONLoggingReceivedReportHandler{ReportLogger: logger},
Timeout: *timeout,
EnableHTTP: *enableHTTP,
}, nil
}

Expand Down
77 changes: 77 additions & 0 deletions pkg/scd/dss_report_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package scd

import (
"context"
"encoding/json"
"github.com/google/uuid"
"github.com/interuss/dss/pkg/api"
restapi "github.com/interuss/dss/pkg/api/scdv1"
dsserr "github.com/interuss/dss/pkg/errors"
"github.com/interuss/dss/pkg/logging"
"github.com/interuss/stacktrace"
"go.uber.org/zap"
)

// ReceivedReportHandler takes care of handling a DSS report received through the MakeDssReport REST handler.
type ReceivedReportHandler interface {
// Handle a DSS report request. Returns the error report passed in 'req' after having set its identifier.
Handle(ctx context.Context, req *restapi.MakeDssReportRequest) (*restapi.ErrorReport, error)
}

// JSONLoggingReceivedReportHandler a DSSReportHandler that simply logs the received report as JSON.
type JSONLoggingReceivedReportHandler struct {
// ReportLogger is the logger to which the received reports will be logged.
ReportLogger *zap.Logger
}

// HandleDssReport logs the received report as a JSON string to a logger.
func (h *JSONLoggingReceivedReportHandler) Handle(ctx context.Context, req *restapi.MakeDssReportRequest) (*restapi.ErrorReport, error) {
reportID, err := uuid.NewRandom()
if err != nil {
return nil, stacktrace.Propagate(err, "Failed to generate report ID")
}
rVal := req.Body
reportIDStr := reportID.String()
rVal.ReportId = &reportIDStr
// Serialize the report to a JSON string:
jsonReport, err := json.Marshal(req.Body)
if err != nil {
logging.WithValuesFromContext(ctx, logging.Logger).Error("Failed to serialize DSS Report", zap.Error(err))
return nil, stacktrace.PropagateWithCode(err, dsserr.BadRequest, "Failed to serialize DSS Report")
}
h.ReportLogger.Info("Received DSS Report", zap.String("reportID", reportIDStr), zap.String("report", string(jsonReport)))
return rVal, nil
}

// MakeDssReport creates an error report about a DSS.
func (a *Server) MakeDssReport(ctx context.Context, req *restapi.MakeDssReportRequest,
) restapi.MakeDssReportResponseSet {
if req.Auth.Error != nil {
resp := restapi.MakeDssReportResponseSet{}
setAuthError(ctx, stacktrace.Propagate(req.Auth.Error, "Auth failed"), &resp.Response401, &resp.Response403, &resp.Response500)
return resp
}

if req.BodyParseError != nil {
return restapi.MakeDssReportResponseSet{Response400: &restapi.ErrorResponse{
Message: dsserr.Handle(ctx, stacktrace.PropagateWithCode(req.BodyParseError, dsserr.BadRequest, "Malformed params"))}}
}

report, err := a.DSSReportHandler.Handle(ctx, req)

if err != nil {
err = stacktrace.Propagate(err, "Could not delete operational intent")
errResp := &restapi.ErrorResponse{Message: dsserr.Handle(ctx, err)}
switch stacktrace.GetCode(err) {
case dsserr.BadRequest:
return restapi.MakeDssReportResponseSet{Response400: errResp}
case dsserr.PermissionDenied:
return restapi.MakeDssReportResponseSet{Response403: errResp}
default:
return restapi.MakeDssReportResponseSet{Response500: &api.InternalServerErrorBody{
ErrorMessage: *dsserr.Handle(ctx, err)}}
}
}

return restapi.MakeDssReportResponseSet{Response201: report}
}
25 changes: 4 additions & 21 deletions pkg/scd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,10 @@ func makeSubscribersToNotify(subscriptions []*scdmodels.Subscription) []restapi.

// Server implements scdv1.Implementation.
type Server struct {
Store scdstore.Store
Timeout time.Duration
EnableHTTP bool
}

// MakeDssReport creates an error report about a DSS.
func (a *Server) MakeDssReport(ctx context.Context, req *restapi.MakeDssReportRequest,
) restapi.MakeDssReportResponseSet {
if req.Auth.Error != nil {
resp := restapi.MakeDssReportResponseSet{}
setAuthError(ctx, stacktrace.Propagate(req.Auth.Error, "Auth failed"), &resp.Response401, &resp.Response403, &resp.Response500)
return resp
}

if req.BodyParseError != nil {
return restapi.MakeDssReportResponseSet{Response400: &restapi.ErrorResponse{
Message: dsserr.Handle(ctx, stacktrace.PropagateWithCode(req.BodyParseError, dsserr.BadRequest, "Malformed params"))}}
}

return restapi.MakeDssReportResponseSet{Response400: &restapi.ErrorResponse{
Message: dsserr.Handle(ctx, stacktrace.NewErrorWithCode(dsserr.BadRequest, "Not yet implemented"))}}
Store scdstore.Store
DSSReportHandler ReceivedReportHandler
Timeout time.Duration
EnableHTTP bool
}

func setAuthError(ctx context.Context, authErr error, resp401, resp403 **restapi.ErrorResponse, resp500 **api.InternalServerErrorBody) {
Expand Down

0 comments on commit 621c04a

Please sign in to comment.