You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ro...@apache.org on 2018/06/04 16:37:55 UTC

[incubator-trafficcontrol] branch master updated (5fa257f -> 7aa432c)

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

rob pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-trafficcontrol.git.


    from 5fa257f  Improve latitude/longitude input field validation
     new 42c8bf3  started adding another read method
     new bfa8ae4  started adding new read method
     new 3e491d4  Added post methods to deliveryservice_server API
     new ac96298  Created strucs in tc package for all DSS responses
     new cdf0907  fixes review issues found in PR #2269 This PR addes the deliveryservice_server endpoints
     new 5b9a539  Completed modifications from change request needed for PR
     new 54e8aff  Fixed bug in GetReplaceHandler using values before they were decoded
     new 2f5e7a4  Added nil checking for the Replace attribute
     new f680025  fixed error reporting for Post methods in deliveryservice_server
     new 7aa432c  Resolved issues with logging and response format

The 10 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 lib/go-tc/deliveryservice_servers.go               | 104 ++-
 .../deliveryservice/servers/servers.go             | 709 ++++++++++++++++++---
 traffic_ops/traffic_ops_golang/routes.go           |   9 +-
 3 files changed, 716 insertions(+), 106 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 05/10: fixes review issues found in PR #2269 This PR addes the deliveryservice_server endpoints

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit cdf09070c118825e20103aa877e88b1773bf244a
Author: ASchmidt <An...@comcast.com>
AuthorDate: Wed May 16 21:04:33 2018 -0600

    fixes review issues found in PR #2269
    This PR addes the deliveryservice_server endpoints
---
 lib/go-tc/deliveryservice_servers.go               | 143 +++++++++++----------
 .../deliveryservice/servers/servers.go             | 119 +++++++++--------
 traffic_ops/traffic_ops_golang/routes.go           |   7 +-
 3 files changed, 140 insertions(+), 129 deletions(-)

diff --git a/lib/go-tc/deliveryservice_servers.go b/lib/go-tc/deliveryservice_servers.go
index f549f76..2239103 100644
--- a/lib/go-tc/deliveryservice_servers.go
+++ b/lib/go-tc/deliveryservice_servers.go
@@ -28,32 +28,39 @@ type DeliveryServiceServerResponse struct {
 }
 
 type DSSMapResponse struct {
-		DsId	int					`json:"dsId"`
-		Replace bool				`json:"replace"`
-		Servers []int				`json:"servers"`
-	}
+	DsId    int   `json:"dsId"`
+	Replace bool  `json:"replace"`
+	Servers []int `json:"servers"`
+}
 
 type DSSReplaceResponse struct {
-	Alerts 		[]Alert             `json:"alerts"`
-	Response 	DSSMapResponse		`json:"response"`
+	Alerts   []Alert        `json:"alerts"`
+	Response DSSMapResponse `json:"response"`
 }
 
 type DSServersResponse struct {
-	Response DeliveryServiceServers  `json:"response"`
+	Response DeliveryServiceServers `json:"response"`
 }
 
 type DeliveryServiceServers struct {
-	ServerNames []string			`json:"serverNames"`
-	XmlId string 					`json:"xmlId"`
+	ServerNames []string `json:"serverNames"`
+	XmlId       string   `json:"xmlId"`
 }
 
 // DeliveryServiceServer ...
 type DeliveryServiceServer struct {
-	Server          *int             `json:"server" db:"server"`
-	DeliveryService *int             `json:"deliveryService" db:"deliveryservice"`
-	LastUpdated     *TimeNoMod       `json:"lastUpdated" db:"last_updated"`
+	Server          *int       `json:"server" db:"server"`
+	DeliveryService *int       `json:"deliveryService" db:"deliveryservice"`
+	LastUpdated     *TimeNoMod `json:"lastUpdated" db:"last_updated"`
 }
 
