diff --git a/app/fetchers/global_usage_summary_fetcher.rb b/app/fetchers/global_usage_summary_fetcher.rb index 7e2c3f7a93b..cda2fd149fe 100644 --- a/app/fetchers/global_usage_summary_fetcher.rb +++ b/app/fetchers/global_usage_summary_fetcher.rb @@ -21,11 +21,39 @@ def summary summary.memory_in_mb = running_task_memory + started_app_memory + summary.routes = Route. + dataset. + count + + summary.service_instances = ServiceInstance. + dataset. + where(is_gateway_service: true). + count + + summary.reserved_ports = Route. + join(:domains, id: :domain_id). + where { (Sequel[:domains][:router_group_guid] !~ nil) & (Sequel[:routes][:port] !~ nil) }. + count + + summary.domains = Domain. + dataset. + where { Sequel[:owning_organization_id] !~ nil }. + count + + summary.per_app_tasks = TaskModel. + dataset. + where(state: [TaskModel::PENDING_STATE, TaskModel::RUNNING_STATE]). + count + + summary.service_keys = ServiceKey. + dataset. + count + summary end class Summary - attr_accessor :started_instances, :memory_in_mb + attr_accessor :started_instances, :memory_in_mb, :routes, :service_instances, :reserved_ports, :domains, :per_app_tasks, :service_keys end end end diff --git a/app/presenters/v3/info_usage_summary_presenter.rb b/app/presenters/v3/info_usage_summary_presenter.rb index b7c112ff2c6..bb02e170b98 100644 --- a/app/presenters/v3/info_usage_summary_presenter.rb +++ b/app/presenters/v3/info_usage_summary_presenter.rb @@ -8,7 +8,13 @@ def to_hash { usage_summary: { started_instances: usage_summary.started_instances, - memory_in_mb: usage_summary.memory_in_mb + memory_in_mb: usage_summary.memory_in_mb, + routes: usage_summary.routes, + service_instances: usage_summary.service_instances, + reserved_ports: usage_summary.reserved_ports, + domains: usage_summary.domains, + per_app_tasks: usage_summary.per_app_tasks, + service_keys: usage_summary.service_keys }, links: { self: { href: build_self } diff --git a/docs/v3/source/includes/api_resources/_info.erb b/docs/v3/source/includes/api_resources/_info.erb index 108e54f2216..4a3753e4350 100644 --- a/docs/v3/source/includes/api_resources/_info.erb +++ b/docs/v3/source/includes/api_resources/_info.erb @@ -42,7 +42,13 @@ { "usage_summary": { "started_instances": 294, - "memory_in_mb": 123945 + "memory_in_mb": 123945, + "routes": 300, + "service_instances": 50, + "reserved_ports": 10, + "domains": 5, + "per_app_tasks": 0, + "service_keys": 20 }, "links": { "self": { "href": "http://api.example.com/v3/info/usage_summary" } diff --git a/docs/v3/source/includes/resources/info/_get_usage_summary.md.erb b/docs/v3/source/includes/resources/info/_get_usage_summary.md.erb index f434e1103c1..373b8f8d475 100644 --- a/docs/v3/source/includes/resources/info/_get_usage_summary.md.erb +++ b/docs/v3/source/includes/resources/info/_get_usage_summary.md.erb @@ -27,10 +27,16 @@ This endpoint retrieves a high-level summary of usage across the entire Cloud Fo #### Usage summary object -| Name | Type | Description | -| ---- | ---- | ----------- | -| **started_instances** | _integer_ | Total number of process instances in the `STARTED` state | -| **memory_in_mb** | _integer_ | Sum of memory usage of all tasks in the `RUNNING` state and all process instances in the `STARTED` state | +| Name | Type | Description | +|-----------------------|-----------|----------------------------------------------------------------------------------------------------------| +| **started_instances** | _integer_ | Total number of process instances in the `STARTED` state | +| **memory_in_mb** | _integer_ | Sum of memory usage of all tasks in the `RUNNING` state and all process instances in the `STARTED` state | +| **routes** | _integer_ | Total number of routes | +| **service_instances** | _integer_ | Total number of managed service instances | +| **reserved_ports** | _integer_ | Total number of reserved ports | +| **domains** | _integer_ | Total number of private domains | +| **per_app_tasks** | _integer_ | Total number of running tasks | +| **service_keys** | _integer_ | Total number of service keys | #### Permitted roles diff --git a/spec/request/info_spec.rb b/spec/request/info_spec.rb index d5003a250fe..26932665f45 100644 --- a/spec/request/info_spec.rb +++ b/spec/request/info_spec.rb @@ -87,7 +87,13 @@ { usage_summary: { started_instances: 21, - memory_in_mb: 2200 + memory_in_mb: 2200, + domains: 1, + per_app_tasks: 1, + reserved_ports: 0, + routes: 0, + service_instances: 0, + service_keys: 0 }, links: { self: { href: "#{link_prefix}/v3/info/usage_summary" } diff --git a/spec/unit/fetchers/global_usage_summary_fetcher_spec.rb b/spec/unit/fetchers/global_usage_summary_fetcher_spec.rb index 754e022594f..6b92dd8a7d3 100644 --- a/spec/unit/fetchers/global_usage_summary_fetcher_spec.rb +++ b/spec/unit/fetchers/global_usage_summary_fetcher_spec.rb @@ -5,19 +5,43 @@ module VCAP::CloudController subject(:fetcher) { GlobalUsageSummaryFetcher } describe '.summary' do - let!(:task) { TaskModel.make(state: TaskModel::RUNNING_STATE, memory_in_mb: 100) } + before do + router_group = double('router_group', type: 'tcp', reservable_ports: [8080]) + routing_api_client = double('routing_api_client', router_group: router_group, enabled?: true) + allow(CloudController::DependencyLocator).to receive(:instance).and_return(double(:api_client, routing_api_client:)) + end + + let!(:org) { Organization.make } + let!(:space) { Space.make(organization: org) } let!(:completed_task) { TaskModel.make(state: TaskModel::SUCCEEDED_STATE, memory_in_mb: 100) } + let!(:running_task) { TaskModel.make(state: TaskModel::RUNNING_STATE, memory_in_mb: 100) } let!(:started_process1) { ProcessModelFactory.make(instances: 3, state: 'STARTED', memory: 100) } let!(:started_process2) { ProcessModelFactory.make(instances: 6, state: 'STARTED', memory: 100) } let!(:started_process3) { ProcessModelFactory.make(instances: 7, state: 'STARTED', memory: 100) } let!(:stopped_process) { ProcessModelFactory.make(instances: 2, state: 'STOPPED', memory: 100) } let!(:process2) { ProcessModelFactory.make(instances: 5, state: 'STARTED', memory: 100) } + let!(:service_instance1) { ServiceInstance.make(is_gateway_service: false) } + let!(:service_instance2) { ServiceInstance.make(is_gateway_service: true) } + let!(:service_instance3) { ServiceInstance.make(is_gateway_service: true) } + let!(:service_key1) { VCAP::CloudController::ServiceKey.make(service_instance: service_instance1) } + let!(:service_key2) { VCAP::CloudController::ServiceKey.make(service_instance: service_instance2) } + let!(:shared_domain_with_router_group) { SharedDomain.make(router_group_guid: 'rg-123') } + let!(:shared_domain_without_router_group) { SharedDomain.make(router_group_guid: nil) } + let!(:private_domain_without_router_group) { PrivateDomain.make(owning_organization: org) } + let!(:route1) { Route.make(host: '', domain: shared_domain_with_router_group, port: 8080) } + let!(:route2) { Route.make(host: '', domain: private_domain_without_router_group, space: space) } it 'returns a summary' do summary = fetcher.summary expect(summary.started_instances).to eq(21) expect(summary.memory_in_mb).to eq(2200) + expect(summary.routes).to eq(2) + expect(summary.service_instances).to eq(2) + expect(summary.reserved_ports).to eq(1) + expect(summary.domains).to eq(2) # system domain "vcap.me" plus :private_domain_without_router_group + expect(summary.per_app_tasks).to eq(1) + expect(summary.service_keys).to eq(2) end end end diff --git a/spec/unit/presenters/v3/info_usage_summary_presenter_spec.rb b/spec/unit/presenters/v3/info_usage_summary_presenter_spec.rb new file mode 100644 index 00000000000..fe813c1f8db --- /dev/null +++ b/spec/unit/presenters/v3/info_usage_summary_presenter_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' +require 'presenters/v3/info_usage_summary_presenter' +require 'fetchers/global_usage_summary_fetcher' + +module VCAP::CloudController::Presenters::V3 + RSpec.describe InfoUsageSummaryPresenter do + describe '#to_hash' do + let(:result) { InfoUsageSummaryPresenter.new(VCAP::CloudController::GlobalUsageSummaryFetcher.summary).to_hash } + + it 'presents the global usage summary as json' do + expect(result[:usage_summary][:started_instances]).to eq(0) + expect(result[:usage_summary][:memory_in_mb]).to eq(0) + expect(result[:usage_summary][:routes]).to eq(0) + expect(result[:usage_summary][:service_instances]).to eq(0) + expect(result[:usage_summary][:reserved_ports]).to eq(0) + expect(result[:usage_summary][:domains]).to eq(1) + expect(result[:usage_summary][:per_app_tasks]).to eq(0) + expect(result[:usage_summary][:service_keys]).to eq(0) + + expect(result[:links][:self][:href]).to match(%r{/v3/info/usage_summary$}) + end + end + end +end