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

mattjackson 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 4d97b0e  Fix APIv4 /servers/{{host name}}/update_status to use 
'response' object (#5778)
4d97b0e is described below

commit 4d97b0e7a3d651b78eb0a9b2c8bc42221d6bc049
Author: ocket8888 <[email protected]>
AuthorDate: Wed Apr 28 09:14:31 2021 -0600

    Fix APIv4 /servers/{{host name}}/update_status to use 'response' object 
(#5778)
    
    * Fix APIv4 /servers/{{host name}}/update_status to use 'response' object
    
    (cherry picked from commit 3ed3f38049fb2f43df4ff54c96e4a92548ddc6a5)
    
    * Remove unused import
    
    * Update CHANGELOG
---
 CHANGELOG.md                                         |  1 +
 .../source/api/v4/servers_hostname_update_status.rst | 13 ++++++++-----
 lib/go-tc/servers.go                                 | 13 +++++++++++++
 .../testing/api/v4/serverupdatestatus_test.go        | 20 ++++++++++++++------
 .../server/servers_update_status.go                  |  6 +++++-
 traffic_ops/v4-client/server.go                      | 15 ++++-----------
 6 files changed, 45 insertions(+), 23 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7b4f8f9..104ff4d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -72,6 +72,7 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 - Updated Apache Tomcat from 8.5.63 to 9.0.43
 - Delivery Service Requests now keep a record of the changes they make.
 - Changed the `goose` provider to the maintained fork 
[`github.com/kevinburke/goose`](https://github.com/kevinburke/goose)
+- The format of the `/servers/{{host name}}/update_status` Traffic Ops API 
endpoint has been changed to use a top-level `response` property, in keeping 
with (most of) the rest of the API.
 
 ### Deprecated
 - The `riak.conf` config file and its corresponding `--riakcfg` option in 
`traffic_ops_golang` have been deprecated. Please use `"traffic_vault_backend": 
"riak"` and `"traffic_vault_config"` (with the existing contents of riak.conf) 
instead.
diff --git a/docs/source/api/v4/servers_hostname_update_status.rst 
b/docs/source/api/v4/servers_hostname_update_status.rst
index d3a28a5..3187e57 100644
--- a/docs/source/api/v4/servers_hostname_update_status.rst
+++ b/docs/source/api/v4/servers_hostname_update_status.rst
@@ -27,7 +27,10 @@ Retrieves information regarding pending updates and 
revalidation jobs for a give
 
 :Auth. Required: Yes
 :Roles Required: None
-:Response Type: ``undefined`` - this endpoint will return a top-level array 
containing the response, as opposed to within a ``response`` object
+:Response Type: Array
+
+.. versionchanged:: 4.0
+       Prior to API version 4.0, the response was a top-level array rather 
than the normal ``response`` object.
 
 Request Structure
 -----------------
@@ -50,7 +53,7 @@ Request Structure
 
 Response Structure
 ------------------
-Each object in the returned array\ [1]_ will contain the following fields:
+Each object in the returned array\ [#uniqueness]_ will contain the following 
fields:
 
 :host_id:              The integral, unique identifier for the server for 
which the other fields in this object represent the pending updates and 
revalidation status
 :host_name:            The (short) hostname of the server for which the other 
fields in this object represent the pending updates and revalidation status
@@ -81,7 +84,7 @@ Each object in the returned array\ [1]_ will contain the 
following fields:
        Date: Mon, 04 Feb 2019 16:24:01 GMT
        Content-Length: 174
 
-       [{
+       { "response": [{
                "host_name": "edge",
                "upd_pending": false,
                "reval_pending": false,
@@ -90,6 +93,6 @@ Each object in the returned array\ [1]_ will contain the 
following fields:
                "status": "REPORTED",
                "parent_pending": false,
                "parent_reval_pending": false
-       }]
+       }]}
 
-.. [1] The returned object is an array, and there is no guarantee that one 
server exists for a given hostname. However, for each server in the array, that 
server's update status will be accurate for the server with that particular 
server ID.
+.. [#uniqueness] The returned object is an array, and there is no guarantee 
that one server exists for a given hostname. However, for each server in the 
array, that server's update status will be accurate for the server with that 
particular server ID.
diff --git a/lib/go-tc/servers.go b/lib/go-tc/servers.go
index a7ebd2b..f45be88 100644
--- a/lib/go-tc/servers.go
+++ b/lib/go-tc/servers.go
@@ -1110,6 +1110,19 @@ type ServerUpdateStatus struct {
        ParentRevalPending bool   `json:"parent_reval_pending"`
 }
 
+// ServerUpdateStatusResponseV40 is the type of a response from the Traffic
+// Ops API to a request to its /servers/{{host name}}/update_status endpoint
+// in API version 4.0.
+type ServerUpdateStatusResponseV40 struct {
+       Response []ServerUpdateStatus `json:"response"`
+       Alerts
+}
+
+// ServerUpdateStatusResponseV4 is the type of a response from the Traffic
+// Ops API to a request to its /servers/{{host name}}/update_status endpoint
+// in the latest minor version of API version 4.
+type ServerUpdateStatusResponseV4 = ServerUpdateStatusResponseV40
+
 type ServerPutStatus struct {
        Status        util.JSONNameOrIDStr `json:"status"`
        OfflineReason *string              `json:"offlineReason"`
diff --git a/traffic_ops/testing/api/v4/serverupdatestatus_test.go 
b/traffic_ops/testing/api/v4/serverupdatestatus_test.go
index 3fb7894..6e5c31d 100644
--- a/traffic_ops/testing/api/v4/serverupdatestatus_test.go
+++ b/traffic_ops/testing/api/v4/serverupdatestatus_test.go
@@ -448,10 +448,14 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
                        cachesByCacheGroup[cacheGroupName] = srvs.Response[0]
                }
                for _, cacheGroupName := range cacheGroupNames {
-                       updateStatusByCacheGroup[cacheGroupName], _, err = 
TOSession.GetServerUpdateStatus(*cachesByCacheGroup[cacheGroupName].HostName, 
nil)
+                       updResp, _, err := 
TOSession.GetServerUpdateStatus(*cachesByCacheGroup[cacheGroupName].HostName, 
nil)
                        if err != nil {
-                               t.Fatalf("unable to get a server from 
cachegroup %s: %s", cacheGroupName, err.Error())
+                               t.Fatalf("unable to get update status for a 
server from Cache Group '%s': %v - alerts: %+v", cacheGroupName, err, 
updResp.Alerts)
+                       }
+                       if len(updResp.Response) < 1 {
+                               t.Fatalf("Expected at least one server with 
Host Name '%s' to have an update status", 
*cachesByCacheGroup[cacheGroupName].HostName)
                        }
+                       updateStatusByCacheGroup[cacheGroupName] = 
updResp.Response[0]
                }
                // updating the server status does not queue updates within the 
same cachegroup
                if *cachesByCacheGroup[midCacheGroup].UpdPending {
@@ -477,10 +481,14 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
                        t.Fatalf("cannot update server status on %s: %s", 
*cachesByCacheGroup[midCacheGroup].HostName, err.Error())
                }
                for _, cacheGroupName := range cacheGroupNames {
-                       updateStatusByCacheGroup[cacheGroupName], _, err = 
TOSession.GetServerUpdateStatus(*cachesByCacheGroup[cacheGroupName].HostName, 
nil)
+                       updResp, _, err := 
TOSession.GetServerUpdateStatus(*cachesByCacheGroup[cacheGroupName].HostName, 
nil)
                        if err != nil {
-                               t.Fatalf("unable to get a server from 
cachegroup %s: %s", cacheGroupName, err.Error())
+                               t.Fatalf("unable to get an update status for a 
server from Cache Group '%s': %v - alerts: %+v", cacheGroupName, err, 
updResp.Alerts)
+                       }
+                       if len(updResp.Response) < 1 {
+                               t.Fatalf("Expected at least one server with 
Host Name '%s' to have an update status", 
*cachesByCacheGroup[cacheGroupName].HostName)
                        }
+                       updateStatusByCacheGroup[cacheGroupName] = 
updResp.Response[0]
                }
 
                // edgeCacheGroup is a descendant of midCacheGroup
@@ -499,9 +507,9 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
                        t.Fatalf("unable to update %s's hostname to %s: %s", 
edgeHostName, *cachesByCacheGroup[midCacheGroup].HostName, err)
                }
 
-               _, _, err = 
TOSession.GetServerUpdateStatus(*cachesByCacheGroup[midCacheGroup].HostName, 
nil)
+               updResp, _, err := 
TOSession.GetServerUpdateStatus(*cachesByCacheGroup[midCacheGroup].HostName, 
nil)
                if err != nil {
-                       t.Fatalf("expected no error getting server updates for 
a non-unique hostname %s, got %s", *cachesByCacheGroup[midCacheGroup].HostName, 
err)
+                       t.Fatalf("expected no error getting server updates for 
a non-unique hostname %s, got: %v - alerts: %+v", 
*cachesByCacheGroup[midCacheGroup].HostName, err, updResp.Alerts)
                }
 
                *cachesByCacheGroup[edgeCacheGroup].HostName = edgeHostName
diff --git a/traffic_ops/traffic_ops_golang/server/servers_update_status.go 
b/traffic_ops/traffic_ops_golang/server/servers_update_status.go
index 78bdd7f..6009002 100644
--- a/traffic_ops/traffic_ops_golang/server/servers_update_status.go
+++ b/traffic_ops/traffic_ops_golang/server/servers_update_status.go
@@ -44,7 +44,11 @@ func GetServerUpdateStatusHandler(w http.ResponseWriter, r 
*http.Request) {
                api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, 
nil, err)
                return
        }
-       api.WriteRespRaw(w, r, serverUpdateStatus)
+       if inf.Version == nil || inf.Version.Major < 4 {
+               api.WriteRespRaw(w, r, serverUpdateStatus)
+       } else {
+               api.WriteResp(w, r, serverUpdateStatus)
+       }
 }
 
 func getServerUpdateStatus(tx *sql.Tx, cfg *config.Config, hostName string) 
([]tc.ServerUpdateStatus, error) {
diff --git a/traffic_ops/v4-client/server.go b/traffic_ops/v4-client/server.go
index 7f38f2f..5da47f5 100644
--- a/traffic_ops/v4-client/server.go
+++ b/traffic_ops/v4-client/server.go
@@ -16,7 +16,6 @@
 package client
 
 import (
-       "errors"
        "fmt"
        "net"
        "net/http"
@@ -206,15 +205,9 @@ func (to *Session) GetServerIDDeliveryServices(server int, 
header http.Header) (
 
 // GetServerUpdateStatus retrieves the Server Update Status of the Server with
 // the given (short) hostname.
-func (to *Session) GetServerUpdateStatus(hostName string, header http.Header) 
(tc.ServerUpdateStatus, toclientlib.ReqInf, error) {
-       path := APIServers + `/` + hostName + `/update_status`
-       data := []tc.ServerUpdateStatus{}
+func (to *Session) GetServerUpdateStatus(hostName string, header http.Header) 
(tc.ServerUpdateStatusResponseV4, toclientlib.ReqInf, error) {
+       path := APIServers + `/` + url.PathEscape(hostName) + `/update_status`
+       var data tc.ServerUpdateStatusResponseV4
        reqInf, err := to.get(path, header, &data)
-       if err != nil {
-               return tc.ServerUpdateStatus{}, reqInf, err
-       }
-       if len(data) == 0 {
-               return tc.ServerUpdateStatus{}, reqInf, errors.New("Traffic Ops 
returned no update statuses for that server")
-       }
-       return data[0], reqInf, nil
+       return data, reqInf, err
 }

Reply via email to