Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9dbb8c2

Browse files
committedJan 21, 2025·
Provide index, show, and destroy endpoints for usage consumers
Allows for usage consumers to de-register themselves with the cloud controller. Index and show methods allow consumers to make informed decisions before initiating a purge of usage events. Usage event endpoint re-ordered to align with convention of other resources.
1 parent fbb490c commit 9dbb8c2

9 files changed

+262
-2
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require 'presenters/v3/app_usage_consumer_presenter'
2+
require 'messages/app_usage_consumers_list_message'
3+
require 'fetchers/app_usage_consumer_list_fetcher'
4+
5+
class AppUsageConsumersController < ApplicationController
6+
def index
7+
message = AppUsageConsumersListMessage.from_params(query_params)
8+
invalid_param!(message.errors.full_messages) unless message.valid?
9+
10+
app_usage_consumers = AppUsageConsumer.where(guid: [])
11+
12+
app_usage_consumers = AppUsageConsumerListFetcher.fetch_all(message, AppUsageConsumer.dataset) if permission_queryer.can_read_globally?
13+
14+
render status: :ok, json: Presenters::V3::PaginatedListPresenter.new(
15+
presenter: Presenters::V3::AppUsageConsumerPresenter,
16+
paginated_result: SequelPaginator.new.get_page(app_usage_consumers, message.try(:pagination_options)),
17+
path: '/v3/app_usage_consumers',
18+
message: message
19+
)
20+
end
21+
22+
def show
23+
app_usage_consumer_not_found! unless permission_queryer.can_read_globally?
24+
app_usage_consumer = AppUsageConsumer.first(guid: hashed_params[:guid])
25+
app_usage_consumer_not_found! unless app_usage_consumer
26+
27+
render status: :ok, json: Presenters::V3::AppUsageConsumerPresenter.new(app_usage_consumer)
28+
end
29+
30+
def destroy
31+
unauthorized! unless permission_queryer.can_write_globally?
32+
33+
app_usage_consumer = AppUsageConsumer.find(consumer_guid: hashed_params[:guid])
34+
35+
resource_not_found!(:app_usage_consumer) unless app_usage_consumer
36+
37+
app_usage_consumer_access = VCAP::CloudController::AppUsageConsumerAccess.new(context: SecurityContext)
38+
unauthorized! unless app_usage_consumer_access.delete?(app_usage_consumer)
39+
40+
app_usage_consumer.destroy
41+
42+
head :no_content
43+
end
44+
45+
private
46+
47+
def app_usage_consumer_not_found!
48+
resource_not_found!(:app_usage_consumer)
49+
end
50+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require 'presenters/v3/service_usage_consumer_presenter'
2+
require 'messages/service_usage_consumers_list_message'
3+
require 'fetchers/service_usage_consumer_list_fetcher'
4+
5+
class ServiceUsageConsumersController < ApplicationController
6+
def index
7+
message = ServiceUsageConsumersListMessage.from_params(query_params)
8+
invalid_param!(message.errors.full_messages) unless message.valid?
9+
10+
service_usage_consumers = ServiceUsageConsumer.where(guid: [])
11+
12+
service_usage_consumers = ServiceUsageConsumerListFetcher.fetch_all(message, ServiceUsageConsumer.dataset) if permission_queryer.can_read_globally?
13+
14+
render status: :ok, json: Presenters::V3::PaginatedListPresenter.new(
15+
presenter: Presenters::V3::ServiceUsageConsumerPresenter,
16+
paginated_result: SequelPaginator.new.get_page(service_usage_consumers, message.try(:pagination_options)),
17+
path: '/v3/service_usage_consumers',
18+
message: message
19+
)
20+
end
21+
22+
def show
23+
service_usage_consumer_not_found! unless permission_queryer.can_read_globally?
24+
service_usage_consumer = ServiceUsageConsumer.first(guid: hashed_params[:guid])
25+
service_usage_consumer_not_found! unless service_usage_consumer
26+
27+
render status: :ok, json: Presenters::V3::ServiceUsageConsumerPresenter.new(service_usage_consumer)
28+
end
29+
30+
def destroy
31+
unauthorized! unless permission_queryer.can_write_globally?
32+
33+
service_usage_consumer = ServiceUsageConsumer.find(consumer_guid: hashed_params[:guid])
34+
35+
resource_not_found!(:service_usage_consumer) unless service_usage_consumer
36+
37+
service_usage_consumer_access = VCAP::CloudController::ServiceUsageConsumerAccess.new(context: SecurityContext)
38+
unauthorized! unless service_usage_consumer_access.delete?(service_usage_consumer)
39+
40+
service_usage_consumer.destroy
41+
42+
head :no_content
43+
end
44+
45+
private
46+
47+
def service_usage_consumer_not_found!
48+
resource_not_found!(:service_usage_consumer)
49+
end
50+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require 'fetchers/base_list_fetcher'
2+
3+
module VCAP::CloudController
4+
class AppUsageConsumerListFetcher
5+
class << self
6+
def fetch_all(message, dataset)
7+
filter(message, dataset)
8+
end
9+
10+
private
11+
12+
def filter(message, dataset)
13+
dataset = dataset.where(consumer_guid: message.consumer_guids) if message.requested?(:consumer_guids)
14+
15+
dataset = dataset.where(last_processed_guid: message.last_processed_guids) if message.requested?(:last_processed_guids)
16+
17+
dataset
18+
end
19+
end
20+
end
21+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require 'fetchers/base_list_fetcher'
2+
3+
module VCAP::CloudController
4+
class ServiceUsageConsumerListFetcher
5+
class << self
6+
def fetch_all(message, dataset)
7+
filter(message, dataset)
8+
end
9+
10+
private
11+
12+
def filter(message, dataset)
13+
dataset = dataset.where(consumer_guid: message.consumer_guids) if message.requested?(:consumer_guids)
14+
15+
dataset = dataset.where(last_processed_guid: message.last_processed_guids) if message.requested?(:last_processed_guids)
16+
17+
dataset
18+
end
19+
end
20+
end
21+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require 'messages/list_message'
2+
3+
module VCAP::CloudController
4+
class AppUsageConsumersListMessage < ListMessage
5+
register_allowed_keys %i[
6+
consumer_guids
7+
last_processed_guids
8+
]
9+
10+
validates_with NoAdditionalKeysValidator
11+
12+
validates :consumer_guids, array: true, allow_nil: true
13+
validates :last_processed_guids, array: true, allow_nil: true
14+
15+
def self.from_params(params)
16+
super(params, %w[consumer_guids last_processed_guids])
17+
end
18+
end
19+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require 'messages/list_message'
2+
3+
module VCAP::CloudController
4+
class ServiceUsageConsumersListMessage < ListMessage
5+
register_allowed_keys %i[
6+
consumer_guids
7+
last_processed_guids
8+
]
9+
10+
validates_with NoAdditionalKeysValidator
11+
12+
validates :consumer_guids, array: true, allow_nil: true
13+
validates :last_processed_guids, array: true, allow_nil: true
14+
15+
def self.from_params(params)
16+
super(params, %w[consumer_guids last_processed_guids])
17+
end
18+
end
19+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require 'presenters/v3/base_presenter'
2+
3+
module VCAP::CloudController::Presenters::V3
4+
class AppUsageConsumerPresenter < BasePresenter
5+
def to_hash
6+
{
7+
guid: consumer_guid,
8+
last_processed_guid: last_processed_guid,
9+
created_at: resource.created_at,
10+
updated_at: resource.updated_at,
11+
links: build_links
12+
}
13+
end
14+
15+
private
16+
17+
def consumer_guid
18+
resource.consumer_guid
19+
end
20+
21+
def last_processed_guid
22+
resource.last_processed_guid
23+
end
24+
25+
def build_links
26+
url_builder = VCAP::CloudController::Presenters::ApiUrlBuilder.new
27+
28+
{
29+
self: {
30+
href: url_builder.build_url(path: "/v3/app_usage_consumers/#{consumer_guid}")
31+
}
32+
}
33+
end
34+
end
35+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require 'presenters/v3/base_presenter'
2+
3+
module VCAP::CloudController::Presenters::V3
4+
class ServiceUsageConsumerPresenter < BasePresenter
5+
def to_hash
6+
{
7+
guid: consumer_guid,
8+
last_processed_guid: last_processed_guid,
9+
created_at: resource.created_at,
10+
updated_at: resource.updated_at,
11+
links: build_links
12+
}
13+
end
14+
15+
private
16+
17+
def consumer_guid
18+
resource.consumer_guid
19+
end
20+
21+
def last_processed_guid
22+
resource.last_processed_guid
23+
end
24+
25+
def build_links
26+
url_builder = VCAP::CloudController::Presenters::ApiUrlBuilder.new
27+
28+
{
29+
self: {
30+
href: url_builder.build_url(path: "/v3/service_usage_consumers/#{consumer_guid}")
31+
}
32+
}
33+
end
34+
end
35+
end

