zrhoffman commented on a change in pull request #5091:
URL: https://github.com/apache/trafficcontrol/pull/5091#discussion_r498384871
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -137,46 +138,145 @@ JOIN server s ON sc.server = s.id ` + where + orderBy +
pagination +
}
func (ssc *TOServerServerCapability) Delete() (error, error, int) {
+ tenantIDs, err := tenant.GetUserTenantIDListTx(ssc.APIInfo().Tx.Tx,
ssc.APIInfo().User.TenantID)
+ if err != nil {
+ return nil, fmt.Errorf("deleting servers_server_capability:
%v", err), http.StatusInternalServerError
+ }
+ accessibleTenants := make(map[int]struct{}, len(tenantIDs))
+ for _, id := range tenantIDs {
+ accessibleTenants[id] = struct{}{}
+ }
+ userErr, sysErr, status :=
checkTopologyBasedDSRequiredCapabilities(ssc, accessibleTenants)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, status
+ }
+
+ userErr, sysErr, status = checkDSRequiredCapabilities(ssc,
accessibleTenants)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, status
+ }
+
+ return api.GenericDelete(ssc)
+}
+
+func checkTopologyBasedDSRequiredCapabilities(ssc *TOServerServerCapability,
accessibleTenants map[int]struct{}) (error, error, int) {
+ dsRows, err :=
ssc.APIInfo().Tx.Tx.Query(getTopologyBasedDSesReqCapQuery(), ssc.ServerID,
ssc.ServerCapability)
+ if err != nil {
+ return nil, fmt.Errorf("querying topology-based DSes with the
required capability %s: %v", *ssc.ServerCapability, err),
http.StatusInternalServerError
+ }
+ defer log.Close(dsRows, "closing dsRows in
checkTopologyBasedDSRequiredCapabilities")
+
+ xmlidToTopology := make(map[string]string)
+ xmlidToTenantID := make(map[string]int)
+ xmlidToReqCaps := make(map[string][]string)
Review comment:
I suppose keeping `xmlid` all-lowercase makes the structure of these
variables more apparent
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -275,6 +375,43 @@ SELECT ARRAY(
AND dsrc.required_capability = $2)`
}
+// get the topology-based DSes (with all their required capabilities) that a
given
+// server is assigned to, filtered by the given capability
+func getTopologyBasedDSesReqCapQuery() string {
+ return `
+SELECT
+ ds.xml_id,
+ ds.topology,
+ ds.tenant_id,
+ array_agg(dsrc.required_capability) as req_caps
+FROM server s
+JOIN cachegroup c ON s.cachegroup = c.id
+JOIN topology_cachegroup tc ON c.name = tc.cachegroup
+JOIN deliveryservice ds ON ds.topology = tc.topology
+JOIN deliveryservices_required_capability dsrc on dsrc.deliveryservice_id =
ds.id
+WHERE s.id = $1
+GROUP BY ds.xml_id, ds.tenant_id, ds.topology
+HAVING $2 = ANY(array_agg(dsrc.required_capability))
+`
+}
+
+// get all the capabilities of the servers in a given server's cachegroup
+// that have a given capability
+func getServerCapabilitiesOfCachegoupQuery() string {
+ return `
+SELECT s.id, array_agg(ssc.server_capability) as capabilities
Review comment:
Another case where ARRAY_AGG should be capitalized for readability
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -275,6 +375,43 @@ SELECT ARRAY(
AND dsrc.required_capability = $2)`
}
+// get the topology-based DSes (with all their required capabilities) that a
given
+// server is assigned to, filtered by the given capability
+func getTopologyBasedDSesReqCapQuery() string {
+ return `
+SELECT
+ ds.xml_id,
+ ds.topology,
+ ds.tenant_id,
+ array_agg(dsrc.required_capability) as req_caps
+FROM server s
+JOIN cachegroup c ON s.cachegroup = c.id
+JOIN topology_cachegroup tc ON c.name = tc.cachegroup
+JOIN deliveryservice ds ON ds.topology = tc.topology
+JOIN deliveryservices_required_capability dsrc on dsrc.deliveryservice_id =
ds.id
+WHERE s.id = $1
+GROUP BY ds.xml_id, ds.tenant_id, ds.topology
+HAVING $2 = ANY(array_agg(dsrc.required_capability))
+`
+}
+
+// get all the capabilities of the servers in a given server's cachegroup
+// that have a given capability
+func getServerCapabilitiesOfCachegoupQuery() string {
+ return `
+SELECT s.id, array_agg(ssc.server_capability) as capabilities
+FROM server s
+JOIN cachegroup c ON c.id = s.cachegroup
+JOIN server_server_capability ssc ON ssc.server = s.id
+WHERE
+ c.id = (SELECT cachegroup FROM server WHERE server.id = $1)
Review comment:
This condition can instead be a second condition for the JOIN on
cachegroup
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -137,46 +138,145 @@ JOIN server s ON sc.server = s.id ` + where + orderBy +
pagination +
}
func (ssc *TOServerServerCapability) Delete() (error, error, int) {
+ tenantIDs, err := tenant.GetUserTenantIDListTx(ssc.APIInfo().Tx.Tx,
ssc.APIInfo().User.TenantID)
+ if err != nil {
+ return nil, fmt.Errorf("deleting servers_server_capability:
%v", err), http.StatusInternalServerError
+ }
+ accessibleTenants := make(map[int]struct{}, len(tenantIDs))
+ for _, id := range tenantIDs {
+ accessibleTenants[id] = struct{}{}
+ }
+ userErr, sysErr, status :=
checkTopologyBasedDSRequiredCapabilities(ssc, accessibleTenants)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, status
+ }
+
+ userErr, sysErr, status = checkDSRequiredCapabilities(ssc,
accessibleTenants)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, status
+ }
+
+ return api.GenericDelete(ssc)
+}
+
+func checkTopologyBasedDSRequiredCapabilities(ssc *TOServerServerCapability,
accessibleTenants map[int]struct{}) (error, error, int) {
+ dsRows, err :=
ssc.APIInfo().Tx.Tx.Query(getTopologyBasedDSesReqCapQuery(), ssc.ServerID,
ssc.ServerCapability)
+ if err != nil {
+ return nil, fmt.Errorf("querying topology-based DSes with the
required capability %s: %v", *ssc.ServerCapability, err),
http.StatusInternalServerError
+ }
+ defer log.Close(dsRows, "closing dsRows in
checkTopologyBasedDSRequiredCapabilities")
+
+ xmlidToTopology := make(map[string]string)
+ xmlidToTenantID := make(map[string]int)
+ xmlidToReqCaps := make(map[string][]string)
+ for dsRows.Next() {
+ xmlID := ""
+ topology := ""
+ tenantID := 0
+ reqCaps := []string{}
Review comment:
These can all be `var` declarations without assignment
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -275,6 +375,43 @@ SELECT ARRAY(
AND dsrc.required_capability = $2)`
}
+// get the topology-based DSes (with all their required capabilities) that a
given
+// server is assigned to, filtered by the given capability
+func getTopologyBasedDSesReqCapQuery() string {
+ return `
+SELECT
+ ds.xml_id,
+ ds.topology,
+ ds.tenant_id,
+ array_agg(dsrc.required_capability) as req_caps
Review comment:
ARRAY_AGG should be capitalized for readability
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -275,6 +375,43 @@ SELECT ARRAY(
AND dsrc.required_capability = $2)`
}
+// get the topology-based DSes (with all their required capabilities) that a
given
+// server is assigned to, filtered by the given capability
+func getTopologyBasedDSesReqCapQuery() string {
+ return `
+SELECT
+ ds.xml_id,
+ ds.topology,
+ ds.tenant_id,
+ array_agg(dsrc.required_capability) as req_caps
+FROM server s
+JOIN cachegroup c ON s.cachegroup = c.id
+JOIN topology_cachegroup tc ON c.name = tc.cachegroup
+JOIN deliveryservice ds ON ds.topology = tc.topology
+JOIN deliveryservices_required_capability dsrc on dsrc.deliveryservice_id =
ds.id
+WHERE s.id = $1
+GROUP BY ds.xml_id, ds.tenant_id, ds.topology
+HAVING $2 = ANY(array_agg(dsrc.required_capability))
+`
+}
+
+// get all the capabilities of the servers in a given server's cachegroup
+// that have a given capability
+func getServerCapabilitiesOfCachegoupQuery() string {
+ return `
+SELECT s.id, array_agg(ssc.server_capability) as capabilities
+FROM server s
+JOIN cachegroup c ON c.id = s.cachegroup
+JOIN server_server_capability ssc ON ssc.server = s.id
+WHERE
+ c.id = (SELECT cachegroup FROM server WHERE server.id = $1)
+ AND s.cdn_id = (SELECT cdn_id FROM server WHERE server.id = $1)
+ AND s.id != $1
+GROUP BY s.id
+HAVING $2 = ANY(array_agg(ssc.server_capability));
Review comment:
Here too ARRAY_AGG should be capitalized for readability
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -137,46 +138,145 @@ JOIN server s ON sc.server = s.id ` + where + orderBy +
pagination +
}
func (ssc *TOServerServerCapability) Delete() (error, error, int) {
+ tenantIDs, err := tenant.GetUserTenantIDListTx(ssc.APIInfo().Tx.Tx,
ssc.APIInfo().User.TenantID)
+ if err != nil {
+ return nil, fmt.Errorf("deleting servers_server_capability:
%v", err), http.StatusInternalServerError
+ }
+ accessibleTenants := make(map[int]struct{}, len(tenantIDs))
+ for _, id := range tenantIDs {
+ accessibleTenants[id] = struct{}{}
+ }
+ userErr, sysErr, status :=
checkTopologyBasedDSRequiredCapabilities(ssc, accessibleTenants)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, status
+ }
+
+ userErr, sysErr, status = checkDSRequiredCapabilities(ssc,
accessibleTenants)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, status
+ }
+
+ return api.GenericDelete(ssc)
+}
+
+func checkTopologyBasedDSRequiredCapabilities(ssc *TOServerServerCapability,
accessibleTenants map[int]struct{}) (error, error, int) {
+ dsRows, err :=
ssc.APIInfo().Tx.Tx.Query(getTopologyBasedDSesReqCapQuery(), ssc.ServerID,
ssc.ServerCapability)
+ if err != nil {
+ return nil, fmt.Errorf("querying topology-based DSes with the
required capability %s: %v", *ssc.ServerCapability, err),
http.StatusInternalServerError
+ }
+ defer log.Close(dsRows, "closing dsRows in
checkTopologyBasedDSRequiredCapabilities")
+
+ xmlidToTopology := make(map[string]string)
+ xmlidToTenantID := make(map[string]int)
+ xmlidToReqCaps := make(map[string][]string)
+ for dsRows.Next() {
+ xmlID := ""
+ topology := ""
+ tenantID := 0
+ reqCaps := []string{}
+ if err := dsRows.Scan(&xmlID, &topology, &tenantID,
pq.Array(&reqCaps)); err != nil {
+ return nil, fmt.Errorf("scanning dsRows in
checkTopologyBasedDSRequiredCapabilities: %v", err),
http.StatusInternalServerError
+ }
+ xmlidToTenantID[xmlID] = tenantID
+ xmlidToTopology[xmlID] = topology
+ xmlidToReqCaps[xmlID] = reqCaps
+ }
+ if len(xmlidToTopology) == 0 {
+ return nil, nil, http.StatusOK
+ }
+
+ serverRows, err :=
ssc.APIInfo().Tx.Tx.Query(getServerCapabilitiesOfCachegoupQuery(),
ssc.ServerID, ssc.ServerCapability)
+ if err != nil {
+ return nil, fmt.Errorf("querying server capabilitites of server
%d's cachegroup: %v", *ssc.ServerID, err), http.StatusInternalServerError
+ }
+ defer log.Close(serverRows, "closing serverRows in
checkTopologyBasedDSRequiredCapabilities")
+
+ serverIDToCapabilities := make(map[int]map[string]struct{})
+ for serverRows.Next() {
+ serverID := 0
+ capabilities := []string{}
Review comment:
These can also be `var` declarations without assignment
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -275,6 +375,43 @@ SELECT ARRAY(
AND dsrc.required_capability = $2)`
}
+// get the topology-based DSes (with all their required capabilities) that a
given
+// server is assigned to, filtered by the given capability
+func getTopologyBasedDSesReqCapQuery() string {
+ return `
+SELECT
+ ds.xml_id,
+ ds.topology,
+ ds.tenant_id,
+ array_agg(dsrc.required_capability) as req_caps
+FROM server s
+JOIN cachegroup c ON s.cachegroup = c.id
+JOIN topology_cachegroup tc ON c.name = tc.cachegroup
+JOIN deliveryservice ds ON ds.topology = tc.topology
+JOIN deliveryservices_required_capability dsrc on dsrc.deliveryservice_id =
ds.id
+WHERE s.id = $1
+GROUP BY ds.xml_id, ds.tenant_id, ds.topology
+HAVING $2 = ANY(array_agg(dsrc.required_capability))
Review comment:
ARRAY_AGG should also be capitalized here for readability
##########
File path: traffic_ops/testing/api/v3/withobjs_test.go
##########
@@ -78,38 +80,40 @@ type TCObjFuncs struct {
}
var withFuncs = map[TCObj]TCObjFuncs{
- CacheGroups: {CreateTestCacheGroups,
DeleteTestCacheGroups},
- CacheGroupsDeliveryServices:
{CreateTestCachegroupsDeliveryServices, DeleteTestCachegroupsDeliveryServices},
- CacheGroupParameters: {CreateTestCacheGroupParameters,
DeleteTestCacheGroupParameters},
- CDNs: {CreateTestCDNs, DeleteTestCDNs},
- CDNFederations: {CreateTestCDNFederations,
DeleteTestCDNFederations},
- Coordinates: {CreateTestCoordinates,
DeleteTestCoordinates},
- DeliveryServices: {CreateTestDeliveryServices,
DeleteTestDeliveryServices},
- DeliveryServicesRegexes:
{CreateTestDeliveryServicesRegexes, DeleteTestDeliveryServicesRegexes},
- DeliveryServiceRequests:
{CreateTestDeliveryServiceRequests, DeleteTestDeliveryServiceRequests},
- DeliveryServiceRequestComments:
{CreateTestDeliveryServiceRequestComments,
DeleteTestDeliveryServiceRequestComments},
- DeliveryServicesRequiredCapabilities:
{CreateTestDeliveryServicesRequiredCapabilities,
DeleteTestDeliveryServicesRequiredCapabilities},
- Divisions: {CreateTestDivisions,
DeleteTestDivisions},
- FederationUsers: {CreateTestFederationUsers,
DeleteTestFederationUsers},
- FederationResolvers: {CreateTestFederationResolvers,
DeleteTestFederationResolvers},
- Origins: {CreateTestOrigins,
DeleteTestOrigins},
- Parameters: {CreateTestParameters,
DeleteTestParameters},
- PhysLocations: {CreateTestPhysLocations,
DeleteTestPhysLocations},
- Profiles: {CreateTestProfiles,
DeleteTestProfiles},
- ProfileParameters: {CreateTestProfileParameters,
DeleteTestProfileParameters},
- Regions: {CreateTestRegions,
DeleteTestRegions},
- Roles: {CreateTestRoles,
DeleteTestRoles},
- ServerCapabilities: {CreateTestServerCapabilities,
DeleteTestServerCapabilities},
- ServerChecks: {CreateTestServerChecks,
DeleteTestServerChecks},
- ServerServerCapabilities:
{CreateTestServerServerCapabilities, DeleteTestServerServerCapabilities},
- Servers: {CreateTestServers,
DeleteTestServers},
- ServiceCategories: {CreateTestServiceCategories,
DeleteTestServiceCategories},
- Statuses: {CreateTestStatuses,
DeleteTestStatuses},
- StaticDNSEntries: {CreateTestStaticDNSEntries,
DeleteTestStaticDNSEntries},
- SteeringTargets: {SetupSteeringTargets,
DeleteTestSteeringTargets},
- Tenants: {CreateTestTenants,
DeleteTestTenants},
- ServerCheckExtensions: {CreateTestServerCheckExtensions,
DeleteTestServerCheckExtensions},
- Topologies: {CreateTestTopologies,
DeleteTestTopologies},
- Types: {CreateTestTypes,
DeleteTestTypes},
- Users: {CreateTestUsers,
ForceDeleteTestUsers},
+ CacheGroups: {CreateTestCacheGroups,
DeleteTestCacheGroups},
+ CacheGroupsDeliveryServices:
{CreateTestCachegroupsDeliveryServices, DeleteTestCachegroupsDeliveryServices},
+ CacheGroupParameters: {CreateTestCacheGroupParameters,
DeleteTestCacheGroupParameters},
+ CDNs: {CreateTestCDNs, DeleteTestCDNs},
+ CDNFederations: {CreateTestCDNFederations,
DeleteTestCDNFederations},
+ Coordinates: {CreateTestCoordinates,
DeleteTestCoordinates},
+ DeliveryServices: {CreateTestDeliveryServices,
DeleteTestDeliveryServices},
+ DeliveryServicesRegexes:
{CreateTestDeliveryServicesRegexes, DeleteTestDeliveryServicesRegexes},
+ DeliveryServiceRequests:
{CreateTestDeliveryServiceRequests, DeleteTestDeliveryServiceRequests},
+ DeliveryServiceRequestComments:
{CreateTestDeliveryServiceRequestComments,
DeleteTestDeliveryServiceRequestComments},
+ DeliveryServicesRequiredCapabilities:
{CreateTestDeliveryServicesRequiredCapabilities,
DeleteTestDeliveryServicesRequiredCapabilities},
+ Divisions: {CreateTestDivisions,
DeleteTestDivisions},
+ FederationUsers: {CreateTestFederationUsers,
DeleteTestFederationUsers},
+ FederationResolvers: {CreateTestFederationResolvers,
DeleteTestFederationResolvers},
+ Origins: {CreateTestOrigins,
DeleteTestOrigins},
+ Parameters: {CreateTestParameters,
DeleteTestParameters},
+ PhysLocations: {CreateTestPhysLocations,
DeleteTestPhysLocations},
+ Profiles: {CreateTestProfiles,
DeleteTestProfiles},
+ ProfileParameters: {CreateTestProfileParameters,
DeleteTestProfileParameters},
+ Regions: {CreateTestRegions,
DeleteTestRegions},
+ Roles: {CreateTestRoles,
DeleteTestRoles},
+ ServerCapabilities: {CreateTestServerCapabilities,
DeleteTestServerCapabilities},
+ ServerChecks: {CreateTestServerChecks,
DeleteTestServerChecks},
+ ServerServerCapabilities:
{CreateTestServerServerCapabilities, DeleteTestServerServerCapabilities},
+ ServerServerCapabilitiesForTopologies:
{CreateTestServerServerCapabilities,
DeleteTestServerServerCapabilitiesForTopologies},
+ Servers: {CreateTestServers,
DeleteTestServers},
+ ServiceCategories: {CreateTestServiceCategories,
DeleteTestServiceCategories},
+ Statuses: {CreateTestStatuses,
DeleteTestStatuses},
+ StaticDNSEntries: {CreateTestStaticDNSEntries,
DeleteTestStaticDNSEntries},
+ SteeringTargets: {SetupSteeringTargets,
DeleteTestSteeringTargets},
+ Tenants: {CreateTestTenants,
DeleteTestTenants},
+ ServerCheckExtensions:
{CreateTestServerCheckExtensions, DeleteTestServerCheckExtensions},
+ Topologies: {CreateTestTopologies,
DeleteTestTopologies},
+ TopologyBasedDeliveryServiceRequiredCapabilities:
{CreateTestTopologyBasedDeliveryServicesRequiredCapabilities,
DeleteTestDeliveryServicesRequiredCapabilities},
+ Types: {CreateTestTypes, DeleteTestTypes},
+ Users: {CreateTestUsers, ForceDeleteTestUsers},
Review comment:
Weird what `gofmt` did with this
##########
File path: traffic_ops/traffic_ops_golang/server/servers_server_capability.go
##########
@@ -137,46 +138,145 @@ JOIN server s ON sc.server = s.id ` + where + orderBy +
pagination +
}
func (ssc *TOServerServerCapability) Delete() (error, error, int) {
+ tenantIDs, err := tenant.GetUserTenantIDListTx(ssc.APIInfo().Tx.Tx,
ssc.APIInfo().User.TenantID)
+ if err != nil {
+ return nil, fmt.Errorf("deleting servers_server_capability:
%v", err), http.StatusInternalServerError
+ }
+ accessibleTenants := make(map[int]struct{}, len(tenantIDs))
+ for _, id := range tenantIDs {
+ accessibleTenants[id] = struct{}{}
+ }
+ userErr, sysErr, status :=
checkTopologyBasedDSRequiredCapabilities(ssc, accessibleTenants)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, status
+ }
+
+ userErr, sysErr, status = checkDSRequiredCapabilities(ssc,
accessibleTenants)
+ if userErr != nil || sysErr != nil {
+ return userErr, sysErr, status
+ }
+
+ return api.GenericDelete(ssc)
+}
+
+func checkTopologyBasedDSRequiredCapabilities(ssc *TOServerServerCapability,
accessibleTenants map[int]struct{}) (error, error, int) {
+ dsRows, err :=
ssc.APIInfo().Tx.Tx.Query(getTopologyBasedDSesReqCapQuery(), ssc.ServerID,
ssc.ServerCapability)
+ if err != nil {
+ return nil, fmt.Errorf("querying topology-based DSes with the
required capability %s: %v", *ssc.ServerCapability, err),
http.StatusInternalServerError
+ }
+ defer log.Close(dsRows, "closing dsRows in
checkTopologyBasedDSRequiredCapabilities")
+
+ xmlidToTopology := make(map[string]string)
+ xmlidToTenantID := make(map[string]int)
+ xmlidToReqCaps := make(map[string][]string)
+ for dsRows.Next() {
+ xmlID := ""
+ topology := ""
+ tenantID := 0
+ reqCaps := []string{}
+ if err := dsRows.Scan(&xmlID, &topology, &tenantID,
pq.Array(&reqCaps)); err != nil {
+ return nil, fmt.Errorf("scanning dsRows in
checkTopologyBasedDSRequiredCapabilities: %v", err),
http.StatusInternalServerError
+ }
+ xmlidToTenantID[xmlID] = tenantID
+ xmlidToTopology[xmlID] = topology
+ xmlidToReqCaps[xmlID] = reqCaps
+ }
+ if len(xmlidToTopology) == 0 {
+ return nil, nil, http.StatusOK
+ }
+
+ serverRows, err :=
ssc.APIInfo().Tx.Tx.Query(getServerCapabilitiesOfCachegoupQuery(),
ssc.ServerID, ssc.ServerCapability)
+ if err != nil {
+ return nil, fmt.Errorf("querying server capabilitites of server
%d's cachegroup: %v", *ssc.ServerID, err), http.StatusInternalServerError
+ }
+ defer log.Close(serverRows, "closing serverRows in
checkTopologyBasedDSRequiredCapabilities")
+
+ serverIDToCapabilities := make(map[int]map[string]struct{})
+ for serverRows.Next() {
+ serverID := 0
+ capabilities := []string{}
+ if err := serverRows.Scan(&serverID, pq.Array(&capabilities));
err != nil {
+ return nil, fmt.Errorf("scanning serverRows in
checkTopologyBasedDSRequiredCapabilities: %v", err),
http.StatusInternalServerError
+ }
+ serverIDToCapabilities[serverID] = make(map[string]struct{})
+ for _, c := range capabilities {
+ serverIDToCapabilities[serverID][c] = struct{}{}
+ }
+ }
+ var dsStrings []string
+ dsStrings = make([]string, 0, len(xmlidToTopology))
+ if len(serverIDToCapabilities) == 0 {
+ for ds, top := range xmlidToTopology {
+ if _, ok := accessibleTenants[xmlidToTenantID[ds]]; ok {
+ dsStrings = append(dsStrings, "(xml_id =
"+ds+", topology = "+top+")")
+ }
+ }
+ return fmt.Errorf("this capability is required by delivery
services, but there are no other servers in this server's cachegroup to satisfy
them %s", strings.Join(dsStrings, ", ")), nil, http.StatusBadRequest
+ }
Review comment:
This case is unnecessary IMO because it saves O(number of delivery
services) which is already spent earlier.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]