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 3aa3bc6  Added filter (host name or ID) to query API route: 
/servercheck (#5545)
3aa3bc6 is described below

commit 3aa3bc657665aa09fd314c3b288d9d7cd49d2e80
Author: Rima Shah <[email protected]>
AuthorDate: Fri Feb 26 10:35:45 2021 -0700

    Added filter (host name or ID) to query API route: /servercheck (#5545)
    
    * Adding query param to servercheck
    
    * Added name as queryparam to servercheck endpoint
    
    * Differentiate name and id param wrt where clause for both server and 
servercheck table
    
    * Added tests
    
    * Updated documentation and changelog
    
    * Updated servercheck.rst for v3
    
    * Updated function name in comments.
    
    * Update based on review commetns
    
    * updated rst and comment
    
    * Updated rst with tabs
    
    * Updated where clause logic to work against all query cases
    
    * Updated comment
    
    * Fixed merge conflict
---
 CHANGELOG.md                                       |  1 +
 docs/source/api/v3/servercheck.rst                 | 42 +++++++++++------
 docs/source/api/v4/servercheck.rst                 | 42 +++++++++++------
 traffic_ops/testing/api/v4/serverchecks_test.go    | 42 ++++++++++++++++-
 .../traffic_ops_golang/servercheck/servercheck.go  | 53 +++++++++++++++++++---
 traffic_ops/v4-client/servercheck.go               | 21 +++++++--
 6 files changed, 163 insertions(+), 38 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b9a51e..98bc05a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 
 ## [unreleased]
 ### Added
+- Traffic Ops: [#3577](https://github.com/apache/trafficcontrol/issues/3577) - 
Added a query param (server host_name or ID) for servercheck API
 - Traffic Portal: 
[#5318](https://github.com/apache/trafficcontrol/issues/5318) - Rename server 
columns for IPv4 address fields.
 - Traffic Portal: 
[#5361](https://github.com/apache/trafficcontrol/issues/5361) - Added the 
ability to change the name of a topology.
 - Traffic Portal: 
[#5340](https://github.com/apache/trafficcontrol/issues/5340) - Added the 
ability to resend a user registration from user screen.
diff --git a/docs/source/api/v3/servercheck.rst 
b/docs/source/api/v3/servercheck.rst
index dc4b7ef..5aa1857 100644
--- a/docs/source/api/v3/servercheck.rst
+++ b/docs/source/api/v3/servercheck.rst
@@ -31,7 +31,33 @@ Fetches identifying and meta information as well as "check" 
values regarding all
 
 Request Structure
 -----------------
-No parameters available.
+.. table:: Request Query Parameters
+
+       
+-----------+------------------------------------------------------------------------------------+
+       | Name      | Description                                               
                         |
+       
+===========+====================================================================================+
+       | id        | Return only :term:`cache servers` with this integral, 
unique identifier (id)       |
+       
+-----------+------------------------------------------------------------------------------------+
+       | name      | Return only :term:`cache servers` with this host_name     
                         |
+       
+-----------+------------------------------------------------------------------------------------+
+
+.. code-block:: http
+       :caption: Request Example with ``name`` query param
+
+       GET /api/4.0/servercheck?name=edge HTTP/1.1
+       Host: trafficops.infra.ciab.test
+       User-Agent: curl/7.47.0
+       Accept: */*
+       Cookie: mojolicious=...
+
+.. code-block:: http
+       :caption: Request Example with ``id`` query param
+
+       GET /api/4.0/servercheck?id=12 HTTP/1.1
+       Host: trafficops.infra.ciab.test
+       User-Agent: curl/7.47.0
+       Accept: */*
+       Cookie: mojolicious=...
 
 Response Structure
 ------------------
@@ -55,9 +81,9 @@ Response Structure
        Access-Control-Allow-Origin: *
        Content-Encoding: gzip
        Content-Type: application/json
-       Set-Cookie: mojolicious=...; Path=/; Expires=Thu, 23 Jan 2020 20:00:19 
GMT; Max-Age=3600; HttpOnly
+       Set-Cookie: mojolicious=...; Path=/; Expires=Thu, 18 Feb 2021 20:00:19 
GMT; Max-Age=3600; HttpOnly
        X-Server-Name: traffic_ops_golang/
-       Date: Thu, 23 Jan 2020 19:00:19 GMT
+       Date: Thu, 18 Feb 2021 19:00:19 GMT
        Content-Length: 352
 
        { "response": [
@@ -70,16 +96,6 @@ Response Structure
                        "profile": "ATS_EDGE_TIER_CACHE",
                        "type": "EDGE",
                        "updPending": false
-               },
-               {
-                       "adminState": "REPORTED",
-                       "cacheGroup": "CDN_in_a_Box_Mid",
-                       "id": 11,
-                       "hostName": "mid",
-                       "revalPending": false,
-                       "profile": "ATS_MID_TIER_CACHE",
-                       "type": "MID",
-                       "updPending": false
                }
        ]}
 
diff --git a/docs/source/api/v4/servercheck.rst 
b/docs/source/api/v4/servercheck.rst
index 77c8a81..8fdab46 100644
--- a/docs/source/api/v4/servercheck.rst
+++ b/docs/source/api/v4/servercheck.rst
@@ -31,7 +31,33 @@ Fetches identifying and meta information as well as "check" 
values regarding all
 
 Request Structure
 -----------------
-No parameters available.
+.. table:: Request Query Parameters
+
+       
+-----------+------------------------------------------------------------------------------------+
+       | Name      | Description                                               
                         |
+       
+===========+====================================================================================+
+       | id        | Return only :term:`cache servers` with this integral, 
unique identifier (id)       |
+       
+-----------+------------------------------------------------------------------------------------+
+       | name      | Return only :term:`cache servers` with this host_name     
                         |
+       
+-----------+------------------------------------------------------------------------------------+
+
+.. code-block:: http
+       :caption: Request Example with ``name`` query param
+
+       GET /api/4.0/servercheck?name=edge HTTP/1.1
+       Host: trafficops.infra.ciab.test
+       User-Agent: curl/7.47.0
+       Accept: */*
+       Cookie: mojolicious=...
+
+.. code-block:: http
+       :caption: Request Example with ``id`` query param
+
+       GET /api/4.0/servercheck?id=12 HTTP/1.1
+       Host: trafficops.infra.ciab.test
+       User-Agent: curl/7.47.0
+       Accept: */*
+       Cookie: mojolicious=...
 
 Response Structure
 ------------------
@@ -55,9 +81,9 @@ Response Structure
        Access-Control-Allow-Origin: *
        Content-Encoding: gzip
        Content-Type: application/json
-       Set-Cookie: mojolicious=...; Path=/; Expires=Thu, 23 Jan 2020 20:00:19 
GMT; Max-Age=3600; HttpOnly
+       Set-Cookie: mojolicious=...; Path=/; Expires=Thu, 18 Feb 2021 20:00:19 
GMT; Max-Age=3600; HttpOnly
        X-Server-Name: traffic_ops_golang/
-       Date: Thu, 23 Jan 2020 19:00:19 GMT
+       Date: Thu, 18 Feb 2021 19:00:19 GMT
        Content-Length: 352
 
        { "response": [
@@ -70,16 +96,6 @@ Response Structure
                        "profile": "ATS_EDGE_TIER_CACHE",
                        "type": "EDGE",
                        "updPending": false
-               },
-               {
-                       "adminState": "REPORTED",
-                       "cacheGroup": "CDN_in_a_Box_Mid",
-                       "id": 11,
-                       "hostName": "mid",
-                       "revalPending": false,
-                       "profile": "ATS_MID_TIER_CACHE",
-                       "type": "MID",
-                       "updPending": false
                }
        ]}
 
diff --git a/traffic_ops/testing/api/v4/serverchecks_test.go 
b/traffic_ops/testing/api/v4/serverchecks_test.go
index de97835..f782e4f 100644
--- a/traffic_ops/testing/api/v4/serverchecks_test.go
+++ b/traffic_ops/testing/api/v4/serverchecks_test.go
@@ -16,6 +16,8 @@ package v4
 */
 
 import (
+       "net/url"
+       "strconv"
        "testing"
        "time"
 
@@ -28,6 +30,8 @@ func TestServerChecks(t *testing.T) {
                CreateTestInvalidServerChecks(t)
                UpdateTestServerChecks(t)
                GetTestServerChecks(t)
+               GetTestServerChecksWithName(t)
+               GetTestServerChecksWithID(t)
        })
 }
 
@@ -101,7 +105,7 @@ func UpdateTestServerChecks(t *testing.T) {
 func GetTestServerChecks(t *testing.T) {
        hostname := testData.Serverchecks[0].HostName
        // Get server checks
-       serverChecksResp, alerts, _, err := TOSession.GetServersChecks()
+       serverChecksResp, alerts, _, err := TOSession.GetServersChecks(nil, nil)
        if err != nil {
                t.Fatalf("could not GET serverchecks: %v (alerts: %+v)", err, 
alerts)
        }
@@ -138,6 +142,42 @@ func GetTestServerChecks(t *testing.T) {
        }
 }
 
+func GetTestServerChecksWithName(t *testing.T) {
+       params := url.Values{}
+       params.Set("name", "atlanta-edge-01")
+
+       // Get server checks
+       scResp, alerts, _, err := TOSession.GetServersChecks(params, nil)
+       if len(scResp) == 0 {
+               t.Fatal("no server checks in response, quitting")
+       }
+       if err != nil {
+               t.Fatalf("could not GET serverchecks by name (%v): %v (alerts: 
%+v)", scResp[0].HostName, err, alerts)
+       }
+}
+
+func GetTestServerChecksWithID(t *testing.T) {
+       params := url.Values{}
+       serverChecksResp, _, _, err := TOSession.GetServersChecks(nil, nil)
+       if len(serverChecksResp) == 0 {
+               t.Fatal("no server checks in response, quitting")
+       }
+       if serverChecksResp[0].ID == 0 {
+               t.Fatal("ID of the response server is nil, quitting")
+       }
+       id := serverChecksResp[0].ID
+       params.Set("id", strconv.Itoa(id))
+
+       // Get server checks
+       scResp, alerts, _, err := TOSession.GetServersChecks(params, nil)
+       if len(scResp) == 0 {
+               t.Fatal("no server checks in response, quitting")
+       }
+       if err != nil {
+               t.Fatalf("could not GET serverchecks by id (%v): %v (alerts: 
%+v)", scResp[0].ID, err, alerts)
+       }
+}
+
 // Need to define no-op function as TCObj interface expects a delete function
 // There is no delete path for serverchecks
 func DeleteTestServerChecks(t *testing.T) {
diff --git a/traffic_ops/traffic_ops_golang/servercheck/servercheck.go 
b/traffic_ops/traffic_ops_golang/servercheck/servercheck.go
index 84449b9..385c9c3 100644
--- a/traffic_ops/traffic_ops_golang/servercheck/servercheck.go
+++ b/traffic_ops/traffic_ops_golang/servercheck/servercheck.go
@@ -50,8 +50,6 @@ LEFT JOIN profile ON server.profile = profile.id
 LEFT JOIN status ON server.status = status.id
 LEFT JOIN cachegroup ON server.cachegroup = cachegroup.id
 LEFT JOIN type ON server.type = type.id
-WHERE type.name LIKE 'MID%' OR type.name LIKE 'EDGE%'
-ORDER BY hostName ASC
 `
 
 const serverChecksQuery = `
@@ -239,6 +237,45 @@ func DeprecatedReadServersChecks(w http.ResponseWriter, r 
*http.Request) {
 
 func handleReadServerCheck(inf *api.APIInfo, tx *sql.Tx) 
([]tc.GenericServerCheck, error, error, int) {
        extensions := make(map[string]string)
+
+       // Query Parameters to Database Query column mappings
+       queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
+               "id":   dbhelpers.WhereColumnInfo{"servercheck.server", 
api.IsInt},
+               "name": dbhelpers.WhereColumnInfo{"server.host_name", nil},
+       }
+
+       where, orderBy, pagination, queryValues, errs := 
dbhelpers.BuildWhereAndOrderByAndPagination(inf.Params, queryParamsToQueryCols)
+       if len(errs) > 0 {
+               return nil, util.JoinErrs(errs), nil, http.StatusBadRequest
+       }
+       // where clause is different for servercheck and server table. Also, it 
differs for the query param.
+       var whereSC, whereSI string
+       if len(inf.Params) < 1 {
+               whereSI = "WHERE type.name LIKE 'MID%' OR type.name LIKE 
'EDGE%' "
+               whereSC = ""
+       } else if len(inf.Params) == 1 {
+               if _, ok := inf.Params["name"]; ok {
+                       whereSI = "WHERE (type.name LIKE 'MID%' OR type.name 
LIKE 'EDGE%') AND server.host_name=:name "
+                       whereSC = ""
+               } else if _, ok = inf.Params["id"]; ok {
+                       whereSI = "WHERE (type.name LIKE 'MID%' OR type.name 
LIKE 'EDGE%') AND server.id=:id "
+                       whereSC = where
+               } else {
+                       whereSI = "WHERE type.name LIKE 'MID%' OR type.name 
LIKE 'EDGE%' "
+                       whereSC = ""
+               }
+       } else if len(inf.Params) > 1 {
+               _, ok := inf.Params["id"]
+               _, ok1 := inf.Params["name"]
+               if ok && ok1 {
+                       whereSI = "WHERE (type.name LIKE 'MID%' OR type.name 
LIKE 'EDGE%') AND (server.host_name=:name AND server.id=:id)"
+                       whereSC = "WHERE servercheck.server=:id"
+               } else {
+                       whereSI = "WHERE type.name LIKE 'MID%' OR type.name 
LIKE 'EDGE%' "
+                       whereSC = ""
+               }
+       }
+
        extRows, err := tx.Query(extensionsQuery)
        if err != nil {
                sysErr := fmt.Errorf("querying for extensions: %v", err)
@@ -254,9 +291,10 @@ func handleReadServerCheck(inf *api.APIInfo, tx *sql.Tx) 
([]tc.GenericServerChec
                extensions[shortName] = checkName
        }
 
-       colRows, err := inf.Tx.Queryx(serverChecksQuery)
+       querySC := serverChecksQuery + whereSC + orderBy + pagination
+       colRows, err := inf.Tx.NamedQuery(querySC, queryValues)
        if err != nil {
-               sysErr := fmt.Errorf("Querying server checks columns: %v", err)
+               sysErr := fmt.Errorf("querying serverchecks columns: %v", err)
                return nil, nil, sysErr, http.StatusInternalServerError
        }
 
@@ -267,13 +305,14 @@ func handleReadServerCheck(inf *api.APIInfo, tx *sql.Tx) 
([]tc.GenericServerChec
                        sysErr := fmt.Errorf("scanning server checks columns: 
%v", err)
                        return nil, nil, sysErr, http.StatusInternalServerError
                }
-
                columns[cols.Server] = cols
        }
 
-       serverRows, err := tx.Query(serverInfoQuery)
+       orderBySI := orderBy + "ORDER BY hostName ASC"
+       querySI := serverInfoQuery + whereSI + orderBySI + pagination
+       serverRows, err := inf.Tx.NamedQuery(querySI, queryValues)
        if err != nil {
-               sysErr := fmt.Errorf("Querying server info for checks: %v", err)
+               sysErr := fmt.Errorf("querying server info for checks: %v", err)
                return nil, nil, sysErr, http.StatusInternalServerError
        }
 
diff --git a/traffic_ops/v4-client/servercheck.go 
b/traffic_ops/v4-client/servercheck.go
index 718d51a..ac48acf 100644
--- a/traffic_ops/v4-client/servercheck.go
+++ b/traffic_ops/v4-client/servercheck.go
@@ -16,6 +16,9 @@
 package client
 
 import (
+       "net/http"
+       "net/url"
+
        "github.com/apache/trafficcontrol/lib/go-tc"
        "github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
@@ -34,11 +37,21 @@ func (to *Session) InsertServerCheckStatus(status 
tc.ServercheckRequestNullable)
 }
 
 // GetServersChecks fetches check and meta information about servers from 
/servercheck.
-func (to *Session) GetServersChecks() ([]tc.GenericServerCheck, tc.Alerts, 
toclientlib.ReqInf, error) {
-       var response struct {
+func (to *Session) GetServersChecks(params url.Values, header http.Header) 
([]tc.GenericServerCheck, tc.Alerts, toclientlib.ReqInf, error) {
+       data := struct {
                tc.Alerts
                Response []tc.GenericServerCheck `json:"response"`
+       }{}
+       route := APIServercheck
+       if params != nil {
+               route += "?" + params.Encode()
+       }
+       reqInf, err := to.get(route, header, &data)
+       if err != nil {
+               return nil, data.Alerts, reqInf, err
+       }
+       if len(data.Response) == 0 {
+               return nil, data.Alerts, reqInf, nil
        }
-       reqInf, err := to.get(APIServercheck, nil, &response)
-       return response.Response, response.Alerts, reqInf, err
+       return data.Response, data.Alerts, reqInf, nil
 }

Reply via email to