This is an automated email from the ASF dual-hosted git repository.

ocket8888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 9ae69f5  Add support for "cdn" query parameter in GET 
/deliveryserviceserver API (#6167)
9ae69f5 is described below

commit 9ae69f5a3dedf6496dd7ed1ceb06a5e6b7796655
Author: Rawlin Peters <[email protected]>
AuthorDate: Thu Sep 9 21:17:49 2021 -0600

    Add support for "cdn" query parameter in GET /deliveryserviceserver API 
(#6167)
    
    * Add support for "cdn" query parameter in GET /deliveryserviceserver API
    
    Allow filtering by CDN name via a new "cdn" query parameter. Also, don't
    sort by default due to this API being very expensive in terms of data
    already.
    
    * Fix test
    
    * Add back default 'orderby' value if not present in the request URL
    
    * Update docs to reflect 'orderby' default and empty value behavior
---
 CHANGELOG.md                                       |  1 +
 docs/source/api/v2/deliveryserviceserver.rst       | 20 ++---
 docs/source/api/v3/deliveryserviceserver.rst       | 20 ++---
 docs/source/api/v4/deliveryserviceserver.rst       | 20 ++---
 .../testing/api/v4/deliveryserviceservers_test.go  | 88 ++++++++++++++++++++++
 traffic_ops/testing/api/v4/tc-fixtures.json        | 62 +++++++++++++++
 .../deliveryservice/servers/servers.go             | 25 ++++--
 7 files changed, 202 insertions(+), 34 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6d79610..cfaca06 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 ## unreleased (but not 6.0)
 ### Added
 - [#5674](https://github.com/apache/trafficcontrol/issues/5674) Added new 
query parameters `cdn` and `maxRevalDurationDays` to the `GET /api/x/jobs` 
Traffic Ops API to filter by CDN name and within the start_time window defined 
by the `maxRevalDurationDays` GLOBAL profile parameter, respectively.
+- [#6034](https://github.com/apache/trafficcontrol/issues/6034) Added new 
query parameter `cdn` to the `GET /api/x/deliveryserviceserver` Traffic Ops API 
to filter by CDN name
 
 ## unreleased
 ### Added
diff --git a/docs/source/api/v2/deliveryserviceserver.rst 
b/docs/source/api/v2/deliveryserviceserver.rst
index f186ab0..9e9d018 100644
--- a/docs/source/api/v2/deliveryserviceserver.rst
+++ b/docs/source/api/v2/deliveryserviceserver.rst
@@ -31,15 +31,17 @@ Request Structure
 -----------------
 .. table:: Request Query Parameters
 
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       |    Name   | Required | Default           |                            
                           Description                                          
         |
-       
+===========+==========+===================+=====================================================================================================================+
-       | page      | no       | 0                 | The page number for use in 
pagination - ``0`` means "no pagination"                                        
         |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       | limit     | no       | 20                | Limits the results to a 
maximum of this number - if pagination is used, this defines the number of 
results per page |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       | orderby   | no       | "deliveryservice" | Choose the ordering of the 
results - must be the name of one of the fields of the objects in the 
``response`` array |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       |    Name   | Required | Default           |                            
                           Description                                          
                                                                  |
+       
+===========+==========+===================+==============================================================================================================================================================================+
+       | cdn       | no       | None              | Limit the results to 
delivery service servers for the given CDN name                                 
                                                                        |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | page      | no       | 0                 | The page number for use in 
pagination - ``0`` means "no pagination"                                        
                                                                  |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | limit     | no       | 20                | Limits the results to a 
maximum of this number - if pagination is used, this defines the number of 
results per page                                                          |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | orderby   | no       | "deliveryService" | Choose the ordering of the 
results - the value must either be the name of one of the fields of the objects 
in the ``response`` array or be empty to skip ordering altogether |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 .. code-block:: http
        :caption: Request Example
diff --git a/docs/source/api/v3/deliveryserviceserver.rst 
b/docs/source/api/v3/deliveryserviceserver.rst
index 4f6e6ae..e31fac7 100644
--- a/docs/source/api/v3/deliveryserviceserver.rst
+++ b/docs/source/api/v3/deliveryserviceserver.rst
@@ -31,15 +31,17 @@ Request Structure
 -----------------
 .. table:: Request Query Parameters
 
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       |    Name   | Required | Default           |                            
                           Description                                          
         |
-       
+===========+==========+===================+=====================================================================================================================+
-       | page      | no       | 0                 | The page number for use in 
pagination - ``0`` means "no pagination"                                        
         |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       | limit     | no       | 20                | Limits the results to a 
maximum of this number - if pagination is used, this defines the number of 
results per page |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       | orderby   | no       | "deliveryservice" | Choose the ordering of the 
results - must be the name of one of the fields of the objects in the 
``response`` array |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       |    Name   | Required | Default           |                            
                           Description                                          
                                                                  |
+       
+===========+==========+===================+==============================================================================================================================================================================+
+       | cdn       | no       | None              | Limit the results to 
delivery service servers for the given CDN name                                 
                                                                        |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | page      | no       | 0                 | The page number for use in 
pagination - ``0`` means "no pagination"                                        
                                                                  |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | limit     | no       | 20                | Limits the results to a 
maximum of this number - if pagination is used, this defines the number of 
results per page                                                          |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | orderby   | no       | "deliveryService" | Choose the ordering of the 
results - the value must either be the name of one of the fields of the objects 
in the ``response`` array or be empty to skip ordering altogether |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 .. code-block:: http
        :caption: Request Example
diff --git a/docs/source/api/v4/deliveryserviceserver.rst 
b/docs/source/api/v4/deliveryserviceserver.rst
index b3c9ab4..169b358 100644
--- a/docs/source/api/v4/deliveryserviceserver.rst
+++ b/docs/source/api/v4/deliveryserviceserver.rst
@@ -31,15 +31,17 @@ Request Structure
 -----------------
 .. table:: Request Query Parameters
 
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       |    Name   | Required | Default           |                            
                           Description                                          
         |
-       
+===========+==========+===================+=====================================================================================================================+
-       | page      | no       | 0                 | The page number for use in 
pagination - ``0`` means "no pagination"                                        
         |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       | limit     | no       | 20                | Limits the results to a 
maximum of this number - if pagination is used, this defines the number of 
results per page |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
-       | orderby   | no       | "deliveryservice" | Choose the ordering of the 
results - must be the name of one of the fields of the objects in the 
``response`` array |
-       
+-----------+----------+-------------------+---------------------------------------------------------------------------------------------------------------------+
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       |    Name   | Required | Default           |                            
                           Description                                          
                                                                  |
+       
+===========+==========+===================+==============================================================================================================================================================================+
+       | cdn       | no       | None              | Limit the results to 
delivery service servers for the given CDN name                                 
                                                                        |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | page      | no       | 0                 | The page number for use in 
pagination - ``0`` means "no pagination"                                        
                                                                  |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | limit     | no       | 20                | Limits the results to a 
maximum of this number - if pagination is used, this defines the number of 
results per page                                                          |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+       | orderby   | no       | "deliveryService" | Choose the ordering of the 
results - the value must either be the name of one of the fields of the objects 
in the ``response`` array or be empty to skip ordering altogether |
+       
+-----------+----------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 .. code-block:: http
        :caption: Request Example
diff --git a/traffic_ops/testing/api/v4/deliveryserviceservers_test.go 
b/traffic_ops/testing/api/v4/deliveryserviceservers_test.go
index b395109..6522737 100644
--- a/traffic_ops/testing/api/v4/deliveryserviceservers_test.go
+++ b/traffic_ops/testing/api/v4/deliveryserviceservers_test.go
@@ -38,6 +38,7 @@ func TestDeliveryServiceServers(t *testing.T) {
                TryToRemoveLastServerInDeliveryService(t)
                AssignServersToNonTopologyBasedDeliveryServiceThatUsesMidTier(t)
                GetTestDSSIMS(t)
+               GetTestDSServerByCDN(t)
        })
 }
 
@@ -513,6 +514,93 @@ func 
CreateTestDeliveryServiceServersWithRequiredCapabilities(t *testing.T) {
        }
 }
 
+func GetTestDSServerByCDN(t *testing.T) {
+       opts := client.NewRequestOptions()
+       cdns, _, err := TOSession.GetCDNs(opts)
+       if err != nil {
+               t.Fatalf("unexpected error getting CDNs: %v", err)
+       } else if len(cdns.Response) < 2 {
+               t.Fatalf("expected at least 2 CDNs but got %d instead", 
len(cdns.Response))
+       }
+       dses, _, err := TOSession.GetDeliveryServices(opts)
+       if err != nil {
+               t.Fatalf("unexpected error getting delivery services: %v", err)
+       }
+       cdnNonTopologyDSMap := make(map[int][]int)
+       dsMap := make(map[int]tc.DeliveryServiceV4)
+       for _, ds := range dses.Response {
+               dsMap[*ds.ID] = ds
+               if ds.Topology != nil && *ds.Topology != "" {
+                       continue
+               }
+               cdnNonTopologyDSMap[*ds.CDNID] = 
append(cdnNonTopologyDSMap[*ds.CDNID], *ds.ID)
+       }
+       servers, _, err := TOSession.GetServers(opts)
+       if err != nil {
+               t.Fatalf("unexpected error getting servers: %v", err)
+       }
+       serverMap := make(map[int]tc.ServerV4)
+       cdnEdgeMap := make(map[int][]int)
+       for _, server := range servers.Response {
+               serverMap[*server.ID] = server
+               if !strings.HasPrefix(server.Type, tc.EdgeTypePrefix) {
+                       continue
+               }
+               cdnEdgeMap[*server.CDNID] = append(cdnEdgeMap[*server.CDNID], 
*server.ID)
+       }
+       emptyCDN := tc.CDN{}
+       cdn1 := tc.CDN{}
+       cdn2 := tc.CDN{}
+       for i, cdn := range cdns.Response {
+               if len(cdnNonTopologyDSMap[cdn.ID]) > 0 && 
len(cdnEdgeMap[cdn.ID]) > 0 {
+                       if cdn1 == emptyCDN {
+                               cdn1 = cdns.Response[i]
+                       } else {
+                               cdn2 = cdns.Response[i]
+                               break
+                       }
+               }
+       }
+       if cdn1 == emptyCDN || cdn2 == emptyCDN {
+               t.Fatalf("expected at least 2 CDNs with at least 1 
non-topology-based deliveryservice and 1 edge each")
+       }
+       _, _, err = 
TOSession.CreateDeliveryServiceServers(cdnNonTopologyDSMap[cdn1.ID][0], 
[]int{cdnEdgeMap[cdn1.ID][0]}, true, client.RequestOptions{})
+       if err != nil {
+               t.Fatalf("unexpected error creating delivery service servers: 
%v", err)
+       }
+       _, _, err = 
TOSession.CreateDeliveryServiceServers(cdnNonTopologyDSMap[cdn2.ID][0], 
[]int{cdnEdgeMap[cdn2.ID][0]}, true, client.RequestOptions{})
+       if err != nil {
+               t.Fatalf("unexpected error creating delivery service servers: 
%v", err)
+       }
+
+       opts.QueryParameters.Set("cdn", cdn1.Name)
+       opts.QueryParameters.Set("limit", "999999999")
+       dss, _, err := TOSession.GetDeliveryServiceServers(opts)
+       if err != nil {
+               t.Fatalf("unexpected error getting delivery service servers by 
cdn: %v", err)
+       } else if len(dss.Response) < 1 {
+               t.Fatalf("getting delivery service servers - expected: at least 
1, actual: %d", len(dss.Response))
+       }
+       for _, d := range dss.Response {
+               if *dsMap[*d.DeliveryService].CDNID != cdn1.ID {
+                       t.Errorf("getting delivery service servers by cdn (%s) 
- found entry that did not match the given cdn (server hostname = %s, server 
CDN name = %s, delivery service xmlId = %s, delivery service CDN name = %s", 
cdn1.Name, *serverMap[*d.Server].HostName, *serverMap[*d.Server].CDNName, 
*dsMap[*d.DeliveryService].XMLID, *dsMap[*d.DeliveryService].CDNName)
+               }
+       }
+       opts.QueryParameters.Set("cdn", cdn2.Name)
+       dss, _, err = TOSession.GetDeliveryServiceServers(opts)
+       if err != nil {
+               t.Fatalf("unexpected error getting delivery service servers by 
cdn: %v", err)
+       } else if len(dss.Response) < 1 {
+               t.Fatalf("getting delivery service servers - expected: at least 
1, actual: %d", len(dss.Response))
+       }
+       for _, d := range dss.Response {
+               if *dsMap[*d.DeliveryService].CDNID != cdn2.ID {
+                       t.Errorf("getting delivery service servers by cdn (%s) 
- found entry that did not match the given cdn", cdn2.Name)
+                       t.Errorf("getting delivery service servers by cdn (%s) 
- found entry that did not match the given cdn (server hostname = %s, server 
CDN name = %s, delivery service xmlId = %s, delivery service CDN name = %s", 
cdn2.Name, *serverMap[*d.Server].HostName, *serverMap[*d.Server].CDNName, 
*dsMap[*d.DeliveryService].XMLID, *dsMap[*d.DeliveryService].CDNName)
+               }
+       }
+}
+
 func CreateTestMSODSServerWithReqCap(t *testing.T) {
        opts := client.NewRequestOptions()
        opts.QueryParameters.Set("xmlID", "msods1")
diff --git a/traffic_ops/testing/api/v4/tc-fixtures.json 
b/traffic_ops/testing/api/v4/tc-fixtures.json
index c3b4cea..8bca765 100644
--- a/traffic_ops/testing/api/v4/tc-fixtures.json
+++ b/traffic_ops/testing/api/v4/tc-fixtures.json
@@ -1311,6 +1311,68 @@
             "checkPath": "",
             "consistentHashQueryParams": [],
             "deepCachingType": "NEVER",
+            "displayName": "basic-ds-in-cdn2",
+            "dnsBypassCname": null,
+            "dnsBypassIp": "",
+            "dnsBypassIp6": "",
+            "dnsBypassTtl": 30,
+            "dscp": 40,
+            "edgeHeaderRewrite": null,
+            "fqPacingRate": 0,
+            "geoLimit": 0,
+            "geoLimitCountries": "",
+            "geoLimitRedirectURL": null,
+            "geoProvider": 0,
+            "globalMaxMbps": 0,
+            "globalMaxTps": 0,
+            "httpBypassFqdn": "",
+            "infoUrl": "TBD",
+            "initialDispersion": 1,
+            "ipv6RoutingEnabled": true,
+            "logsEnabled": false,
+            "longDesc": "",
+            "longDesc1": "",
+            "longDesc2": "",
+            "matchList": [
+                {
+                    "pattern": ".*\\.basic-ds-in-cdn2\\..*",
+                    "setNumber": 0,
+                    "type": "HOST_REGEXP"
+                }
+            ],
+            "maxDnsAnswers": 0,
+            "midHeaderRewrite": null,
+            "missLat": 41.881944,
+            "missLong": -87.627778,
+            "multiSiteOrigin": false,
+            "orgServerFqdn": "http://example.org";,
+            "originShield": null,
+            "profileDescription": null,
+            "profileName": null,
+            "protocol": 0,
+            "qstringIgnore": 0,
+            "rangeRequestHandling": 0,
+            "regexRemap": null,
+            "regionalGeoBlocking": false,
+            "remapText": null,
+            "routingName": "cdn",
+            "signed": false,
+            "signingAlgorithm": null,
+            "sslKeyVersion": 0,
+            "tenant": "tenant1",
+            "tenantName": "tenant1",
+            "type": "HTTP",
+            "xmlId": "basic-ds-in-cdn2",
+            "anonymousBlockingEnabled": false,
+            "maxRequestHeaderBytes": 131072
+        },
+        {
+            "active": true,
+            "cdnName": "cdn2",
+            "ccrDnsTtl": 3600,
+            "checkPath": "",
+            "consistentHashQueryParams": [],
+            "deepCachingType": "NEVER",
             "displayName": "top-ds-in-cdn2",
             "dnsBypassCname": null,
             "dnsBypassIp": "",
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index 82b8dc0..e5bdc88 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -53,6 +53,7 @@ type TODeliveryServiceServer struct {
        TenantIDs          pq.Int64Array `json:"-" db:"accessibleTenants"`
        DeliveryServiceIDs pq.Int64Array `json:"-" db:"dsids"`
        ServerIDs          pq.Int64Array `json:"-" db:"serverids"`
+       CDN                string        `json:"-" db:"cdn"`
 }
 
 func (dss TODeliveryServiceServer) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -175,7 +176,13 @@ func ReadDSSHandler(w http.ResponseWriter, r 
*http.Request) {
 func (dss *TODeliveryServiceServer) readDSS(h http.Header, tx *sqlx.Tx, user 
*auth.CurrentUser, params map[string]string, intParams map[string]int, dsIDs 
[]int64, serverIDs []int64, useIMS bool) (*tc.DeliveryServiceServerResponse, 
error, *time.Time) {
        var maxTime time.Time
        var runSecond bool
-       orderby := params["orderby"]
+       // NOTE: if the 'orderby' query param exists but has an empty value, 
that means no ordering should be done.
+       // If the 'orderby' query param does not exist, order by 
"deliveryService" by default. This allows clients to
+       // specifically skip sorting if it's unnecessary, reducing load on the 
DB.
+       orderby, ok := params["orderby"]
+       if !ok {
+               orderby = "deliveryService"
+       }
        limit := 20
        offset := 0
        page := 0
@@ -191,9 +198,6 @@ func (dss *TODeliveryServiceServer) readDSS(h http.Header, 
tx *sqlx.Tx, user *au
                }
                offset *= limit
        }
-       if orderby == "" {
-               orderby = "deliveryService"
-       }
 
        tenantIDs, err := tenant.GetUserTenantIDListTx(tx.Tx, user.TenantID)
        if err != nil {
@@ -204,7 +208,9 @@ func (dss *TODeliveryServiceServer) readDSS(h http.Header, 
tx *sqlx.Tx, user *au
        }
        dss.ServerIDs = serverIDs
        dss.DeliveryServiceIDs = dsIDs
-       query1, err := selectQuery(orderby, strconv.Itoa(limit), 
strconv.Itoa(offset), dsIDs, serverIDs, true)
+       cdn := params["cdn"]
+       dss.CDN = cdn
+       query1, err := selectQuery(orderby, strconv.Itoa(limit), 
strconv.Itoa(offset), dsIDs, serverIDs, true, cdn)
        if err != nil {
                log.Warnf("Error getting the max last updated query %v", err)
        }
@@ -221,7 +227,7 @@ func (dss *TODeliveryServiceServer) readDSS(h http.Header, 
tx *sqlx.Tx, user *au
        } else {
                log.Debugln("Non IMS request")
        }
-       query, err := selectQuery(orderby, strconv.Itoa(limit), 
strconv.Itoa(offset), dsIDs, serverIDs, false)
+       query, err := selectQuery(orderby, strconv.Itoa(limit), 
strconv.Itoa(offset), dsIDs, serverIDs, false, cdn)
        if err != nil {
                return nil, errors.New("creating query for 
DeliveryserviceServers: " + err.Error()), nil
        }
@@ -243,7 +249,7 @@ func (dss *TODeliveryServiceServer) readDSS(h http.Header, 
tx *sqlx.Tx, user *au
        return &tc.DeliveryServiceServerResponse{Orderby: orderby, Response: 
servers, Size: page, Limit: limit}, nil, &maxTime
 }
 
-func selectQuery(orderBy string, limit string, offset string, dsIDs []int64, 
serverIDs []int64, getMaxQuery bool) (string, error) {
+func selectQuery(orderBy string, limit string, offset string, dsIDs []int64, 
serverIDs []int64, getMaxQuery bool, cdn string) (string, error) {
        selectStmt := `SELECT
        s.deliveryService,
        s.server,
@@ -283,6 +289,11 @@ AND s.deliveryservice = ANY(:dsids)
 AND s.server = ANY(:serverids)
 `
        }
+       if len(cdn) > 0 {
+               selectStmt += `
+AND d.cdn_id = (SELECT id FROM cdn WHERE name = :cdn)
+`
+       }
 
        if getMaxQuery {
                selectStmt += ` GROUP BY s.deliveryservice`

Reply via email to