blob: 7ffb96d4415203ecd20db7d0a149db3df4f356f4 [file] [log] [blame]
package crconfig
/*
* 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 (
"database/sql"
"errors"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/lib/pq"
)
// getCachegroupFallbacks returns a map[primaryCacheGroupID][]fallbackCacheGroupName.
func getCachegroupFallbacks(tx *sql.Tx) (map[int][]string, error) {
q := `
SELECT
cachegroup_fallbacks.primary_cg,
cachegroup.name
FROM
cachegroup_fallbacks
JOIN cachegroup on cachegroup_fallbacks.backup_cg = cachegroup.id
ORDER BY cachegroup_fallbacks.set_order
`
rows, err := tx.Query(q)
if err != nil {
return nil, errors.New("Error retrieving from cachegroup_fallbacks: " + err.Error())
}
defer rows.Close()
fallbacks := map[int][]string{} // map[primaryCacheGroupID][]fallbackCacheGroupName
for rows.Next() {
primaryCGID := 0
fallbackCG := ""
if err := rows.Scan(&primaryCGID, &fallbackCG); err != nil {
return nil, errors.New("scanning cachegroup_fallbacks: " + err.Error())
}
fallbacks[primaryCGID] = append(fallbacks[primaryCGID], fallbackCG)
}
if err := rows.Err(); err != nil {
return nil, errors.New("cachegroup_fallbacks rows: " + err.Error())
}
return fallbacks, nil
}
func makeLocations(cdn string, tx *sql.Tx) (map[string]tc.CRConfigLatitudeLongitude, map[string]tc.CRConfigLatitudeLongitude, error) {
edgeLocs := map[string]tc.CRConfigLatitudeLongitude{}
routerLocs := map[string]tc.CRConfigLatitudeLongitude{}
fallbacks, err := getCachegroupFallbacks(tx)
if err != nil {
return nil, nil, err
}
// TODO test whether it's faster to do a single query, joining lat/lon into servers
q := `
select cg.name, cg.id, t.name as type, co.latitude, co.longitude, COALESCE(cg.fallback_to_closest, TRUE),
(SELECT array_agg(method::text) as localization_methods FROM cachegroup_localization_method WHERE cachegroup = cg.id)
from cachegroup as cg
left join coordinate as co on co.id = cg.coordinate
inner join server as s on s.cachegroup = cg.id
inner join type as t on t.id = s.type
inner join status as st ON st.id = s.status
where s.cdn_id = (select id from cdn where name = $1)
and (t.name like 'EDGE%' or t.name = 'CCR')
and (st.name = 'REPORTED' or st.name = 'ONLINE' or st.name = 'ADMIN_DOWN')
`
// TODO pass edge type prefix, router type name
rows, err := tx.Query(q, cdn)
if err != nil {
return nil, nil, errors.New("Error querying cachegroups: " + err.Error())
}
defer rows.Close()
for rows.Next() {
cachegroup := ""
primaryCacheID := 0
ttype := ""
fallbackToClosest := true
latlon := tc.CRConfigLatitudeLongitude{}
if err := rows.Scan(&cachegroup, &primaryCacheID, &ttype, &latlon.Lat, &latlon.Lon, &fallbackToClosest, pq.Array(&latlon.LocalizationMethods)); err != nil {
return nil, nil, errors.New("Error scanning cachegroup: " + err.Error())
}
if len(latlon.LocalizationMethods) == 0 {
// to keep current default behavior when localizationMethods is unset/empty, enable all current localization methods
latlon.LocalizationMethods = []tc.LocalizationMethod{tc.LocalizationMethodGeo, tc.LocalizationMethodCZ, tc.LocalizationMethodDeepCZ}
}
if ttype == tc.RouterTypeName {
routerLocs[cachegroup] = latlon
} else {
latlon.BackupLocations.FallbackToClosest = fallbackToClosest
latlon.BackupLocations.List = fallbacks[primaryCacheID]
edgeLocs[cachegroup] = latlon
}
}
if err := rows.Err(); err != nil {
return nil, nil, errors.New("Error iterating cachegroup rows: " + err.Error())
}
return edgeLocs, routerLocs, nil
}