‎config/routes.rb

+12-2
Original file line numberDiff line numberDiff line change
@@ -323,15 +323,25 @@
323323
get '/audit_events/:guid', to: 'events#show'
324324

325325
# app usage events
326-
get '/app_usage_events/:guid', to: 'app_usage_events#show'
327326
get '/app_usage_events', to: 'app_usage_events#index'
327+
get '/app_usage_events/:guid', to: 'app_usage_events#show'
328328
post '/app_usage_events/actions/destructively_purge_all_and_reseed', to: 'app_usage_events#destructively_purge_all_and_reseed'
329329

330330
# service usage events
331-
get '/service_usage_events/:guid', to: 'service_usage_events#show'
332331
get '/service_usage_events', to: 'service_usage_events#index'
332+
get '/service_usage_events/:guid', to: 'service_usage_events#show'
333333
post '/service_usage_events/actions/destructively_purge_all_and_reseed', to: 'service_usage_events#destructively_purge_all_and_reseed'
334334

335+
# app usage consumers
336+
get '/app_usage_consumers', to: 'app_usage_consumers#index'
337+
get '/app_usage_consumers/:guid', to: 'app_usage_consumers#show'
338+
delete '/app_usage_consumers/:guid', to: 'app_usage_consumers#destroy'
339+
340+
# service usage consumers
341+
get '/service_usage_consumers', to: 'service_usage_consumers#index'
342+
get '/service_usage_consumers/:guid', to: 'service_usage_consumers#show'
343+
delete '/service_usage_consumers/:guid', to: 'service_usage_consumers#destroy'
344+
335345
# environment variable groups
336346
get '/environment_variable_groups/:name', to: 'environment_variable_groups#show'
337347
patch '/environment_variable_groups/:name', to: 'environment_variable_groups#update'

0 commit comments

Comments
 (0)
Please sign in to comment.