dangogh closed pull request #2093: Added functionality to attach parameters to 
the profile response if an id is sent
URL: https://github.com/apache/incubator-trafficcontrol/pull/2093
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/lib/go-tc/v13/parameters.go b/lib/go-tc/v13/parameters.go
new file mode 100644
index 000000000..e02d9b525
--- /dev/null
+++ b/lib/go-tc/v13/parameters.go
@@ -0,0 +1,56 @@
+package v13
+
+import (
+       "encoding/json"
+
+       tc "github.com/apache/incubator-trafficcontrol/lib/go-tc"
+)
+
+/*
+ * 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.
+ */
+
+// ParametersResponse ...
+type ParametersResponse struct {
+       Response []Parameter `json:"response"`
+}
+
+// Parameter ...
+type Parameter struct {
+       ConfigFile  string          `json:"configFile" db:"config_file"`
+       ID          int             `json:"id" db:"id"`
+       LastUpdated tc.TimeNoMod    `json:"lastUpdated" db:"last_updated"`
+       Name        string          `json:"name" db:"name"`
+       Profiles    json.RawMessage `json:"profiles" db:"profiles"`
+       Secure      bool            `json:"secure" db:"secure"`
+       Value       string          `json:"value" db:"value"`
+}
+
+// ParameterNullable - a struct version that allows for all fields to be null, 
mostly used by the API side
+type ParameterNullable struct {
+       //
+       // NOTE: the db: struct tags are used for testing to map to their 
equivalent database column (if there is one)
+       //
+       ConfigFile  *string         `json:"configFile" db:"config_file"`
+       ID          *int            `json:"id" db:"id"`
+       LastUpdated *tc.TimeNoMod   `json:"lastUpdated" db:"last_updated"`
+       Name        *string         `json:"name" db:"name"`
+       Profiles    json.RawMessage `json:"profiles" db:"profiles"`
+       Secure      *bool           `json:"secure" db:"secure"`
+       Value       *string         `json:"value" db:"value"`
+}
diff --git a/lib/go-tc/v13/profiles.go b/lib/go-tc/v13/profiles.go
new file mode 100644
index 000000000..71587dfdb
--- /dev/null
+++ b/lib/go-tc/v13/profiles.go
@@ -0,0 +1,92 @@
+package v13
+
+import tc "github.com/apache/incubator-trafficcontrol/lib/go-tc"
+
+/*
+ * 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.
+ */
+
+// ProfilesResponse ...
+type ProfilesResponse struct {
+       Response []Profile `json:"response"`
+}
+
+// A Single Profile Response for Update and Create to depict what changed
+// swagger:response ProfileResponse
+// in: body
+type ProfileResponse struct {
+       // in: body
+       Response Profile `json:"response"`
+}
+
+// Profile ...
+type Profile struct {
+       ID int `json:"id" db:"id"`
+
+       // LastUpdated
+       //
+       LastUpdated tc.TimeNoMod `json:"lastUpdated" db:"last_updated"`
+
+       Name            string              `json:"name"`
+       Description     string              `json:"description"`
+       CDNName         string              `json:"cdnName"`
+       CDNID           int                 `json:"cdn"`
+       RoutingDisabled bool                `json:"routingDisabled"`
+       Type            string              `json:"type"`
+       Parameters      []ParameterNullable `json:"params,omitempty"`
+}
+
+// ProfileNullable ...
+type ProfileNullable struct {
+
+       // Unique identifier for the Profile
+       //
+       ID *int `json:"id" db:"id"`
+
+       // LastUpdated
+       //
+       LastUpdated *tc.TimeNoMod `json:"lastUpdated" db:"last_updated"`
+
+       // The Profile name
+       //
+       Name *string `json:"name" db:"name"`
+
+       // The Profile Description
+       //
+       Description *string `json:"description" db:"description"`
+
+       // The CDN name associated with the Profile
+       //
+       CDNName *string `json:"cdnName" db:"cdn_name"`
+
+       // The CDN id associated with the Profile
+       //
+       CDNID *int `json:"cdn" db:"cdn"`
+
+       // Enables
+       //
+       RoutingDisabled *bool `json:"routingDisabled" db:"routing_disabled"`
+
+       // The Type name associated with the Profile
+       //
+       Type *string `json:"type" db:"type"`
+
+       // Parameters associated to the profile
+       //
+       Parameters []ParameterNullable `json:"params,omitempty"`
+}
diff --git a/traffic_ops/client/v13/profile.go 
b/traffic_ops/client/v13/profile.go
index 0eb9b667d..dba1b12b6 100644
--- a/traffic_ops/client/v13/profile.go
+++ b/traffic_ops/client/v13/profile.go
@@ -23,14 +23,15 @@ import (
        "net/url"
 
        "github.com/apache/incubator-trafficcontrol/lib/go-tc"
+       "github.com/apache/incubator-trafficcontrol/lib/go-tc/v13"
 )
 
 const (
-       API_v13_Profiles = "/api/1.3/profiles-wip"
+       API_v13_Profiles = "/api/1.3/profiles"
 )
 
 // Create a Profile
