Skip to content
This repository was archived by the owner on Nov 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- SANs information to the SSL key endpoint and Traffic Portal page.

### Fixed
- [#6197](https://github.com/apache/trafficcontrol/issues/6197) - TO `/deliveryservices/:id/routing` makes requests to all TRs instead of by CDN.
- Fixed Traffic Router crs/stats to prevent overflow and to correctly record the time used in averages.
- [#5893](https://github.com/apache/trafficcontrol/issues/5893) - A self signed certificate is created when an HTTPS delivery service is created or an HTTP delivery service is updated to HTTPS.
- [#6255](https://github.com/apache/trafficcontrol/issues/6255) - Unreadable Prod Mode CDN Notifications in Traffic Portal
Expand Down
4 changes: 2 additions & 2 deletions traffic_ops/traffic_ops_golang/crstats/dsrouting.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func GetDSRouting(w http.ResponseWriter, r *http.Request) {
return
}

dsType, exists, err := dbhelpers.GetDeliveryServiceType(dsID, tx)
dsType, cdnName, exists, err := dbhelpers.GetDeliveryServiceTypeAndCDNName(dsID, tx)
if err != nil {
api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, fmt.Errorf("getting delivery service type: %v", err))
return
Expand Down Expand Up @@ -85,7 +85,7 @@ func GetDSRouting(w http.ResponseWriter, r *http.Request) {
return
}

routers, err := getCDNRouterFQDNs(tx, nil)
routers, err := getCDNRouterFQDNs(tx, &cdnName)
if err != nil {
api.HandleErr(w, r, tx, http.StatusInternalServerError, nil, errors.New("getting monitors: "+err.Error()))
return
Expand Down
12 changes: 10 additions & 2 deletions traffic_ops/traffic_ops_golang/crstats/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ func getCRSStats(respond chan<- RouterResp, wg *sync.WaitGroup, routerFQDN, cdn

// getCDNRouterFQDNs returns an FQDN, including port, of an online router for each CDN, for each router. If a CDN has no online routers, that CDN will not have an entry in the map. The port returned is the API port.
func getCDNRouterFQDNs(tx *sql.Tx, requiredCDN *string) (map[tc.CDNName][]string, error) {
rows, err := tx.Query(`
var args interface{}
query := `
SELECT s.host_name, s.domain_name, max(pa.value) as port, c.name as cdn
FROM server as s
JOIN type as t ON s.type = t.id
Expand All @@ -218,8 +219,15 @@ JOIN profile_parameter as pp ON pp.profile = pr.id
LEFT JOIN parameter as pa ON (pp.parameter = pa.id AND pa.name = 'api.port' AND pa.config_file = 'server.xml')
WHERE t.name = '` + tc.RouterTypeName + `'
AND st.name = '` + RouterOnlineStatus + `'
`
if requiredCDN != nil {
query += `AND c.name = $1`
args = *requiredCDN
}
query += `
GROUP BY s.host_name, s.domain_name, c.name
`)
`
rows, err := tx.Query(query, args)
if err != nil {
return nil, errors.New("querying routers: " + err.Error())
}
Expand Down
105 changes: 105 additions & 0 deletions traffic_ops/traffic_ops_golang/crstats/routing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package crstats

/*
* 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 (
"context"
"testing"
"time"

"github.com/apache/trafficcontrol/lib/go-util"

"gopkg.in/DATA-DOG/go-sqlmock.v1"
)

func TestGetCDNRouterFQDNs(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}

mock.ExpectBegin()
rows := sqlmock.NewRows([]string{
"host_name",
"domain_name",
"port",
"cdn"})

rows.AddRow("host1", "test", 2500, "ott")
mock.ExpectQuery("SELECT").WithArgs("ott").WillReturnRows(rows)
mock.ExpectCommit()

dbCtx, cancelTx := context.WithTimeout(context.TODO(), 10*time.Second)
defer cancelTx()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
result, err := getCDNRouterFQDNs(tx, util.StrPtr("ott"))
if err != nil {
t.Fatalf("error Getting CDN router FQDN: %v", err)
}
if len(result) != 1 {
t.Fatalf("expected to receive one item in the response, but got %d", len(result))
}
if _, ok := result["ott"]; !ok {
t.Fatal("expected to get an item with 'ott' key, but got nothing")
}
}

func TestGetCDNRouterFQDNsWithoutCDN(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}

mock.ExpectBegin()
rows := sqlmock.NewRows([]string{
"host_name",
"domain_name",
"port",
"cdn"})

rows.AddRow("host1", "test", 2500, "ott")
rows.AddRow("host2", "test2", 3500, "newCDN")
mock.ExpectQuery("SELECT").WithArgs(nil).WillReturnRows(rows)
mock.ExpectCommit()

dbCtx, cancelTx := context.WithTimeout(context.TODO(), 10*time.Second)
defer cancelTx()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatal("creating transaction: ", err)
}

result, err := getCDNRouterFQDNs(tx, nil)
if err != nil {
t.Fatalf("error Getting CDN router FQDN: %v", err)
}
if len(result) != 2 {
t.Fatalf("expected to receive two items in the response, but got %d", len(result))
}
if _, ok := result["ott"]; !ok {
t.Fatal("expected to get an item with 'ott' key, but got nothing")
}
if _, ok := result["newCDN"]; !ok {
t.Fatal("expected to get an item with 'newCDN' key, but got nothing")
}
}
13 changes: 7 additions & 6 deletions traffic_ops/traffic_ops_golang/dbhelpers/db_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1421,16 +1421,17 @@ func CachegroupParameterAssociationExists(id int, cachegroup int, tx *sql.Tx) (b
return count > 0, nil
}

// GetDeliveryServiceType returns the type of the deliveryservice.
func GetDeliveryServiceType(dsID int, tx *sql.Tx) (tc.DSType, bool, error) {
// GetDeliveryServiceTypeAndCDNName returns the type and the CDN name of the deliveryservice.
func GetDeliveryServiceTypeAndCDNName(dsID int, tx *sql.Tx) (tc.DSType, string, bool, error) {
var dsType tc.DSType
if err := tx.QueryRow(`SELECT t.name FROM deliveryservice as ds JOIN type t ON ds.type = t.id WHERE ds.id=$1`, dsID).Scan(&dsType); err != nil {
var cdnName string
if err := tx.QueryRow(`SELECT t.name, c.name as cdn FROM deliveryservice as ds JOIN type t ON ds.type = t.id JOIN cdn c ON c.id = ds.cdn_id WHERE ds.id=$1`, dsID).Scan(&dsType, &cdnName); err != nil {
if err == sql.ErrNoRows {
return tc.DSTypeInvalid, false, nil
return tc.DSTypeInvalid, cdnName, false, nil
}
return tc.DSTypeInvalid, false, errors.New("querying type from delivery service: " + err.Error())
return tc.DSTypeInvalid, cdnName, false, errors.New("querying type from delivery service: " + err.Error())
}
return dsType, true, nil
return dsType, cdnName, true, nil
}

// GetDeliveryServiceTypeAndTopology returns the type of the deliveryservice and the name of its topology.
Expand Down
2 changes: 1 addition & 1 deletion traffic_ops/traffic_ops_golang/server/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ func getServers(h http.Header, params map[string]string, tx *sqlx.Tx, user *auth
queryAddition = fmt.Sprintf(deliveryServiceServersJoin, joinSubQuery)

// depending on ds type, also need to add mids
dsType, _, err := dbhelpers.GetDeliveryServiceType(dsID, tx.Tx)
dsType, _, _, err := dbhelpers.GetDeliveryServiceTypeAndCDNName(dsID, tx.Tx)
if err != nil {
return nil, 0, nil, err, http.StatusInternalServerError, nil
}
Expand Down