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 <andrew_schm...@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
r...@apache.org.

Reply via email to