Skip to content

Commit a1ba4ec

Browse files
authored
Enhance global /v3/info/usage_summary endpoint (#4477)
* Enhance global /v3/info/usage_summary endpoint * return the same information as for /v3/organizations/:guid/usage_summary, aggregated over all orgs * New tests for /v3/info/usage_summary * Update info_spec tests with enhanced /v3/info/usage_summary * Update docu for enhanced /v3/info/usage_summary endpoint * Fix service instance filtering * include managed service instances, not user-provided service instances * Fix /v3/info/usage_summary docu * "service_instances" contains only managed services, not user-provided services
1 parent 4fd16ab commit a1ba4ec

File tree

7 files changed

+109
-9
lines changed

7 files changed

+109
-9
lines changed

app/fetchers/global_usage_summary_fetcher.rb

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,39 @@ def summary
2121

2222
summary.memory_in_mb = running_task_memory + started_app_memory
2323

24+
summary.routes = Route.
25+
dataset.
26+
count
27+
28+
summary.service_instances = ServiceInstance.
29+
dataset.
30+
where(is_gateway_service: true).
31+
count
32+
33+
summary.reserved_ports = Route.
34+
join(:domains, id: :domain_id).
35+
where { (Sequel[:domains][:router_group_guid] !~ nil) & (Sequel[:routes][:port] !~ nil) }.
36+
count
37+
38+
summary.domains = Domain.
39+
dataset.
40+
where { Sequel[:owning_organization_id] !~ nil }.
41+
count
42+
43+
summary.per_app_tasks = TaskModel.
44+
dataset.
45+
where(state: [TaskModel::PENDING_STATE, TaskModel::RUNNING_STATE]).
46+
count
47+
48+
summary.service_keys = ServiceKey.
49+
dataset.
50+
count
51+
2452
summary
2553
end
2654

2755
class Summary
28-
attr_accessor :started_instances, :memory_in_mb
56+
attr_accessor :started_instances, :memory_in_mb, :routes, :service_instances, :reserved_ports, :domains, :per_app_tasks, :service_keys
2957
end
3058
end
3159
end

app/presenters/v3/info_usage_summary_presenter.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ def to_hash
88
{
99
usage_summary: {
1010
started_instances: usage_summary.started_instances,
11-
memory_in_mb: usage_summary.memory_in_mb
11+
memory_in_mb: usage_summary.memory_in_mb,
12+
routes: usage_summary.routes,
13+
service_instances: usage_summary.service_instances,
14+
reserved_ports: usage_summary.reserved_ports,
15+
domains: usage_summary.domains,
16+
per_app_tasks: usage_summary.per_app_tasks,
17+
service_keys: usage_summary.service_keys
1218
},
1319
links: {
1420
self: { href: build_self }

docs/v3/source/includes/api_resources/_info.erb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@
4242
{
4343
"usage_summary": {
4444
"started_instances": 294,
45-
"memory_in_mb": 123945
45+
"memory_in_mb": 123945,
46+
"routes": 300,
47+
"service_instances": 50,
48+
"reserved_ports": 10,
49+
"domains": 5,
50+
"per_app_tasks": 0,
51+
"service_keys": 20
4652
},
4753
"links": {
4854
"self": { "href": "http://api.example.com/v3/info/usage_summary" }

docs/v3/source/includes/resources/info/_get_usage_summary.md.erb

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,16 @@ This endpoint retrieves a high-level summary of usage across the entire Cloud Fo
2727

2828
#### Usage summary object
2929

30-
| Name | Type | Description |
31-
| ---- | ---- | ----------- |
32-
| **started_instances** | _integer_ | Total number of process instances in the `STARTED` state |
33-
| **memory_in_mb** | _integer_ | Sum of memory usage of all tasks in the `RUNNING` state and all process instances in the `STARTED` state |
30+
| Name | Type | Description |
31+
|-----------------------|-----------|----------------------------------------------------------------------------------------------------------|
32+
| **started_instances** | _integer_ | Total number of process instances in the `STARTED` state |
33+
| **memory_in_mb** | _integer_ | Sum of memory usage of all tasks in the `RUNNING` state and all process instances in the `STARTED` state |
34+
| **routes** | _integer_ | Total number of routes |
35+
| **service_instances** | _integer_ | Total number of managed service instances |
36+
| **reserved_ports** | _integer_ | Total number of reserved ports |
37+
| **domains** | _integer_ | Total number of private domains |
38+
| **per_app_tasks** | _integer_ | Total number of running tasks |
39+
| **service_keys** | _integer_ | Total number of service keys |
3440

3541
#### Permitted roles
3642

spec/request/info_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,13 @@
8787
{
8888
usage_summary: {
8989
started_instances: 21,
90-
memory_in_mb: 2200
90+
memory_in_mb: 2200,
91+
domains: 1,
92+
per_app_tasks: 1,
93+
reserved_ports: 0,
94+
routes: 0,
95+
service_instances: 0,
96+
service_keys: 0
9197
},
9298
links: {
9399
self: { href: "#{link_prefix}/v3/info/usage_summary" }

spec/unit/fetchers/global_usage_summary_fetcher_spec.rb

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,43 @@ module VCAP::CloudController
55
subject(:fetcher) { GlobalUsageSummaryFetcher }
66

77
describe '.summary' do
8-
let!(:task) { TaskModel.make(state: TaskModel::RUNNING_STATE, memory_in_mb: 100) }
8+
before do
9+
router_group = double('router_group', type: 'tcp', reservable_ports: [8080])
10+
routing_api_client = double('routing_api_client', router_group: router_group, enabled?: true)
11+
allow(CloudController::DependencyLocator).to receive(:instance).and_return(double(:api_client, routing_api_client:))
12+
end
13+
14+
let!(:org) { Organization.make }
15+
let!(:space) { Space.make(organization: org) }
916
let!(:completed_task) { TaskModel.make(state: TaskModel::SUCCEEDED_STATE, memory_in_mb: 100) }
17+
let!(:running_task) { TaskModel.make(state: TaskModel::RUNNING_STATE, memory_in_mb: 100) }
1018
let!(:started_process1) { ProcessModelFactory.make(instances: 3, state: 'STARTED', memory: 100) }
1119
let!(:started_process2) { ProcessModelFactory.make(instances: 6, state: 'STARTED', memory: 100) }
1220
let!(:started_process3) { ProcessModelFactory.make(instances: 7, state: 'STARTED', memory: 100) }
1321
let!(:stopped_process) { ProcessModelFactory.make(instances: 2, state: 'STOPPED', memory: 100) }
1422
let!(:process2) { ProcessModelFactory.make(instances: 5, state: 'STARTED', memory: 100) }
23+
let!(:service_instance1) { ServiceInstance.make(is_gateway_service: false) }
24+
let!(:service_instance2) { ServiceInstance.make(is_gateway_service: true) }
25+
let!(:service_instance3) { ServiceInstance.make(is_gateway_service: true) }
26+
let!(:service_key1) { VCAP::CloudController::ServiceKey.make(service_instance: service_instance1) }
27+
let!(:service_key2) { VCAP::CloudController::ServiceKey.make(service_instance: service_instance2) }
28+
let!(:shared_domain_with_router_group) { SharedDomain.make(router_group_guid: 'rg-123') }
29+
let!(:shared_domain_without_router_group) { SharedDomain.make(router_group_guid: nil) }
30+
let!(:private_domain_without_router_group) { PrivateDomain.make(owning_organization: org) }
31+
let!(:route1) { Route.make(host: '', domain: shared_domain_with_router_group, port: 8080) }
32+
let!(:route2) { Route.make(host: '', domain: private_domain_without_router_group, space: space) }
1533

1634
it 'returns a summary' do
1735
summary = fetcher.summary
1836

1937
expect(summary.started_instances).to eq(21)
2038
expect(summary.memory_in_mb).to eq(2200)
39+
expect(summary.routes).to eq(2)
40+
expect(summary.service_instances).to eq(2)
41+
expect(summary.reserved_ports).to eq(1)
42+
expect(summary.domains).to eq(2) # system domain "vcap.me" plus :private_domain_without_router_group
43+
expect(summary.per_app_tasks).to eq(1)
44+
expect(summary.service_keys).to eq(2)
2145
end
2246
end
2347
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'spec_helper'
2+
require 'presenters/v3/info_usage_summary_presenter'
3+
require 'fetchers/global_usage_summary_fetcher'
4+
5+
module VCAP::CloudController::Presenters::V3
6+
RSpec.describe InfoUsageSummaryPresenter do
7+
describe '#to_hash' do
8+
let(:result) { InfoUsageSummaryPresenter.new(VCAP::CloudController::GlobalUsageSummaryFetcher.summary).to_hash }
9+
10+
it 'presents the global usage summary as json' do
11+
expect(result[:usage_summary][:started_instances]).to eq(0)
12+
expect(result[:usage_summary][:memory_in_mb]).to eq(0)
13+
expect(result[:usage_summary][:routes]).to eq(0)
14+
expect(result[:usage_summary][:service_instances]).to eq(0)
15+
expect(result[:usage_summary][:reserved_ports]).to eq(0)
16+
expect(result[:usage_summary][:domains]).to eq(1)
17+
expect(result[:usage_summary][:per_app_tasks]).to eq(0)
18+
expect(result[:usage_summary][:service_keys]).to eq(0)
19+
20+
expect(result[:links][:self][:href]).to match(%r{/v3/info/usage_summary$})
21+
end
22+
end
23+
end
24+
end

0 commit comments

Comments
 (0)