package network
import (
"encoding/json"
"net/http"
"strings"
"sync"
"time"
"github.com/xssed/owlcache/cache"
owlconfig "github.com/xssed/owlcache/config"
"github.com/xssed/owlcache/group"
owllog "github.com/xssed/owlcache/log"
"github.com/xssed/owlcache/network/httpclient"
owltools "github.com/xssed/owlcache/tools"
)
func (owlhandler *OwlHandler) GetGroupData(w http.ResponseWriter, r *http.Request) {
if string(owlhandler.owlrequest.Value) != "info" {
resmap := owlhandler.conversionContent(owlhandler.getHttpData())
if len(resmap) == 0 {
owlhandler.Transmit(NOT_FOUND)
owlhandler.owlresponse.Data = []byte("")
return
}
owlhandler.Transmit(SUCCESS)
owlhandler.owlresponse.Data = resmap[0]["Data"].([]byte)
return
}
resmap := owlhandler.conversionContentInfo(owlhandler.getHttpData())
if len(resmap) == 0 {
owlhandler.Transmit(NOT_FOUND)
return
}
owlhandler.Transmit(SUCCESS)
w.Header().Set("Content-Type", "application/json; charset=utf-8;")
data, _ := json.Marshal(&resmap)
owlhandler.owlresponse.Data = data
return
}
func (owlhandler *OwlHandler) getHttpData() []OwlResponse {
list := ServerGroupList.Values()
groupKVlist := group.NewServergroup()
var wg sync.WaitGroup
if len(owlhandler.owlrequest.Target) > 3 {
for k := range list {
val, ok := list[k].(group.OwlServerGroupRequest)
if ok {
if owlhandler.owlrequest.Target == val.Address {
wg.Add(1)
go owlhandler.parseContent(val.Address, owlhandler.owlrequest.Key, groupKVlist, &wg)
wg.Wait()
}
}
}
} else {
for k := range list {
val, ok := list[k].(group.OwlServerGroupRequest)
if ok {
wg.Add(1)
go owlhandler.parseContent(val.Address, owlhandler.owlrequest.Key, groupKVlist, &wg)
}
}
wg.Wait()
}
bubblesortlist := owlhandler.bubbleSortContent(groupKVlist)
return bubblesortlist
}
func (owlhandler *OwlHandler) parseContent(address, key string, kvlist *group.Servergroup, wg *sync.WaitGroup) {
defer wg.Done()
bhgc_key := owltools.JoinString(address, ":", key)
bhgc_key_RHKCT := owltools.JoinString(address, ":", key, ":", "RHKCT")
bhgc_key_state := owltools.JoinString(address, ":", key, ":", "State")
if v, found := BaseHttpGroupCache.GetKvStore(bhgc_key); found {
var resbody OwlResponse
resbody.Status = ResStatus(200)
resbody.Key = key
resbody.Data = v.(*cache.KvStore).Value
if v2, found2 := BaseHttpGroupCache.GetKvStore(bhgc_key_RHKCT); found2 {
infos := strings.Split(string(v2.(*cache.KvStore).Value), "|")
resbody.ResponseHost = infos[0]
cache_t, cterr := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", infos[1])
if cterr != nil {
owllog.OwlLogHttpG.Info("OwlHandler parseContent Keycreatetime time.Parse failed: " + cterr.Error())
}
resbody.KeyCreateTime = cache_t
} else {
resbody.ResponseHost = ""
resbody.KeyCreateTime = v.(*cache.KvStore).CreateTime
}
kvlist.Add(resbody)
return
} else {
exptime, _ := time.ParseDuration(owltools.JoinString(owlconfig.OwlConfigModel.HttpClientRequestLocalCacheLifeTime, "ms"))
if v3, found3 := BaseHttpGroupCache.GetKvStore(bhgc_key_state); found3 {
if string(v3.(*cache.KvStore).Value) == "0" {
return
}
}
var HttpClient *httpclient.OwlClient
HttpClient = httpclient.NewOwlClient()
s := HttpClient.GetValue(address, key)
if s != nil {
var resbody OwlResponse
resbody.Status = ResStatus(s.StatusCode)
resbody.Key = s.Header.Get("Key")
resbody.Data = s.Byte()
tkt := s.Header.Get("Keycreatetime")
if len(tkt) > 37 {
tkt = strings.TrimSpace(tkt[0:37])
}
t, terr := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", tkt)
if terr != nil {
owllog.OwlLogHttpG.Info("OwlHandler parseContent Keycreatetime time.Parse failed: " + terr.Error())
}
resbody.KeyCreateTime = t
resbody.ResponseHost = s.Header.Get("Responsehost")
kvlist.Add(resbody)
if owlconfig.OwlConfigModel.HttpClientRequestLocalCacheLifeTime != "0" {
BaseHttpGroupCache.Set(bhgc_key_state, []byte("1"), exptime)
rhkct_text := []byte(owltools.JoinString(resbody.ResponseHost, "|", tkt))
BaseHttpGroupCache.Set(bhgc_key_RHKCT, rhkct_text, exptime)
BaseHttpGroupCache.Set(bhgc_key, resbody.Data, exptime)
}
return
}
if owlconfig.OwlConfigModel.HttpClientRequestLocalCacheLifeTime != "0" {
BaseHttpGroupCache.Set(bhgc_key_state, []byte("0"), exptime)
}
return
}
}
func (owlhandler *OwlHandler) bubbleSortContent(kvlist *group.Servergroup) []OwlResponse {
var array []OwlResponse
list := kvlist.Values()
for k := range list {
val, ok := list[k].(OwlResponse)
if ok {
array = append(array, val)
}
}
var sorted = false
for !sorted {
sorted = true
for i := 0; i < len(array)-1; i++ {
if array[i].KeyCreateTime.Unix() < array[i+1].KeyCreateTime.Unix() {
sorted = false
array[i], array[i+1] = array[i+1], array[i]
}
}
}
return array
}
func (owlhandler *OwlHandler) conversionContentInfo(res_slice []OwlResponse) []map[string]interface{} {
var response_list []map[string]interface{}
for index := range res_slice {
oldresponse := res_slice[index]
if oldresponse.Status == 200 {
temp_map := make(map[string]interface{})
temp_map["Address"] = oldresponse.ResponseHost
temp_map["Key"] = oldresponse.Key
temp_map["Data"] = oldresponse.Data
temp_map["Status"] = oldresponse.Status
temp_map["KeyCreateTime"] = oldresponse.KeyCreateTime
response_list = append(response_list, temp_map)
}
}
return response_list
}
func (owlhandler *OwlHandler) conversionContent(res_slice []OwlResponse) []map[string]interface{} {
var response_list []map[string]interface{}
for index := range res_slice {
oldresponse := res_slice[index]
if oldresponse.Status == 200 {
temp_map := make(map[string]interface{})
temp_map["Data"] = oldresponse.Data
response_list = append(response_list, temp_map)
}
}
return response_list
}