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 2a502b7 Rewrite /cachegroups/{{id}}/parameters to Go (#3900)
2a502b7 is described below
commit 2a502b724d75d7224ee04517c86f40a54248f5d3
Author: Michael Hoppal <[email protected]>
AuthorDate: Thu Sep 5 09:26:13 2019 -0600
Rewrite /cachegroups/{{id}}/parameters to Go (#3900)
* Rewrite get cg parameter to golang
* Update documentation with query parameters
* Fix some apache license headers and doc spelling error
* Address PR reviews and fix missing error handling
* Minor test fixes
* Fix return struct type to omit profile and check for cg existing
* Add context to error returned
---
docs/source/api/cachegroups_id_parameters.rst | 8 +
lib/go-tc/cachegroup_parameters.go | 58 +++++
traffic_ops/client/cachegroup_parameters.go | 103 +++++++++
.../testing/api/v14/cachegroups_parameters_test.go | 99 +++++++++
traffic_ops/testing/api/v14/traffic_control.go | 1 +
traffic_ops/testing/api/v14/withobjs.go | 4 +-
.../traffic_ops_golang/cachegroup/parameters.go | 111 ++++++++++
.../cachegroup/parameters_test.go | 236 +++++++++++++++++++++
traffic_ops/traffic_ops_golang/routing/routes.go | 2 +
9 files changed, 621 insertions(+), 1 deletion(-)
diff --git a/docs/source/api/cachegroups_id_parameters.rst
b/docs/source/api/cachegroups_id_parameters.rst
index 2999af0..7f86f53 100644
--- a/docs/source/api/cachegroups_id_parameters.rst
+++ b/docs/source/api/cachegroups_id_parameters.rst
@@ -28,6 +28,14 @@ Gets all the :term:`Parameters` associated with a
:term:`Cache Group`
Request Structure
-----------------
+.. table:: Request Query Parameters
+
+
+-------------+----------+---------------------------------------------------+
+ | Name | Required | Description
|
+
+=============+==========+===================================================+
+ | parameterId | no | Show only the :term:`Parameter` with the
given ID |
+
+-------------+----------+---------------------------------------------------+
+
.. table:: Request Path Parameters
+-----------+----------------------------------------------------------+
diff --git a/lib/go-tc/cachegroup_parameters.go
b/lib/go-tc/cachegroup_parameters.go
new file mode 100644
index 0000000..dabc9c6
--- /dev/null
+++ b/lib/go-tc/cachegroup_parameters.go
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+package tc
+
+// CacheGroupParameterRequest Cache Group Parameter request body
+type CacheGroupParameterRequest struct {
+ CacheGroupID int `json:"cacheGroupId"`
+ ParameterID int `json:"parameterId"`
+}
+
+// CacheGroupParameterPostResponse Response body when Posting to associate a
Parameter with a Cache Group
+type CacheGroupParametersPostResponse struct {
+ Response []CacheGroupParameterRequest `json:"response"`
+ Alerts
+}
+
+// CacheGroupParameterResponse Cache Group Parameter response body
+type CacheGroupParametersResponse struct {
+ Response []CacheGroupParameter `json:"response"`
+ Alerts
+}
+
+// CacheGroupParameter ...
+type CacheGroupParameter struct {
+ ConfigFile string `json:"configFile"`
+ ID int `json:"id"`
+ LastUpdated TimeNoMod `json:"lastUpdated"`
+ Name string `json:"name"`
+ Secure bool `json:"secure"`
+ Value string `json:"value"`
+}
+
+// CacheGroupParameterNullable ...
+type CacheGroupParameterNullable struct {
+ ConfigFile *string `json:"configFile" db:"config_file"`
+ ID *int `json:"id" db:"id"`
+ LastUpdated *TimeNoMod `json:"lastUpdated" db:"last_updated"`
+ Name *string `json:"name" db:"name"`
+ Secure *bool `json:"secure" db:"secure"`
+ Value *string `json:"value" db:"value"`
+}
diff --git a/traffic_ops/client/cachegroup_parameters.go
b/traffic_ops/client/cachegroup_parameters.go
new file mode 100644
index 0000000..528ed41
--- /dev/null
+++ b/traffic_ops/client/cachegroup_parameters.go
@@ -0,0 +1,103 @@
+/*
+
+ Licensed 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.
+*/
+
+package client
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+const (
+ API_v14_CacheGroupParameters = "/api/1.4/cachegroupparameters"
+)
+
+// GetCacheGroupParameters Gets a Cache Group's Parameters
+func (to *Session) GetCacheGroupParameters(cacheGroupID int)
([]tc.CacheGroupParameter, ReqInf, error) {
+ route := fmt.Sprintf("%s/%d/parameters", API_v13_CacheGroups,
cacheGroupID)
+ resp, remoteAddr, err := to.request(http.MethodGet, route, nil)
+ reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr:
remoteAddr}
+ if err != nil {
+ return nil, reqInf, err
+ }
+ defer resp.Body.Close()
+
+ var data tc.CacheGroupParametersResponse
+ if err = json.NewDecoder(resp.Body).Decode(&data); err != nil {
+ return nil, reqInf, err
+ }
+ return data.Response, reqInf, nil
+}
+
+// GetCacheGroupParametersByQueryParams Gets a Cache Group's Parameters with
query parameters
+func (to *Session) GetCacheGroupParametersByQueryParams(cacheGroupID int,
queryParams string) ([]tc.CacheGroupParameter, ReqInf, error) {
+ route := fmt.Sprintf("%s/%d/parameters%s", API_v13_CacheGroups,
cacheGroupID, queryParams)
+ resp, remoteAddr, err := to.request(http.MethodGet, route, nil)
+ reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr:
remoteAddr}
+ if err != nil {
+ return nil, reqInf, err
+ }
+ defer resp.Body.Close()
+
+ var data tc.CacheGroupParametersResponse
+ if err = json.NewDecoder(resp.Body).Decode(&data); err != nil {
+ return nil, reqInf, err
+ }
+ return data.Response, reqInf, nil
+}
+
+// DeleteCacheGroupParameter Deassociates a Parameter with a Cache Group
+func (to *Session) DeleteCacheGroupParameter(cacheGroupID, parameterID int)
(tc.Alerts, ReqInf, error) {
+ route := fmt.Sprintf("%s/%d/%d", API_v14_CacheGroupParameters,
cacheGroupID, parameterID)
+ resp, remoteAddr, err := to.request(http.MethodDelete, route, nil)
+ reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr:
remoteAddr}
+ if err != nil {
+ return tc.Alerts{}, reqInf, err
+ }
+ defer resp.Body.Close()
+
+ var alerts tc.Alerts
+ if err = json.NewDecoder(resp.Body).Decode(&alerts); err != nil {
+ return tc.Alerts{}, reqInf, err
+ }
+ return alerts, reqInf, nil
+}
+
+// CreateCacheGroupParameter Associates a Parameter with a Cache Group
+func (to *Session) CreateCacheGroupParameter(cacheGroupID, parameterID int)
(*tc.CacheGroupParametersPostResponse, ReqInf, error) {
+ cacheGroupParameterReq := tc.CacheGroupParameterRequest{
+ CacheGroupID: cacheGroupID,
+ ParameterID: parameterID,
+ }
+ reqBody, err := json.Marshal(cacheGroupParameterReq)
+ if err != nil {
+ return nil, ReqInf{}, err
+ }
+ resp, remoteAddr, err := to.request(http.MethodPost,
API_v14_CacheGroupParameters, reqBody)
+ reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr:
remoteAddr}
+ if err != nil {
+ return nil, reqInf, err
+ }
+ defer resp.Body.Close()
+
+ var data tc.CacheGroupParametersPostResponse
+ if err = json.NewDecoder(resp.Body).Decode(&data); err != nil {
+ return nil, reqInf, err
+ }
+ return &data, reqInf, nil
+}
diff --git a/traffic_ops/testing/api/v14/cachegroups_parameters_test.go
b/traffic_ops/testing/api/v14/cachegroups_parameters_test.go
new file mode 100644
index 0000000..6fd6b18
--- /dev/null
+++ b/traffic_ops/testing/api/v14/cachegroups_parameters_test.go
@@ -0,0 +1,99 @@
+/*
+
+ Licensed 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.
+*/
+
+package v14
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+func TestCacheGroupParameters(t *testing.T) {
+ WithObjs(t, []TCObj{Types, Parameters, CacheGroups,
CacheGroupParameters}, func() {
+ GetTestCacheGroupParameters(t)
+ })
+}
+
+func CreateTestCacheGroupParameters(t *testing.T) {
+ firstCacheGroup := testData.CacheGroups[0]
+ cacheGroupResp, _, err :=
TOSession.GetCacheGroupNullableByName(*firstCacheGroup.Name)
+ if err != nil {
+ t.Errorf("cannot GET Cache Group by name: %v - %v\n",
firstCacheGroup.Name, err)
+ }
+
+ if cacheGroupResp == nil {
+ t.Fatalf("Cache Groups response should not be nil")
+ }
+
+ firstParameter := testData.Parameters[0]
+ paramResp, _, err := TOSession.GetParameterByName(firstParameter.Name)
+ if err != nil {
+ t.Errorf("cannot GET Parameter by name: %v - %v\n",
firstParameter.Name, err)
+ }
+ if paramResp == nil {
+ t.Fatalf("Parameter response should not be nil")
+ }
+
+ cacheGroupID := cacheGroupResp[0].ID
+ parameterID := paramResp[0].ID
+ resp, _, err := TOSession.CreateCacheGroupParameter(*cacheGroupID,
parameterID)
+ if err != nil {
+ t.Errorf("could not CREATE cache group parameter: %v\n", err)
+ }
+ if resp == nil {
+ t.Fatalf("Cache Group Parameter response should not be nil")
+ }
+ testData.CacheGroupParameterRequests =
append(testData.CacheGroupParameterRequests, resp.Response...)
+}
+
+func GetTestCacheGroupParameters(t *testing.T) {
+ for _, cgp := range testData.CacheGroupParameterRequests {
+ resp, _, err :=
TOSession.GetCacheGroupParameters(cgp.CacheGroupID)
+ if err != nil {
+ t.Errorf("cannot GET Parameter by cache group: %v -
%v\n", err, resp)
+ }
+ }
+}
+
+func DeleteTestCacheGroupParameters(t *testing.T) {
+ for _, cgp := range testData.CacheGroupParameterRequests {
+ DeleteTestCacheGroupParameter(t, cgp)
+ }
+}
+
+func DeleteTestCacheGroupParameter(t *testing.T, cgp
tc.CacheGroupParameterRequest) {
+
+ delResp, _, err :=
TOSession.DeleteCacheGroupParameter(cgp.CacheGroupID, cgp.ParameterID)
+ if err != nil {
+ t.Errorf("cannot DELETE Parameter by cache group: %v - %v\n",
err, delResp)
+ }
+
+ // Retrieve the Cache Group Parameter to see if it got deleted
+ queryParams := fmt.Sprintf("?parameterId=%d", cgp.ParameterID)
+
+ parameters, _, err :=
TOSession.GetCacheGroupParametersByQueryParams(cgp.CacheGroupID, queryParams)
+ if err != nil {
+ t.Errorf("error deleting Parameter name: %s\n", err.Error())
+ }
+ if parameters == nil {
+ t.Fatalf("Cache Group Parameters response should not be nil")
+ }
+ if len(parameters) > 0 {
+ t.Errorf("expected Parameter: %d to be to be disassociated from
Cache Group: %d\n", cgp.ParameterID, cgp.CacheGroupID)
+ }
+
+}
diff --git a/traffic_ops/testing/api/v14/traffic_control.go
b/traffic_ops/testing/api/v14/traffic_control.go
index 64148ff..2bb195f 100644
--- a/traffic_ops/testing/api/v14/traffic_control.go
+++ b/traffic_ops/testing/api/v14/traffic_control.go
@@ -24,6 +24,7 @@ type TrafficControl struct {
ASNs []tc.ASN
`json:"asns"`
CDNs []tc.CDN
`json:"cdns"`
CacheGroups []tc.CacheGroupNullable
`json:"cachegroups"`
+ CacheGroupParameterRequests []tc.CacheGroupParameterRequest
`json:"cachegroupParameters"`
Coordinates []tc.Coordinate
`json:"coordinates"`
DeliveryServiceRequests []tc.DeliveryServiceRequest
`json:"deliveryServiceRequests"`
DeliveryServiceRequestComments []tc.DeliveryServiceRequestComment
`json:"deliveryServiceRequestComments"`
diff --git a/traffic_ops/testing/api/v14/withobjs.go
b/traffic_ops/testing/api/v14/withobjs.go
index e39d0d8..14e24f4 100644
--- a/traffic_ops/testing/api/v14/withobjs.go
+++ b/traffic_ops/testing/api/v14/withobjs.go
@@ -37,6 +37,7 @@ type TCObj int
const (
CacheGroups TCObj = iota
+ CacheGroupParameters
CDNs
CDNFederations
Coordinates
@@ -68,6 +69,7 @@ type TCObjFuncs struct {
var withFuncs = map[TCObj]TCObjFuncs{
CacheGroups: {CreateTestCacheGroups,
DeleteTestCacheGroups},
+ CacheGroupParameters: {CreateTestCacheGroupParameters,
DeleteTestCacheGroupParameters},
CDNs: {CreateTestCDNs, DeleteTestCDNs},
CDNFederations: {CreateTestCDNFederations,
DeleteTestCDNFederations},
Coordinates: {CreateTestCoordinates,
DeleteTestCoordinates},
@@ -89,5 +91,5 @@ var withFuncs = map[TCObj]TCObjFuncs{
Tenants: {CreateTestTenants, DeleteTestTenants},
Types: {CreateTestTypes, DeleteTestTypes},
Users: {CreateTestUsers, ForceDeleteTestUsers},
- UsersDeliveryServices: {CreateTestUsersDeliveryServices,
DeleteTestUsersDeliveryServices},
+ UsersDeliveryServices: {CreateTestUsersDeliveryServices,
DeleteTestUsersDeliveryServices},
}
diff --git a/traffic_ops/traffic_ops_golang/cachegroup/parameters.go
b/traffic_ops/traffic_ops_golang/cachegroup/parameters.go
new file mode 100644
index 0000000..7fb0b25
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/cachegroup/parameters.go
@@ -0,0 +1,111 @@
+package cachegroup
+
+/*
+ * 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 (
+ "errors"
+ "net/http"
+ "strconv"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
+
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
+
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/parameter"
+)
+
+const (
+ CacheGroupIDQueryParam = "id"
+ ParameterIDQueryParam = "parameterId"
+)
+
+//we need a type alias to define functions on
+type TOCacheGroupParameter struct {
+ api.APIInfoImpl `json:"-"`
+ tc.CacheGroupParameterNullable
+}
+
+func (cgparam *TOCacheGroupParameter) ParamColumns()
map[string]dbhelpers.WhereColumnInfo {
+ return map[string]dbhelpers.WhereColumnInfo{
+ CacheGroupIDQueryParam:
dbhelpers.WhereColumnInfo{"cgp.cachegroup", api.IsInt},
+ ParameterIDQueryParam: dbhelpers.WhereColumnInfo{"p.id",
api.IsInt},
+ }
+}
+
+func (cgparam *TOCacheGroupParameter) GetType() string {
+ return "cachegroup_params"
+}
+
+func (cgparam *TOCacheGroupParameter) Read() ([]interface{}, error, error,
int) {
+ queryParamsToQueryCols := cgparam.ParamColumns()
+ parameters := cgparam.APIInfo().Params
+ where, orderBy, pagination, queryValues, errs :=
dbhelpers.BuildWhereAndOrderByAndPagination(parameters, queryParamsToQueryCols)
+ if len(errs) > 0 {
+ return nil, util.JoinErrs(errs), nil, http.StatusBadRequest
+ }
+
+ cgID, err := strconv.Atoi(parameters[CacheGroupIDQueryParam])
+ if err != nil {
+ return nil, nil, errors.New("cache group id must be an
integer"), http.StatusInternalServerError
+ }
+
+ _, ok, err := getCGNameFromID(cgparam.ReqInfo.Tx.Tx, int64(cgID))
+ if err != nil {
+ return nil, nil, err, http.StatusInternalServerError
+ } else if !ok {
+ return nil, errors.New("cachegroup does not exist"), nil,
http.StatusNotFound
+ }
+
+ query := selectQuery() + where + orderBy + pagination
+ rows, err := cgparam.ReqInfo.Tx.NamedQuery(query, queryValues)
+ if err != nil {
+ return nil, nil, errors.New("querying " + cgparam.GetType() +
": " + err.Error()), http.StatusInternalServerError
+ }
+ defer rows.Close()
+
+ params := []interface{}{}
+ for rows.Next() {
+ var p tc.CacheGroupParameterNullable
+ if err = rows.StructScan(&p); err != nil {
+ return nil, nil, errors.New("scanning " +
cgparam.GetType() + ": " + err.Error()), http.StatusInternalServerError
+ }
+ if p.Secure != nil && *p.Secure &&
cgparam.ReqInfo.User.PrivLevel < auth.PrivLevelAdmin {
+ p.Value = ¶meter.HiddenField
+ }
+ params = append(params, p)
+ }
+
+ return params, nil, nil, http.StatusOK
+}
+
+func selectQuery() string {
+
+ query := `SELECT
+p.config_file,
+p.id,
+p.last_updated,
+p.name,
+p.value,
+p.secure
+FROM parameter p
+LEFT JOIN cachegroup_parameter cgp ON cgp.parameter = p.id`
+ return query
+}
diff --git a/traffic_ops/traffic_ops_golang/cachegroup/parameters_test.go
b/traffic_ops/traffic_ops_golang/cachegroup/parameters_test.go
new file mode 100644
index 0000000..a120f82
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/cachegroup/parameters_test.go
@@ -0,0 +1,236 @@
+package cachegroup
+
+/*
+ * 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 (
+ "errors"
+ "net/http"
+ "testing"
+ "time"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
+ "github.com/jmoiron/sqlx"
+ sqlmock "gopkg.in/DATA-DOG/go-sqlmock.v1"
+)
+
+var (
+ cgpRows = []string{
+ "config_file",
+ "id",
+ "last_updated",
+ "name",
+ "value",
+ "secure",
+ }
+ cgRows = []string{
+ "name",
+ }
+)
+
+func TestReadCacheGroupParameters(t *testing.T) {
+
+ var testCases = []struct {
+ description string
+ storageError error
+ expectedUserError bool
+ params map[string]string
+ cgParams []tc.CacheGroupParameterNullable
+ cgExists bool
+ cgExistsStorageError error
+ expectedReturnCode int
+ }{
+ {
+ description: "Success: Read Cache Group
Parameters",
+ storageError: nil,
+ expectedUserError: false,
+ params: map[string]string{
+ "id": "1",
+ },
+ cgParams: []tc.CacheGroupParameterNullable{
+ generateParameter("global", "param1", "val1",
false, 1),
+ generateParameter("global", "param2", "val2",
false, 2),
+ },
+ cgExists: true,
+ cgExistsStorageError: nil,
+ expectedReturnCode: http.StatusOK,
+ },
+ {
+ description: "Success: Read Cache Group
Parameters with parameter id",
+ storageError: nil,
+ expectedUserError: false,
+ params: map[string]string{
+ "id": "1",
+ "parameterId": "1",
+ },
+ cgParams: []tc.CacheGroupParameterNullable{
+ generateParameter("global", "param1", "val1",
false, 1),
+ },
+ cgExists: true,
+ cgExistsStorageError: nil,
+ expectedReturnCode: http.StatusOK,
+ },
+ {
+ description: "Success: Read Cache Group
Parameters no data",
+ storageError: nil,
+ expectedUserError: false,
+ params: map[string]string{
+ "id": "1",
+ },
+ cgParams:
[]tc.CacheGroupParameterNullable{},
+ cgExists: true,
+ cgExistsStorageError: nil,
+ expectedReturnCode: http.StatusOK,
+ },
+ {
+ description: "Failure: Storage Error reading
Cache Group Parameters",
+ storageError: errors.New("failure getting cache
group parameters"),
+ expectedUserError: false,
+ params: map[string]string{
+ "id": "1",
+ },
+ cgParams:
[]tc.CacheGroupParameterNullable{},
+ cgExists: true,
+ cgExistsStorageError: nil,
+ expectedReturnCode: http.StatusInternalServerError,
+ },
+ {
+ description: "Failure: User Error invalid params",
+ storageError: nil,
+ expectedUserError: true,
+ params: map[string]string{
+ "id": "not_an_id",
+ },
+ cgParams:
[]tc.CacheGroupParameterNullable{},
+ cgExists: true,
+ cgExistsStorageError: nil,
+ expectedReturnCode: http.StatusBadRequest,
+ },
+ {
+ description: "Failure: System Error getting cache
group",
+ storageError: nil,
+ expectedUserError: false,
+ params: map[string]string{
+ "id": "1",
+ },
+ cgParams:
[]tc.CacheGroupParameterNullable{},
+ cgExists: true,
+ cgExistsStorageError: errors.New("error getting cache
group"),
+ expectedReturnCode: http.StatusInternalServerError,
+ },
+ {
+ description: "Failure: Cache group does not
exist",
+ storageError: nil,
+ expectedUserError: true,
+ params: map[string]string{
+ "id": "1",
+ },
+ cgParams:
[]tc.CacheGroupParameterNullable{},
+ cgExists: false,
+ cgExistsStorageError: nil,
+ expectedReturnCode: http.StatusNotFound,
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.description, func(t *testing.T) {
+ t.Log("Starting test scenario: ", testCase.description)
+ mockDB, mock, err := sqlmock.New()
+ if err != nil {
+ t.Fatalf("an error '%s' was not expected when
opening a stub database connection", err)
+ }
+ defer mockDB.Close()
+ db := sqlx.NewDb(mockDB, "sqlmock")
+ defer db.Close()
+ rows := sqlmock.NewRows(cgpRows)
+ for _, cgParam := range testCase.cgParams {
+ rows = rows.AddRow(
+ cgParam.ConfigFile,
+ cgParam.ID,
+ cgParam.LastUpdated,
+ cgParam.Name,
+ cgParam.Value,
+ cgParam.Secure,
+ )
+ }
+ mock.ExpectBegin()
+ cgr := sqlmock.NewRows(cgRows)
+ if testCase.cgExistsStorageError != nil {
+
mock.ExpectQuery("cachegroup").WillReturnError(testCase.cgExistsStorageError)
+ } else {
+ if testCase.cgExists {
+ cgr = cgr.AddRow("cachegroup_name")
+ }
+
mock.ExpectQuery("cachegroup").WillReturnRows(cgr)
+ }
+
+ if testCase.storageError != nil {
+
mock.ExpectQuery("cachegroup_parameter").WillReturnError(testCase.storageError)
+ } else {
+
mock.ExpectQuery("cachegroup_parameter").WillReturnRows(rows)
+ }
+ mock.ExpectCommit()
+
+ reqInfo := api.APIInfo{Tx: db.MustBegin(), Params:
testCase.params}
+ obj := TOCacheGroupParameter{
+ api.APIInfoImpl{&reqInfo},
+ tc.CacheGroupParameterNullable{},
+ }
+ parameters, userErr, sysErr, returnCode := obj.Read()
+
+ if testCase.storageError != nil {
+ if sysErr == nil {
+ t.Errorf("Read error expected: received
no sysErr")
+ }
+ } else if testCase.expectedUserError {
+ if userErr == nil {
+ t.Errorf("User error expected: received
no userErr")
+ }
+ } else if testCase.cgExistsStorageError != nil {
+ if sysErr == nil {
+ t.Errorf("Read error expected: received
no sysErr")
+ }
+ } else {
+ if userErr != nil || sysErr != nil {
+ t.Errorf("Read expected: no errors,
actual: %v %v", userErr, sysErr)
+ }
+ if len(parameters) != len(testCase.cgParams) {
+ t.Errorf("cdn.Read expected:
len(parameters) == %v, actual: %v", len(testCase.cgParams), len(parameters))
+ }
+ }
+ if testCase.expectedReturnCode != returnCode {
+ t.Errorf("Expected return code: %d, actual %d",
testCase.expectedReturnCode, returnCode)
+ }
+ })
+ }
+}
+
+func generateParameter(configFile, param, val string, secureFlag bool, id int)
tc.CacheGroupParameterNullable {
+ lastUpdated := tc.TimeNoMod{}
+ lastUpdated.Scan(time.Now())
+ testParameter := tc.CacheGroupParameterNullable{
+ ConfigFile: &configFile,
+ ID: &id,
+ LastUpdated: &lastUpdated,
+ Name: ¶m,
+ Secure: &secureFlag,
+ Value: &val,
+ }
+ return testParameter
+}
diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go
b/traffic_ops/traffic_ops_golang/routing/routes.go
index 7b99390..f518eab 100644
--- a/traffic_ops/traffic_ops_golang/routing/routes.go
+++ b/traffic_ops/traffic_ops_golang/routing/routes.go
@@ -119,6 +119,8 @@ func Routes(d ServerData) ([]Route, []RawRoute,
http.Handler, error) {
{1.1, http.MethodPost, `cachegroups/{id}/queue_update$`,
cachegroup.QueueUpdates, auth.PrivLevelOperations, Authenticated, nil},
{1.1, http.MethodPost, `cachegroups/{id}/deliveryservices/?$`,
cachegroup.DSPostHandler, auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet,
`cachegroups/{id}/parameters/?(\.json)?$`,
api.ReadHandler(&cachegroup.TOCacheGroupParameter{}), auth.PrivLevelReadOnly,
Authenticated, nil},
+
//CDN
{1.1, http.MethodGet, `cdns/name/{name}/sslkeys/?(\.json)?$`,
cdn.GetSSLKeys, auth.PrivLevelAdmin, Authenticated, nil},
{1.1, http.MethodGet, `cdns/metric_types`,
notImplementedHandler, 0, NoAuth, nil}, // MUST NOT end in $, because the 1.x
route is longer