mirror of
https://github.com/foomo/neosproxy.git
synced 2025-10-16 12:35:39 +00:00
stream initial status report
This commit is contained in:
parent
8de4e11d32
commit
397708958a
35
model/report.go
Normal file
35
model/report.go
Normal file
@ -0,0 +1,35 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type ReportStatus string
|
||||
type MessageStatus string
|
||||
|
||||
const (
|
||||
ReportStatusValid ReportStatus = "valid"
|
||||
ReportStatusInvalid ReportStatus = "invalid"
|
||||
ReportStatusUnknown ReportStatus = "unknown"
|
||||
|
||||
MessageStatusInfo MessageStatus = "info"
|
||||
MessageStatusWarning MessageStatus = "warning"
|
||||
MessageStatusError MessageStatus = "error"
|
||||
)
|
||||
|
||||
type Report struct {
|
||||
Name string
|
||||
URL string
|
||||
|
||||
Status ReportStatus
|
||||
DateTime time.Time
|
||||
Hash string
|
||||
Workspace string
|
||||
|
||||
Messages struct {
|
||||
Status MessageStatus
|
||||
NodeID string
|
||||
Message string
|
||||
Data map[string]string
|
||||
}
|
||||
}
|
||||
7
model/status.go
Normal file
7
model/status.go
Normal file
@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
type Status struct {
|
||||
Workspaces []string
|
||||
ProviderReports map[string]Report `json:"providerReports"`
|
||||
ConsumerReports map[string]Report `json:"consumerReports"`
|
||||
}
|
||||
55
proxy/api.go
55
proxy/api.go
@ -13,10 +13,22 @@ import (
|
||||
"github.com/foomo/neosproxy/client/cms"
|
||||
"github.com/foomo/neosproxy/logging"
|
||||
"github.com/gorilla/mux"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
content_cache "github.com/foomo/neosproxy/cache/content"
|
||||
)
|
||||
|
||||
type mime string
|
||||
|
||||
const (
|
||||
mimeTextPlain mime = "text/plain"
|
||||
mimeApplicationJSON mime = "application/json"
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ~ Proxy handler methods
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
func (p *Proxy) getContent(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// duration
|
||||
@ -199,6 +211,34 @@ func (p *Proxy) streamCachedNeosContentServerExport(w http.ResponseWriter, r *ht
|
||||
log.WithDuration(start).WithField("size", bytefmt.ByteSize(uint64(written))).Info("streamed file")
|
||||
}
|
||||
|
||||
func (p *Proxy) streamStatus(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// logger
|
||||
log := p.setupLogger(r, "status")
|
||||
|
||||
// stream
|
||||
var errEncode error
|
||||
contentNegotioation := parseAcceptHeader(r.Header.Get("accept"))
|
||||
switch contentNegotioation {
|
||||
case mimeApplicationJSON:
|
||||
w.Header().Set("Content-Type", string(mimeApplicationJSON))
|
||||
encoder := json.NewEncoder(w)
|
||||
errEncode = encoder.Encode(p.status)
|
||||
case mimeTextPlain:
|
||||
w.Header().Set("Content-Type", "application/x-yaml")
|
||||
encoder := yaml.NewEncoder(w)
|
||||
errEncode = encoder.Encode(p.status)
|
||||
}
|
||||
|
||||
// error handling
|
||||
if errEncode != nil {
|
||||
log.WithError(errEncode).WithField("content-negotiation", contentNegotioation).Error("failed streaming status")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ~ Private methods
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -213,3 +253,18 @@ func getParameter(m map[string]string, key string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func parseAcceptHeader(accept string) mime {
|
||||
mimes := strings.Split(accept, ",")
|
||||
for _, mime := range mimes {
|
||||
values := strings.Split(mime, ";")
|
||||
|
||||
switch values[0] {
|
||||
case string(mimeApplicationJSON):
|
||||
return mimeApplicationJSON
|
||||
case string(mimeTextPlain):
|
||||
return mimeTextPlain
|
||||
}
|
||||
}
|
||||
return mimeApplicationJSON
|
||||
}
|
||||
|
||||
22
proxy/api_test.go
Normal file
22
proxy/api_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseAcceptHeader(t *testing.T) {
|
||||
|
||||
var accept mime
|
||||
|
||||
accept = parseAcceptHeader("text/plain,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
|
||||
assert.Equal(t, string(mimeTextPlain), string(accept))
|
||||
|
||||
accept = parseAcceptHeader("application/xhtml+xml,application/json;q=0.9,image/webp,image/apng,*/*;q=0.8")
|
||||
assert.Equal(t, string(mimeApplicationJSON), string(accept))
|
||||
|
||||
accept = parseAcceptHeader("application/xhtml+xml")
|
||||
assert.Equal(t, string(mimeApplicationJSON), string(accept))
|
||||
|
||||
}
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"github.com/foomo/neosproxy/client/cms"
|
||||
"github.com/foomo/neosproxy/config"
|
||||
"github.com/foomo/neosproxy/logging"
|
||||
"github.com/foomo/neosproxy/model"
|
||||
"github.com/foomo/neosproxy/notifier"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
@ -28,6 +29,12 @@ func New(cfg *config.Config, contentLoader cms.ContentLoader, contentStore store
|
||||
router: mux.NewRouter(),
|
||||
proxyHandler: httputil.NewSingleHostReverseProxy(cfg.Neos.URL),
|
||||
contentCache: content_cache.New(cacheLifetime, contentStore, contentLoader, broker),
|
||||
|
||||
status: &model.Status{
|
||||
Workspaces: cfg.Neos.Workspaces,
|
||||
ProviderReports: map[string]model.Report{},
|
||||
ConsumerReports: map[string]model.Report{},
|
||||
},
|
||||
}
|
||||
p.setupRoutes()
|
||||
for _, workspace := range cfg.Neos.Workspaces {
|
||||
|
||||
@ -8,13 +8,6 @@ import (
|
||||
"github.com/foomo/neosproxy/logging"
|
||||
)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ~ Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const neosproxyPath = "/neosproxy"
|
||||
const routeContentServerExport = "/contentserver/export"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ~ Public methods
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -24,38 +17,6 @@ func (p *Proxy) Run() error {
|
||||
return http.ListenAndServe(p.config.Proxy.Address, p.router)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ~ Private methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
func (p *Proxy) setupRoutes() {
|
||||
|
||||
// hijack content server export routes
|
||||
p.router.HandleFunc(routeContentServerExport, p.streamCachedNeosContentServerExport)
|
||||
p.router.HandleFunc(routeContentServerExport, p.streamCachedNeosContentServerExport).Queries("workspace", "{workspace}")
|
||||
|
||||
// /contentserver/export/de/571fd1ae-c8e4-4d91-a708-d97025fb015c?workspace=stage
|
||||
p.router.HandleFunc(routeContentServerExport+"/{dimension}/{id}", p.getContent)
|
||||
p.router.HandleFunc(routeContentServerExport+"/{dimension}/{id}", p.getContent).Queries("workspace", "{workspace}")
|
||||
|
||||
// api
|
||||
// neosproxy/cache/%s?workspace=%s
|
||||
neosproxyRouter := p.router.PathPrefix(neosproxyPath).Subrouter()
|
||||
neosproxyRouter.Use(p.middlewareTokenAuth)
|
||||
neosproxyRouter.HandleFunc("/cache/{id}", p.invalidateCache).Methods(http.MethodDelete)
|
||||
neosproxyRouter.HandleFunc("/cache/{id}", p.invalidateCache).Methods(http.MethodDelete).Queries("workspace", "{workspace}").Name("api-delete-cache")
|
||||
|
||||
// middlewares
|
||||
p.router.Use(p.middlewareServiceUnavailable)
|
||||
|
||||
// error handling
|
||||
p.router.NotFoundHandler = http.HandlerFunc(p.notFound)
|
||||
p.router.MethodNotAllowedHandler = http.HandlerFunc(p.methodNotAllowed)
|
||||
|
||||
// fallback to proxy
|
||||
p.router.PathPrefix("/").Handler(p.proxyHandler)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ~ Error handler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
43
proxy/routes.go
Normal file
43
proxy/routes.go
Normal file
@ -0,0 +1,43 @@
|
||||
package proxy
|
||||
|
||||
import "net/http"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ~ Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const neosproxyPath = "/neosproxy"
|
||||
const routeContentServerExport = "/contentserver/export"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ~ Private methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
func (p *Proxy) setupRoutes() {
|
||||
|
||||
// hijack content server export routes
|
||||
p.router.HandleFunc(routeContentServerExport, p.streamCachedNeosContentServerExport)
|
||||
p.router.HandleFunc(routeContentServerExport, p.streamCachedNeosContentServerExport).Queries("workspace", "{workspace}")
|
||||
|
||||
// /contentserver/export/de/571fd1ae-c8e4-4d91-a708-d97025fb015c?workspace=stage
|
||||
p.router.HandleFunc(routeContentServerExport+"/{dimension}/{id}", p.getContent)
|
||||
p.router.HandleFunc(routeContentServerExport+"/{dimension}/{id}", p.getContent).Queries("workspace", "{workspace}")
|
||||
|
||||
// api
|
||||
// neosproxy/cache/%s?workspace=%s
|
||||
neosproxyRouter := p.router.PathPrefix(neosproxyPath).Subrouter()
|
||||
neosproxyRouter.Use(p.middlewareTokenAuth)
|
||||
neosproxyRouter.HandleFunc("/cache/{id}", p.invalidateCache).Methods(http.MethodDelete)
|
||||
neosproxyRouter.HandleFunc("/cache/{id}", p.invalidateCache).Methods(http.MethodDelete).Queries("workspace", "{workspace}").Name("api-delete-cache")
|
||||
neosproxyRouter.HandleFunc("/status", p.streamStatus).Methods(http.MethodGet)
|
||||
|
||||
// middlewares
|
||||
p.router.Use(p.middlewareServiceUnavailable)
|
||||
|
||||
// error handling
|
||||
p.router.NotFoundHandler = http.HandlerFunc(p.notFound)
|
||||
p.router.MethodNotAllowedHandler = http.HandlerFunc(p.methodNotAllowed)
|
||||
|
||||
// fallback to proxy
|
||||
p.router.PathPrefix("/").Handler(p.proxyHandler)
|
||||
}
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"github.com/foomo/neosproxy/cache"
|
||||
"github.com/foomo/neosproxy/config"
|
||||
"github.com/foomo/neosproxy/logging"
|
||||
"github.com/foomo/neosproxy/model"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
content_cache "github.com/foomo/neosproxy/cache/content"
|
||||
@ -22,6 +23,8 @@ type Proxy struct {
|
||||
router *mux.Router
|
||||
proxyHandler *httputil.ReverseProxy
|
||||
contentCache *content_cache.Cache
|
||||
|
||||
status *model.Status
|
||||
}
|
||||
|
||||
type basicAuth struct {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user