Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit e096c38

Browse files
authored
v3(services): refactor delete for service instance (cloudfoundry#1980)
We have moved to a pattern where a controller either uses an action to do something, or schedules a job to do something, and the job uses an action under the hood. The services instances delete endpoint was using an action to schedule a job, which could be confusing as it's different to other endpoints. [#171728591](https://www.pivotaltracker.com/story/show/171728591)
1 parent 06b711d commit e096c38

3 files changed

Lines changed: 50 additions & 57 deletions

File tree

app/actions/v3/service_instance_delete.rb

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ def delete(service_instance)
1818

1919
lock = DeleterLock.new(service_instance)
2020

21-
job = case service_instance
22-
when ManagedServiceInstance
23-
asynchronous_destroy(service_instance)
24-
when UserProvidedServiceInstance
25-
lock.lock!
26-
synchronous_destroy(service_instance, lock)
27-
end
28-
29-
job
21+
case service_instance
22+
when ManagedServiceInstance
23+
return false
24+
when UserProvidedServiceInstance
25+
lock.lock!
26+
synchronous_destroy(service_instance, lock)
27+
return true
28+
end
3029
end
3130

3231
private
@@ -37,16 +36,6 @@ def synchronous_destroy(service_instance, lock)
3736
nil
3837
end
3938

40-
def asynchronous_destroy(service_instance)
41-
delete_job = V3::DeleteServiceInstanceJob.new(
42-
service_instance.guid,
43-
service_event_repository.user_audit_info)
44-
45-
pollable_job = Jobs::Enqueuer.new(delete_job, queue: Jobs::Queues.generic).enqueue_pollable
46-
47-
pollable_job.guid
48-
end
49-
5039
def association_not_empty!
5140
raise AssociationNotEmptyError
5241
end

app/controllers/v3/service_instances_controller.rb

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,7 @@ def create
9292
end
9393

9494
def update
95-
service_instance = ServiceInstance.first(guid: hashed_params[:guid])
96-
resource_not_found!(:service_instance) unless service_instance && can_read_service_instance?(service_instance)
97-
unauthorized! unless can_write_space?(service_instance.space)
95+
service_instance = fetch_writable_service_instance(hashed_params[:guid])
9896

9997
case service_instance
10098
when ManagedServiceInstance
@@ -105,24 +103,21 @@ def update
105103
end
106104

107105
def destroy
108-
service_instance = ServiceInstance.first(guid: hashed_params[:guid])
109-
service_instance_not_found! unless service_instance && can_read_service_instance?(service_instance)
106+
service_instance = fetch_writable_service_instance(hashed_params[:guid])
110107
purge = params['purge'] == 'true'
111-
112-
unauthorized! unless can_write_space?(service_instance.space)
113-
114108
service_event_repository = VCAP::CloudController::Repositories::ServiceEventRepository.new(user_audit_info)
115109

116110
if purge
117111
ServiceInstancePurge.new(service_event_repository).purge(service_instance)
118112
return [:no_content, nil]
119113
end
120114

121-
job_guid = V3::ServiceInstanceDelete.new(service_event_repository).delete(service_instance)
115+
deleted = V3::ServiceInstanceDelete.new(service_event_repository).delete(service_instance)
122116

123-
if job_guid.blank?
117+
if deleted
124118
head :no_content
125119
else
120+
job_guid = enqueue_delete_job(service_instance)
126121
head :accepted, 'Location' => url_builder.build_url(path: "/v3/jobs/#{job_guid}")
127122
end
128123
rescue V3::ServiceInstanceDelete::AssociationNotEmptyError
@@ -294,10 +289,6 @@ def update_managed(service_instance)
294289
raise CloudController::Errors::ApiError.new_from_details('AsyncServiceBindingOperationInProgress', e.service_binding.app.name, e.service_binding.service_instance.name)
295290
end
296291

297-
def admin?
298-
permission_queryer.can_write_globally?
299-
end
300-
301292
def check_spaces_exist_and_are_writeable!(service_instance, request_guids, found_spaces)
302293
unreadable_spaces = found_spaces.reject { |s| can_read_space?(s) }
303294
unwriteable_spaces = found_spaces.reject { |s| can_write_space?(s) || unreadable_spaces.include?(s) }
@@ -316,6 +307,33 @@ def check_spaces_exist_and_are_writeable!(service_instance, request_guids, found
316307
end
317308
end
318309

310+
def build_create_message(params)
311+
generic_message = ServiceInstanceCreateMessage.new(params)
312+
unprocessable!(generic_message.errors.full_messages) unless generic_message.valid?
313+
314+
specific_message = if generic_message.type == 'managed'
315+
ServiceInstanceCreateManagedMessage.new(params)
316+
else
317+
ServiceInstanceCreateUserProvidedMessage.new(params)
318+
end
319+
320+
unprocessable!(specific_message.errors.full_messages) unless specific_message.valid?
321+
specific_message
322+
end
323+
324+
def fetch_writable_service_instance(guid)
325+
service_instance = ServiceInstance.first(guid: guid)
326+
service_instance_not_found! unless service_instance && can_read_service_instance?(service_instance)
327+
unauthorized! unless can_write_space?(service_instance.space)
328+
service_instance
329+
end
330+
331+
def enqueue_delete_job(service_instance)
332+
delete_job = V3::DeleteServiceInstanceJob.new(service_instance.guid, user_audit_info)
333+
pollable_job = Jobs::Enqueuer.new(delete_job, queue: Jobs::Queues.generic).enqueue_pollable
334+
pollable_job.guid
335+
end
336+
319337
def unreadable_error_message(service_instance_name, unreadable_space_guids)
320338
if unreadable_space_guids.any?
321339
unreadable_guid_list = unreadable_space_guids.map { |g| "'#{g}'" }.join(', ')
@@ -349,22 +367,8 @@ def can_write_space?(space)
349367
permission_queryer.can_write_to_space?(space.guid)
350368
end
351369

352-
def build_create_message(params)
353-
generic_message = ServiceInstanceCreateMessage.new(params)
354-
unprocessable!(generic_message.errors.full_messages) unless generic_message.valid?
355-
356-
specific_message = if generic_message.type == 'managed'
357-
ServiceInstanceCreateManagedMessage.new(params)
358-
else
359-
ServiceInstanceCreateUserProvidedMessage.new(params)
360-
end
361-
362-
unprocessable!(specific_message.errors.full_messages) unless specific_message.valid?
363-
specific_message
364-
end
365-
366-
def service_instance_not_found!
367-
resource_not_found!(:service_instance)
370+
def admin?
371+
permission_queryer.can_write_globally?
368372
end
369373

370374
def service_plan_valid?(service_plan, space)
@@ -373,6 +377,10 @@ def service_plan_valid?(service_plan, space)
373377
service_plan.visible_in_space?(space)
374378
end
375379

380+
def service_instance_not_found!
381+
resource_not_found!(:service_instance)
382+
end
383+
376384
def unprocessable_space!
377385
unprocessable!('Invalid space. Ensure that the space exists and you have access to it.')
378386
end

spec/unit/actions/v3/service_instance_delete_spec.rb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,16 @@ module CloudController
5555
with(:delete, instance_of(UserProvidedServiceInstance))
5656
end
5757

58-
it 'returns nothing' do
59-
expect(subject.delete(service_instance)).to be_nil
58+
it 'returns true' do
59+
expect(subject.delete(service_instance)).to be_truthy
6060
end
6161
end
6262

6363
context 'managed service instances' do
6464
let!(:service_instance) { VCAP::CloudController::ManagedServiceInstance.make }
6565

66-
it 'enqueues a job and returns the job guid' do
67-
job_guid = subject.delete(service_instance)
68-
job = VCAP::CloudController::PollableJobModel.last
69-
70-
expect(job.guid).to eq(job_guid)
71-
expect(job.resource_guid).to eq(service_instance.guid)
66+
it 'returns false' do
67+
expect(subject.delete(service_instance)).to be_falsey
7268
end
7369
end
7470

0 commit comments

Comments
 (0)