Skip to content

Commit

Permalink
fix active channels
Browse files Browse the repository at this point in the history
  • Loading branch information
nicpottier committed May 11, 2017
1 parent 22fb67a commit 8f91be1
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 42 deletions.
54 changes: 29 additions & 25 deletions util.go → responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,35 @@ import (
validator "gopkg.in/go-playground/validator.v9"
)

// WriteError writes a JSON response for the passed in error
func WriteError(w http.ResponseWriter, err error) error {
errors := []string{err.Error()}

vErrs, isValidation := err.(validator.ValidationErrors)
if isValidation {
errors = []string{}
for i := range vErrs {
errors = append(errors, fmt.Sprintf("field '%s' %s", strings.ToLower(vErrs[i].Field()), vErrs[i].Tag()))
}
}
return writeResponse(w, http.StatusBadRequest, &errorResponse{errors})
}

// WriteIgnored writes a JSON response for the passed in message
func WriteIgnored(w http.ResponseWriter, message string) error {
return writeData(w, http.StatusOK, message, struct{}{})
}

// WriteReceiveSuccess writes a JSON response for the passed in msg indicating we handled it
func WriteReceiveSuccess(w http.ResponseWriter, msg *Msg) error {
return writeData(w, http.StatusOK, "Message Accepted", &receiveData{msg.UUID})
}

// WriteStatusSuccess writes a JSON response for the passed in status update indicating we handled it
func WriteStatusSuccess(w http.ResponseWriter, status *MsgStatusUpdate) error {
return writeData(w, http.StatusOK, "Status Update Accepted", &statusData{status.Status})
}

type errorResponse struct {
Text []string `json:"errors"`
}
Expand All @@ -35,28 +64,3 @@ func writeResponse(w http.ResponseWriter, statusCode int, response interface{})
func writeData(w http.ResponseWriter, statusCode int, message string, response interface{}) error {
return writeResponse(w, statusCode, &successResponse{message, response})
}

func WriteError(w http.ResponseWriter, err error) error {
errors := []string{err.Error()}

vErrs, isValidation := err.(validator.ValidationErrors)
if isValidation {
errors = []string{}
for i := range vErrs {
errors = append(errors, fmt.Sprintf("field '%s' %s", strings.ToLower(vErrs[i].Field()), vErrs[i].Tag()))
}
}
return writeResponse(w, http.StatusBadRequest, &errorResponse{errors})
}

func WriteIgnored(w http.ResponseWriter, message string) error {
return writeData(w, http.StatusOK, message, struct{}{})
}

func WriteReceiveSuccess(w http.ResponseWriter, msg *Msg) error {
return writeData(w, http.StatusOK, "Message Accepted", &receiveData{msg.UUID})
}

func WriteStatusSuccess(w http.ResponseWriter, status *MsgStatusUpdate) error {
return writeData(w, http.StatusOK, "Status Update Accepted", &statusData{status.Status})
}
37 changes: 26 additions & 11 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/gorilla/mux"
"github.com/jmoiron/sqlx"
"github.com/nyaruka/courier/config"
"github.com/nyaruka/courier/utils"
)

