93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
mysqlstorage "hyapp/services/statistics-service/internal/storage/mysql"
|
|
)
|
|
|
|
type queryHTTPServer struct {
|
|
repo *mysqlstorage.Repository
|
|
server *http.Server
|
|
listener net.Listener
|
|
}
|
|
|
|
func newQueryHTTPServer(addr string, repo *mysqlstorage.Repository) (*queryHTTPServer, error) {
|
|
addr = strings.TrimSpace(addr)
|
|
if addr == "" {
|
|
return nil, nil
|
|
}
|
|
listener, err := net.Listen("tcp", addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s := &queryHTTPServer{repo: repo, listener: listener}
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/internal/v1/statistics/overview", s.overview)
|
|
s.server = &http.Server{Handler: mux, ReadHeaderTimeout: 2 * time.Second}
|
|
return s, nil
|
|
}
|
|
|
|
func (s *queryHTTPServer) Run() error {
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
err := s.server.Serve(s.listener)
|
|
if errors.Is(err, http.ErrServerClosed) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (s *queryHTTPServer) Close(ctx context.Context) error {
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
return s.server.Shutdown(ctx)
|
|
}
|
|
|
|
func (s *queryHTTPServer) overview(w http.ResponseWriter, r *http.Request) {
|
|
query := r.URL.Query()
|
|
startMS := parseInt64(query.Get("start_ms"))
|
|
endMS := parseInt64(query.Get("end_ms"))
|
|
if startMS <= 0 {
|
|
now := time.Now().UTC()
|
|
startMS = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC).UnixMilli()
|
|
}
|
|
if endMS <= startMS {
|
|
endMS = startMS + 24*time.Hour.Milliseconds()
|
|
}
|
|
overview, err := s.repo.QueryOverview(r.Context(), mysqlstorage.OverviewQuery{
|
|
AppCode: query.Get("app_code"),
|
|
StartMS: startMS,
|
|
EndMS: endMS,
|
|
SeriesStartMS: parseInt64(query.Get("series_start_ms")),
|
|
SeriesEndMS: parseInt64(query.Get("series_end_ms")),
|
|
CountryID: parseInt64(query.Get("country_id")),
|
|
RegionID: parseInt64(query.Get("region_id")),
|
|
})
|
|
if err != nil {
|
|
writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()})
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, overview)
|
|
}
|
|
|
|
func parseInt64(value string) int64 {
|
|
parsed, _ := strconv.ParseInt(strings.TrimSpace(value), 10, 64)
|
|
return parsed
|
|
}
|
|
|
|
func writeJSON(w http.ResponseWriter, status int, payload any) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(status)
|
|
_ = json.NewEncoder(w).Encode(payload)
|
|
}
|