You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
3.5 KiB
149 lines
3.5 KiB
package mockserver
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type notification struct {
|
|
NamespaceName string `json:"namespaceName,omitempty"`
|
|
NotificationID int `json:"notificationId,omitempty"`
|
|
}
|
|
|
|
type result struct {
|
|
// AppID string `json:"appId"`
|
|
// Cluster string `json:"cluster"`
|
|
NamespaceName string `json:"namespaceName"`
|
|
Configurations map[string]string `json:"configurations"`
|
|
ReleaseKey string `json:"releaseKey"`
|
|
}
|
|
|
|
type mockServer struct {
|
|
server http.Server
|
|
|
|
lock sync.Mutex
|
|
notifications map[string]int
|
|
config map[string]map[string]string
|
|
}
|
|
|
|
func (s *mockServer) NotificationHandler(rw http.ResponseWriter, req *http.Request) {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
req.ParseForm()
|
|
var notifications []notification
|
|
if err := json.Unmarshal([]byte(req.FormValue("notifications")), ¬ifications); err != nil {
|
|
rw.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
var changes []notification
|
|
for _, noti := range notifications {
|
|
if currentID := s.notifications[noti.NamespaceName]; currentID != noti.NotificationID {
|
|
changes = append(changes, notification{NamespaceName: noti.NamespaceName, NotificationID: currentID})
|
|
}
|
|
}
|
|
|
|
if len(changes) == 0 {
|
|
rw.WriteHeader(http.StatusNotModified)
|
|
return
|
|
}
|
|
bts, err := json.Marshal(&changes)
|
|
if err != nil {
|
|
rw.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
rw.Write(bts)
|
|
}
|
|
|
|
func (s *mockServer) ConfigHandler(rw http.ResponseWriter, req *http.Request) {
|
|
req.ParseForm()
|
|
|
|
strs := strings.Split(req.RequestURI, "/")
|
|
var namespace, releaseKey = strings.Split(strs[4], "?")[0], req.FormValue("releaseKey")
|
|
config := s.Get(namespace)
|
|
|
|
var result = result{NamespaceName: namespace, Configurations: config, ReleaseKey: releaseKey}
|
|
bts, err := json.Marshal(&result)
|
|
if err != nil {
|
|
rw.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
rw.Write(bts)
|
|
}
|
|
|
|
var server *mockServer
|
|
|
|
func (s *mockServer) Set(namespace, key, value string) {
|
|
server.lock.Lock()
|
|
defer server.lock.Unlock()
|
|
|
|
notificationID := s.notifications[namespace]
|
|
notificationID++
|
|
s.notifications[namespace] = notificationID
|
|
|
|
if kv, ok := s.config[namespace]; ok {
|
|
kv[key] = value
|
|
return
|
|
}
|
|
kv := map[string]string{key: value}
|
|
s.config[namespace] = kv
|
|
}
|
|
|
|
func (s *mockServer) Get(namespace string) map[string]string {
|
|
server.lock.Lock()
|
|
defer server.lock.Unlock()
|
|
|
|
return s.config[namespace]
|
|
}
|
|
|
|
func (s *mockServer) Delete(namespace, key string) {
|
|
server.lock.Lock()
|
|
defer server.lock.Unlock()
|
|
|
|
if kv, ok := s.config[namespace]; ok {
|
|
delete(kv, key)
|
|
}
|
|
|
|
notificationID := s.notifications[namespace]
|
|
notificationID++
|
|
s.notifications[namespace] = notificationID
|
|
}
|
|
|
|
// Set namespace's key value
|
|
func Set(namespace, key, value string) {
|
|
server.Set(namespace, key, value)
|
|
}
|
|
|
|
// Delete namespace's key
|
|
func Delete(namespace, key string) {
|
|
server.Delete(namespace, key)
|
|
}
|
|
|
|
// Run mock server
|
|
func Run() error {
|
|
initServer()
|
|
return server.server.ListenAndServe()
|
|
}
|
|
|
|
func initServer() {
|
|
server = &mockServer{
|
|
notifications: map[string]int{},
|
|
config: map[string]map[string]string{},
|
|
}
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/notifications/", http.HandlerFunc(server.NotificationHandler))
|
|
mux.Handle("/configs/", http.HandlerFunc(server.ConfigHandler))
|
|
server.server.Handler = mux
|
|
server.server.Addr = ":8080"
|
|
}
|
|
|
|
// Close mock server
|
|
func Close() error {
|
|
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second))
|
|
defer cancel()
|
|
|
|
return server.server.Shutdown(ctx)
|
|
}
|
|
|