// Server is the main interface ChannelHandlers use to interact with the database and redis. It provides an
Expand Down Expand Up @@ -156,13 +157,8 @@ func (s *server) Start() error {
// wire up our index page
s.router.HandleFunc("/", s.handleIndex).Name("Index")

// register each of our handlers
for _, handler := range handlers {
err := handler.Initialize(s)
if err != nil {
log.Fatal(err)
}
}
// initialize our handlers
s.initializeChannelHandlers()

// build a map of the routes we have installed
var help bytes.Buffer
Expand Down Expand Up @@ -257,6 +253,25 @@ type server struct {
routeHelp string
}

func (s *server) initializeChannelHandlers() {
includes := s.config.Include_Channels
excludes := s.config.Exclude_Channels

// initialize handlers which are included/not-excluded in the config
for _, handler := range registeredHandlers {
channelType := string(handler.ChannelType())
if (includes == nil || utils.StringArrayContains(includes, channelType)) && (excludes == nil || !utils.StringArrayContains(excludes, channelType)) {
err := handler.Initialize(s)
if err != nil {
log.Fatal(err)
}
activeHandlers[handler.ChannelType()] = handler

log.Printf("[X] Server: initialized handler for channel type \"%s\" (%s)", handler.ChannelName(), channelType)
}
}
}

func (s *server) Router() *mux.Router { return s.chanRouter }
func (s *server) RouteHelp() string { return s.routeHelp }

Expand Down Expand Up @@ -318,13 +333,13 @@ func (s *server) handleIndex(w http.ResponseWriter, r *http.Request) {

// RegisterHandler adds a new handler for a channel type, this is called by individual handlers when they are initialized
func RegisterHandler(handler ChannelHandler) {
if handlers == nil {
handlers = make(map[ChannelType]ChannelHandler)
}
handlers[handler.ChannelType()] = handler
registeredHandlers[handler.ChannelType()] = handler
}

var registeredHandlers = make(map[ChannelType]ChannelHandler)
var handlers map[ChannelType]ChannelHandler
var activeHandlers = make(map[ChannelType]ChannelHandler)

var splash = `
____________ _____
___ ____/_________ ___________(_)____________
Expand Down
23 changes: 17 additions & 6 deletions test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"

"github.com/gorilla/mux"
_ "github.com/lib/pq"
_ "github.com/lib/pq" // postgres driver
"github.com/nyaruka/courier/config"
)

Expand Down Expand Up @@ -44,19 +44,23 @@ func NewMockServer() *MockServer {
return ts
}

// Router returns the Gorilla router our server
func (ts *MockServer) Router() *mux.Router { return ts.router }

// GetLastQueueMsg returns the last message queued to the server
func (ts *MockServer) GetLastQueueMsg() (*Msg, error) {
if len(ts.queueMsgs) == 0 {
return nil, ErrMsgNotFound
}
return ts.queueMsgs[len(ts.queueMsgs)-1], nil
}

// SetErrorOnQueue is a mock method which makes the QueueMsg call throw the passed in error on next call
func (ts *MockServer) SetErrorOnQueue(shouldError bool) {
ts.errorOnQueue = shouldError
}

// QueueMsg queues the passed in message internally
func (ts *MockServer) QueueMsg(m *Msg) error {
if ts.errorOnQueue {
return errors.New("unable to queue message")
Expand All @@ -66,18 +70,17 @@ func (ts *MockServer) QueueMsg(m *Msg) error {
return nil
}

// UpdateMsgStatus writes the status update to our queue
func (ts *MockServer) UpdateMsgStatus(status *MsgStatusUpdate) error {
return nil
}

func (ts *MockServer) SaveMedia(Msg, []byte) (string, error) {
return "", fmt.Errorf("Save media not implemented on test server")
}

// GetConfig returns the config for our server
func (ts *MockServer) GetConfig() *config.Courier {
return ts.config
}

// GetChannel returns
func (ts *MockServer) GetChannel(cType ChannelType, uuid string) (*Channel, error) {
cUUID, err := NewChannelUUID(uuid)
if err != nil {
Expand All @@ -95,12 +98,18 @@ func (ts *MockServer) AddChannel(channel *Channel) {
ts.channels[channel.UUID] = channel
}

// ClearChannels is a utility function on our mock server to clear all added channels
func (ts *MockServer) ClearChannels() {
ts.channels = nil
}

// Start starts our mock server
func (ts *MockServer) Start() error { return nil }
func (ts *MockServer) Stop() {}

// Stop stops our mock server
func (ts *MockServer) Stop() {}

// ClearQueueMsgs clears our mock msg queue
func (ts *MockServer) ClearQueueMsgs() {
ts.queueMsgs = nil
}
Expand All @@ -121,6 +130,7 @@ func (ts *MockServer) channelFunctionWrapper(handler ChannelHandler, handlerFunc
}
}

// AddChannelRoute adds the passed in handler to our router
func (ts *MockServer) AddChannelRoute(handler ChannelHandler, method string, action string, handlerFunc ChannelActionHandlerFunc) *mux.Route {
path := fmt.Sprintf("/%s/{uuid:[a-zA-Z0-9-]{36}}/%s/", strings.ToLower(string(handler.ChannelType())), action)
route := ts.chanRouter.HandleFunc(path, ts.channelFunctionWrapper(handler, handlerFunc))
Expand All @@ -133,6 +143,7 @@ func (ts *MockServer) AddChannelRoute(handler ChannelHandler, method string, act
// Mock channel implementation
//-----------------------------------------------------------------------------

// NewMockChannel creates a new mock channel for the passed in type, address, country and config
func NewMockChannel(uuid string, channelType string, address string, country string, config map[string]string) *Channel {
cUUID, _ := NewChannelUUID(uuid)

Expand Down

0 comments on commit 8f91be1

Please sign in to comment.