summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2017-05-06 22:59:54 +0200
committerChristian Pointner <equinox@spreadspace.org>2017-05-06 22:59:54 +0200
commit41244fe22f2ced08ca45aeba96663bbfdc1dde64 (patch)
tree4f2515c0e002507b10a14648259032ec86e89259
parentre-added handler for last update id (diff)
get update list implemented ... some thinking necessary
-rw-r--r--src/hub/src/spreadspace.org/sfive/s5srvWeb.go194
1 files changed, 107 insertions, 87 deletions
diff --git a/src/hub/src/spreadspace.org/sfive/s5srvWeb.go b/src/hub/src/spreadspace.org/sfive/s5srvWeb.go
index 3593f62..2379078 100644
--- a/src/hub/src/spreadspace.org/sfive/s5srvWeb.go
+++ b/src/hub/src/spreadspace.org/sfive/s5srvWeb.go
@@ -37,10 +37,9 @@ import (
// "io"
"net"
"net/http"
- "time"
- // "strconv"
- "fmt"
"path"
+ "strconv"
+ "time"
)
type webErrorResponse struct {
@@ -56,7 +55,6 @@ func webNotFound(srv *Server, w http.ResponseWriter, r *http.Request) {
// /healthz
type webHealthzResponse struct {
- Error string `json:"error,omitempty"`
Status string `json:"status"`
HubId string `json:"hub-uuid"`
}
@@ -76,8 +74,7 @@ func webHealthz(srv *Server, w http.ResponseWriter, r *http.Request) {
// /hubs
type webHubsResponse struct {
- Error string `json:"error,omitempty"`
- Hubs []string `json:"hubs"`
+ Hubs []string `json:"hubs"`
}
func webHubs(srv *Server, w http.ResponseWriter, r *http.Request) {
@@ -89,7 +86,8 @@ func webHubs(srv *Server, w http.ResponseWriter, r *http.Request) {
var err error
resp := webHubsResponse{}
if resp.Hubs, err = srv.store.GetHubs(); err != nil {
- resp.Error = fmt.Sprintf("%v", err)
+ sendWebResponse(w, http.StatusInternalServerError, webErrorResponse{err.Error()})
+ return
}
sendWebResponse(w, http.StatusOK, resp)
}
@@ -97,7 +95,6 @@ func webHubs(srv *Server, w http.ResponseWriter, r *http.Request) {
// /sources
type webSourcesResponse struct {
- Error string `json:"error,omitempty"`
Sources []SourceId `json:"sources"`
}
@@ -110,69 +107,91 @@ func webSources(srv *Server, w http.ResponseWriter, r *http.Request) {
var err error
resp := webSourcesResponse{}
if resp.Sources, err = srv.store.GetSources(); err != nil {
- resp.Error = fmt.Sprintf("%v", err)
+ sendWebResponse(w, http.StatusInternalServerError, webErrorResponse{err.Error()})
+ return
}
sendWebResponse(w, http.StatusOK, resp)
}
-// func (srv Server) webGetUpdateList(c web.C, w http.ResponseWriter, r *http.Request) {
-// const resourceName = "updates"
-// from := 0
-// if fromStr := r.FormValue("from"); fromStr != "" {
-// fromInt, err := strconv.Atoi(fromStr)
-// if err != nil {
-// http.Error(w, fmt.Sprintf("failed to parse from field: %v", err), http.StatusBadRequest)
-// return
-// }
-// from = fromInt
-// }
+// /updates/:ID
-// limit := -1
-// if limitStr := r.FormValue("limit"); limitStr != "" {
-// limitInt, err := strconv.Atoi(limitStr)
-// if err != nil {
-// http.Error(w, fmt.Sprintf("failed to parse limit field: %v", err), http.StatusBadRequest)
-// return
-// }
-// limit = limitInt
-// }
+func webUpdate(srv *Server, w http.ResponseWriter, r *http.Request) {
+ if r.Method != "GET" {
+ sendInvalidMethod(w, r.Method)
+ return
+ }
-// values, err := srv.GetUpdatesAfter(from, limit)
-// if err != nil {
-// http.Error(w, fmt.Sprintf("failed to retrieve %s: %v", resourceName, err), http.StatusInternalServerError)
-// return
-// }
-// jsonString, err := json.Marshal(GenericDataContainer{values})
-// if err != nil {
-// http.Error(w, fmt.Sprintf("failed to marshal %s: %v", resourceName, err), http.StatusInternalServerError)
-// return
-// }
-// fmt.Fprintf(w, "%s", jsonString)
-// }
+ if matched, err := path.Match("/updates/?*", r.URL.Path); err != nil || !matched {
+ sendWebResponse(w, http.StatusBadRequest, webErrorResponse{"invalid update id"})
+ return
+ }
+ id, err := strconv.Atoi(path.Base(r.URL.Path))
+ if err != nil {
+ sendWebResponse(w, http.StatusBadRequest, webErrorResponse{"invalid update id: " + err.Error()})
+ return
+ }
+ var upd DataUpdateFull
+ if upd, err = srv.store.GetUpdate(id); err != nil {
+ status := http.StatusInternalServerError
+ if err == ErrNotFound {
+ status = http.StatusNotFound
+ }
+ sendWebResponse(w, status, webErrorResponse{err.Error()})
+ return
+ }
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ encoder := NewStatelessEncoder(w)
+ encoder.Encode(upd) // TODO: handle error
+}
-// func (srv Server) webGetUpdate(c web.C, w http.ResponseWriter, r *http.Request) {
-// const resourceName = "updates"
-// id, err := strconv.Atoi(c.URLParams["id"])
-// if err != nil {
-// http.Error(w, fmt.Sprintf("invalid id: %s: %v", resourceName, err), http.StatusBadRequest)
-// return
-// }
-// value, err := srv.store.GetUpdate(int(id))
-// if err != nil {
-// if err == ErrNotFound {
-// http.Error(w, fmt.Sprintf("failed to retrieve %s: %v", resourceName, err), http.StatusNotFound)
-// } else {
-// http.Error(w, fmt.Sprintf("failed to retrieve %s: %v", resourceName, err), http.StatusInternalServerError)
-// }
-// return
-// }
-// jsonString, err := json.Marshal(value)
-// if err != nil {
-// http.Error(w, fmt.Sprintf("failed to marshal %s: %v", resourceName, err), http.StatusInternalServerError)
-// return
-// }
-// fmt.Fprintf(w, "%s", jsonString)
-// }
+// /updates
+
+func webUpdates(srv *Server, w http.ResponseWriter, r *http.Request) {
+ switch r.Method {
+ case "GET":
+ webUpdatesGet(srv, w, r)
+ //case "POST":
+ // TODO: call webPostUpdate(s)
+ default:
+ sendInvalidMethod(w, r.Method)
+ }
+}
+
+func webUpdatesGet(srv *Server, w http.ResponseWriter, r *http.Request) {
+ from := 0
+ limit := -1
+
+ q := r.URL.Query()
+ var err error
+
+ fromStr := q.Get("from")
+ if fromStr != "" {
+ if from, err = strconv.Atoi(fromStr); err != nil {
+ sendWebResponse(w, http.StatusBadRequest, webErrorResponse{"invalid from value: " + err.Error()})
+ return
+ }
+ }
+ limitStr := q.Get("limit")
+ if limitStr != "" {
+ if limit, err = strconv.Atoi(limitStr); err != nil {
+ sendWebResponse(w, http.StatusBadRequest, webErrorResponse{"invalid limit value: " + err.Error()})
+ return
+ }
+ }
+
+ var upds []DataUpdateFull
+ if upds, err = srv.store.GetUpdatesAfter(from, limit); err != nil {
+ sendWebResponse(w, http.StatusInternalServerError, webErrorResponse{err.Error()})
+ return
+ }
+ w.Header().Set("Content-Type", "application/json") // this is actually multiple json documents...
+ w.WriteHeader(http.StatusOK)
+ encoder := NewStatelessEncoder(w)
+ for _, upd := range upds { // TODO: inside container?
+ encoder.Encode(upd) // TODO: handle error
+ }
+}
// func (srv Server) webPostUpdateBulk(c web.C, w http.ResponseWriter, r *http.Request) {
// decoder, err := NewStatefulDecoder(r.Body)
@@ -225,53 +244,53 @@ func webSources(srv *Server, w http.ResponseWriter, r *http.Request) {
// }
// }
-// /lastupdate
+// /lastupdate/:UUID
-type webLastUpdateIdResponse struct {
- Error string `json:"error,omitempty"`
+type webLastUpdateIdForUuidResponse struct {
HubUuid string `json:"hub-uuid"`
LastUpdateId int `json:"lastupdate"`
}
-func webLastUpdateId(srv *Server, w http.ResponseWriter, r *http.Request) {
+func webLastUpdateIdForUuid(srv *Server, w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
sendInvalidMethod(w, r.Method)
return
}
+ if matched, err := path.Match("/lastupdate/?*", r.URL.Path); err != nil || !matched {
+ sendWebResponse(w, http.StatusBadRequest, webErrorResponse{"invalid uuid"})
+ return
+ }
+
var err error
- resp := webLastUpdateIdResponse{}
- resp.HubUuid = srv.GetHubId()
- if resp.LastUpdateId, err = srv.store.GetLastUpdateId(); err != nil {
- resp.Error = fmt.Sprintf("%v", err)
+ resp := webLastUpdateIdForUuidResponse{}
+ resp.HubUuid = path.Base(r.URL.Path)
+ if resp.LastUpdateId, err = srv.store.GetLastUpdateIdForUuid(resp.HubUuid); err != nil {
+ sendWebResponse(w, http.StatusInternalServerError, webErrorResponse{err.Error()})
+ return
}
sendWebResponse(w, http.StatusOK, resp)
}
-// /lastupdate/:UUID
+// /lastupdate
-type webLastUpdateIdForUuidResponse struct {
- Error string `json:"error,omitempty"`
+type webLastUpdateIdResponse struct {
HubUuid string `json:"hub-uuid"`
LastUpdateId int `json:"lastupdate"`
}
-func webLastUpdateIdForUuid(srv *Server, w http.ResponseWriter, r *http.Request) {
+func webLastUpdateId(srv *Server, w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
sendInvalidMethod(w, r.Method)
return
}
- if matched, err := path.Match("/lastupdate/*", r.URL.Path); err != nil || !matched {
- sendWebResponse(w, http.StatusBadRequest, webErrorResponse{"invalid uuid"})
- return
- }
-
var err error
- resp := webLastUpdateIdForUuidResponse{}
- _, resp.HubUuid = path.Split(r.URL.Path)
- if resp.LastUpdateId, err = srv.store.GetLastUpdateIdForUuid(resp.HubUuid); err != nil {
- resp.Error = fmt.Sprintf("%v", err)
+ resp := webLastUpdateIdResponse{}
+ resp.HubUuid = srv.GetHubId()
+ if resp.LastUpdateId, err = srv.store.GetLastUpdateId(); err != nil {
+ sendWebResponse(w, http.StatusInternalServerError, webErrorResponse{err.Error()})
+ return
}
sendWebResponse(w, http.StatusOK, resp)
}
@@ -320,9 +339,10 @@ func webRun(listener *net.TCPListener, srv *Server) (err error) {
mux.Handle("/healthz", webHandler{srv, webHealthz})
mux.Handle("/hubs", webHandler{srv, webHubs})
mux.Handle("/sources", webHandler{srv, webSources})
- // mux.Handle("/updates", webHandler{srv, webUpdates})
- mux.Handle("/lastupdate", webHandler{srv, webLastUpdateId})
+ mux.Handle("/updates/", webHandler{srv, webUpdate})
+ mux.Handle("/updates", webHandler{srv, webUpdates})
mux.Handle("/lastupdate/", webHandler{srv, webLastUpdateIdForUuid})
+ mux.Handle("/lastupdate", webHandler{srv, webLastUpdateId})
// mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir( ..staticDir.. ))))
mux.Handle("/", webHandler{srv, webNotFound})