diff --git a/node/api.go b/node/api.go index 81ddcf5..ae96a1c 100644 --- a/node/api.go +++ b/node/api.go @@ -4,12 +4,15 @@ import ( "github.com/gorilla/mux" "log" "net/http" + "strings" "time" ) // ListTXTHandler ... func (es ESConf) ListTXTHandler(w http.ResponseWriter, r *http.Request) { + LogRequest(r) + ch := make(chan []byte) // Get echolist go func() { @@ -22,11 +25,45 @@ func (es ESConf) ListTXTHandler(w http.ResponseWriter, r *http.Request) { w.Write(echoes) } +// XFeaturesHandler list supported features +func XFeaturesHandler(w http.ResponseWriter, r *http.Request) { + features := []string{"list.txt", "x/features"} + + LogRequest(r) + + w.WriteHeader(200) + w.Write([]byte(strings.Join(features, "\n"))) +} + +// EHandler /e/ schema +func (es ESConf) EHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + echo := vars["echo"] + + LogRequest(r) + + ch := make(chan []string) + // Get echolist + go func() { + ch <- es.GetEchoMessageHashes(echo) + }() + + messages := <-ch + + w.WriteHeader(200) + w.Write([]byte(strings.Join(messages, "\n"))) +} + // Serve ... func Serve(listen string, es ESConf) { r := mux.NewRouter() r.HandleFunc("/list.txt", es.ListTXTHandler) - http.Handle("/list.txt", r) + r.HandleFunc("/x/features", XFeaturesHandler) + + // Standart schemas + r.HandleFunc("/e/{echo}", es.EHandler) + + http.Handle("/", r) srv := http.Server{ Handler: r, diff --git a/node/elastic.go b/node/elastic.go index c38ddcc..fef6c67 100644 --- a/node/elastic.go +++ b/node/elastic.go @@ -25,6 +25,44 @@ type Bucket struct { DocCount int `json:"doc_count"` } +// GetEchoMessageHashes ... +func (es ESConf) GetEchoMessageHashes(echo string) []string { + var hashes []string + + searchURI := strings.Join([]string{es.Host, es.Index, es.Type, "_search"}, "/") + searchQ := []byte(strings.Join([]string{ + `{"sort": [ + {"date":{ "order": "desc" }},{ "_score":{ "order": "desc" }}], + "query": {"query_string" : {"fields": ["msgid", "echo"], "query":"`, echo, `"}}, "size": 500}`}, "")) + + req, err := http.NewRequest("POST", searchURI, bytes.NewBuffer(searchQ)) + client := &http.Client{} + resp, err := client.Do(req) + + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return hashes + } + + esresp, err := gabs.ParseJSON(body) + if err != nil { + panic(err) + } + + hits, _ := esresp.Path("hits.hits").Data().([]interface{}) + for _, hit := range hits { + h := make(map[string]interface{}) + h = hit.(map[string]interface{}) + source := make(map[string]interface{}) + source = h["_source"].(map[string]interface{}) + hashes = append(hashes, source["msgid"].(string)) + } + + return hashes +} + // GetListTXT ... func (es ESConf) GetListTXT() []byte { searchURI := strings.Join([]string{es.Host, es.Index, es.Type, "_search"}, "/") diff --git a/node/logger.go b/node/logger.go new file mode 100644 index 0000000..9796bc7 --- /dev/null +++ b/node/logger.go @@ -0,0 +1,13 @@ +package node + +import ( + "log" + "net/http" + "strings" +) + +// LogRequest ... +func LogRequest(r *http.Request) { + logString := strings.Join([]string{r.Method, string(r.ContentLength), r.RequestURI, r.RemoteAddr}, " ") + log.Print("[API] ", logString) +}