Skip to content

Commit c1c1cfb

Browse files
authored
refactor command service to use one method per file (micromdm#416)
Updated the command service to have the same structure as all the other services within platform/...
1 parent a668161 commit c1c1cfb

8 files changed

Lines changed: 116 additions & 331 deletions

File tree

cmd/micromdm/serve.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -217,18 +217,7 @@ func serve(args []string) error {
217217
checkinHandlers = checkin.MakeHTTPHandlers(ctx, e, opts...)
218218
}
219219

220-
var commandHandlers command.HTTPHandlers
221-
{
222-
e := command.Endpoints{
223-
NewCommandEndpoint: command.MakeNewCommandEndpoint(sm.commandService),
224-
}
225-
226-
opts := []httptransport.ServerOption{
227-
httptransport.ServerErrorLogger(httpLogger),
228-
httptransport.ServerErrorEncoder(connect.EncodeError),
229-
}
230-
commandHandlers = command.MakeHTTPHandlers(ctx, e, opts...)
231-
}
220+
commandEndpoints := command.MakeServerEndpoints(sm.commandService)
232221

233222
connectOpts := []httptransport.ServerOption{
234223
httptransport.ServerErrorLogger(httpLogger),
@@ -325,6 +314,7 @@ func serve(args []string) error {
325314
depHandlers := depapi.MakeHTTPHandler(depEndpoints, logger)
326315
apnsHandlers := apns.MakeHTTPHandler(apnsEndpoints, logger)
327316
depsyncHandlers := depsync.MakeHTTPHandler(depsyncEndpoints, logger)
317+
commandHandler := command.MakeHTTPHandler(commandEndpoints, logger)
328318

329319
// API commands. Only handled if the user provides an api key.
330320
if *flAPIKey != "" {
@@ -343,7 +333,7 @@ func serve(args []string) error {
343333
r.Handle("/v1/dep/profiles", apiAuthMiddleware(*flAPIKey, depHandlers))
344334
r.Handle("/v1/dep/syncnow", apiAuthMiddleware(*flAPIKey, depsyncHandlers))
345335
r.Handle("/v1/dep/autoassigners", apiAuthMiddleware(*flAPIKey, depsyncHandlers))
346-
r.Handle("/v1/commands", apiAuthMiddleware(*flAPIKey, commandHandlers.NewCommandHandler)).Methods("POST")
336+
r.Handle("/v1/commands", apiAuthMiddleware(*flAPIKey, commandHandler))
347337
r.Handle("/push/{udid}", apiAuthMiddleware(*flAPIKey, apnsHandlers))
348338
} else {
349339
mainLogger.Log("msg", "no api key specified")
@@ -478,7 +468,7 @@ func (c *server) setupCommandService() {
478468
if c.err != nil {
479469
return
480470
}
481-
c.commandService, c.err = command.New(c.db, c.pubclient)
471+
c.commandService, c.err = command.New(c.pubclient)
482472
}
483473

484474
func (c *server) setupWebhooks() {

platform/command/command.go

Lines changed: 0 additions & 84 deletions
This file was deleted.

platform/command/endpoint.go

Lines changed: 0 additions & 78 deletions
This file was deleted.

platform/command/new_command.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package command
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/go-kit/kit/endpoint"
7+
"github.com/pkg/errors"
8+
"golang.org/x/net/context"
9+
10+
"github.com/micromdm/micromdm/mdm/mdm"
11+
"github.com/micromdm/micromdm/pkg/httputil"
12+
)
13+
14+
const (
15+
// CommandTopic is a PubSub topic that events are published to.
16+
CommandTopic = "mdm.Command"
17+
)
18+
19+
func (svc *CommandService) NewCommand(ctx context.Context, request *mdm.CommandRequest) (*mdm.CommandPayload, error) {
20+
if request == nil {
21+
return nil, errors.New("empty CommandRequest")
22+
}
23+
payload, err := mdm.NewCommandPayload(request)
24+
if err != nil {
25+
return nil, errors.Wrap(err, "creating mdm payload")
26+
}
27+
event := NewEvent(payload, request.UDID)
28+
msg, err := MarshalEvent(event)
29+
if err != nil {
30+
return nil, errors.Wrap(err, "marshalling mdm command event")
31+
}
32+
if err := svc.publisher.Publish(context.TODO(), CommandTopic, msg); err != nil {
33+
return nil, errors.Wrapf(err, "publish mdm command on topic: %s", CommandTopic)
34+
}
35+
return payload, nil
36+
}
37+
38+
type newCommandRequest struct {
39+
mdm.CommandRequest
40+
}
41+
42+
type newCommandResponse struct {
43+
Payload *mdm.CommandPayload `json:"payload,omitempty"`
44+
Err error `json:"error,omitempty"`
45+
}
46+
47+
func (r newCommandResponse) Failed() error { return r.Err }
48+
func (r newCommandResponse) StatusCode() int { return http.StatusCreated }
49+
50+
func decodeNewCommandRequest(ctx context.Context, r *http.Request) (interface{}, error) {
51+
var req newCommandRequest
52+
err := httputil.DecodeJSONRequest(r, &req)
53+
return req, err
54+
}
55+
56+
var errEmptyRequest = errors.New("request must contain UDID of the device")
57+
58+
// MakeNewCommandEndpoint creates an endpoint which creates new MDM Commands.
59+
func MakeNewCommandEndpoint(svc Service) endpoint.Endpoint {
60+
return func(ctx context.Context, request interface{}) (interface{}, error) {
61+
req := request.(newCommandRequest)
62+
if req.UDID == "" || req.RequestType == "" {
63+
return newCommandResponse{Err: errEmptyRequest}, nil
64+
}
65+
payload, err := svc.NewCommand(ctx, &req.CommandRequest)
66+
if err != nil {
67+
return newCommandResponse{Err: err}, nil
68+
}
69+
return newCommandResponse{Payload: payload}, nil
70+
}
71+
}

platform/command/server.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package command
2+
3+
import (
4+
"github.com/go-kit/kit/endpoint"
5+
"github.com/go-kit/kit/log"
6+
httptransport "github.com/go-kit/kit/transport/http"
7+
"github.com/gorilla/mux"
8+
"github.com/micromdm/micromdm/pkg/httputil"
9+
)
10+
11+
type Endpoints struct {
12+
NewCommandEndpoint endpoint.Endpoint
13+
}
14+
15+
func MakeServerEndpoints(s Service) Endpoints {
16+
return Endpoints{
17+
NewCommandEndpoint: MakeNewCommandEndpoint(s),
18+
}
19+
}
20+
21+
func MakeHTTPHandler(e Endpoints, logger log.Logger) *mux.Router {
22+
r, options := httputil.NewRouter(logger)
23+
24+
// POST /v1/commands Add new MDM Command to device queue.
25+
26+
r.Methods("POST").Path("/v1/commands").Handler(httptransport.NewServer(
27+
e.NewCommandEndpoint,
28+
decodeNewCommandRequest,
29+
httputil.EncodeJSONResponse,
30+
options...,
31+
))
32+
33+
return r
34+
}

platform/command/service.go

Lines changed: 7 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,66 +2,22 @@
22
package command
33

44
import (
5-
"time"
6-
7-
"github.com/go-kit/kit/log"
8-
"github.com/go-kit/kit/metrics"
95
"github.com/micromdm/micromdm/mdm/mdm"
6+
"github.com/micromdm/micromdm/platform/pubsub"
107
"golang.org/x/net/context"
118
)
129

1310
type Service interface {
1411
NewCommand(context.Context, *mdm.CommandRequest) (*mdm.CommandPayload, error)
1512
}
1613

17-
// Middleware describes a service (as opposed to endpoint) middleware.
18-
type Middleware func(Service) Service
19-
20-
// ServiceLoggingMiddleware returns a service middleware that logs the
21-
// parameters and result of each method invocation.
22-
func ServiceLoggingMiddleware(logger log.Logger) Middleware {
23-
return func(next Service) Service {
24-
return serviceLoggingMiddleware{
25-
logger: logger,
26-
next: next,
27-
}
28-
}
29-
}
30-
31-
func (mw serviceLoggingMiddleware) NewCommand(ctx context.Context, req *mdm.CommandRequest) (p *mdm.CommandPayload, err error) {
32-
defer func(begin time.Time) {
33-
mw.logger.Log(
34-
"method", "NewCommand",
35-
"error", err,
36-
"took", time.Since(begin),
37-
)
38-
}(time.Now())
39-
return mw.next.NewCommand(ctx, req)
14+
type CommandService struct {
15+
publisher pubsub.Publisher
4016
}
4117

42-
type serviceLoggingMiddleware struct {
43-
logger log.Logger
44-
next Service
45-
}
46-
47-
// ServiceInstrumentingMiddleware returns a service middleware that tracks the
48-
// number of payloads created by the service.
49-
func ServiceInstrumentingMiddleware(p metrics.Counter) Middleware {
50-
return func(next Service) Service {
51-
return serviceInstrumentingMiddleware{
52-
payloads: p,
53-
next: next,
54-
}
18+
func New(pub pubsub.Publisher) (*CommandService, error) {
19+
svc := CommandService{
20+
publisher: pub,
5521
}
56-
}
57-
58-
type serviceInstrumentingMiddleware struct {
59-
payloads metrics.Counter
60-
next Service
61-
}
62-
63-
func (mw serviceInstrumentingMiddleware) NewCommand(ctx context.Context, req *mdm.CommandRequest) (*mdm.CommandPayload, error) {
64-
p, err := mw.next.NewCommand(ctx, req)
65-
mw.payloads.Add(1)
66-
return p, err
22+
return &svc, nil
6723
}

0 commit comments

Comments
 (0)