mirror of
https://github.com/foomo/contentserver.git
synced 2025-10-16 12:25:44 +00:00
117 lines
3.4 KiB
Go
117 lines
3.4 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/foomo/contentserver/log"
|
|
"github.com/foomo/contentserver/repo"
|
|
"github.com/foomo/contentserver/requests"
|
|
"github.com/foomo/contentserver/responses"
|
|
"github.com/foomo/contentserver/status"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
|
|
|
func handleRequest(r *repo.Repo, handler Handler, jsonBytes []byte, metrics *status.Metrics) (replyBytes []byte, err error) {
|
|
|
|
var (
|
|
reply interface{}
|
|
apiErr error
|
|
jsonErr error
|
|
start = time.Now()
|
|
processIfJSONIsOk = func(err error, processingFunc func()) {
|
|
if err != nil {
|
|
jsonErr = err
|
|
return
|
|
}
|
|
processingFunc()
|
|
}
|
|
)
|
|
|
|
// handle and process
|
|
switch handler {
|
|
case HandlerGetURIs:
|
|
getURIRequest := &requests.URIs{}
|
|
processIfJSONIsOk(json.Unmarshal(jsonBytes, &getURIRequest), func() {
|
|
reply = r.GetURIs(getURIRequest.Dimension, getURIRequest.IDs)
|
|
})
|
|
addMetrics(metrics, HandlerGetURIs, start, jsonErr, apiErr)
|
|
case HandlerGetContent:
|
|
contentRequest := &requests.Content{}
|
|
processIfJSONIsOk(json.Unmarshal(jsonBytes, &contentRequest), func() {
|
|
reply, apiErr = r.GetContent(contentRequest)
|
|
})
|
|
addMetrics(metrics, HandlerGetContent, start, jsonErr, apiErr)
|
|
case HandlerGetNodes:
|
|
nodesRequest := &requests.Nodes{}
|
|
processIfJSONIsOk(json.Unmarshal(jsonBytes, &nodesRequest), func() {
|
|
reply = r.GetNodes(nodesRequest)
|
|
})
|
|
addMetrics(metrics, HandlerGetNodes, start, jsonErr, apiErr)
|
|
case HandlerUpdate:
|
|
updateRequest := &requests.Update{}
|
|
processIfJSONIsOk(json.Unmarshal(jsonBytes, &updateRequest), func() {
|
|
reply = r.Update()
|
|
})
|
|
addMetrics(metrics, HandlerUpdate, start, jsonErr, apiErr)
|
|
case HandlerGetRepo:
|
|
repoRequest := &requests.Repo{}
|
|
processIfJSONIsOk(json.Unmarshal(jsonBytes, &repoRequest), func() {
|
|
reply = r.GetRepo()
|
|
})
|
|
addMetrics(metrics, HandlerGetRepo, start, jsonErr, apiErr)
|
|
default:
|
|
reply = responses.NewError(1, "unknown handler: "+string(handler))
|
|
addMetrics(metrics, "default", start, jsonErr, apiErr)
|
|
}
|
|
|
|
// error handling
|
|
if jsonErr != nil {
|
|
log.Error(" could not read incoming json:", jsonErr)
|
|
reply = responses.NewError(2, "could not read incoming json "+jsonErr.Error())
|
|
} else if apiErr != nil {
|
|
log.Error(" an API error occured:", apiErr)
|
|
reply = responses.NewError(3, "internal error "+apiErr.Error())
|
|
}
|
|
|
|
return encodeReply(reply)
|
|
}
|
|
|
|
func addMetrics(metrics *status.Metrics, handlerName Handler, start time.Time, errJSON error, errAPI error) {
|
|
|
|
var (
|
|
duration = time.Since(start)
|
|
s = "succeeded"
|
|
)
|
|
if errJSON != nil || errAPI != nil {
|
|
s = "failed"
|
|
}
|
|
|
|
metrics.ServiceRequestCounter.With(prometheus.Labels{
|
|
status.MetricLabelHandler: string(handlerName),
|
|
status.MetricLabelStatus: s,
|
|
}).Inc()
|
|
|
|
metrics.ServiceRequestDuration.With(prometheus.Labels{
|
|
status.MetricLabelHandler: string(handlerName),
|
|
status.MetricLabelStatus: s,
|
|
}).Observe(float64(duration.Nanoseconds()))
|
|
}
|
|
|
|
// encodeReply takes an interface and encodes it as JSON
|
|
// it returns the resulting JSON and a marshalling error
|
|
func encodeReply(reply interface{}) (replyBytes []byte, err error) {
|
|
|
|
// @TODO: why use marshal indent here???
|
|
replyBytes, err = json.MarshalIndent(map[string]interface{}{
|
|
"reply": reply,
|
|
}, "", " ")
|
|
if err != nil {
|
|
log.Error(" could not encode reply " + fmt.Sprint(err))
|
|
}
|
|
return
|
|
}
|