-
Notifications
You must be signed in to change notification settings - Fork 360
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implements PATCH /v3/routes/:guid/transfer_owner
Note: This is probably note the right endpoint defintion for this action current frontrunners are: PATCH v3/routes/:guid/relationships/space -d { "data": {"guid": "space-2-guid" }} PATCH /v3/routes/:guid/actioins/transfer_owner -d {"guid": "space-2-guid" } Co-authored-by: Merric de Launey <mdelauney@pivotal.io> Co-authored-by: Michael Oleske <moleske@pivotal.io> Co-authored-by: David Alvarado <alvaradoda@vmware.com> Co-authored-by: Alex Rocha <alexr1@vmware.com>
- Loading branch information
1 parent
b0e0573
commit 351b1f4
Showing
7 changed files
with
293 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
require 'repositories/route_event_repository' | ||
|
||
module VCAP::CloudController | ||
class RouteTransferOwner | ||
class Error < ::StandardError | ||
end | ||
|
||
class << self | ||
def transfer(route, target_space, user_audit_info) | ||
return route if target_space.name == route.space.name | ||
|
||
original_space = route.space | ||
Route.db.transaction do | ||
route.space = target_space | ||
route.remove_shared_space(target_space) | ||
route.add_shared_space(original_space) | ||
route.save | ||
end | ||
Repositories::RouteEventRepository.new.record_route_transfer_owner( | ||
route, user_audit_info, original_space, target_space.guid) | ||
end | ||
|
||
private | ||
|
||
def error!(message) | ||
raise Error.new(message) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
require 'messages/base_message' | ||
|
||
module VCAP::CloudController | ||
class RouteTransferOwnerMessage < BaseMessage | ||
register_allowed_keys [:guid] | ||
|
||
validates_with NoAdditionalKeysValidator | ||
validates :guid, presence: true, string: true, allow_nil: false, allow_blank: false | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
require 'spec_helper' | ||
require 'actions/route_transfer_owner' | ||
|
||
module VCAP::CloudController | ||
RSpec.describe RouteTransferOwner do | ||
let(:route_share) { RouteShare.new } | ||
let(:route) { Route.make domain: SharedDomain.make, space: original_owning_space } | ||
let(:original_owning_space) { Space.make name: 'original_owning_space' } | ||
let(:target_space) { Space.make name: 'target_space' } | ||
let(:shared_space) { Space.make name: 'shared_space' } | ||
let(:user_audit_info) { UserAuditInfo.new(user_guid: 'user-guid-1', user_email: 'user@email.com') } | ||
|
||
describe '#transfer' do | ||
before do | ||
route_share.create(route, [shared_space], user_audit_info) | ||
end | ||
|
||
it 'makes the target space the new owner' do | ||
RouteTransferOwner.transfer(route, target_space, user_audit_info) | ||
expect(route.space.name).to eq target_space.name | ||
end | ||
|
||
context 'route was previously shared with the target space' do | ||
before do | ||
route_share.create(route, [target_space], user_audit_info) | ||
end | ||
|
||
it 'removes the target space from the list of shared spaces' do | ||
expect(route.shared_spaces.map(&:name)).to include target_space.name | ||
RouteTransferOwner.transfer(route, target_space, user_audit_info) | ||
route.reload | ||
expect(route.shared_spaces.map(&:name)).not_to include target_space.name | ||
end | ||
end | ||
|
||
it 'shares the route with the original owning space' do | ||
expect(route.shared_spaces.map(&:name)).not_to include original_owning_space.name | ||
RouteTransferOwner.transfer(route, target_space, user_audit_info) | ||
route.reload | ||
expect(route.shared_spaces.map(&:name)).to include original_owning_space.name | ||
end | ||
|
||
context 'target space is already the owning space' do | ||
it ' it does nothing and succeeds' do | ||
expect { RouteTransferOwner.transfer(route, original_owning_space, user_audit_info) }.not_to raise_error | ||
expect(route.shared_spaces.map(&:name)).not_to include original_owning_space.name | ||
expect(route.space.name).to eq original_owning_space.name | ||
end | ||
end | ||
|
||
it 'records a transfer event' do | ||
expect_any_instance_of(Repositories::RouteEventRepository).to receive(:record_route_transfer_owner).with( | ||
route, user_audit_info, target_space.guid) | ||
|
||
RouteTransferOwner.transfer(route, target_space, user_audit_info) | ||
end | ||
|
||
context 'when tranfering ownership fails' do | ||
before do | ||
allow(route).to receive(:save).and_raise('db failure') | ||
end | ||
|
||
it 'does not change the owning space' do | ||
expect(route.space.name).to eq original_owning_space.name | ||
expect { | ||
RouteTransferOwner.transfer(route, target_space, user_audit_info) | ||
}.to raise_error('db failure') | ||
route.reload | ||
expect(route.space.name).to eq original_owning_space.name | ||
end | ||
|
||
it 'does not change the shared spaces' do | ||
expect(route.shared_spaces.length).to eq 1 | ||
expect(route.shared_spaces.map(&:name)).to include shared_space.name | ||
expect { | ||
RouteTransferOwner.transfer(route, target_space, user_audit_info) | ||
}.to raise_error('db failure') | ||
route.reload | ||
expect(route.shared_spaces.map(&:name)).to include shared_space.name | ||
expect(route.shared_spaces.length).to eq 1 | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
require 'spec_helper' | ||
require 'messages/process_scale_message' | ||
require 'messages/base_message' | ||
|
||
module VCAP::CloudController | ||
RSpec.describe RouteTransferOwnerMessage do | ||
context 'when unexpected keys are requested' do | ||
let(:params) { { guid: 'some-guid', unexpected: 'foo' } } | ||
|
||
it 'is not valid' do | ||
message = RouteTransferOwnerMessage.new(params) | ||
|
||
expect(message).not_to be_valid | ||
expect(message.errors.full_messages[0]).to include("Unknown field(s): 'unexpected'") | ||
end | ||
end | ||
|
||
context 'when guid is not a string' do | ||
let(:params) { { guid: 5 } } | ||
|
||
it 'is not valid' do | ||
message = RouteTransferOwnerMessage.new(params) | ||
|
||
expect(message).not_to be_valid | ||
expect(message.errors.count).to eq(1) | ||
expect(message.errors[:guid]).to include('must be a string') | ||
end | ||
end | ||
|
||
context 'when guid is not present' do | ||
let(:params) { { guid: '' } } | ||
|
||
it 'is not valid' do | ||
message = RouteTransferOwnerMessage.new(params) | ||
|
||
expect(message).not_to be_valid | ||
expect(message.errors.count).to eq(1) | ||
expect(message.errors[:guid]).to include("can't be blank") | ||
end | ||
end | ||
end | ||
end |