Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

subscription: use const Method + some refactoring #16

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions handler/notification_server_handler.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
// Handler for managing notification data received through subscriptions.
// Package handler for managing notification data received through subscriptions.
// Thanks to Matt Silverlock (https://twitter.com/@elithrar)
// for the idea on handlers with errors.
package handler

import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"

"github.com/phoops/ngsiv2/model"
)

// Error embeds the error interface and has a HTTP status code
// Error embeds the error interface and has an HTTP status code
type Error interface {
error
Status() int
}

// StatusError is an error with a HTTP status code
// StatusError is an error with an HTTP status code
type StatusError struct {
Code int
Err error
Expand All @@ -29,14 +30,14 @@ func (se StatusError) Error() string {
return se.Err.Error()
}

// Returns the HTTP status code associated with the error
// Status returns the HTTP status code associated with the error
func (se StatusError) Status() int {
return se.Code
}

// NotificationReceiver receives notifications from subscriptions
type NotificationReceiver interface {
Receive(subscritionId string, entities []*model.Entity)
Receive(subscriptionId string, entities []*model.Entity)
}

// Handler struct for managing errors and notification receivers
Expand Down Expand Up @@ -66,30 +67,28 @@ func NewNgsiV2SubscriptionHandler(receivers ...NotificationReceiver) Handler {
}

func NgsiV2SubscriptionHandler(receivers []NotificationReceiver, w http.ResponseWriter, r *http.Request) error {
if r.Method != "POST" {
return StatusError{http.StatusMethodNotAllowed, errors.New("Expected a POST")}
if r.Method != http.MethodPost {
return StatusError{http.StatusMethodNotAllowed, fmt.Errorf("expected method POST, got %s", r.Method)}
}

if ct := r.Header.Get("Content-Type"); ct != "" {
if !strings.HasPrefix(ct, "application/json") {
return StatusError{http.StatusBadRequest, errors.New("Invalid notification payload")}
return StatusError{Code: http.StatusBadRequest, Err: errors.New("invalid notification payload")}
}
}

// maximum read of 8MB, the current max for Orion (https://fiware-orion.readthedocs.io/en/master/user/known_limitations/index.html)
r.Body = http.MaxBytesReader(w, r.Body, 8*1024*1024)

decoder := json.NewDecoder(r.Body)
r.Body = http.MaxBytesReader(w, r.Body, 8<<20)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of using the bitwise operation instead of the numeric multiplication?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I my opinion it is better to use bit shifting for multiplication of power of two, even if finally is the same result but I think we should use a const for readability. What do you think about it?


var n model.Notification
err := decoder.Decode(&n)
err := json.NewDecoder(r.Body).Decode(&n)
if err != nil {
// unfortunately, it is not defined yet
if err.Error() == "http: request body too large" {
return StatusError{http.StatusRequestEntityTooLarge, err}
} else {
return StatusError{http.StatusBadRequest, err}
return StatusError{Code: http.StatusRequestEntityTooLarge, Err: err}
}

return StatusError{Code: http.StatusBadRequest, Err: err}
}

for _, r := range receivers {
Expand Down
12 changes: 6 additions & 6 deletions handler/notification_server_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ type testReceiver struct {
}

func newTestReceiver() *testReceiver {
tr := &testReceiver{}
tr.notifications = make(map[string][]*model.Entity)
return tr
return &testReceiver{
notifications: make(map[string][]*model.Entity),
}
}

func (tr *testReceiver) Receive(subscritionId string, entities []*model.Entity) {
Expand All @@ -26,7 +26,7 @@ func (tr *testReceiver) Receive(subscritionId string, entities []*model.Entity)

func TestSubscriptionHandlerNotificationInvalidMethod(t *testing.T) {
receiver := newTestReceiver()
req, _ := http.NewRequest("GET", "/test", nil)
req, _ := http.NewRequest(http.MethodGet, "/test", nil)
rr := httptest.NewRecorder()
h := handler.NewNgsiV2SubscriptionHandler(receiver)

Expand All @@ -39,7 +39,7 @@ func TestSubscriptionHandlerNotificationInvalidMethod(t *testing.T) {

func TestSubscriptionHandlerNotificationInvalidHeader(t *testing.T) {
receiver := newTestReceiver()
req, _ := http.NewRequest("POST", "/test", strings.NewReader(`
req, _ := http.NewRequest(http.MethodPost, "/test", strings.NewReader(`
{
"data": [
{
Expand Down Expand Up @@ -67,7 +67,7 @@ func TestSubscriptionHandlerNotificationInvalidHeader(t *testing.T) {

func TestSubscriptionHandlerNotificationOneData(t *testing.T) {
receiver := newTestReceiver()
req, _ := http.NewRequest("POST", "/test", strings.NewReader(`
req, _ := http.NewRequest(http.MethodPost, "/test", strings.NewReader(`
{
"data": [
{
Expand Down