blob: a516ae5a551afd303176e64fba57a62716dce6f3 [file] [log] [blame]
package tc
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import (
"database/sql"
"encoding/json"
"errors"
"time"
"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
"github.com/apache/trafficcontrol/lib/go-util"
validation "github.com/go-ozzo/ozzo-validation"
)
const dateFormat = "2006-01-02"
// StatsSummaryResponse is the structure of a response from Traffic Ops to
// GET requests made to its /stats_summary API endpoint.
type StatsSummaryResponse struct {
Response []StatsSummary `json:"response"`
Alerts
}
// StatsSummary is a summary of some kind of statistic for a CDN and/or
// Delivery Service.
type StatsSummary struct {
CDNName *string `json:"cdnName" db:"cdn_name"`
DeliveryService *string `json:"deliveryServiceName" db:"deliveryservice_name"`
// The name of the stat, which can be whatever the TO API client wants.
StatName *string `json:"statName" db:"stat_name"`
// The value of the stat - this cannot actually be nil in a valid
// StatsSummary.
StatValue *float64 `json:"statValue" db:"stat_value"`
SummaryTime time.Time `json:"summaryTime" db:"summary_time"`
StatDate *time.Time `json:"statDate" db:"stat_date"`
}
// Validate implements the
// github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api.ParseValidator
// interface.
func (ss StatsSummary) Validate(tx *sql.Tx) error {
errs := tovalidate.ToErrors(validation.Errors{
"statName": validation.Validate(ss.StatName, validation.Required),
"statValue": validation.Validate(ss.StatValue, validation.Required),
})
return util.JoinErrs(errs)
}
// UnmarshalJSON implements the encoding/json.Unmarshaler interface with a
// customized decoding to force the date format on StatDate.
func (ss *StatsSummary) UnmarshalJSON(data []byte) error {
type Alias StatsSummary
resp := struct {
SummaryTime string `json:"summaryTime"`
StatDate *string `json:"statDate"`
*Alias
}{
Alias: (*Alias)(ss),
}
err := json.Unmarshal(data, &resp)
if err != nil {
return err
}
if resp.StatDate != nil {
statDate, err := parseTime(*resp.StatDate)
if err != nil {
return errors.New("invalid timestamp given for statDate")
}
ss.StatDate = &statDate
}
ss.SummaryTime, err = parseTime(resp.SummaryTime)
if err != nil {
return errors.New("invalid timestamp given for summaryTime")
}
return nil
}
func parseTime(ts string) (time.Time, error) {
rt, err := time.Parse(time.RFC3339, ts)
if err == nil {
return rt, err
}
rt, err = time.Parse(TimeLayout, ts)
if err == nil {
return rt, err
}
return time.Parse(dateFormat, ts)
}
// MarshalJSON implements the encoding/json.Marshaler interface with a
// customized encoding to force the date format on StatDate.
func (ss StatsSummary) MarshalJSON() ([]byte, error) {
type Alias StatsSummary
resp := struct {
StatDate *string `json:"statDate"`
SummaryTime string `json:"summaryTime"`
Alias
}{
SummaryTime: ss.SummaryTime.Format(TimeLayout),
Alias: (Alias)(ss),
}
if ss.StatDate != nil {
resp.StatDate = util.StrPtr(ss.StatDate.Format(dateFormat))
}
return json.Marshal(&resp)
}
// StatsSummaryLastUpdated is the type of the `response` property of a response
// from Traffic Ops to a GET request made to its /stats_summary endpoint when
// the 'lastSummaryDate' query string parameter is passed as 'true'.
type StatsSummaryLastUpdated struct {
SummaryTime *time.Time `json:"summaryTime" db:"summary_time"`
}
// MarshalJSON implements the encoding/json.Marshaler interface with a
// customized encoding to force the date format on SummaryTime.
func (ss StatsSummaryLastUpdated) MarshalJSON() ([]byte, error) {
resp := struct {
SummaryTime *string `json:"summaryTime"`
}{}
if ss.SummaryTime != nil {
resp.SummaryTime = util.StrPtr(ss.SummaryTime.Format(TimeLayout))
}
return json.Marshal(&resp)
}
// UnmarshalJSON implements the encoding/json.Unmarshaler interface with a
// customized decoding to force the SummaryTime format.
func (ss *StatsSummaryLastUpdated) UnmarshalJSON(data []byte) error {
resp := struct {
SummaryTime *string `json:"summaryTime"`
}{}
err := json.Unmarshal(data, &resp)
if err != nil {
return err
}
if resp.SummaryTime != nil {
var summaryTime time.Time
summaryTime, err = time.Parse(time.RFC3339, *resp.SummaryTime)
if err == nil {
ss.SummaryTime = &summaryTime
return nil
}
summaryTime, err = time.Parse(TimeLayout, *resp.SummaryTime)
ss.SummaryTime = &summaryTime
return err
}
return nil
}
// StatsSummaryLastUpdatedResponse is the type of a response from Traffic Ops
// to a GET request made to its /stats_summary endpoint when the
// 'lastSummaryDate' query string parameter is passed as 'true'.
//
// Deprecated: This structure includes an unknown field and drops Alerts
// returned by the API - use StatsSummaryLastUpdatedAPIResponse instead.
type StatsSummaryLastUpdatedResponse struct {
// This field has unknown purpose and meaning - do not depend on its value
// for anything.
Version string `json:"version"`
Response StatsSummaryLastUpdated `json:"response"`
}
// StatsSummaryLastUpdatedAPIResponse is the type of a response from Traffic
// Ops to a request to its /stats_summary endpoint with the 'lastSummaryDate'
// query string parameter set to 'true'.
type StatsSummaryLastUpdatedAPIResponse struct {
Response StatsSummaryLastUpdated `json:"response"`
Alerts
}