-func (to *Session) CreateProfile(pl tc.Profile) (tc.Alerts, ReqInf, error) {
+func (to *Session) CreateProfile(pl v13.Profile) (tc.Alerts, ReqInf, error) {
 
        var remoteAddr net.Addr
        reqBody, err := json.Marshal(pl)
@@ -49,7 +50,7 @@ func (to *Session) CreateProfile(pl tc.Profile) (tc.Alerts, 
ReqInf, error) {
 }
 
 // Update a Profile by ID
-func (to *Session) UpdateProfileByID(id int, pl tc.Profile) (tc.Alerts, 
ReqInf, error) {
+func (to *Session) UpdateProfileByID(id int, pl v13.Profile) (tc.Alerts, 
ReqInf, error) {
 
        var remoteAddr net.Addr
        reqBody, err := json.Marshal(pl)
@@ -69,7 +70,7 @@ func (to *Session) UpdateProfileByID(id int, pl tc.Profile) 
(tc.Alerts, ReqInf,
 }
 
 // Returns a list of Profiles
-func (to *Session) GetProfiles() ([]tc.Profile, ReqInf, error) {
+func (to *Session) GetProfiles() ([]v13.Profile, ReqInf, error) {
        resp, remoteAddr, err := to.request(http.MethodGet, API_v13_Profiles, 
nil)
        reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr: 
remoteAddr}
        if err != nil {
@@ -77,13 +78,13 @@ func (to *Session) GetProfiles() ([]tc.Profile, ReqInf, 
error) {
        }
        defer resp.Body.Close()
 
-       var data tc.ProfilesResponse
+       var data v13.ProfilesResponse
        err = json.NewDecoder(resp.Body).Decode(&data)
        return data.Response, reqInf, nil
 }
 
 // GET a Profile by the Profile ID
-func (to *Session) GetProfileByID(id int) ([]tc.Profile, ReqInf, error) {
+func (to *Session) GetProfileByID(id int) ([]v13.Profile, ReqInf, error) {
        route := fmt.Sprintf("%s/%d", API_v13_Profiles, id)
        resp, remoteAddr, err := to.request(http.MethodGet, route, nil)
        reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr: 
remoteAddr}
@@ -92,7 +93,7 @@ func (to *Session) GetProfileByID(id int) ([]tc.Profile, 
ReqInf, error) {
        }
        defer resp.Body.Close()
 
-       var data tc.ProfilesResponse
+       var data v13.ProfilesResponse
        if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
                return nil, reqInf, err
        }
@@ -101,7 +102,7 @@ func (to *Session) GetProfileByID(id int) ([]tc.Profile, 
ReqInf, error) {
 }
 
 // GET a Profile by the Profile name
-func (to *Session) GetProfileByName(name string) ([]tc.Profile, ReqInf, error) 
{
+func (to *Session) GetProfileByName(name string) ([]v13.Profile, ReqInf, 
error) {
        URI := API_v13_Profiles + "?name=" + url.QueryEscape(name)
        resp, remoteAddr, err := to.request(http.MethodGet, URI, nil)
        reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr: 
remoteAddr}
@@ -110,7 +111,7 @@ func (to *Session) GetProfileByName(name string) 
([]tc.Profile, ReqInf, error) {
        }
        defer resp.Body.Close()
 
-       var data tc.ProfilesResponse
+       var data v13.ProfilesResponse
        if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
                return nil, reqInf, err
        }
diff --git a/traffic_ops/testing/api/v13/profiles_test.go 
b/traffic_ops/testing/api/v13/profiles_test.go
index c7fa48ba4..94677f88a 100644
--- a/traffic_ops/testing/api/v13/profiles_test.go
+++ b/traffic_ops/testing/api/v13/profiles_test.go
@@ -27,8 +27,13 @@ func TestProfiles(t *testing.T) {
        CreateTestCDNs(t)
        CreateTestTypes(t)
        CreateTestProfiles(t)
+       CreateTestParameters(t)
+       CreateTestProfileParameters(t)
        UpdateTestProfiles(t)
        GetTestProfiles(t)
+       GetTestProfilesWithParameters(t)
+       DeleteTestProfileParameters(t)
+       DeleteTestParameters(t)
        DeleteTestProfiles(t)
        DeleteTestTypes(t)
        DeleteTestCDNs(t)
@@ -90,6 +95,27 @@ func GetTestProfiles(t *testing.T) {
                }
        }
 }
+func GetTestProfilesWithParameters(t *testing.T) {
+       firstProfile := testData.Profiles[0]
+       resp, _, err := TOSession.GetProfileByName(firstProfile.Name)
+       if len(resp) > 0 {
+               respProfile := resp[0]
+               resp, _, err := TOSession.GetProfileByID(respProfile.ID)
+               if err != nil {
+                       t.Errorf("cannot GET Profile by name: %v - %v\n", err, 
resp)
+               }
+               if len(resp) > 0 {
+                       respProfile = resp[0]
+                       respParameters := respProfile.Parameters
+                       if len(respParameters) == 0 {
+                               t.Errorf("expected a profile with parameters to 
be retrieved: %v - %v\n", err, respParameters)
+                       }
+               }
+       }
+       if err != nil {
+               t.Errorf("cannot GET Profile by name: %v - %v\n", err, resp)
+       }
+}
 
 func DeleteTestProfiles(t *testing.T) {
 
diff --git a/traffic_ops/testing/api/v13/traffic_control.go 
b/traffic_ops/testing/api/v13/traffic_control.go
index f21198b79..015089e43 100644
--- a/traffic_ops/testing/api/v13/traffic_control.go
+++ b/traffic_ops/testing/api/v13/traffic_control.go
@@ -29,7 +29,7 @@ type TrafficControl struct {
        DeliveryServiceRequestComments []v12.DeliveryServiceRequestComment 
`json:"deliveryServiceRequestComments"`
        DeliveryServices               []v12.DeliveryService               
`json:"deliveryservices"`
        Divisions                      []v12.Division                      
`json:"divisions"`
-       Profiles                       []v12.Profile                       
`json:"profiles"`
+       Profiles                       []v13.Profile                       
`json:"profiles"`
        Parameters                     []v12.Parameter                     
`json:"parameters"`
        ProfileParameters              []v13.ProfileParameter              
`json:"profileParameters"`
        PhysLocations                  []v12.PhysLocation                  
`json:"physLocations"`
diff --git a/traffic_ops/traffic_ops_golang/parameter/parameters.go 
b/traffic_ops/traffic_ops_golang/parameter/parameters.go
index a75de8c8d..6eb6b30b9 100644
--- a/traffic_ops/traffic_ops_golang/parameter/parameters.go
+++ b/traffic_ops/traffic_ops_golang/parameter/parameters.go
@@ -36,6 +36,18 @@ import (
        "github.com/lib/pq"
 )
 
+const (
+       NameQueryParam       = "name"
+       SecureQueryParam     = "secure"
+       ConfigFileQueryParam = "configFile"
+       IDQueryParam         = "id"
+       ValueQueryParam      = "value"
+)
+
+var (
+       HiddenField = "********"
+)
+
 //we need a type alias to define functions on
 type TOParameter tc.ParameterNullable
 
@@ -47,19 +59,19 @@ func GetRefType() *TOParameter {
 }
 
 func (parameter TOParameter) GetKeyFieldsInfo() []api.KeyFieldInfo {
-       return []api.KeyFieldInfo{{"id", api.GetIntKey}}
+       return []api.KeyFieldInfo{{IDQueryParam, api.GetIntKey}}
 }
 
 //Implementation of the Identifier, Validator interface functions
 func (parameter TOParameter) GetKeys() (map[string]interface{}, bool) {
        if parameter.ID == nil {
-               return map[string]interface{}{"id": 0}, false
+               return map[string]interface{}{IDQueryParam: 0}, false
        }
-       return map[string]interface{}{"id": *parameter.ID}, true
+       return map[string]interface{}{IDQueryParam: *parameter.ID}, true
 }
 
 func (parameter *TOParameter) SetKeys(keys map[string]interface{}) {
-       i, _ := keys["id"].(int) //this utilizes the non panicking type 
assertion, if the thrown away ok variable is false i will be the zero of the 
type, 0 here.
+       i, _ := keys[IDQueryParam].(int) //this utilizes the non panicking type 
assertion, if the thrown away ok variable is false i will be the zero of the 
type, 0 here.
        parameter.ID = &i
 }
 
@@ -85,9 +97,9 @@ func (parameter TOParameter) Validate(db *sqlx.DB) []error {
        // - Admin rights only
        // - Do not allow duplicate parameters by name+config_file+value
        errs := validation.Errors{
-               "name":       validation.Validate(parameter.Name, 
validation.Required),
-               "configFile": validation.Validate(parameter.ConfigFile, 
validation.Required),
-               "value":      validation.Validate(parameter.Value, 
validation.Required),
+               NameQueryParam:       validation.Validate(parameter.Name, 
validation.Required),
+               ConfigFileQueryParam: validation.Validate(parameter.ConfigFile, 
validation.Required),
+               ValueQueryParam:      validation.Validate(parameter.Value, 
validation.Required),
        }
 
        return tovalidate.ToErrors(errs)
@@ -152,7 +164,7 @@ func (pl *TOParameter) Create(db *sqlx.DB, user 
auth.CurrentUser) (error, tc.Api
                return tc.DBError, tc.SystemError
        }
 
-       pl.SetKeys(map[string]interface{}{"id": id})
+       pl.SetKeys(map[string]interface{}{IDQueryParam: id})
        pl.LastUpdated = &lastUpdated
        err = tx.Commit()
        if err != nil {
@@ -184,11 +196,10 @@ func (parameter *TOParameter) Read(db *sqlx.DB, 
parameters map[string]string, us
        // Query Parameters to Database Query column mappings
        // see the fields mapped in the SQL query
        queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
-               "config_file":  dbhelpers.WhereColumnInfo{"p.config_file", nil},
-               "id":           dbhelpers.WhereColumnInfo{"p.id", api.IsInt},
-               "last_updated": dbhelpers.WhereColumnInfo{"p.last_updated", 
nil},
-               "name":         dbhelpers.WhereColumnInfo{"p.name", nil},
-               "secure":       dbhelpers.WhereColumnInfo{"p.secure", 
api.IsBool},
+               ConfigFileQueryParam: 
dbhelpers.WhereColumnInfo{"p.config_file", nil},
+               IDQueryParam:         dbhelpers.WhereColumnInfo{"p.id", 
api.IsInt},
+               NameQueryParam:       dbhelpers.WhereColumnInfo{"p.name", nil},
+               SecureQueryParam:     dbhelpers.WhereColumnInfo{"p.secure", 
api.IsBool},
        }
 
        where, orderBy, queryValues, errs := 
dbhelpers.BuildWhereAndOrderBy(parameters, queryParamsToQueryCols)
@@ -207,7 +218,6 @@ func (parameter *TOParameter) Read(db *sqlx.DB, parameters 
map[string]string, us
        defer rows.Close()
 
        params := []interface{}{}
-       hiddenField := "********"
        for rows.Next() {
                var p tc.ParameterNullable
                if err = rows.StructScan(&p); err != nil {
@@ -220,7 +230,7 @@ func (parameter *TOParameter) Read(db *sqlx.DB, parameters 
map[string]string, us
                }
 
                if isSecure && (privLevel < auth.PrivLevelAdmin) {
-                       p.Value = &hiddenField
+                       p.Value = &HiddenField
                }
                params = append(params, p)
        }
diff --git a/traffic_ops/traffic_ops_golang/profile/profiles.go 
b/traffic_ops/traffic_ops_golang/profile/profiles.go
index faccb26fe..d848c6e5a 100644
--- a/traffic_ops/traffic_ops_golang/profile/profiles.go
+++ b/traffic_ops/traffic_ops_golang/profile/profiles.go
@@ -26,39 +26,50 @@ import (
 
        "github.com/apache/incubator-trafficcontrol/lib/go-log"
        "github.com/apache/incubator-trafficcontrol/lib/go-tc"
+       "github.com/apache/incubator-trafficcontrol/lib/go-tc/v13"
        
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/api"
        
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/auth"
        
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
+       
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/parameter"
        
"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tovalidate"
        validation "github.com/go-ozzo/ozzo-validation"
        "github.com/jmoiron/sqlx"
        "github.com/lib/pq"
 )
 
+const (
+       CDNQueryParam         = "cdn"
+       NameQueryParam        = "name"
+       IDQueryParam          = "id"
+       DescriptionQueryParam = "description"
+       TypeQueryParam        = "type"
+)
+
 //we need a type alias to define functions on
-type TOProfile tc.ProfileNullable
+type TOProfile v13.ProfileNullable
+type TOParameter v13.ParameterNullable
 
 //the refType is passed into the handlers where a copy of its type is used to 
decode the json.
-var refType = TOProfile(tc.ProfileNullable{})
+var refType = TOProfile{}
 
 func GetRefType() *TOProfile {
        return &refType
 }
 
 func (prof TOProfile) GetKeyFieldsInfo() []api.KeyFieldInfo {
-       return []api.KeyFieldInfo{{"id", api.GetIntKey}}
+       return []api.KeyFieldInfo{{IDQueryParam, api.GetIntKey}}
 }
 
 //Implementation of the Identifier, Validator interface functions
 func (prof TOProfile) GetKeys() (map[string]interface{}, bool) {
        if prof.ID == nil {
-               return map[string]interface{}{"id": 0}, false
+               return map[string]interface{}{IDQueryParam: 0}, false
        }
-       return map[string]interface{}{"id": *prof.ID}, true
+       return map[string]interface{}{IDQueryParam: *prof.ID}, true
 }
 
 func (prof *TOProfile) SetKeys(keys map[string]interface{}) {
-       i, _ := keys["id"].(int) //this utilizes the non panicking type 
assertion, if the thrown away ok variable is false i will be the zero of the 
type, 0 here.
+       i, _ := keys[IDQueryParam].(int) //this utilizes the non panicking type 
assertion, if the thrown away ok variable is false i will be the zero of the 
type, 0 here.
        prof.ID = &i
 }
 
@@ -78,10 +89,10 @@ func (prof *TOProfile) GetType() string {
 
 func (prof *TOProfile) Validate(db *sqlx.DB) []error {
        errs := validation.Errors{
-               "name":        validation.Validate(prof.Name, 
validation.Required),
-               "description": validation.Validate(prof.Description, 
validation.Required),
-               "cdn":         validation.Validate(prof.CDNID, 
validation.Required),
-               "type":        validation.Validate(prof.Type, 
validation.Required),
+               NameQueryParam:        validation.Validate(prof.Name, 
validation.Required),
+               DescriptionQueryParam: validation.Validate(prof.Description, 
validation.Required),
+               CDNQueryParam:         validation.Validate(prof.CDNID, 
validation.Required),
+               TypeQueryParam:        validation.Validate(prof.Type, 
validation.Required),
        }
        if errs != nil {
                return tovalidate.ToErrors(errs)
@@ -95,15 +106,15 @@ func (prof *TOProfile) Read(db *sqlx.DB, parameters 
map[string]string, user auth
        // Query Parameters to Database Query column mappings
        // see the fields mapped in the SQL query
        queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
-               "name": dbhelpers.WhereColumnInfo{"prof.name", nil},
-               "id":   dbhelpers.WhereColumnInfo{"prof.id", api.IsInt},
+               NameQueryParam: dbhelpers.WhereColumnInfo{"prof.name", nil},
+               IDQueryParam:   dbhelpers.WhereColumnInfo{"prof.id", api.IsInt},
        }
        where, orderBy, queryValues, errs := 
dbhelpers.BuildWhereAndOrderBy(parameters, queryParamsToQueryCols)
        if len(errs) > 0 {
                return nil, errs, tc.DataConflictError
        }
 
-       query := selectQuery() + where + orderBy
+       query := selectProfilesQuery() + where + orderBy
        log.Debugln("Query is ", query)
 
        rows, err := db.NamedQuery(query, queryValues)
@@ -115,11 +126,21 @@ func (prof *TOProfile) Read(db *sqlx.DB, parameters 
map[string]string, user auth
 
        profiles := []interface{}{}
        for rows.Next() {
-               var p tc.ProfileNullable
+               var p v13.ProfileNullable
                if err = rows.StructScan(&p); err != nil {
                        log.Errorf("error parsing Profile rows: %v", err)
                        return nil, []error{tc.DBError}, tc.SystemError
                }
+
+               // Attach Parameters if the 'id' parameter is sent
+               if _, ok := parameters[IDQueryParam]; ok {
+                       params, err := ReadParameters(db, parameters, user, p)
+                       p.Parameters = params
+                       if len(errs) > 0 {
+                               log.Errorf("Error getting Parameters: %v", err)
+                               return nil, []error{tc.DBError}, tc.SystemError
+                       }
+               }
                profiles = append(profiles, p)
        }
 
@@ -127,7 +148,7 @@ func (prof *TOProfile) Read(db *sqlx.DB, parameters 
map[string]string, user auth
 
 }
 
-func selectQuery() string {
+func selectProfilesQuery() string {
 
        query := `SELECT
 prof.description,
@@ -144,6 +165,56 @@ JOIN cdn c ON prof.cdn = c.id`
        return query
 }
 
+func ReadParameters(db *sqlx.DB, parameters map[string]string, user 
auth.CurrentUser, profile v13.ProfileNullable) ([]v13.ParameterNullable, 
[]error) {
+
+       var rows *sqlx.Rows
+       privLevel := user.PrivLevel
+       queryValues := make(map[string]interface{})
+       queryValues["profile_id"] = *profile.ID
+
+       query := selectParametersQuery()
+       rows, err := db.NamedQuery(query, queryValues)
+       if err != nil {
+               log.Errorf("Error querying Parameter: %v", err)
+               return nil, []error{tc.DBError}
+       }
+       defer rows.Close()
+
+       var params []v13.ParameterNullable
+       for rows.Next() {
+               var param v13.ParameterNullable
+
+               if err = rows.StructScan(&param); err != nil {
+                       log.Errorf("error parsing parameter rows: %v", err)
+                       return nil, []error{tc.DBError}
+               }
+               var isSecure bool
+               if param.Secure != nil {
+                       isSecure = *param.Secure
+               }
+               if isSecure && (privLevel < auth.PrivLevelAdmin) {
+                       param.Value = &parameter.HiddenField
+               }
+               params = append(params, param)
+       }
+       return params, []error{}
+}
+
+func selectParametersQuery() string {
+
+       query := `SELECT
+p.id,
+p.name,
+p.config_file,
+p.value,
+p.secure
+FROM parameter p
+JOIN profile_parameter pp ON pp.parameter = p.id 
+WHERE pp.profile = :profile_id`
+
+       return query
+}
+
 //The TOProfile implementation of the Updater interface
 //all implementations of Updater should use transactions and return the proper 
errorType
 //ParsePQUniqueConstraintError is used to determine if a profile with 
conflicting values exists
@@ -231,8 +302,6 @@ func (prof *TOProfile) Create(db *sqlx.DB, user 
auth.CurrentUser) (error, tc.Api
                log.Error.Printf("could not begin transaction: %v", err)
                return tc.DBError, tc.SystemError
        }
-       q := insertQuery()
-       fmt.Printf("q ---> %v\n", q)
        resultRows, err := tx.NamedQuery(insertQuery(), prof)
        if err != nil {
                if pqErr, ok := err.(*pq.Error); ok {
@@ -268,7 +337,7 @@ func (prof *TOProfile) Create(db *sqlx.DB, user 
auth.CurrentUser) (error, tc.Api
                return tc.DBError, tc.SystemError
        }
 
-       prof.SetKeys(map[string]interface{}{"id": id})
+       prof.SetKeys(map[string]interface{}{IDQueryParam: id})
        prof.LastUpdated = &lastUpdated
        err = tx.Commit()
        if err != nil {
diff --git a/traffic_ops/traffic_ops_golang/routes.go 
b/traffic_ops/traffic_ops_golang/routes.go
index c928fd13b..96865c8db 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -194,11 +194,11 @@ func Routes(d ServerData) ([]Route, http.Handler, error) {
                {1.2, http.MethodGet, `servers/{host_name}/update_status$`, 
server.GetServerUpdateStatusHandler(d.DB), auth.PrivLevelReadOnly, 
Authenticated, nil},
 
                //Profiles
-               {1.3, http.MethodGet, `profiles-wip/?(\.json)?$`, 
api.ReadHandler(profile.GetRefType(), d.DB), auth.PrivLevelReadOnly, 
Authenticated, nil},
-               {1.3, http.MethodGet, `profiles-wip/{id}$`, 
api.ReadHandler(profile.GetRefType(), d.DB), auth.PrivLevelReadOnly, 
Authenticated, nil},
-               {1.3, http.MethodPut, `profiles-wip/{id}$`, 
api.UpdateHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, 
Authenticated, nil},
-               {1.3, http.MethodPost, `profiles-wip/?$`, 
api.CreateHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, 
Authenticated, nil},
-               {1.3, http.MethodDelete, `profiles-wip/{id}$`, 
api.DeleteHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, 
Authenticated, nil},
+               {1.3, http.MethodGet, `profiles/?(\.json)?$`, 
api.ReadHandler(profile.GetRefType(), d.DB), auth.PrivLevelReadOnly, 
Authenticated, nil},
+               {1.3, http.MethodGet, `profiles/{id}$`, 
api.ReadHandler(profile.GetRefType(), d.DB), auth.PrivLevelReadOnly, 
Authenticated, nil},
+               {1.3, http.MethodPut, `profiles/{id}$`, 
api.UpdateHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, 
Authenticated, nil},
+               {1.3, http.MethodPost, `profiles/?$`, 
api.CreateHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, 
Authenticated, nil},
+               {1.3, http.MethodDelete, `profiles/{id}$`, 
api.DeleteHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, 
Authenticated, nil},
 
                //ProfileParameters
                {1.3, http.MethodGet, `profile_parameters/?(\.json)?$`, 
api.ReadHandler(profileparameter.GetRefType(), d.DB), auth.PrivLevelReadOnly, 
Authenticated, nil},
diff --git a/traffic_ops/traffic_ops_golang/swaggerdocs/v13/cdns.go 
b/traffic_ops/traffic_ops_golang/swaggerdocs/v13/cdns.go
index 77968ef9a..ee7bcf10a 100644
--- a/traffic_ops/traffic_ops_golang/swaggerdocs/v13/cdns.go
+++ b/traffic_ops/traffic_ops_golang/swaggerdocs/v13/cdns.go
@@ -58,7 +58,7 @@ type CDNQueryParams struct {
        //
        ID string `json:"id"`
 
-       // The CDN name for the CDN
+       // The CDN name
        //
        Name string `json:"name"`
 
diff --git a/traffic_ops/traffic_ops_golang/swaggerdocs/v13/profiles.go 
b/traffic_ops/traffic_ops_golang/swaggerdocs/v13/profiles.go
new file mode 100644
index 000000000..18d7063f1
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/swaggerdocs/v13/profiles.go
@@ -0,0 +1,161 @@
+package v13
+
+/*
+ * 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 v13 "github.com/apache/incubator-trafficcontrol/lib/go-tc/v13"
+
+// Profiles -  ProfilesResponse to get the "response" top level key
+// swagger:response Profiles
+// in: body
+type Profiles struct {
+       // Profile Response Body
+       // in: body
+       ProfilesResponse v13.ProfilesResponse `json:"response"`
+}
+
+// Profile -  ProfileResponse to get the "response" top level key
+// swagger:response Profile
+// in: body
+type Profile struct {
+       // Profile Response Body
+       // in: body
+       ProfileResponse v13.ProfileResponse
+}
+
+// ProfileQueryParams
+//
+// swagger:parameters GetProfiles
+type ProfileQueryParams struct {
+
+       // ProfilesQueryParams
+
+       // Enables Domain Name System Security Extensions (DNSSEC) for the 
Profile
+       //
+       DNSSecEnabled string `json:"dnssecEnabled"`
+
+       // The domain name for the Profile
+       //
+       DomainName string `json:"domainName"`
+
+       // Unique identifier for the Profile
+       //
+       ID string `json:"id"`
+
+       // The Profile name for the Profile
+       //
+       Name string `json:"name"`
+
+       //
+       //
+       Orderby string `json:"orderby"`
+}
+
+// swagger:parameters PostProfile
+type ProfilePostParam struct {
+       // Profile Request Body
+       //
+       // in: body
+       // required: true
+       Profile v13.Profile
+}
+
+// swagger:parameters GetProfileById DeleteProfile
+type ProfilePathParams struct {
+
+       // Id associated to the Profile
+       // in: path
+       ID int `json:"id"`
+}
+
+// PostProfile swagger:route POST /cdns Profile PostProfile
+//
+// Create a Profile
+//
+// A Profile is a collection of Delivery Services
+//
+// Responses:
+//          200: Alerts
+func PostProfile(entity ProfilePostParam) (Profile, Alerts) {
+       return Profile{}, Alerts{}
+}
+
+// GetProfiles swagger:route GET /cdns Profile GetProfiles
+//
+// Retrieve a list of Profiles
+//
+// List of Profiles
+//
+// Responses:
+//          200: Profiles
+//          400: Alerts
+func GetProfiles() (Profiles, Alerts) {
+       return Profiles{}, Alerts{}
+}
+
+// swagger:parameters PutProfile
+type ProfilePutParam struct {
+
+       // ID
+       // in: path
+       ID int `json:"id"`
+
+       // Profile Request Body
+       //
+       // in: body
+       // required: true
+       Profile v13.Profile
+}
+
+// PutProfile swagger:route PUT /cdns/{id} Profile PutProfile
+//
+// Update a Profile by Id
+//
+// Update a Profile
+//
+// Responses:
+//          200: Profile
+func PutProfile(entity ProfilePutParam) (Profile, Alerts) {
+       return Profile{}, Alerts{}
+}
+
+// GetProfileById swagger:route GET /cdns/{id} Profile GetProfileById
+//
+// Retrieve a specific Profile by Id
+//
+// Retrieve a specific Profile
+//
+// Responses:
+//          200: Profiles
+//          400: Alerts
+func GetProfileById() (Profiles, Alerts) {
+       return Profiles{}, Alerts{}
+}
+
+// DeleteProfile swagger:route DELETE /cdns/{id} Profile DeleteProfile
+//
+// Delete a Profile by Id
+//
+// Delete a Profile
+//
+// Responses:
+//          200: Alerts
+func DeleteProfile(entityId int) Alerts {
+       return Alerts{}
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to