+type Filter int
+const (
+	ASSIGNED Filter = iota
+	UNASSIGNED
+	ELIGIBLE
+)
+
 type DSServer struct {
 	Cachegroup       *string              `json:"cachegroup" db:"cachegroup"`
 	CachegroupID     *int                 `json:"cachegroupId" db:"cachegroup_id"`
@@ -100,64 +107,62 @@ type DSServer struct {
 	UpdPending       *bool                `json:"updPending" db:"upd_pending"`
 }
 
-// DeliveryServiceNullable - a version of the deliveryservice that allows for all fields to be null
+// DSSDeliveryService - a version of the deliveryservice that allows for all fields to be null
 type DSSDeliveryService struct {
 	// NOTE: the db: struct tags are used for testing to map to their equivalent database column (if there is one)
 	//
-	Active                   *bool                   `json:"active" db:"active"`
-	CacheURL                 *string                 `json:"cacheurl" db:"cacheurl"`
-	CCRDNSTTL                *int                    `json:"ccrDnsTtl" db:"ccr_dns_ttl"`
-	CDNID                    *int                    `json:"cdnId" db:"cdn_id"`
-	CDNName                  *string                 `json:"cdnName"`
-	CheckPath                *string                 `json:"checkPath" db:"check_path"`
-	DeepCachingType          *DeepCachingType        `json:"deepCachingType" db:"deep_caching_type"`
-	DisplayName              *string                 `json:"displayName" db:"display_name"`
-	DNSBypassCNAME           *string                 `json:"dnsBypassCname" db:"dns_bypass_cname"`
-	DNSBypassIP              *string                 `json:"dnsBypassIp" db:"dns_bypass_ip"`
-	DNSBypassIP6             *string                 `json:"dnsBypassIp6" db:"dns_bypass_ip6"`
-	DNSBypassTTL             *int                    `json:"dnsBypassTtl" db:"dns_bypass_ttl"`
-	DSCP                     *int                    `json:"dscp" db:"dscp"`
-	EdgeHeaderRewrite        *string                 `json:"edgeHeaderRewrite" db:"edge_header_rewrite"`
-	FQPacingRate             *int                    `json:"fqPacingRate" db:"fq_pacing_rate"`
-	GeoLimit                 *int                    `json:"geoLimit" db:"geo_limit"`
-	GeoLimitCountries        *string                 `json:"geoLimitCountries" db:"geo_limit_countries"`
-	GeoLimitRedirectURL      *string                 `json:"geoLimitRedirectURL" db:"geolimit_redirect_url"`
-	GeoProvider              *int                    `json:"geoProvider" db:"geo_provider"`
-	GlobalMaxMBPS            *int                    `json:"globalMaxMbps" db:"global_max_mbps"`
-	GlobalMaxTPS             *int                    `json:"globalMaxTps" db:"global_max_tps"`
-	HTTPBypassFQDN           *string                 `json:"httpBypassFqdn" db:"http_bypass_fqdn"`
-	ID                       *int                    `json:"id" db:"id"`
-	InfoURL                  *string                 `json:"infoUrl" db:"info_url"`
-	InitialDispersion        *int                    `json:"initialDispersion" db:"initial_dispersion"`
-	IPV6RoutingEnabled       *bool                   `json:"ipv6RoutingEnabled" db:"ipv6_routing_enabled"`
-	LastUpdated              *TimeNoMod              `json:"lastUpdated" db:"last_updated"`
-	LogsEnabled              *bool                   `json:"logsEnabled" db:"logs_enabled"`
-	LongDesc                 *string                 `json:"longDesc" db:"long_desc"`
-	LongDesc1                *string                 `json:"longDesc1" db:"long_desc_1"`
-	LongDesc2                *string                 `json:"longDesc2" db:"long_desc_2"`
-	MaxDNSAnswers            *int                    `json:"maxDnsAnswers" db:"max_dns_answers"`
-	MidHeaderRewrite         *string                 `json:"midHeaderRewrite" db:"mid_header_rewrite"`
-	MissLat                  *float64                `json:"missLat" db:"miss_lat"`
-	MissLong                 *float64                `json:"missLong" db:"miss_long"`
-	MultiSiteOrigin          *bool                   `json:"multiSiteOrigin" db:"multi_site_origin"`
-	OriginShield             *string                 `json:"originShield" db:"origin_shield"`
-	OrgServerFQDN            *string                 `json:"orgServerFqdn" db:"org_server_fqdn"`
-	ProfileDesc              *string                 `json:"profileDescription"`
-	ProfileID                *int                    `json:"profileId" db:"profile"`
-	ProfileName              *string                 `json:"profileName"`
-	Protocol                 *int                    `json:"protocol" db:"protocol"`
-	QStringIgnore            *int                    `json:"qstringIgnore" db:"qstring_ignore"`
-	RangeRequestHandling     *int                    `json:"rangeRequestHandling" db:"range_request_handling"`
-	RegexRemap               *string                 `json:"regexRemap" db:"regex_remap"`
-	RegionalGeoBlocking      *bool                   `json:"regionalGeoBlocking" db:"regional_geo_blocking"`
-	RemapText                *string                 `json:"remapText" db:"remap_text"`
-	RoutingName              *string                 `json:"routingName" db:"routing_name"`
-	SigningAlgorithm         *string                 `json:"signingAlgorithm" db:"signing_algorithm"`
-	SSLKeyVersion            *int                    `json:"sslKeyVersion" db:"ssl_key_version"`
-	TRRequestHeaders         *string                 `json:"trRequestHeaders" db:"tr_request_headers"`
-	TRResponseHeaders        *string                 `json:"trResponseHeaders" db:"tr_response_headers"`
-	TenantID                 *int                    `json:"tenantId" db:"tenant_id"`
-	TypeName                 *string                 `json:"typeName"`
-	TypeID                   *int                    `json:"typeId" db:"type"`
-	XMLID                    *string                 `json:"xmlId" db:"xml_id"`
+	Active               *bool            `json:"active" db:"active"`
+	CacheURL             *string          `json:"cacheurl" db:"cacheurl"`
+	CCRDNSTTL            *int             `json:"ccrDnsTtl" db:"ccr_dns_ttl"`
+	CDNID                *int             `json:"cdnId" db:"cdn_id"`
+	CheckPath            *string          `json:"checkPath" db:"check_path"`
+	DeepCachingType      *DeepCachingType `json:"deepCachingType" db:"deep_caching_type"`
+	DisplayName          *string          `json:"displayName" db:"display_name"`
+	DNSBypassCNAME       *string          `json:"dnsBypassCname" db:"dns_bypass_cname"`
+	DNSBypassIP          *string          `json:"dnsBypassIp" db:"dns_bypass_ip"`
+	DNSBypassIP6         *string          `json:"dnsBypassIp6" db:"dns_bypass_ip6"`
+	DNSBypassTTL         *int             `json:"dnsBypassTtl" db:"dns_bypass_ttl"`
+	DSCP                 *int             `json:"dscp" db:"dscp"`
+	EdgeHeaderRewrite    *string          `json:"edgeHeaderRewrite" db:"edge_header_rewrite"`
+	FQPacingRate         *int             `json:"fqPacingRate" db:"fq_pacing_rate"`
+	GeoLimit             *int             `json:"geoLimit" db:"geo_limit"`
+	GeoLimitCountries    *string          `json:"geoLimitCountries" db:"geo_limit_countries"`
+	GeoLimitRedirectURL  *string          `json:"geoLimitRedirectURL" db:"geolimit_redirect_url"`
+	GeoProvider          *int             `json:"geoProvider" db:"geo_provider"`
+	GlobalMaxMBPS        *int             `json:"globalMaxMbps" db:"global_max_mbps"`
+	GlobalMaxTPS         *int             `json:"globalMaxTps" db:"global_max_tps"`
+	HTTPBypassFQDN       *string          `json:"httpBypassFqdn" db:"http_bypass_fqdn"`
+	ID                   *int             `json:"id" db:"id"`
+	InfoURL              *string          `json:"infoUrl" db:"info_url"`
+	InitialDispersion    *int             `json:"initialDispersion" db:"initial_dispersion"`
+	IPV6RoutingEnabled   *bool            `json:"ipv6RoutingEnabled" db:"ipv6_routing_enabled"`
+	LastUpdated          *TimeNoMod       `json:"lastUpdated" db:"last_updated"`
+	LogsEnabled          *bool            `json:"logsEnabled" db:"logs_enabled"`
+	LongDesc             *string          `json:"longDesc" db:"long_desc"`
+	LongDesc1            *string          `json:"longDesc1" db:"long_desc_1"`
+	LongDesc2            *string          `json:"longDesc2" db:"long_desc_2"`
+	MaxDNSAnswers        *int             `json:"maxDnsAnswers" db:"max_dns_answers"`
+	MidHeaderRewrite     *string          `json:"midHeaderRewrite" db:"mid_header_rewrite"`
+	MissLat              *float64         `json:"missLat" db:"miss_lat"`
+	MissLong             *float64         `json:"missLong" db:"miss_long"`
+	MultiSiteOrigin      *bool            `json:"multiSiteOrigin" db:"multi_site_origin"`
+	MultiSiteOriginAlgo  *int             `json:"multiSiteOriginAlgo" db:"multi_site_origin_algorithm"`
+	OriginShield         *string          `json:"originShield" db:"origin_shield"`
+	OrgServerFQDN        *string          `json:"orgServerFqdn" db:"org_server_fqdn"`
+	ProfileDesc          *string          `json:"profileDescription"`
+	ProfileID            *int             `json:"profileId" db:"profile"`
+	Protocol             *int             `json:"protocol" db:"protocol"`
+	QStringIgnore        *int             `json:"qstringIgnore" db:"qstring_ignore"`
+	RangeRequestHandling *int             `json:"rangeRequestHandling" db:"range_request_handling"`
+	RegexRemap           *string          `json:"regexRemap" db:"regex_remap"`
+	RegionalGeoBlocking  *bool            `json:"regionalGeoBlocking" db:"regional_geo_blocking"`
+	RemapText            *string          `json:"remapText" db:"remap_text"`
+	RoutingName          *string          `json:"routingName" db:"routing_name"`
+	SigningAlgorithm     *string          `json:"signingAlgorithm" db:"signing_algorithm"`
+	SSLKeyVersion        *int             `json:"sslKeyVersion" db:"ssl_key_version"`
+	TRRequestHeaders     *string          `json:"trRequestHeaders" db:"tr_request_headers"`
+	TRResponseHeaders    *string          `json:"trResponseHeaders" db:"tr_response_headers"`
+	TenantID             *int             `json:"tenantId" db:"tenant_id"`
+	TypeID               *int             `json:"typeId" db:"type"`
+	XMLID                *string          `json:"xmlId" db:"xml_id"`
 }
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index ccd84f4..3b65680 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -32,11 +32,11 @@ import (
 	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tovalidate"
 	"github.com/go-ozzo/ozzo-validation"
 
+	"encoding/json"
+	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
 	"github.com/jmoiron/sqlx"
 	"github.com/lib/pq"
 	"net/http"
-	"encoding/json"
-	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
 )
 
 // TODeliveryServiceRequest provides a type alias to define functions on
@@ -140,7 +140,7 @@ func ReadDSSHandler(db *sqlx.DB) http.HandlerFunc {
 func (dss *TODeliveryServiceServer) readDSS(db *sqlx.DB, params map[string]string, user auth.CurrentUser) (*tc.DeliveryServiceServerResponse, []error, tc.ApiErrorType) {
 	limitstr := params["limit"]
 	pagestr := params["page"]
-	orderby := params["deliveryService"]
+	orderby := params["orderby"]
 	limit := 20
 	offset := 1
 	page := 1
@@ -175,7 +175,7 @@ func (dss *TODeliveryServiceServer) readDSS(db *sqlx.DB, params map[string]strin
 		orderby = "deliveryService"
 	}
 
-	query := selectQuery(orderby, strconv.Itoa(limit), strconv.Itoa(offset))
+	query, err := selectQuery(orderby, strconv.Itoa(limit), strconv.Itoa(offset))
 	log.Debugln("Query is ", query)
 
 	rows, err := db.NamedQuery(query, dss)
@@ -195,7 +195,7 @@ func (dss *TODeliveryServiceServer) readDSS(db *sqlx.DB, params map[string]strin
 		servers = append(servers, s)
 	}
 
-	return &tc.DeliveryServiceServerResponse{orderby, servers,page, limit}, []error{}, tc.NoError
+	return &tc.DeliveryServiceServerResponse{orderby, servers, page, limit}, []error{}, tc.NoError
 }
 
 //all implementations of Deleter should use transactions and return the proper errorType
@@ -244,16 +244,34 @@ func (dss *TODeliveryServiceServer) Delete(db *sqlx.DB, user auth.CurrentUser) (
 	return nil, tc.NoError
 }
 
-func selectQuery( orderby string, limit string, offset string) string {
+func selectQuery(orderBy string, limit string, offset string) (string, error) {
 
 	selectStmt := `SELECT
 	s.deliveryService,
 	s.server,
 	s.last_updated
-	FROM deliveryservice_server s
-	ORDER BY `+ orderby +` LIMIT `+limit+` OFFSET `+offset+` ROWS`
+	FROM deliveryservice_server s`
+
+	allowedOrderByCols := map[string]string{
+		"":                "",
+		"deliveryservice": "s.deliveryService",
+		"server":          "s.server",
+		"lastupdated":     "s.last_updated",
+		"deliveryService": "s.deliveryService",
+		"lastUpdated":     "s.last_updated",
+		"last_updated":    "s.last_updated",
+	}
+	orderBy, ok := allowedOrderByCols[orderBy]
+	if !ok {
+		return "", errors.New("orderBy '" + orderBy + "' not permitted")
+	}
 
-	return selectStmt
+	if orderBy != "" {
+		selectStmt += ` ORDER BY ` + orderBy
+	}
+
+	selectStmt += ` LIMIT ` + limit + ` OFFSET ` + offset + ` ROWS`
+	return selectStmt, nil
 }
 
 func deleteQuery() string {
@@ -262,22 +280,23 @@ func deleteQuery() string {
 	return query
 }
 
-
 type DSServers struct {
-	DsId *int 						`json:"dsId" db:"deliveryservice"`
-	Servers []int					`json:"servers"`
-	Replace *bool	 				`json:"replace"`
+	DsId    *int  `json:"dsId" db:"deliveryservice"`
+	Servers []int `json:"servers"`
+	Replace *bool `json:"replace"`
 }
 
 type TODSServers DSServers
+
 var dsserversRef = TODSServers(DSServers{})
 
 func GetServersForDsIdRef() *TODSServers {
 	return &dsserversRef
 }
 
-func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
+func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
+		defer r.Body.Close()
 		handleErrs := tc.GetHandleErrorsFunc(w, r)
 		ctx := r.Context()
 		user, err := auth.GetCurrentUser(ctx)
@@ -288,10 +307,9 @@ func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
 		}
 
 		// get list of server Ids to insert
-		defer r.Body.Close()
 		payload := GetServersForDsIdRef()
 		servers := payload.Servers
-		dsId    := payload.DsId
+		dsId := payload.DsId
 
 		if err := json.NewDecoder(r.Body).Decode(payload); err != nil {
 			log.Errorf("Error trying to decode the request body: %s", err)
@@ -340,7 +358,7 @@ func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
 
 		if *payload.Replace {
 			// delete existing
-			rows, err := db.Queryx( "DELETE FROM deliveryservice_server WHERE deliveryservice = $1", *dsId)
+			rows, err := db.Queryx("DELETE FROM deliveryservice_server WHERE deliveryservice = $1", *dsId)
 			if err != nil {
 				log.Errorf("unable to remove the existing servers assigned to the delivery service: %s", err)
 				handleErrs(http.StatusInternalServerError, err)
@@ -354,7 +372,7 @@ func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
 		respServers := []int{}
 
 		for i < len(servers) {
-			dtos := map[string]interface{}{"id":dsId, "server":servers[i]}
+			dtos := map[string]interface{}{"id": dsId, "server": servers[i]}
 			resultRows, err := tx.NamedQuery(insertIdsQuery(), dtos)
 			if err != nil {
 				if pqErr, ok := err.(*pq.Error); ok {
@@ -381,9 +399,8 @@ func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
 			log.Errorln("Could not commit transaction: ", err)
 			return
 		}
-		rollbackTransaction = false
-		resAlerts := []tc.Alert{ tc.Alert{"sever assignement","success"}}
-		repRes := tc.DSSReplaceResponse{resAlerts, tc.DSSMapResponse{*dsId,*payload.Replace,respServers }}
+		resAlerts := []tc.Alert{tc.Alert{"server assignements complete", "success"}}
+		repRes := tc.DSSReplaceResponse{resAlerts, tc.DSSMapResponse{*dsId, *payload.Replace, respServers}}
 
 		// marshal the results to the response stream
 		respBts, err := json.Marshal(repRes)
@@ -393,15 +410,13 @@ func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
 			return
 		}
 
+		rollbackTransaction = false
 		w.Header().Set(tc.ContentType, tc.ApplicationJson)
 		fmt.Fprintf(w, "%s", respBts)
 		return
 	}
 }
 
-
-
-
 type TODeliveryServiceServers tc.DeliveryServiceServers
 
 var serversRef = TODeliveryServiceServers(tc.DeliveryServiceServers{})
@@ -411,7 +426,7 @@ func GetServersRef() *TODeliveryServiceServers {
 }
 
 // api/1.1/deliveryservices/{xml_id}/servers
-func GetCreateHandler( db *sqlx.DB ) http.HandlerFunc {
+func GetCreateHandler(db *sqlx.DB) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		handleErrs := tc.GetHandleErrorsFunc(w, r)
 
@@ -420,6 +435,7 @@ func GetCreateHandler( db *sqlx.DB ) http.HandlerFunc {
 		if err != nil {
 			log.Errorf("unable to get parameters from request: %s", err)
 			handleErrs(http.StatusInternalServerError, err)
+			return
 		}
 
 		xmlId, ok := params["xml_id"]
@@ -451,6 +467,10 @@ func GetCreateHandler( db *sqlx.DB ) http.HandlerFunc {
 			case tc.ForbiddenError:
 				handleErrs(http.StatusForbidden, err)
 				return
+			default:
+				e := http.StatusInternalServerError
+				handleErrs(e, err)
+				return
 			}
 		}
 
@@ -511,7 +531,7 @@ func GetCreateHandler( db *sqlx.DB ) http.HandlerFunc {
 		for serverIds.Next() {
 			var serverId int
 			err := serverIds.Scan(&serverId)
-			dtos := map[string]interface{}{"id":dsId, "server":serverId}
+			dtos := map[string]interface{}{"id": dsId, "server": serverId}
 			resultRows, err := tx.NamedQuery(insertIdsQuery(), dtos)
 			if err != nil {
 				if pqErr, ok := err.(*pq.Error); ok {
@@ -535,7 +555,6 @@ func GetCreateHandler( db *sqlx.DB ) http.HandlerFunc {
 			log.Errorln("Could not commit transaction: ", err)
 			return
 		}
-		rollbackTransaction = false
 
 		// marshal the results to the response stream
 		tcPayload := tc.DeliveryServiceServers{payload.ServerNames, payload.XmlId}
@@ -547,6 +566,7 @@ func GetCreateHandler( db *sqlx.DB ) http.HandlerFunc {
 			return
 		}
 
+		rollbackTransaction = false
 		w.Header().Set(tc.ContentType, tc.ApplicationJson)
 		fmt.Fprintf(w, "%s", respBts)
 		return
@@ -569,8 +589,8 @@ func selectServerIds() string {
 	return query
 }
 
-// api/1.1/deliveryservices/{id}/servers|unassigned_servers|eligible
-func GetReadHandler(db *sqlx.DB, filter string) http.HandlerFunc {
+// GetReadHandler api/1.1/deliveryservices/{id}/servers|unassigned_servers|eligible
+func GetReadHandler(db *sqlx.DB, filter tc.Filter) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		handleErrs := tc.GetHandleErrorsFunc(w, r)
 		params, err := api.GetCombinedParams(r)
@@ -581,7 +601,7 @@ func GetReadHandler(db *sqlx.DB, filter string) http.HandlerFunc {
 
 		where := `WHERE s.id in (select server from deliveryservice_server where deliveryservice = $1)`
 
-		if filter[0] == 'u' {
+		if filter == tc.UNASSIGNED {
 			where = `WHERE s.id not in (select server from deliveryservice_server where deliveryservice = $1)`
 		}
 
@@ -644,7 +664,6 @@ func read(db *sqlx.DB, params map[string]string, user auth.CurrentUser, where st
 	return servers, []error{}, tc.NoError
 }
 
-
 func dssSelectQuery() string {
 
 	const JumboFrameBPS = 9000
@@ -711,7 +730,7 @@ func GetDServiceRef() *TODSSDeliveryService {
 	return &dserviceRef
 }
 
-// api/1.1/servers/{id}/deliveryservices$
+// Read api/1.1/servers/{id}/deliveryservices$
 func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
 	var err error = nil
 	orderby := params["orderby"]
@@ -724,7 +743,7 @@ func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, use
 	query := SDSSelectQuery()
 	log.Debugln("Query is ", query)
 
-	rows, err := db.Queryx(query, serverId )
+	rows, err := db.Queryx(query, serverId)
 	if err != nil {
 		log.Errorf("Error querying DeliveryserviceServers: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -746,29 +765,19 @@ func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, use
 
 func SDSSelectQuery() string {
 
-	const JumboFrameBPS = 9000
-
-	// COALESCE is needed to default values that are nil in the database
-	// because Go does not allow that to marshal into the struct
 	selectStmt := `SELECT
-		active,
-	    cacheurl,
+ 		active,
 		ccr_dns_ttl,
 		cdn_id,
-		cdnName,
-		check_path,
-		deep_caching_type,
-		display_name,
+		cacheurl,
 		check_path,
-		deep_caching_type,
-		display_name,
 		dns_bypass_cname,
 		dns_bypass_ip,
 		dns_bypass_ip6,
 		dns_bypass_ttl,
 		dscp,
+		display_name,
 		edge_header_rewrite,
-		fq_pacing_rate,
 		geo_limit,
 		geo_limit_countries,
 		geolimit_redirect_url,
@@ -777,9 +786,9 @@ func SDSSelectQuery() string {
 		global_max_tps,
 		http_bypass_fqdn,
 		id,
+		ipv6_routing_enabled,
 		info_url,
 		initial_dispersion,
-		ipv6_routing_enabled,
 		last_updated,
 		logs_enabled,
 		long_desc,
@@ -790,11 +799,10 @@ func SDSSelectQuery() string {
 		miss_lat,
 		miss_long,
 		multi_site_origin,
-		origin_sheild,
+		multi_site_origin_algorithm,
 		org_server_fqdn,
-		profileDescription,
+		origin_shield,
 		profile,
-		profileName,
 		protocol,
 		qstring_ignore,
 		range_request_handling,
@@ -802,17 +810,16 @@ func SDSSelectQuery() string {
 		regional_geo_blocking,
 		remap_text,
 		routing_name,
-		signing_algorithm,
 		ssl_key_version,
+		signing_algorithm,
 		tr_request_headers,
 		tr_response_headers,
 		tenant_id,
-		typeName,
 		type,
 		xml_id
-		FROM deliveryservice
-		WHERE id in (SELECT deliveryservice FROM deliverservice_server where server = $1)`
-		return selectStmt
+	FROM deliveryservice d
+		WHERE id in (SELECT deliveryService FROM deliveryservice_server where server = $1)`
+	return selectStmt
 }
 
 func updateQuery() string {
@@ -825,5 +832,3 @@ func updateQuery() string {
       RETURNING last_updated`
 	return query
 }
-
-
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index 752c8d8..9240c45 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -59,6 +59,7 @@ import (
 
 	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/origin"
 	"github.com/basho/riak-go-client"
+	"github.com/apache/incubator-trafficcontrol/lib/go-tc"
 )
 
 // Authenticated ...
@@ -167,9 +168,9 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodPost,`deliveryserviceserver$`, dsserver.GetReplaceHandler(d.DB),auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodPost,`deliveryservices/{xml_id}/servers$`, dsserver.GetCreateHandler( d.DB ) ,auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(dsserver.GetDServiceRef(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, dsserver.GetReadHandler(d.DB, "assigned"),auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, dsserver.GetReadHandler(d.DB, "unassigned"),auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.DB, "eligible"),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, dsserver.GetReadHandler(d.DB, "Assigned"),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, dsserver.GetReadHandler(d.DB, "Unassigned"),auth.PrivLevelReadOnly, Authenticated, nil},
+		//{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.DB, "Eligible"),auth.PrivLevelReadOnly, Authenticated, nil},
 
 		//Server
 		{1.1, http.MethodGet, `servers/checks$`, handlerToFunc(proxyHandler), 0, NoAuth, []Middleware{}},

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 09/10: fixed error reporting for Post methods in deliveryservice_server

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f6800255f6ac640ac14374aabf99a2166baa3f4d
Author: ASchmidt <An...@comcast.com>
AuthorDate: Wed May 23 23:29:38 2018 -0600

    fixed error reporting for Post methods in deliveryservice_server
---
 .../traffic_ops_golang/deliveryservice/servers/servers.go    | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index febb24e..4a8b5f4 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -319,20 +319,20 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 		dsId := payload.DsId
 
 		if servers == nil {
-			log.Error.Printf("no servers sent in POST; could not begin transaction: %v", err)
-			handleErrs(http.StatusBadRequest, err)
+			log.Error.Printf("no servers sent in POST; could not begin transaction")
+			api.HandleErr(w, r, http.StatusBadRequest, errors.New("servers must exist in post"), nil)
 			return
 		}
 
 		if dsId == nil {
-			log.Error.Printf("no deliveryservice id sent in POST; could not begin transaction: %v", err)
-			handleErrs(http.StatusBadRequest, err)
+			log.Error.Printf("no deliveryservice id sent in POST; could not begin transaction")
+			api.HandleErr(w, r, http.StatusBadRequest, errors.New("dsid must exist in post"), nil)
 			return
 		}
 
 		if payload.Replace == nil {
-			log.Error.Printf("no 'replace' indicator sent in POST; could not begin transaction: %v", err)
-			handleErrs(http.StatusBadRequest, err)
+			log.Error.Printf("no 'replace' indicator sent in POST; could not begin transaction")
+			api.HandleErr(w, r, http.StatusBadRequest, errors.New("replace must exist in post"), nil)
 			return
 		}
 

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 03/10: Added post methods to deliveryservice_server API

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3e491d40df9c85a0f90eeb07649f62b8db26f9cd
Author: ASchmidt <An...@comcast.com>
AuthorDate: Mon May 14 07:23:16 2018 -0600

    Added post methods to deliveryservice_server API
---
 lib/go-tc/deliveryservice_servers.go               |  11 +-
 .../deliveryservice/servers/servers.go             | 702 ++++++++++++++++++---
 traffic_ops/traffic_ops_golang/routes.go           |  11 +-
 3 files changed, 617 insertions(+), 107 deletions(-)

diff --git a/lib/go-tc/deliveryservice_servers.go b/lib/go-tc/deliveryservice_servers.go
index 85bfde9..d24d1b6 100644
--- a/lib/go-tc/deliveryservice_servers.go
+++ b/lib/go-tc/deliveryservice_servers.go
@@ -19,21 +19,20 @@ import "time"
 
 // DeliveryServiceServerResponse ...
 type DeliveryServiceServerResponse struct {
+	Orderby  string                  `json:"orderby"`
 	Response []DeliveryServiceServer `json:"response"`
 	Size     int                     `json:"size"`
-	OrderBy  string                  `json:"orderby"`
 	Limit    int                     `json:"limit"`
 }
 
 // DeliveryServiceServer ...
 type DeliveryServiceServer struct {
-	Server          *int             `json:"server"`
-	DeliveryService *int             `json:"deliveryService"`
+	Server          *int             `json:"server" db:"server"`
+	DeliveryService *int             `json:"deliveryService" db:"deliveryservice"`
 	LastUpdated     *TimeNoMod       `json:"lastUpdated" db:"last_updated"`
 }
 
-
-type DssServer struct {
+type DSServer struct {
 	Cachegroup       *string              `json:"cachegroup" db:"cachegroup"`
 	CachegroupID     *int                 `json:"cachegroupId" db:"cachegroup_id"`
 	CDNID            *int                 `json:"cdnId" db:"cdn_id"`
@@ -80,7 +79,7 @@ type DssServer struct {
 }
 
 // DeliveryServiceNullable - a version of the deliveryservice that allows for all fields to be null
-type DssDeliveryService struct {
+type DSSDeliveryService struct {
 	// NOTE: the db: struct tags are used for testing to map to their equivalent database column (if there is one)
 	//
 	Active                   *bool                   `json:"active" db:"active"`
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index f212937..8f534ca 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -34,6 +34,9 @@ import (
 
 	"github.com/jmoiron/sqlx"
 	"github.com/lib/pq"
+	"net/http"
+	"encoding/json"
+	"github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
 )
 
 // TODeliveryServiceRequest provides a type alias to define functions on
@@ -97,130 +100,107 @@ func (dss *TODeliveryServiceServer) Validate(db *sqlx.DB) []error {
 	return tovalidate.ToErrors(errs)
 }
 
-//The TODeliveryServiceServer implementation of the Creator interface
-//all implementations of Creator should use transactions and return the proper errorType
-//ParsePQUniqueConstraintError is used to determine if a profileparameter with conflicting values exists
-//if so, it will return an errorType of DataConflict and the type should be appended to the
-//generic error message returned
-//The insert sql returns the profile and lastUpdated values of the newly inserted profileparameter and have
-//to be added to the struct
-func (dss *TODeliveryServiceServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
+// api/1.1/deliveryserviceserver$
+func ReadDSSHandler(db *sqlx.DB) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		//create error function with ResponseWriter and Request
+		handleErrs := tc.GetHandleErrorsFunc(w, r)
+
+		ctx := r.Context()
+
+		// Load the PathParams into the query parameters for pass through
+		params, err := api.GetCombinedParams(r)
+		if err != nil {
+			log.Errorf("unable to get parameters from request: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
 		}
-		err := tx.Rollback()
+
+		user, err := auth.GetCurrentUser(ctx)
 		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
+			log.Errorf("unable to retrieve current user from context: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
 		}
-	}()
 
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), dss)
-	if err != nil {
-		if pqErr, ok := err.(*pq.Error); ok {
-			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
-			if eType == tc.DataConflictError {
-				return errors.New("a parameter with " + err.Error()), eType
-			}
-			return err, eType
+		results, errs, errType := GetRefType().readDSS(db, params, *user)
+		if len(errs) > 0 {
+			tc.HandleErrorsWithType(errs, errType, handleErrs)
+			return
 		}
-		log.Errorf("received non pq error: %++v from create execution", err)
-		return tc.DBError, tc.SystemError
-	}
-	defer resultRows.Close()
-
-	var ds_id int
-	var server_id int
-	var lastUpdated tc.TimeNoMod
-	rowsAffected := 0
-	for resultRows.Next() {
-		rowsAffected++
-		if err := resultRows.Scan(&ds_id, &server_id, &lastUpdated); err != nil {
-			log.Error.Printf("could not scan dss from insert: %s\n", err)
-			return tc.DBError, tc.SystemError
+		respBts, err := json.Marshal(results)
+		if err != nil {
+			handleErrs(http.StatusInternalServerError, err)
+			return
 		}
-	}
-	if rowsAffected == 0 {
-		err = errors.New("no deliveryServiceServer was inserted, nothing to return")
-		log.Errorln(err)
-		return tc.DBError, tc.SystemError
-	}
-	if rowsAffected > 1 {
-		err = errors.New("too many ids returned from parameter insert")
-		log.Errorln(err)
-		return tc.DBError, tc.SystemError
-	}
 
-	dss.SetKeys(map[string]interface{}{"deliveryservice": ds_id, "server": server_id})
-	dss.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
+		w.Header().Set("Content-Type", "application/json")
+		fmt.Fprintf(w, "%s", respBts)
 	}
-	rollbackTransaction = false
-	return nil, tc.NoError
 }
+func (dss *TODeliveryServiceServer) readDSS(db *sqlx.DB, params map[string]string, user auth.CurrentUser) (*tc.DeliveryServiceServerResponse, []error, tc.ApiErrorType) {
+	limitstr := params["limit"]
+	pagestr := params["page"]
+	orderby := params["deliveryService"]
+	limit := 20
+	offset := 1
+	page := 1
+	var err error = nil
+
+	if limitstr != "" {
+		limit, err = strconv.Atoi(limitstr)
 
-func insertQuery() string {
-	query := `INSERT INTO deliveryservice_server (
-deliveryservice,
-server) VALUES (
-:ds_id,
-:server_id) RETURNING deliveryservice, server, last_updated`
-	return query
-}
+		if err != nil {
+			log.Errorf("limit parameter is not an integer")
+			return nil, []error{errors.New("limit parameter must be an integer.")}, tc.SystemError
+		}
+	}
 
-func (dss *TODeliveryServiceServer) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
-	idstr, ok := params["id"]
+	if pagestr != "" {
+		offset, err = strconv.Atoi(pagestr)
+		page, err = strconv.Atoi(pagestr)
 
-	if !ok {
-		log.Errorf("Deliveryservice Server Id missing")
-		return nil, []error{errors.New("Deliverservice id is required.")}, tc.DataMissingError
+		if err != nil {
+			log.Errorf("page parameter is not an integer")
+			return nil, []error{errors.New("page parameter must be an integer.")}, tc.SystemError
+		}
+
+		if offset > 0 {
+			offset -= 1
+		}
+
+		offset *= limit
 	}
-	id, err := strconv.Atoi(idstr)
 
-	if err != nil {
-		log.Errorf("Deliveryservice Server Id is not an integer")
-		return nil, []error{errors.New("Deliverservice id is not an integer.")}, tc.SystemError
+	if orderby == "" {
+		orderby = "deliveryService"
 	}
 
-	query := selectQuery()
+	query := selectQuery(orderby, strconv.Itoa(limit), strconv.Itoa(offset))
 	log.Debugln("Query is ", query)
 
-	rows, err := db.Queryx(query, id)
+	rows, err := db.NamedQuery(query, dss)
 	if err != nil {
 		log.Errorf("Error querying DeliveryserviceServers: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
 	}
 	defer rows.Close()
 
-	servers := []interface{}{}
+	servers := []tc.DeliveryServiceServer{}
 	for rows.Next() {
-		var s tc.DssServer
+		var s tc.DeliveryServiceServer
 		if err = rows.StructScan(&s); err != nil {
 			log.Errorf("error parsing dss rows: %v", err)
 			return nil, []error{tc.DBError}, tc.SystemError
 		}
-		hiddenField := ""
-		if user.PrivLevel < auth.PrivLevelAdmin {
-			s.ILOPassword = &hiddenField
-		}
 		servers = append(servers, s)
 	}
 
-	return servers, []error{}, tc.NoError
-
+	return &tc.DeliveryServiceServerResponse{orderby, servers,page, limit}, []error{}, tc.NoError
 }
 
-//The Parameter implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
+
+//The Parameter implementation of the Deleter interface
 func (dss *TODeliveryServiceServer) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
 	rollbackTransaction := true
 	tx, err := db.Beginx()
@@ -263,7 +243,418 @@ func (dss *TODeliveryServiceServer) Delete(db *sqlx.DB, user auth.CurrentUser) (
 	rollbackTransaction = false
 	return nil, tc.NoError
 }
-func selectQuery() string {
+
+func selectQuery( orderby string, limit string, offset string) string {
+
+	selectStmt := `SELECT
+	s.deliveryService,
+	s.server,
+	s.last_updated
+	FROM deliveryservice_server s
+	ORDER BY `+ orderby +` LIMIT `+limit+` OFFSET `+offset+` ROWS`
+
+	return selectStmt
+}
+
+func deleteQuery() string {
+	query := `DELETE FROM deliveryservice_server
+	WHERE deliveryservice=:deliveryservice and server=:server`
+	return query
+}
+
+
+type DSServers struct {
+	DsId *int 						`json:"dsId" db:"deliveryservice"`
+	Servers []int					`json:"servers"`
+	Replace *bool	 				`json:"replace"`
+}
+
+type TODSServers DSServers
+var dsserversRef = TODSServers(DSServers{})
+
+func GetServersForDsIdRef() *TODSServers {
+	return &dsserversRef
+}
+
+func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		handleErrs := tc.GetHandleErrorsFunc(w, r)
+		ctx := r.Context()
+		user, err := auth.GetCurrentUser(ctx)
+		if err != nil {
+			log.Errorf("unable to retrieve current user from context: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		// get list of server Ids to insert
+		defer r.Body.Close()
+		payload := GetServersForDsIdRef()
+		servers := payload.Servers
+		dsId    := payload.DsId
+
+		if err := json.NewDecoder(r.Body).Decode(payload); err != nil {
+			log.Errorf("Error trying to decode the request body: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		// if the object has tenancy enabled, check that user is able to access the tenant
+		// check user tenancy access to this resource.
+		row := db.QueryRow("SELECT xml_id FROM deliveryservice WHERE id = $1", *dsId)
+		var xmlId string
+		row.Scan(&xmlId)
+		hasAccess, err, apiStatus := tenant.HasTenant(*user, xmlId, db)
+		if !hasAccess {
+			switch apiStatus {
+			case tc.SystemError:
+				handleErrs(http.StatusInternalServerError, err)
+				return
+			case tc.DataMissingError:
+				handleErrs(http.StatusBadRequest, err)
+				return
+			case tc.ForbiddenError:
+				handleErrs(http.StatusForbidden, err)
+				return
+			}
+		}
+
+		// perform the insert transaction
+		rollbackTransaction := true
+		tx, err := db.Beginx()
+		defer func() {
+			if tx == nil || !rollbackTransaction {
+				return
+			}
+			err := tx.Rollback()
+			if err != nil {
+				log.Errorln(errors.New("rolling back transaction: " + err.Error()))
+			}
+		}()
+
+		if err != nil {
+			log.Error.Printf("could not begin transaction: %v", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		if *payload.Replace {
+			// delete existing
+			rows, err := db.Queryx( "DELETE FROM deliveryservice_server WHERE deliveryservice = $1", *dsId)
+			if err != nil {
+				log.Errorf("unable to remove the existing servers assigned to the delivery service: %s", err)
+				handleErrs(http.StatusInternalServerError, err)
+				return
+			}
+
+			defer rows.Close()
+		}
+
+		i := 0
+		respServers := []int{}
+
+		for i < len(servers) {
+			dtos := map[string]interface{}{"id":dsId, "server":servers[i]}
+			resultRows, err := tx.NamedQuery(insertIdsQuery(), dtos)
+			if err != nil {
+				if pqErr, ok := err.(*pq.Error); ok {
+					err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
+					log.Error.Printf("could not begin transaction: %v", err)
+					if eType == tc.DataConflictError {
+						handleErrs(http.StatusInternalServerError, err)
+						return
+					}
+					handleErrs(http.StatusInternalServerError, err)
+					return
+				}
+				log.Errorf("received non pq error: %++v from create execution", err)
+				return
+			}
+			respServers = append(respServers, servers[i])
+			resultRows.Next()
+			i++
+			defer resultRows.Close()
+		}
+
+		err = tx.Commit()
+		if err != nil {
+			log.Errorln("Could not commit transaction: ", err)
+			return
+		}
+		rollbackTransaction = false
+
+		// marshal the results to the response stream
+		respBts, err := json.Marshal(respServers)
+		if err != nil {
+			log.Errorln("Could not marshal the response as expected: ", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		w.Header().Set(tc.ContentType, tc.ApplicationJson)
+		fmt.Fprintf(w, "%s", respBts)
+		return
+	}
+}
+
+
+type DeliveryServiceServers struct {
+	ServerNames []string			`json:"serverNames"`
+	XmlId string 					`json:"xmlId"`
+}
+
+type TODeliveryServiceServers DeliveryServiceServers
+
+var serversRef = TODeliveryServiceServers(DeliveryServiceServers{})
+
+func GetServersRef() *TODeliveryServiceServers {
+	return &serversRef
+}
+
+// api/1.1/deliveryservices/{xml_id}/servers
+func GetCreateHandler( db *sqlx.DB ) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		handleErrs := tc.GetHandleErrorsFunc(w, r)
+
+		// find the delivery service Id dsId matching the xml_id
+		params, err := api.GetCombinedParams(r)
+		if err != nil {
+			log.Errorf("unable to get parameters from request: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+		}
+
+		xmlId, ok := params["xml_id"]
+		if !ok {
+			log.Errorf("unable to get xml_id parameter from request: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		ctx := r.Context()
+		user, err := auth.GetCurrentUser(ctx)
+		if err != nil {
+			log.Errorf("unable to retrieve current user from context: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		// if the object has tenancy enabled, check that user is able to access the tenant
+		// check user tenancy access to this resource.
+		hasAccess, err, apiStatus := tenant.HasTenant(*user, xmlId, db)
+		if !hasAccess {
+			switch apiStatus {
+			case tc.SystemError:
+				handleErrs(http.StatusInternalServerError, err)
+				return
+			case tc.DataMissingError:
+				handleErrs(http.StatusBadRequest, err)
+				return
+			case tc.ForbiddenError:
+				handleErrs(http.StatusForbidden, err)
+				return
+			}
+		}
+
+		row := db.QueryRow(selectDeliveryService(), xmlId)
+		var dsId int
+		row.Scan(&dsId)
+
+		// get list of server Ids to insert
+		defer r.Body.Close()
+		payload := GetServersRef()
+
+		if err := json.NewDecoder(r.Body).Decode(payload); err != nil {
+			log.Errorf("Error trying to decode the request body: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		payload.XmlId = xmlId
+		serverNames := payload.ServerNames
+		q, arg, err := sqlx.In(selectServerIds(), serverNames)
+
+		if err != nil {
+			log.Error.Printf("Could not form IN query : %v", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+		q = sqlx.Rebind(sqlx.DOLLAR, q)
+		serverIds, err := db.Query(q, arg...)
+		defer serverIds.Close()
+		if err != nil {
+			log.Error.Printf("Could not select the ServerIds: %v", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		// perform the insert transaction
+		rollbackTransaction := true
+		tx, err := db.Beginx()
+		defer func() {
+			if tx == nil || !rollbackTransaction {
+				return
+			}
+			err := tx.Rollback()
+			if err != nil {
+				log.Errorln(errors.New("rolling back transaction: " + err.Error()))
+			}
+		}()
+
+		if err != nil {
+			log.Error.Printf("could not begin transaction: %v", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		// We have to get the server Ids and iterate through them because of a bug in the Go
+		// transaction which returns an error if you perform a Select after an Insert in
+		// the same transaction
+		for serverIds.Next() {
+			var serverId int
+			err := serverIds.Scan(&serverId)
+			dtos := map[string]interface{}{"id":dsId, "server":serverId}
+			resultRows, err := tx.NamedQuery(insertIdsQuery(), dtos)
+			if err != nil {
+				if pqErr, ok := err.(*pq.Error); ok {
+					err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
+					log.Error.Printf("could not begin transaction: %v", err)
+					if eType == tc.DataConflictError {
+						handleErrs(http.StatusInternalServerError, err)
+						return
+					}
+					handleErrs(http.StatusInternalServerError, err)
+					return
+				}
+				log.Errorf("received non pq error: %++v from create execution", err)
+				return
+			}
+			resultRows.Next()
+		}
+
+		err = tx.Commit()
+		if err != nil {
+			log.Errorln("Could not commit transaction: ", err)
+			return
+		}
+		rollbackTransaction = false
+
+		// marshal the results to the response stream
+		payloadResp := struct { Response TODeliveryServiceServers  `json:"response"`}{*payload}
+		respBts, err := json.Marshal(payloadResp)
+		if err != nil {
+			log.Errorln("Could not marshal the response as expected: ", err)
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		w.Header().Set(tc.ContentType, tc.ApplicationJson)
+		fmt.Fprintf(w, "%s", respBts)
+		return
+	}
+}
+
+func selectDeliveryService() string {
+	query := `SELECT id FROM deliveryservice WHERE xml_id = $1`
+	return query
+}
+
+func selectServerIds() string {
+	query := `SELECT id FROM server WHERE host_name in (?)`
+	return query
+}
+
+func insertQuery() string {
+	query := `INSERT INTO deliveryservice_server (deliveryservice, server) 
+(SELECT d.id, s.id FROM deliveryservice d, server s 
+WHERE d.xml_id=:xml_id and s.host_name=:server) 
+RETURNING server`
+	return query
+}
+
+func insertIdsQuery() string {
+	query := `INSERT INTO deliveryservice_server (deliveryservice, server) 
+VALUES (:id, :server )`
+	return query
+}
+
+
+// api/1.1/deliveryservices/{id}/servers|unassigned_servers|eligible
+func GetReadHandler(db *sqlx.DB, filter string) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		handleErrs := tc.GetHandleErrorsFunc(w, r)
+		params, err := api.GetCombinedParams(r)
+		if err != nil {
+			log.Errorf("unable to get parameters from request: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+		}
+
+		where := `WHERE s.id in (select server from deliveryservice_server where deliveryservice = $1)`
+
+		if filter[0] == 'u' {
+			where = `WHERE s.id not in (select server from deliveryservice_server where deliveryservice = $1)`
+		}
+
+		servers, errors, etype := read(db, params, auth.CurrentUser{}, where)
+
+		if len(errors) > 0 {
+			tc.HandleErrorsWithType(errors, etype, handleErrs)
+			return
+		}
+
+		respBts, err := json.Marshal(servers)
+		if err != nil {
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		w.Header().Set(tc.ContentType, tc.ApplicationJson)
+		fmt.Fprintf(w, "%s", respBts)
+	}
+}
+
+func read(db *sqlx.DB, params map[string]string, user auth.CurrentUser, where string) ([]interface{}, []error, tc.ApiErrorType) {
+	idstr, ok := params["id"]
+
+	if !ok {
+		log.Errorf("Deliveryservice Server Id missing")
+		return nil, []error{errors.New("Deliverservice id is required.")}, tc.DataMissingError
+	}
+	id, err := strconv.Atoi(idstr)
+
+	if err != nil {
+		log.Errorf("Deliveryservice Server Id is not an integer")
+		return nil, []error{errors.New("Deliverservice id is not an integer.")}, tc.SystemError
+	}
+
+	query := dssSelectQuery() + where
+	log.Debugln("Query is ", query)
+
+	rows, err := db.Queryx(query, id)
+	if err != nil {
+		log.Errorf("Error querying DeliveryserviceServers: %v", err)
+		return nil, []error{tc.DBError}, tc.SystemError
+	}
+	defer rows.Close()
+
+	servers := []interface{}{}
+	for rows.Next() {
+		var s tc.DSServer
+		if err = rows.StructScan(&s); err != nil {
+			log.Errorf("error parsing dss rows: %v", err)
+			return nil, []error{tc.DBError}, tc.SystemError
+		}
+		hiddenField := ""
+		if user.PrivLevel < auth.PrivLevelAdmin {
+			s.ILOPassword = &hiddenField
+		}
+		servers = append(servers, s)
+	}
+
+	return servers, []error{}, tc.NoError
+}
+
+
+func dssSelectQuery() string {
 
 	const JumboFrameBPS = 9000
 
@@ -316,12 +707,133 @@ func selectQuery() string {
 	JOIN phys_location pl ON s.phys_location = pl.id
 	JOIN profile p ON s.profile = p.id
 	JOIN status st ON s.status = st.id
-	JOIN type t ON s.type = t.id
-	WHERE s.id in (select server from deliveryservice_server where deliveryservice = $1)`
+	JOIN type t ON s.type = t.id `
 
 	return selectStmt
 }
 
+type TODSSDeliveryService tc.DSSDeliveryService
+
+var dserviceRef = TODSSDeliveryService(tc.DSSDeliveryService{})
+
+func GetDServiceRef() *TODSSDeliveryService {
+	return &dserviceRef
+}
+
+// api/1.1/servers/{id}/deliveryservices$
+func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+	var err error = nil
+	orderby := params["orderby"]
+	serverId := params["id"]
+
+	if orderby == "" {
+		orderby = "deliveryService"
+	}
+
+	query := SDSSelectQuery()
+	log.Debugln("Query is ", query)
+
+	rows, err := db.Queryx(query, serverId )
+	if err != nil {
+		log.Errorf("Error querying DeliveryserviceServers: %v", err)
+		return nil, []error{tc.DBError}, tc.SystemError
+	}
+	defer rows.Close()
+
+	services := []interface{}{}
+	for rows.Next() {
+		var s tc.DSSDeliveryService
+		if err = rows.StructScan(&s); err != nil {
+			log.Errorf("error parsing dss rows: %v", err)
+			return nil, []error{tc.DBError}, tc.SystemError
+		}
+		services = append(services, s)
+	}
+
+	return services, []error{}, tc.NoError
+}
+
+func SDSSelectQuery() string {
+
+	const JumboFrameBPS = 9000
+
+	// COALESCE is needed to default values that are nil in the database
+	// because Go does not allow that to marshal into the struct
+	selectStmt := `SELECT
+		active,
+	    cacheurl,
+		ccr_dns_ttl,
+		cdn_id,
+		cdnName,
+		check_path,
+		deep_caching_type,
+		display_name,
+		check_path,
+		deep_caching_type,
+		display_name,
+		dns_bypass_cname,
+		dns_bypass_ip,
+		dns_bypass_ip6,
+		dns_bypass_ttl,
+		dscp,
+		edge_header_rewrite,
+		fq_pacing_rate,
+		geo_limit,
+		geo_limit_countries,
+		geolimit_redirect_url,
+		geo_provider,
+		global_max_mbps,
+		global_max_tps,
+		http_bypass_fqdn,
+		id,
+		info_url,
+		initial_dispersion,
+		ipv6_routing_enabled,
+		last_updated,
+		logs_enabled,
+		long_desc,
+		long_desc_1,
+		long_desc_2,
+		max_dns_answers,
+		mid_header_rewrite,
+		miss_lat,
+		miss_long,
+		multi_site_origin,
+		origin_sheild,
+		org_server_fqdn,
+		profileDescription,
+		profile,
+		profileName,
+		protocol,
+		qstring_ignore,
+		range_request_handling,
+		regex_remap,
+		regional_geo_blocking,
+		remap_text,
+		routing_name,
+		signing_algorithm,
+		ssl_key_version,
+		tr_request_headers,
+		tr_response_headers,
+		tenant_id,
+		typeName,
+		type,
+		xml_id
+		FROM deliveryservice
+		WHERE id in (SELECT deliveryservice FROM deliverservice_server where server = $1)`
+		return selectStmt
+}
+
+
+func insertFromNamesQuery() string {
+	query := `INSERT INTO deliveryservice_server (
+	deliveryservice,
+	server) VALUES (
+	:select id from deliveryservice where xml_id=:xml_id,
+	select id from server where host_name=:server_name) RETURNING deliveryservice, server, last_updated`
+	return query
+}
+
 func updateQuery() string {
 	query := `UPDATE
 	profile_parameter SET
@@ -333,8 +845,4 @@ func updateQuery() string {
 	return query
 }
 
-func deleteQuery() string {
-	query := `DELETE FROM profile_parameter
-	WHERE profile=:profile_id and parameter=:parameter_id`
-	return query
-}
+
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index e6efb81..ff0eebd 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -163,10 +163,13 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodDelete, `regions/{id}$`, api.DeleteHandler(region.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
 
 		// get all edge servers associated with a delivery service (from deliveryservice_server table)
-		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(serverdss.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryserviceserver$`, dsserver.ReadDSSHandler(d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+		//{1.1, http.MethodPost,`deliveryserviceserver$`, dsserver.GetReplaceHandler(d.DB),auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost,`deliveryservices/{xml_id}/servers$`, dsserver.GetCreateHandler( d.DB ) ,auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(dsserver.GetDServiceRef(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, dsserver.GetReadHandler(d.DB, "assigned"),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, dsserver.GetReadHandler(d.DB, "unassigned"),auth.PrivLevelReadOnly, Authenticated, nil},
+		//{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.DB, "eligible"),auth.PrivLevelReadOnly, Authenticated, nil},
 
 		//Server
 		{1.1, http.MethodGet, `servers/checks$`, handlerToFunc(proxyHandler), 0, NoAuth, []Middleware{}},

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 01/10: started adding another read method

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 42c8bf32fa145a2646957fa18fb44b8e6740ffc6
Author: ASchmidt <An...@comcast.com>
AuthorDate: Mon May 7 11:29:40 2018 -0600

    started adding another read method
---
 .../servers/deliveryservicestoServer.go            | 359 +++++++++++++++++++++
 1 file changed, 359 insertions(+)

diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go
new file mode 100644
index 0000000..768dab0
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go
@@ -0,0 +1,359 @@
+package servers
+
+/*
+ * 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"
+	"fmt"
+	"strconv"
+
+	"github.com/apache/incubator-trafficcontrol/lib/go-log"
+	"github.com/apache/incubator-trafficcontrol/lib/go-tc"
+	"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/tovalidate"
+	"github.com/go-ozzo/ozzo-validation"
+
+	"github.com/jmoiron/sqlx"
+	"github.com/lib/pq"
+)
+
+// TODeliveryServiceRequest provides a type alias to define functions on
+type TODeliveryServiceServer tc.DeliveryServiceServer
+
+//the refType is passed into the handlers where a copy of its type is used to decode the json.
+var refType = TODeliveryServiceServer(tc.DeliveryServiceServer{})
+
+func GetRefType() *TODeliveryServiceServer {
+	return &refType
+}
+
+/*
+# get all delivery services associated with a server (from deliveryservice_server table)
+$r->get( "/api/$version/servers/:id/deliveryservices" => [ id => qr/\d+/ ] )->over( authenticated => 1, not_ldap => 1 )->to( 'Deliveryservice#get_deliveryservices_by_serverId', namespace => $namespace );
+
+# delivery service / server assignments
+$r->post("/api/$version/deliveryservices/:xml_id/servers")->over( authenticated => 1, not_ldap => 1 )
+->to( 'Deliveryservice#assign_servers', namespace => $namespace );
+$r->delete("/api/$version/deliveryservice_server/:dsId/:serverId" => [ dsId => qr/\d+/, serverId => qr/\d+/ ] )->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#remove_server_from_ds', namespace => $namespace );
+	# -- DELIVERYSERVICES: SERVERS
+	# Supports ?orderby=key
+	$r->get("/api/$version/deliveryserviceserver")->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#index', namespace => $namespace );
+	$r->post("/api/$version/deliveryserviceserver")->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#assign_servers_to_ds', namespace => $namespace );
+
+		{1.2, http.MethodGet, `deliveryservices/{id}/servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.2, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.2, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+
+*/
+
+func (dss TODeliveryServiceServer) GetKeyFieldsInfo() []api.KeyFieldInfo {
+	return []api.KeyFieldInfo{{"deliveryservice", api.GetIntKey}, {"server", api.GetIntKey}}
+}
+
+//Implementation of the Identifier, Validator interface functions
+func (dss TODeliveryServiceServer) GetKeys() (map[string]interface{}, bool) {
+	if dss.DeliveryService == nil {
+		return map[string]interface{}{"deliveryservice": 0}, false
+	}
+	if dss.Server == nil {
+		return map[string]interface{}{"server": 0}, false
+	}
+	keys := make(map[string]interface{})
+	ds_id := *dss.DeliveryService
+	server_id := *dss.Server
+
+	keys["deliveryservice"] = ds_id
+	keys["server"] = server_id
+	return keys, true
+}
+
+func (dss *TODeliveryServiceServer) GetAuditName() string {
+	if dss.DeliveryService != nil {
+		return strconv.Itoa(*dss.DeliveryService) + "-" + strconv.Itoa(*dss.Server)
+	}
+	return "unknown"
+}
+
+func (dss *TODeliveryServiceServer) GetType() string {
+	return "deliveryserviceServers"
+}
+
+func (dss *TODeliveryServiceServer) SetKeys(keys map[string]interface{}) {
+	ds_id, _ := keys["deliveryservice"].(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.
+	dss.DeliveryService = &ds_id
+
+	server_id, _ := keys["server"].(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.
+	dss.Server = &server_id
+}
+
+// Validate fulfills the api.Validator interface
+func (dss *TODeliveryServiceServer) Validate(db *sqlx.DB) []error {
+
+	errs := validation.Errors{
+		"deliveryservice": validation.Validate(dss.DeliveryService, validation.Required),
+		"server":          validation.Validate(dss.Server, validation.Required),
+	}
+
+	return tovalidate.ToErrors(errs)
+}
+
+//The TODeliveryServiceServer implementation of the Creator interface
+//all implementations of Creator should use transactions and return the proper errorType
+//ParsePQUniqueConstraintError is used to determine if a profileparameter with conflicting values exists
+//if so, it will return an errorType of DataConflict and the type should be appended to the
+//generic error message returned
+//The insert sql returns the profile and lastUpdated values of the newly inserted profileparameter and have
+//to be added to the struct
+func (dss *TODeliveryServiceServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
+	rollbackTransaction := true
+	tx, err := db.Beginx()
+	defer func() {
+		if tx == nil || !rollbackTransaction {
+			return
+		}
+		err := tx.Rollback()
+		if err != nil {
+			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
+		}
+	}()
+
+	if err != nil {
+		log.Error.Printf("could not begin transaction: %v", err)
+		return tc.DBError, tc.SystemError
+	}
+	resultRows, err := tx.NamedQuery(insertQuery(), dss)
+	if err != nil {
+		if pqErr, ok := err.(*pq.Error); ok {
+			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
+			if eType == tc.DataConflictError {
+				return errors.New("a parameter with " + err.Error()), eType
+			}
+			return err, eType
+		}
+		log.Errorf("received non pq error: %++v from create execution", err)
+		return tc.DBError, tc.SystemError
+	}
+	defer resultRows.Close()
+
+	var ds_id int
+	var server_id int
+	var lastUpdated tc.TimeNoMod
+	rowsAffected := 0
+	for resultRows.Next() {
+		rowsAffected++
+		if err := resultRows.Scan(&ds_id, &server_id, &lastUpdated); err != nil {
+			log.Error.Printf("could not scan dss from insert: %s\n", err)
+			return tc.DBError, tc.SystemError
+		}
+	}
+	if rowsAffected == 0 {
+		err = errors.New("no deliveryServiceServer was inserted, nothing to return")
+		log.Errorln(err)
+		return tc.DBError, tc.SystemError
+	}
+	if rowsAffected > 1 {
+		err = errors.New("too many ids returned from parameter insert")
+		log.Errorln(err)
+		return tc.DBError, tc.SystemError
+	}
+
+	dss.SetKeys(map[string]interface{}{"deliveryservice": ds_id, "server": server_id})
+	dss.LastUpdated = &lastUpdated
+	err = tx.Commit()
+	if err != nil {
+		log.Errorln("Could not commit transaction: ", err)
+		return tc.DBError, tc.SystemError
+	}
+	rollbackTransaction = false
+	return nil, tc.NoError
+}
+
+func insertQuery() string {
+	query := `INSERT INTO deliveryservice_server (
+deliveryservice,
+server) VALUES (
+:ds_id,
+:server_id) RETURNING deliveryservice, server, last_updated`
+	return query
+}
+
+func (dss *TODeliveryServiceServer) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+	idstr, ok := params["id"]
+
+	if !ok {
+		log.Errorf("Deliveryservice Server Id missing")
+		return nil, []error{errors.New("Deliverservice id is required.")}, tc.DataMissingError
+	}
+	id, err := strconv.Atoi(idstr)
+
+	if err != nil {
+		log.Errorf("Deliveryservice Server Id is not an integer")
+		return nil, []error{errors.New("Deliverservice id is not an integer.")}, tc.SystemError
+	}
+
+	query := selectQuery()
+	log.Debugln("Query is ", query)
+
+	rows, err := db.Queryx(query, id)
+	if err != nil {
+		log.Errorf("Error querying DeliveryserviceServers: %v", err)
+		return nil, []error{tc.DBError}, tc.SystemError
+	}
+	defer rows.Close()
+
+	servers := []interface{}{}
+	for rows.Next() {
+		var s tc.DssServer
+		if err = rows.StructScan(&s); err != nil {
+			log.Errorf("error parsing dss rows: %v", err)
+			return nil, []error{tc.DBError}, tc.SystemError
+		}
+		hiddenField := ""
+		if user.PrivLevel < auth.PrivLevelAdmin {
+			s.ILOPassword = &hiddenField
+		}
+		servers = append(servers, s)
+	}
+
+	return servers, []error{}, tc.NoError
+
+}
+
+//The Parameter implementation of the Deleter interface
+//all implementations of Deleter should use transactions and return the proper errorType
+func (dss *TODeliveryServiceServer) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
+	rollbackTransaction := true
+	tx, err := db.Beginx()
+	defer func() {
+		if tx == nil || !rollbackTransaction {
+			return
+		}
+		err := tx.Rollback()
+		if err != nil {
+			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
+		}
+	}()
+
+	if err != nil {
+		log.Error.Printf("could not begin transaction: %v", err)
+		return tc.DBError, tc.SystemError
+	}
+	log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), dss)
+	result, err := tx.NamedExec(deleteQuery(), dss)
+	if err != nil {
+		log.Errorf("received error: %++v from delete execution", err)
+		return tc.DBError, tc.SystemError
+	}
+	rowsAffected, err := result.RowsAffected()
+	if err != nil {
+		return tc.DBError, tc.SystemError
+	}
+	if rowsAffected < 1 {
+		return errors.New("no parameter with that id found"), tc.DataMissingError
+	}
+	if rowsAffected > 1 {
+		return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
+	}
+
+	err = tx.Commit()
+	if err != nil {
+		log.Errorln("Could not commit transaction: ", err)
+		return tc.DBError, tc.SystemError
+	}
+	rollbackTransaction = false
+	return nil, tc.NoError
+}
+func selectQuery() string {
+
+	const JumboFrameBPS = 9000
+
+	// COALESCE is needed to default values that are nil in the database
+	// because Go does not allow that to marshal into the struct
+	selectStmt := `SELECT
+	cg.name as cachegroup,
+	s.cachegroup as cachegroup_id,
+	s.cdn_id,
+	cdn.name as cdn_name,
+	s.domain_name,
+	s.guid,
+	s.host_name,
+	s.https_port,
+	s.id,
+	s.ilo_ip_address,
+	s.ilo_ip_gateway,
+	s.ilo_ip_netmask,
+	s.ilo_password,
+	s.ilo_username,
+	COALESCE(s.interface_mtu, ` + strconv.Itoa(JumboFrameBPS) + `) as interface_mtu,
+	s.interface_name,
+	s.ip6_address,
+	s.ip6_gateway,
+	s.ip_address,
+	s.ip_gateway,
+	s.ip_netmask,
+	s.last_updated,
+	s.mgmt_ip_address,
+	s.mgmt_ip_gateway,
+	s.mgmt_ip_netmask,
+	s.offline_reason,
+	pl.name as phys_location,
+	s.phys_location as phys_location_id,
+	p.name as profile,
+	p.description as profile_desc,
+	s.profile as profile_id,
+	s.rack,
+	s.router_host_name,
+	s.router_port_name,
+	st.name as status,
+	s.status as status_id,
+	s.tcp_port,
+	t.name as server_type,
+	s.type as server_type_id,
+	s.upd_pending as upd_pending
+	FROM server s
+	JOIN cachegroup cg ON s.cachegroup = cg.id
+	JOIN cdn cdn ON s.cdn_id = cdn.id
+	JOIN phys_location pl ON s.phys_location = pl.id
+	JOIN profile p ON s.profile = p.id
+	JOIN status st ON s.status = st.id
+	JOIN type t ON s.type = t.id
+	WHERE s.id in (select server from deliveryservice_server where deliveryservice = $1)`
+
+	return selectStmt
+}
+
+func updateQuery() string {
+	query := `UPDATE
+	profile_parameter SET
+	profile=:profile_id,
+	parameter=:parameter_id
+	WHERE profile=:profile_id AND 
+      parameter = :parameter_id 
+      RETURNING last_updated`
+	return query
+}
+
+func deleteQuery() string {
+	query := `DELETE FROM profile_parameter
+	WHERE profile=:profile_id and parameter=:parameter_id`
+	return query
+}

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 06/10: Completed modifications from change request needed for PR

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 5b9a5394006e172323d0dd788d84e7b2373a9cf4
Author: ASchmidt <An...@comcast.com>
AuthorDate: Tue May 22 08:55:29 2018 -0600

    Completed modifications from change request needed for PR
---
 lib/go-tc/deliveryservice_servers.go               |  8 +++----
 .../deliveryservice/servers/servers.go             | 28 +++++++++++-----------
 traffic_ops/traffic_ops_golang/routes.go           |  6 ++---
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/lib/go-tc/deliveryservice_servers.go b/lib/go-tc/deliveryservice_servers.go
index 2239103..06d731a 100644
--- a/lib/go-tc/deliveryservice_servers.go
+++ b/lib/go-tc/deliveryservice_servers.go
@@ -56,9 +56,9 @@ type DeliveryServiceServer struct {
 
 type Filter int
 const (
-	ASSIGNED Filter = iota
-	UNASSIGNED
-	ELIGIBLE
+	Assigned Filter = iota
+	Unassigned
+	Eligible
 )
 
 type DSServer struct {
@@ -107,7 +107,7 @@ type DSServer struct {
 	UpdPending       *bool                `json:"updPending" db:"upd_pending"`
 }
 
-// DSSDeliveryService - a version of the deliveryservice that allows for all fields to be null
+// DSSDeliveryService is a representation of a deliveryservice that allows for all fields to be null
 type DSSDeliveryService struct {
 	// NOTE: the db: struct tags are used for testing to map to their equivalent database column (if there is one)
 	//
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index 3b65680..c6ba71a 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -100,7 +100,7 @@ func (dss *TODeliveryServiceServer) Validate(db *sqlx.DB) []error {
 	return tovalidate.ToErrors(errs)
 }
 
-// api/1.1/deliveryserviceserver$
+// ReadDSSHandler list all of the Deliveryservice Servers in response to requests to api/1.1/deliveryserviceserver$
 func ReadDSSHandler(db *sqlx.DB) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		//create error function with ResponseWriter and Request
@@ -288,9 +288,9 @@ type DSServers struct {
 
 type TODSServers DSServers
 
-var dsserversRef = TODSServers(DSServers{})
 
-func GetServersForDsIdRef() *TODSServers {
+func createServersForDsIdRef() *TODSServers {
+	var dsserversRef = TODSServers(DSServers{})
 	return &dsserversRef
 }
 
@@ -307,7 +307,7 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 		}
 
 		// get list of server Ids to insert
-		payload := GetServersForDsIdRef()
+		payload :=  createServersForDsIdRef() 
 		servers := payload.Servers
 		dsId := payload.DsId
 
@@ -371,8 +371,8 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 		i := 0
 		respServers := []int{}
 
-		for i < len(servers) {
-			dtos := map[string]interface{}{"id": dsId, "server": servers[i]}
+		for _ , server := range servers {
+			dtos := map[string]interface{}{"id": dsId, "server": server}
 			resultRows, err := tx.NamedQuery(insertIdsQuery(), dtos)
 			if err != nil {
 				if pqErr, ok := err.(*pq.Error); ok {
@@ -388,7 +388,7 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 				log.Errorf("received non pq error: %++v from create execution", err)
 				return
 			}
-			respServers = append(respServers, servers[i])
+			respServers = append(respServers, server)
 			resultRows.Next()
 			i++
 			defer resultRows.Close()
@@ -419,13 +419,13 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 
 type TODeliveryServiceServers tc.DeliveryServiceServers
 
-var serversRef = TODeliveryServiceServers(tc.DeliveryServiceServers{})
 
-func GetServersRef() *TODeliveryServiceServers {
+func createServersRef() *TODeliveryServiceServers {
+	serversRef := TODeliveryServiceServers(tc.DeliveryServiceServers{})
 	return &serversRef
 }
 
-// api/1.1/deliveryservices/{xml_id}/servers
+// GetCreateHandler assigns an existing Server to and existing Deliveryservice in response to api/1.1/deliveryservices/{xml_id}/servers
 func GetCreateHandler(db *sqlx.DB) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		handleErrs := tc.GetHandleErrorsFunc(w, r)
@@ -480,7 +480,7 @@ func GetCreateHandler(db *sqlx.DB) http.HandlerFunc {
 
 		// get list of server Ids to insert
 		defer r.Body.Close()
-		payload := GetServersRef()
+		payload := createServersRef()
 
 		if err := json.NewDecoder(r.Body).Decode(payload); err != nil {
 			log.Errorf("Error trying to decode the request body: %s", err)
@@ -589,7 +589,7 @@ func selectServerIds() string {
 	return query
 }
 
-// GetReadHandler api/1.1/deliveryservices/{id}/servers|unassigned_servers|eligible
+// GetReadHandler retrieves lists of servers  based in the filter identified in the request: api/1.1/deliveryservices/{id}/servers|unassigned_servers|eligible
 func GetReadHandler(db *sqlx.DB, filter tc.Filter) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		handleErrs := tc.GetHandleErrorsFunc(w, r)
@@ -601,7 +601,7 @@ func GetReadHandler(db *sqlx.DB, filter tc.Filter) http.HandlerFunc {
 
 		where := `WHERE s.id in (select server from deliveryservice_server where deliveryservice = $1)`
 
-		if filter == tc.UNASSIGNED {
+		if filter == tc.Unassigned {
 			where = `WHERE s.id not in (select server from deliveryservice_server where deliveryservice = $1)`
 		}
 
@@ -730,7 +730,7 @@ func GetDServiceRef() *TODSSDeliveryService {
 	return &dserviceRef
 }
 
-// Read api/1.1/servers/{id}/deliveryservices$
+// Read shows all of the delivery services associated with the specified server.
 func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
 	var err error = nil
 	orderby := params["orderby"]
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index 9240c45..6a39edb 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -168,9 +168,9 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodPost,`deliveryserviceserver$`, dsserver.GetReplaceHandler(d.DB),auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodPost,`deliveryservices/{xml_id}/servers$`, dsserver.GetCreateHandler( d.DB ) ,auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(dsserver.GetDServiceRef(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, dsserver.GetReadHandler(d.DB, "Assigned"),auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, dsserver.GetReadHandler(d.DB, "Unassigned"),auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.DB, "Eligible"),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, dsserver.GetReadHandler(d.DB, tc.Assigned),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, dsserver.GetReadHandler(d.DB, tc.Unassigned),auth.PrivLevelReadOnly, Authenticated, nil},
+		//{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.DB, tc.Eligible),auth.PrivLevelReadOnly, Authenticated, nil},
 
 		//Server
 		{1.1, http.MethodGet, `servers/checks$`, handlerToFunc(proxyHandler), 0, NoAuth, []Middleware{}},

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 04/10: Created strucs in tc package for all DSS responses

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ac962989ba20935dad991d56e5a2aadfdf99d917
Author: ASchmidt <An...@comcast.com>
AuthorDate: Mon May 14 15:23:07 2018 -0600

    Created strucs in tc package for all DSS responses
---
 lib/go-tc/deliveryservice_servers.go               | 24 +++++++++++-
 .../deliveryservice/servers/servers.go             | 43 ++++++----------------
 traffic_ops/traffic_ops_golang/routes.go           |  2 +-
 3 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/lib/go-tc/deliveryservice_servers.go b/lib/go-tc/deliveryservice_servers.go
index d24d1b6..f549f76 100644
--- a/lib/go-tc/deliveryservice_servers.go
+++ b/lib/go-tc/deliveryservice_servers.go
@@ -1,6 +1,8 @@
 package tc
 
-import "time"
+import (
+	"time"
+)
 
 /*
 
@@ -25,6 +27,26 @@ type DeliveryServiceServerResponse struct {
 	Limit    int                     `json:"limit"`
 }
 
+type DSSMapResponse struct {
+		DsId	int					`json:"dsId"`
+		Replace bool				`json:"replace"`
+		Servers []int				`json:"servers"`
+	}
+
+type DSSReplaceResponse struct {
+	Alerts 		[]Alert             `json:"alerts"`
+	Response 	DSSMapResponse		`json:"response"`
+}
+
+type DSServersResponse struct {
+	Response DeliveryServiceServers  `json:"response"`
+}
+
+type DeliveryServiceServers struct {
+	ServerNames []string			`json:"serverNames"`
+	XmlId string 					`json:"xmlId"`
+}
+
 // DeliveryServiceServer ...
 type DeliveryServiceServer struct {
 	Server          *int             `json:"server" db:"server"`
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index 8f534ca..ccd84f4 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -382,9 +382,11 @@ func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
 			return
 		}
 		rollbackTransaction = false
+		resAlerts := []tc.Alert{ tc.Alert{"sever assignement","success"}}
+		repRes := tc.DSSReplaceResponse{resAlerts, tc.DSSMapResponse{*dsId,*payload.Replace,respServers }}
 
 		// marshal the results to the response stream
-		respBts, err := json.Marshal(respServers)
+		respBts, err := json.Marshal(repRes)
 		if err != nil {
 			log.Errorln("Could not marshal the response as expected: ", err)
 			handleErrs(http.StatusInternalServerError, err)
@@ -398,14 +400,11 @@ func GetReplaceHandler( db *sqlx.DB ) http.HandlerFunc {
 }
 
 
-type DeliveryServiceServers struct {
-	ServerNames []string			`json:"serverNames"`
-	XmlId string 					`json:"xmlId"`
-}
 
-type TODeliveryServiceServers DeliveryServiceServers
 
-var serversRef = TODeliveryServiceServers(DeliveryServiceServers{})
+type TODeliveryServiceServers tc.DeliveryServiceServers
+
+var serversRef = TODeliveryServiceServers(tc.DeliveryServiceServers{})
 
 func GetServersRef() *TODeliveryServiceServers {
 	return &serversRef
@@ -539,7 +538,8 @@ func GetCreateHandler( db *sqlx.DB ) http.HandlerFunc {
 		rollbackTransaction = false
 
 		// marshal the results to the response stream
-		payloadResp := struct { Response TODeliveryServiceServers  `json:"response"`}{*payload}
+		tcPayload := tc.DeliveryServiceServers{payload.ServerNames, payload.XmlId}
+		payloadResp := tc.DSServersResponse{tcPayload}
 		respBts, err := json.Marshal(payloadResp)
 		if err != nil {
 			log.Errorln("Could not marshal the response as expected: ", err)
@@ -558,25 +558,16 @@ func selectDeliveryService() string {
 	return query
 }
 
-func selectServerIds() string {
-	query := `SELECT id FROM server WHERE host_name in (?)`
-	return query
-}
-
-func insertQuery() string {
-	query := `INSERT INTO deliveryservice_server (deliveryservice, server) 
-(SELECT d.id, s.id FROM deliveryservice d, server s 
-WHERE d.xml_id=:xml_id and s.host_name=:server) 
-RETURNING server`
-	return query
-}
-
 func insertIdsQuery() string {
 	query := `INSERT INTO deliveryservice_server (deliveryservice, server) 
 VALUES (:id, :server )`
 	return query
 }
 
+func selectServerIds() string {
+	query := `SELECT id FROM server WHERE host_name in (?)`
+	return query
+}
 
 // api/1.1/deliveryservices/{id}/servers|unassigned_servers|eligible
 func GetReadHandler(db *sqlx.DB, filter string) http.HandlerFunc {
@@ -824,16 +815,6 @@ func SDSSelectQuery() string {
 		return selectStmt
 }
 
-
-func insertFromNamesQuery() string {
-	query := `INSERT INTO deliveryservice_server (
-	deliveryservice,
-	server) VALUES (
-	:select id from deliveryservice where xml_id=:xml_id,
-	select id from server where host_name=:server_name) RETURNING deliveryservice, server, last_updated`
-	return query
-}
-
 func updateQuery() string {
 	query := `UPDATE
 	profile_parameter SET
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index ff0eebd..752c8d8 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -164,7 +164,7 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 
 		// get all edge servers associated with a delivery service (from deliveryservice_server table)
 		{1.1, http.MethodGet, `deliveryserviceserver$`, dsserver.ReadDSSHandler(d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodPost,`deliveryserviceserver$`, dsserver.GetReplaceHandler(d.DB),auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost,`deliveryserviceserver$`, dsserver.GetReplaceHandler(d.DB),auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodPost,`deliveryservices/{xml_id}/servers$`, dsserver.GetCreateHandler( d.DB ) ,auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(dsserver.GetDServiceRef(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, dsserver.GetReadHandler(d.DB, "assigned"),auth.PrivLevelReadOnly, Authenticated, nil},

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 02/10: started adding new read method

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit bfa8ae4aa27771b0f5967639e8b6a6258b83ccea
Author: ASchmidt <An...@comcast.com>
AuthorDate: Mon May 7 11:35:15 2018 -0600

    started adding new read method
---
 lib/go-tc/deliveryservice_servers.go               |  62 ++++
 .../servers/deliveryservicestoServer.go            | 359 ---------------------
 traffic_ops/traffic_ops_golang/routes.go           |   3 +
 3 files changed, 65 insertions(+), 359 deletions(-)

diff --git a/lib/go-tc/deliveryservice_servers.go b/lib/go-tc/deliveryservice_servers.go
index aa0ec99..85bfde9 100644
--- a/lib/go-tc/deliveryservice_servers.go
+++ b/lib/go-tc/deliveryservice_servers.go
@@ -78,3 +78,65 @@ type DssServer struct {
 	TypeID           *int                 `json:"typeId" db:"server_type_id"`
 	UpdPending       *bool                `json:"updPending" db:"upd_pending"`
 }
+
+// DeliveryServiceNullable - a version of the deliveryservice that allows for all fields to be null
+type DssDeliveryService struct {
+	// NOTE: the db: struct tags are used for testing to map to their equivalent database column (if there is one)
+	//
+	Active                   *bool                   `json:"active" db:"active"`
+	CacheURL                 *string                 `json:"cacheurl" db:"cacheurl"`
+	CCRDNSTTL                *int                    `json:"ccrDnsTtl" db:"ccr_dns_ttl"`
+	CDNID                    *int                    `json:"cdnId" db:"cdn_id"`
+	CDNName                  *string                 `json:"cdnName"`
+	CheckPath                *string                 `json:"checkPath" db:"check_path"`
+	DeepCachingType          *DeepCachingType        `json:"deepCachingType" db:"deep_caching_type"`
+	DisplayName              *string                 `json:"displayName" db:"display_name"`
+	DNSBypassCNAME           *string                 `json:"dnsBypassCname" db:"dns_bypass_cname"`
+	DNSBypassIP              *string                 `json:"dnsBypassIp" db:"dns_bypass_ip"`
+	DNSBypassIP6             *string                 `json:"dnsBypassIp6" db:"dns_bypass_ip6"`
+	DNSBypassTTL             *int                    `json:"dnsBypassTtl" db:"dns_bypass_ttl"`
+	DSCP                     *int                    `json:"dscp" db:"dscp"`
+	EdgeHeaderRewrite        *string                 `json:"edgeHeaderRewrite" db:"edge_header_rewrite"`
+	FQPacingRate             *int                    `json:"fqPacingRate" db:"fq_pacing_rate"`
+	GeoLimit                 *int                    `json:"geoLimit" db:"geo_limit"`
+	GeoLimitCountries        *string                 `json:"geoLimitCountries" db:"geo_limit_countries"`
+	GeoLimitRedirectURL      *string                 `json:"geoLimitRedirectURL" db:"geolimit_redirect_url"`
+	GeoProvider              *int                    `json:"geoProvider" db:"geo_provider"`
+	GlobalMaxMBPS            *int                    `json:"globalMaxMbps" db:"global_max_mbps"`
+	GlobalMaxTPS             *int                    `json:"globalMaxTps" db:"global_max_tps"`
+	HTTPBypassFQDN           *string                 `json:"httpBypassFqdn" db:"http_bypass_fqdn"`
+	ID                       *int                    `json:"id" db:"id"`
+	InfoURL                  *string                 `json:"infoUrl" db:"info_url"`
+	InitialDispersion        *int                    `json:"initialDispersion" db:"initial_dispersion"`
+	IPV6RoutingEnabled       *bool                   `json:"ipv6RoutingEnabled" db:"ipv6_routing_enabled"`
+	LastUpdated              *TimeNoMod              `json:"lastUpdated" db:"last_updated"`
+	LogsEnabled              *bool                   `json:"logsEnabled" db:"logs_enabled"`
+	LongDesc                 *string                 `json:"longDesc" db:"long_desc"`
+	LongDesc1                *string                 `json:"longDesc1" db:"long_desc_1"`
+	LongDesc2                *string                 `json:"longDesc2" db:"long_desc_2"`
+	MaxDNSAnswers            *int                    `json:"maxDnsAnswers" db:"max_dns_answers"`
+	MidHeaderRewrite         *string                 `json:"midHeaderRewrite" db:"mid_header_rewrite"`
+	MissLat                  *float64                `json:"missLat" db:"miss_lat"`
+	MissLong                 *float64                `json:"missLong" db:"miss_long"`
+	MultiSiteOrigin          *bool                   `json:"multiSiteOrigin" db:"multi_site_origin"`
+	OriginShield             *string                 `json:"originShield" db:"origin_shield"`
+	OrgServerFQDN            *string                 `json:"orgServerFqdn" db:"org_server_fqdn"`
+	ProfileDesc              *string                 `json:"profileDescription"`
+	ProfileID                *int                    `json:"profileId" db:"profile"`
+	ProfileName              *string                 `json:"profileName"`
+	Protocol                 *int                    `json:"protocol" db:"protocol"`
+	QStringIgnore            *int                    `json:"qstringIgnore" db:"qstring_ignore"`
+	RangeRequestHandling     *int                    `json:"rangeRequestHandling" db:"range_request_handling"`
+	RegexRemap               *string                 `json:"regexRemap" db:"regex_remap"`
+	RegionalGeoBlocking      *bool                   `json:"regionalGeoBlocking" db:"regional_geo_blocking"`
+	RemapText                *string                 `json:"remapText" db:"remap_text"`
+	RoutingName              *string                 `json:"routingName" db:"routing_name"`
+	SigningAlgorithm         *string                 `json:"signingAlgorithm" db:"signing_algorithm"`
+	SSLKeyVersion            *int                    `json:"sslKeyVersion" db:"ssl_key_version"`
+	TRRequestHeaders         *string                 `json:"trRequestHeaders" db:"tr_request_headers"`
+	TRResponseHeaders        *string                 `json:"trResponseHeaders" db:"tr_response_headers"`
+	TenantID                 *int                    `json:"tenantId" db:"tenant_id"`
+	TypeName                 *string                 `json:"typeName"`
+	TypeID                   *int                    `json:"typeId" db:"type"`
+	XMLID                    *string                 `json:"xmlId" db:"xml_id"`
+}
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go
deleted file mode 100644
index 768dab0..0000000
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go
+++ /dev/null
@@ -1,359 +0,0 @@
-package servers
-
-/*
- * 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"
-	"fmt"
-	"strconv"
-
-	"github.com/apache/incubator-trafficcontrol/lib/go-log"
-	"github.com/apache/incubator-trafficcontrol/lib/go-tc"
-	"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/tovalidate"
-	"github.com/go-ozzo/ozzo-validation"
-
-	"github.com/jmoiron/sqlx"
-	"github.com/lib/pq"
-)
-
-// TODeliveryServiceRequest provides a type alias to define functions on
-type TODeliveryServiceServer tc.DeliveryServiceServer
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TODeliveryServiceServer(tc.DeliveryServiceServer{})
-
-func GetRefType() *TODeliveryServiceServer {
-	return &refType
-}
-
-/*
-# get all delivery services associated with a server (from deliveryservice_server table)
-$r->get( "/api/$version/servers/:id/deliveryservices" => [ id => qr/\d+/ ] )->over( authenticated => 1, not_ldap => 1 )->to( 'Deliveryservice#get_deliveryservices_by_serverId', namespace => $namespace );
-
-# delivery service / server assignments
-$r->post("/api/$version/deliveryservices/:xml_id/servers")->over( authenticated => 1, not_ldap => 1 )
-->to( 'Deliveryservice#assign_servers', namespace => $namespace );
-$r->delete("/api/$version/deliveryservice_server/:dsId/:serverId" => [ dsId => qr/\d+/, serverId => qr/\d+/ ] )->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#remove_server_from_ds', namespace => $namespace );
-	# -- DELIVERYSERVICES: SERVERS
-	# Supports ?orderby=key
-	$r->get("/api/$version/deliveryserviceserver")->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#index', namespace => $namespace );
-	$r->post("/api/$version/deliveryserviceserver")->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#assign_servers_to_ds', namespace => $namespace );
-
-		{1.2, http.MethodGet, `deliveryservices/{id}/servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.2, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.2, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
-
-*/
-
-func (dss TODeliveryServiceServer) GetKeyFieldsInfo() []api.KeyFieldInfo {
-	return []api.KeyFieldInfo{{"deliveryservice", api.GetIntKey}, {"server", api.GetIntKey}}
-}
-
-//Implementation of the Identifier, Validator interface functions
-func (dss TODeliveryServiceServer) GetKeys() (map[string]interface{}, bool) {
-	if dss.DeliveryService == nil {
-		return map[string]interface{}{"deliveryservice": 0}, false
-	}
-	if dss.Server == nil {
-		return map[string]interface{}{"server": 0}, false
-	}
-	keys := make(map[string]interface{})
-	ds_id := *dss.DeliveryService
-	server_id := *dss.Server
-
-	keys["deliveryservice"] = ds_id
-	keys["server"] = server_id
-	return keys, true
-}
-
-func (dss *TODeliveryServiceServer) GetAuditName() string {
-	if dss.DeliveryService != nil {
-		return strconv.Itoa(*dss.DeliveryService) + "-" + strconv.Itoa(*dss.Server)
-	}
-	return "unknown"
-}
-
-func (dss *TODeliveryServiceServer) GetType() string {
-	return "deliveryserviceServers"
-}
-
-func (dss *TODeliveryServiceServer) SetKeys(keys map[string]interface{}) {
-	ds_id, _ := keys["deliveryservice"].(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.
-	dss.DeliveryService = &ds_id
-
-	server_id, _ := keys["server"].(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.
-	dss.Server = &server_id
-}
-
-// Validate fulfills the api.Validator interface
-func (dss *TODeliveryServiceServer) Validate(db *sqlx.DB) []error {
-
-	errs := validation.Errors{
-		"deliveryservice": validation.Validate(dss.DeliveryService, validation.Required),
-		"server":          validation.Validate(dss.Server, validation.Required),
-	}
-
-	return tovalidate.ToErrors(errs)
-}
-
-//The TODeliveryServiceServer implementation of the Creator interface
-//all implementations of Creator should use transactions and return the proper errorType
-//ParsePQUniqueConstraintError is used to determine if a profileparameter with conflicting values exists
-//if so, it will return an errorType of DataConflict and the type should be appended to the
-//generic error message returned
-//The insert sql returns the profile and lastUpdated values of the newly inserted profileparameter and have
-//to be added to the struct
-func (dss *TODeliveryServiceServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), dss)
-	if err != nil {
-		if pqErr, ok := err.(*pq.Error); ok {
-			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
-			if eType == tc.DataConflictError {
-				return errors.New("a parameter with " + err.Error()), eType
-			}
-			return err, eType
-		}
-		log.Errorf("received non pq error: %++v from create execution", err)
-		return tc.DBError, tc.SystemError
-	}
-	defer resultRows.Close()
-
-	var ds_id int
-	var server_id int
-	var lastUpdated tc.TimeNoMod
-	rowsAffected := 0
-	for resultRows.Next() {
-		rowsAffected++
-		if err := resultRows.Scan(&ds_id, &server_id, &lastUpdated); err != nil {
-			log.Error.Printf("could not scan dss from insert: %s\n", err)
-			return tc.DBError, tc.SystemError
-		}
-	}
-	if rowsAffected == 0 {
-		err = errors.New("no deliveryServiceServer was inserted, nothing to return")
-		log.Errorln(err)
-		return tc.DBError, tc.SystemError
-	}
-	if rowsAffected > 1 {
-		err = errors.New("too many ids returned from parameter insert")
-		log.Errorln(err)
-		return tc.DBError, tc.SystemError
-	}
-
-	dss.SetKeys(map[string]interface{}{"deliveryservice": ds_id, "server": server_id})
-	dss.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
-	return nil, tc.NoError
-}
-
-func insertQuery() string {
-	query := `INSERT INTO deliveryservice_server (
-deliveryservice,
-server) VALUES (
-:ds_id,
-:server_id) RETURNING deliveryservice, server, last_updated`
-	return query
-}
-
-func (dss *TODeliveryServiceServer) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
-	idstr, ok := params["id"]
-
-	if !ok {
-		log.Errorf("Deliveryservice Server Id missing")
-		return nil, []error{errors.New("Deliverservice id is required.")}, tc.DataMissingError
-	}
-	id, err := strconv.Atoi(idstr)
-
-	if err != nil {
-		log.Errorf("Deliveryservice Server Id is not an integer")
-		return nil, []error{errors.New("Deliverservice id is not an integer.")}, tc.SystemError
-	}
-
-	query := selectQuery()
-	log.Debugln("Query is ", query)
-
-	rows, err := db.Queryx(query, id)
-	if err != nil {
-		log.Errorf("Error querying DeliveryserviceServers: %v", err)
-		return nil, []error{tc.DBError}, tc.SystemError
-	}
-	defer rows.Close()
-
-	servers := []interface{}{}
-	for rows.Next() {
-		var s tc.DssServer
-		if err = rows.StructScan(&s); err != nil {
-			log.Errorf("error parsing dss rows: %v", err)
-			return nil, []error{tc.DBError}, tc.SystemError
-		}
-		hiddenField := ""
-		if user.PrivLevel < auth.PrivLevelAdmin {
-			s.ILOPassword = &hiddenField
-		}
-		servers = append(servers, s)
-	}
-
-	return servers, []error{}, tc.NoError
-
-}
-
-//The Parameter implementation of the Deleter interface
-//all implementations of Deleter should use transactions and return the proper errorType
-func (dss *TODeliveryServiceServer) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), dss)
-	result, err := tx.NamedExec(deleteQuery(), dss)
-	if err != nil {
-		log.Errorf("received error: %++v from delete execution", err)
-		return tc.DBError, tc.SystemError
-	}
-	rowsAffected, err := result.RowsAffected()
-	if err != nil {
-		return tc.DBError, tc.SystemError
-	}
-	if rowsAffected < 1 {
-		return errors.New("no parameter with that id found"), tc.DataMissingError
-	}
-	if rowsAffected > 1 {
-		return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
-	}
-
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
-	return nil, tc.NoError
-}
-func selectQuery() string {
-
-	const JumboFrameBPS = 9000
-
-	// COALESCE is needed to default values that are nil in the database
-	// because Go does not allow that to marshal into the struct
-	selectStmt := `SELECT
-	cg.name as cachegroup,
-	s.cachegroup as cachegroup_id,
-	s.cdn_id,
-	cdn.name as cdn_name,
-	s.domain_name,
-	s.guid,
-	s.host_name,
-	s.https_port,
-	s.id,
-	s.ilo_ip_address,
-	s.ilo_ip_gateway,
-	s.ilo_ip_netmask,
-	s.ilo_password,
-	s.ilo_username,
-	COALESCE(s.interface_mtu, ` + strconv.Itoa(JumboFrameBPS) + `) as interface_mtu,
-	s.interface_name,
-	s.ip6_address,
-	s.ip6_gateway,
-	s.ip_address,
-	s.ip_gateway,
-	s.ip_netmask,
-	s.last_updated,
-	s.mgmt_ip_address,
-	s.mgmt_ip_gateway,
-	s.mgmt_ip_netmask,
-	s.offline_reason,
-	pl.name as phys_location,
-	s.phys_location as phys_location_id,
-	p.name as profile,
-	p.description as profile_desc,
-	s.profile as profile_id,
-	s.rack,
-	s.router_host_name,
-	s.router_port_name,
-	st.name as status,
-	s.status as status_id,
-	s.tcp_port,
-	t.name as server_type,
-	s.type as server_type_id,
-	s.upd_pending as upd_pending
-	FROM server s
-	JOIN cachegroup cg ON s.cachegroup = cg.id
-	JOIN cdn cdn ON s.cdn_id = cdn.id
-	JOIN phys_location pl ON s.phys_location = pl.id
-	JOIN profile p ON s.profile = p.id
-	JOIN status st ON s.status = st.id
-	JOIN type t ON s.type = t.id
-	WHERE s.id in (select server from deliveryservice_server where deliveryservice = $1)`
-
-	return selectStmt
-}
-
-func updateQuery() string {
-	query := `UPDATE
-	profile_parameter SET
-	profile=:profile_id,
-	parameter=:parameter_id
-	WHERE profile=:profile_id AND 
-      parameter = :parameter_id 
-      RETURNING last_updated`
-	return query
-}
-
-func deleteQuery() string {
-	query := `DELETE FROM profile_parameter
-	WHERE profile=:profile_id and parameter=:parameter_id`
-	return query
-}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index ebe3ca3..e6efb81 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -164,6 +164,9 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 
 		// get all edge servers associated with a delivery service (from deliveryservice_server table)
 		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(serverdss.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+		//{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
 
 		//Server
 		{1.1, http.MethodGet, `servers/checks$`, handlerToFunc(proxyHandler), 0, NoAuth, []Middleware{}},

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 08/10: Added nil checking for the Replace attribute

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2f5e7a480e8175026a7f00050e1a1f3522deb622
Author: ASchmidt <An...@comcast.com>
AuthorDate: Tue May 22 16:59:52 2018 -0600

    Added nil checking for the Replace attribute
---
 traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index a1d6ecf..febb24e 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -325,7 +325,13 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 		}
 
 		if dsId == nil {
-			log.Error.Printf("no delivery service id sent in POST; could not begin transaction: %v", err)
+			log.Error.Printf("no deliveryservice id sent in POST; could not begin transaction: %v", err)
+			handleErrs(http.StatusBadRequest, err)
+			return
+		}
+
+		if payload.Replace == nil {
+			log.Error.Printf("no 'replace' indicator sent in POST; could not begin transaction: %v", err)
 			handleErrs(http.StatusBadRequest, err)
 			return
 		}

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 10/10: Resolved issues with logging and response format

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7aa432c219054156b4393a21a5c48e5110a3de91
Author: ASchmidt <An...@comcast.com>
AuthorDate: Thu May 24 18:20:21 2018 -0600

    Resolved issues with logging and response format
---
 lib/go-tc/deliveryservice_servers.go               |  4 +++
 .../deliveryservice/servers/servers.go             | 32 ++++++++++------------
 2 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/lib/go-tc/deliveryservice_servers.go b/lib/go-tc/deliveryservice_servers.go
index 06d731a..4bf023e 100644
--- a/lib/go-tc/deliveryservice_servers.go
+++ b/lib/go-tc/deliveryservice_servers.go
@@ -61,6 +61,10 @@ const (
 	Eligible
 )
 
+type DSServersAttrResponse struct {
+	Response []DSServer 	`json:"response"`
+}
+
 type DSServer struct {
 	Cachegroup       *string              `json:"cachegroup" db:"cachegroup"`
 	CachegroupID     *int                 `json:"cachegroupId" db:"cachegroup_id"`
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index 4a8b5f4..beea968 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -215,7 +215,7 @@ func (dss *TODeliveryServiceServer) Delete(db *sqlx.DB, user auth.CurrentUser) (
 	}()
 
 	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
+		log.Errorln("could not begin transaction: %v", err)
 		return tc.DBError, tc.SystemError
 	}
 	log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), dss)
@@ -280,17 +280,17 @@ func deleteQuery() string {
 	return query
 }
 
-type DSServers struct {
+type DSServerIds struct {
 	DsId    *int  `json:"dsId" db:"deliveryservice"`
 	Servers []int `json:"servers"`
 	Replace *bool `json:"replace"`
 }
 
-type TODSServers DSServers
+type TODSServerIds DSServerIds
 
 
-func createServersForDsIdRef() *TODSServers {
-	var dsserversRef = TODSServers(DSServers{})
+func createServersForDsIdRef() *TODSServerIds {
+	var dsserversRef = TODSServerIds(DSServerIds{})
 	return &dsserversRef
 }
 
@@ -319,19 +319,16 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 		dsId := payload.DsId
 
 		if servers == nil {
-			log.Error.Printf("no servers sent in POST; could not begin transaction")
 			api.HandleErr(w, r, http.StatusBadRequest, errors.New("servers must exist in post"), nil)
 			return
 		}
 
 		if dsId == nil {
-			log.Error.Printf("no deliveryservice id sent in POST; could not begin transaction")
 			api.HandleErr(w, r, http.StatusBadRequest, errors.New("dsid must exist in post"), nil)
 			return
 		}
 
 		if payload.Replace == nil {
-			log.Error.Printf("no 'replace' indicator sent in POST; could not begin transaction")
 			api.HandleErr(w, r, http.StatusBadRequest, errors.New("replace must exist in post"), nil)
 			return
 		}
@@ -370,7 +367,7 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 		}()
 
 		if err != nil {
-			log.Error.Printf("could not begin transaction: %v", err)
+			log.Errorln("could not begin transaction: %v", err)
 			handleErrs(http.StatusInternalServerError, err)
 			return
 		}
@@ -396,7 +393,7 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 			if err != nil {
 				if pqErr, ok := err.(*pq.Error); ok {
 					err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
-					log.Error.Printf("could not begin transaction: %v", err)
+					log.Errorln("could not begin transaction: %v", err)
 					if eType == tc.DataConflictError {
 						handleErrs(http.StatusInternalServerError, err)
 						return
@@ -512,7 +509,7 @@ func GetCreateHandler(db *sqlx.DB) http.HandlerFunc {
 		q, arg, err := sqlx.In(selectServerIds(), serverNames)
 
 		if err != nil {
-			log.Error.Printf("Could not form IN query : %v", err)
+			log.Errorln("Could not form IN query : %v", err)
 			handleErrs(http.StatusInternalServerError, err)
 			return
 		}
@@ -520,7 +517,7 @@ func GetCreateHandler(db *sqlx.DB) http.HandlerFunc {
 		serverIds, err := db.Query(q, arg...)
 		defer serverIds.Close()
 		if err != nil {
-			log.Error.Printf("Could not select the ServerIds: %v", err)
+			log.Errorln("Could not select the ServerIds: %v", err)
 			handleErrs(http.StatusInternalServerError, err)
 			return
 		}
@@ -539,7 +536,7 @@ func GetCreateHandler(db *sqlx.DB) http.HandlerFunc {
 		}()
 
 		if err != nil {
-			log.Error.Printf("could not begin transaction: %v", err)
+			log.Errorln("could not begin transaction: %v", err)
 			handleErrs(http.StatusInternalServerError, err)
 			return
 		}
@@ -555,7 +552,7 @@ func GetCreateHandler(db *sqlx.DB) http.HandlerFunc {
 			if err != nil {
 				if pqErr, ok := err.(*pq.Error); ok {
 					err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
-					log.Error.Printf("could not begin transaction: %v", err)
+					log.Errorln("could not begin transaction: %v", err)
 					if eType == tc.DataConflictError {
 						handleErrs(http.StatusInternalServerError, err)
 						return
@@ -631,7 +628,8 @@ func GetReadHandler(db *sqlx.DB, filter tc.Filter) http.HandlerFunc {
 			return
 		}
 
-		respBts, err := json.Marshal(servers)
+		dssres := tc.DSServersAttrResponse{ servers }
+		respBts, err := json.Marshal(dssres)
 		if err != nil {
 			handleErrs(http.StatusInternalServerError, err)
 			return
@@ -642,7 +640,7 @@ func GetReadHandler(db *sqlx.DB, filter tc.Filter) http.HandlerFunc {
 	}
 }
 
-func read(db *sqlx.DB, params map[string]string, user auth.CurrentUser, where string) ([]interface{}, []error, tc.ApiErrorType) {
+func read(db *sqlx.DB, params map[string]string, user auth.CurrentUser, where string) ([]tc.DSServer, []error, tc.ApiErrorType) {
 	idstr, ok := params["id"]
 
 	if !ok {
@@ -666,7 +664,7 @@ func read(db *sqlx.DB, params map[string]string, user auth.CurrentUser, where st
 	}
 	defer rows.Close()
 
-	servers := []interface{}{}
+	servers := []tc.DSServer{}
 	for rows.Next() {
 		var s tc.DSServer
 		if err = rows.StructScan(&s); err != nil {

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.

[incubator-trafficcontrol] 07/10: Fixed bug in GetReplaceHandler using values before they were decoded

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 54e8aff6ad6a6717760f8d84be46a55aac20829f
Author: ASchmidt <An...@comcast.com>
AuthorDate: Tue May 22 16:43:35 2018 -0600

    Fixed bug in GetReplaceHandler using values before they were decoded
---
 .../deliveryservice/servers/servers.go                  | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index c6ba71a..a1d6ecf 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -308,8 +308,6 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 
 		// get list of server Ids to insert
 		payload :=  createServersForDsIdRef() 
-		servers := payload.Servers
-		dsId := payload.DsId
 
 		if err := json.NewDecoder(r.Body).Decode(payload); err != nil {
 			log.Errorf("Error trying to decode the request body: %s", err)
@@ -317,6 +315,21 @@ func GetReplaceHandler(db *sqlx.DB) http.HandlerFunc {
 			return
 		}
 
+		servers := payload.Servers
+		dsId := payload.DsId
+
+		if servers == nil {
+			log.Error.Printf("no servers sent in POST; could not begin transaction: %v", err)
+			handleErrs(http.StatusBadRequest, err)
+			return
+		}
+
+		if dsId == nil {
+			log.Error.Printf("no delivery service id sent in POST; could not begin transaction: %v", err)
+			handleErrs(http.StatusBadRequest, err)
+			return
+		}
+
 		// if the object has tenancy enabled, check that user is able to access the tenant
 		// check user tenancy access to this resource.
 		row := db.QueryRow("SELECT xml_id FROM deliveryservice WHERE id = $1", *dsId)

-- 
To stop receiving notification emails like this one, please contact
rob@apache.org.