2019-01-24 20:15:10 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
2018-12-07 09:59:31 +00:00
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package satellitedb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-02-01 18:50:12 +00:00
|
|
|
"fmt"
|
2018-12-07 09:59:31 +00:00
|
|
|
"time"
|
|
|
|
|
2019-02-01 18:50:12 +00:00
|
|
|
"github.com/zeebo/errs"
|
2019-01-28 19:45:25 +00:00
|
|
|
|
2018-12-07 09:59:31 +00:00
|
|
|
"storj.io/storj/pkg/bwagreement"
|
2019-01-28 19:45:25 +00:00
|
|
|
"storj.io/storj/pkg/pb"
|
2019-02-01 18:50:12 +00:00
|
|
|
"storj.io/storj/pkg/storj"
|
2018-12-07 09:59:31 +00:00
|
|
|
dbx "storj.io/storj/satellite/satellitedb/dbx"
|
|
|
|
)
|
|
|
|
|
|
|
|
type bandwidthagreement struct {
|
|
|
|
db *dbx.DB
|
|
|
|
}
|
|
|
|
|
2019-02-22 21:17:35 +00:00
|
|
|
func (b *bandwidthagreement) CreateAgreement(ctx context.Context, rba *pb.Order) (err error) {
|
2019-01-28 19:45:25 +00:00
|
|
|
expiration := time.Unix(rba.PayerAllocation.ExpirationUnixSec, 0)
|
|
|
|
_, err = b.db.Create_Bwagreement(
|
2018-12-07 09:59:31 +00:00
|
|
|
ctx,
|
2019-01-28 19:45:25 +00:00
|
|
|
dbx.Bwagreement_Serialnum(rba.PayerAllocation.SerialNumber+rba.StorageNodeId.String()),
|
2019-02-01 18:50:12 +00:00
|
|
|
dbx.Bwagreement_StorageNodeId(rba.StorageNodeId.Bytes()),
|
|
|
|
dbx.Bwagreement_UplinkId(rba.PayerAllocation.UplinkId.Bytes()),
|
2019-01-28 21:16:21 +00:00
|
|
|
dbx.Bwagreement_Action(int64(rba.PayerAllocation.Action)),
|
|
|
|
dbx.Bwagreement_Total(rba.Total),
|
2019-01-28 19:45:25 +00:00
|
|
|
dbx.Bwagreement_ExpiresAt(expiration),
|
2018-12-07 09:59:31 +00:00
|
|
|
)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-02-01 18:50:12 +00:00
|
|
|
//GetTotals returns stats about an uplink
|
|
|
|
func (b *bandwidthagreement) GetUplinkStats(ctx context.Context, from, to time.Time) (stats []bwagreement.UplinkStat, err error) {
|
|
|
|
|
|
|
|
var uplinkSQL = fmt.Sprintf(`SELECT uplink_id, SUM(total),
|
|
|
|
COUNT(CASE WHEN action = %d THEN total ELSE null END),
|
|
|
|
COUNT(CASE WHEN action = %d THEN total ELSE null END), COUNT(*)
|
|
|
|
FROM bwagreements WHERE created_at > ?
|
|
|
|
AND created_at <= ? GROUP BY uplink_id ORDER BY uplink_id`,
|
|
|
|
pb.BandwidthAction_PUT, pb.BandwidthAction_GET)
|
2019-02-05 16:33:14 +00:00
|
|
|
rows, err := b.db.DB.Query(b.db.Rebind(uplinkSQL), from.UTC(), to.UTC())
|
2018-12-07 09:59:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
defer func() { err = errs.Combine(err, rows.Close()) }()
|
|
|
|
for rows.Next() {
|
|
|
|
var nodeID []byte
|
|
|
|
stat := bwagreement.UplinkStat{}
|
|
|
|
err := rows.Scan(&nodeID, &stat.TotalBytes, &stat.PutActionCount, &stat.GetActionCount, &stat.TotalTransactions)
|
2019-01-28 19:45:25 +00:00
|
|
|
if err != nil {
|
2019-02-01 18:50:12 +00:00
|
|
|
return stats, err
|
2019-01-28 19:45:25 +00:00
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
id, err := storj.NodeIDFromBytes(nodeID)
|
|
|
|
if err != nil {
|
|
|
|
return stats, err
|
|
|
|
}
|
|
|
|
stat.NodeID = id
|
|
|
|
stats = append(stats, stat)
|
2018-12-07 09:59:31 +00:00
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
return stats, nil
|
2018-12-07 09:59:31 +00:00
|
|
|
}
|
|
|
|
|
2019-02-01 18:50:12 +00:00
|
|
|
//GetTotals returns the sum of each bandwidth type after (exluding) a given date range
|
|
|
|
func (b *bandwidthagreement) GetTotals(ctx context.Context, from, to time.Time) (bwa map[storj.NodeID][]int64, err error) {
|
|
|
|
var getTotalsSQL = fmt.Sprintf(`SELECT storage_node_id,
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END),
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END),
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END),
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END),
|
|
|
|
SUM(CASE WHEN action = %d THEN total ELSE 0 END)
|
|
|
|
FROM bwagreements WHERE created_at > ? AND created_at <= ?
|
|
|
|
GROUP BY storage_node_id ORDER BY storage_node_id`, pb.BandwidthAction_PUT,
|
|
|
|
pb.BandwidthAction_GET, pb.BandwidthAction_GET_AUDIT,
|
|
|
|
pb.BandwidthAction_GET_REPAIR, pb.BandwidthAction_PUT_REPAIR)
|
2019-02-05 16:33:14 +00:00
|
|
|
rows, err := b.db.DB.Query(b.db.Rebind(getTotalsSQL), from.UTC(), to.UTC())
|
2018-12-07 09:59:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
defer func() { err = errs.Combine(err, rows.Close()) }()
|
2018-12-07 09:59:31 +00:00
|
|
|
|
2019-02-01 18:50:12 +00:00
|
|
|
totals := make(map[storj.NodeID][]int64)
|
|
|
|
for i := 0; rows.Next(); i++ {
|
|
|
|
var nodeID []byte
|
|
|
|
data := make([]int64, len(pb.BandwidthAction_value))
|
|
|
|
err := rows.Scan(&nodeID, &data[pb.BandwidthAction_PUT], &data[pb.BandwidthAction_GET],
|
|
|
|
&data[pb.BandwidthAction_GET_AUDIT], &data[pb.BandwidthAction_GET_REPAIR], &data[pb.BandwidthAction_PUT_REPAIR])
|
|
|
|
if err != nil {
|
|
|
|
return totals, err
|
|
|
|
}
|
|
|
|
id, err := storj.NodeIDFromBytes(nodeID)
|
2019-01-28 19:45:25 +00:00
|
|
|
if err != nil {
|
2019-02-01 18:50:12 +00:00
|
|
|
return totals, err
|
2019-01-28 19:45:25 +00:00
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
totals[id] = data
|
2018-12-07 09:59:31 +00:00
|
|
|
}
|
2019-02-01 18:50:12 +00:00
|
|
|
return totals, nil
|
2018-12-07 09:59:31 +00:00
|
|
|
}
|
2019-01-10 18:30:55 +00:00
|
|
|
|
|
|
|
func (b *bandwidthagreement) DeletePaidAndExpired(ctx context.Context) error {
|
|
|
|
// TODO: implement deletion of paid and expired BWAs
|
|
|
|
return Error.New("DeletePaidAndExpired not implemented")
|
|
|
|
}
|