diff --git a/app/controllers/api/physical_switches_controller.rb b/app/controllers/api/physical_switches_controller.rb index 8e869827d3..f1ab34bd41 100644 --- a/app/controllers/api/physical_switches_controller.rb +++ b/app/controllers/api/physical_switches_controller.rb @@ -12,8 +12,59 @@ def refresh_resource(type, id, _data = nil) end end + def restart_resource(type, id, _data = nil) + perform_action(:restart, type, id) + end + private + def perform_action(action, type, id) + if single_resource? + enqueue_action_single_resource(action, type, id) + else + enqueue_action_multiple_resources(action, type, id) + end + end + + # + # Enqueues the action for a single resource. + # + # @param [symbol] action - action to be enqueued + # @param [symbol] type - type of the resource + # @param [number] id - id of the resource + # + def enqueue_action_single_resource(action, type, id) + raise BadRequestError, "Must specify an id for changing a #{type} resource" unless id + + physical_switch = resource_search(id, type, collection_class(type)) + + api_action(type, id) do + begin + desc = "Performing #{action} for #{physical_switch_ident(physical_switch)}" + api_log_info(desc) + task_id = queue_object_action(physical_switch, desc, :method_name => action, :role => :ems_operations) + action_result(true, desc, :task_id => task_id) + rescue StandardError => err + action_result(false, err.to_s) + end + end + end + + # + # Enqueues the action for multiple resources. + # For multiple resources, when an error occurs, the error messages must + # be built individually for each resource. Always responding with status 200. + # + # @param [symbol] action - action to be enqueued + # @param [symbol] type - type of the resource + # @param [number] id - id of the resource + # + def enqueue_action_multiple_resources(action, type, id) + enqueue_action_single_resource(action, type, id) + rescue ActiveRecord::RecordNotFound => err + action_result(false, _(err.message)) + end + def ensure_resource_exists(type, id) raise NotFoundError, "#{type} with id:#{id} not found" unless collection_class(type).exists?(id) end diff --git a/config/api.yml b/config/api.yml index 6c07c3dd8d..37c3bd9cbb 100644 --- a/config/api.yml +++ b/config/api.yml @@ -1847,6 +1847,8 @@ :identifier: physical_switch_show_list - :name: refresh :identifier: physical_switch_refresh + - :name: restart + :identifier: physical_switch_restart :resource_actions: :get: - :name: read @@ -1854,6 +1856,8 @@ :post: - :name: refresh :identifier: physical_switch_refresh + - :name: restart + :identifier: physical_switch_restart :pictures: :description: Pictures :options: diff --git a/spec/requests/physical_switches_spec.rb b/spec/requests/physical_switches_spec.rb index f13142fae9..438e235169 100644 --- a/spec/requests/physical_switches_spec.rb +++ b/spec/requests/physical_switches_spec.rb @@ -1,7 +1,10 @@ describe "Physical Switches API" do + let(:physical_switch) { FactoryGirl.create(:physical_switch) } + context "GET /api/physical_switches" do it "returns all Physical Switches" do - physical_switch = FactoryGirl.create(:physical_switch) + physical_switch + api_basic_authorize('physical_switch_show_list') get(api_physical_switches_url) @@ -17,7 +20,6 @@ context "GET /api/physical_switches/:id" do it "returns a single Physical Switch" do - physical_switch = FactoryGirl.create(:physical_switch) api_basic_authorize('physical_switch_show') get(api_physical_switch_url(nil, physical_switch)) @@ -44,7 +46,6 @@ context "without an appropriate role" do it "it responds with 403 Forbidden" do - physical_switch = FactoryGirl.create(:physical_switch) api_basic_authorize post(api_physical_switch_url(nil, physical_switch), :params => gen_request(:refresh)) @@ -63,7 +64,6 @@ end it "refresh of a single Physical Switch" do - physical_switch = FactoryGirl.create(:physical_switch) api_basic_authorize('physical_switch_refresh') post(api_physical_switch_url(nil, physical_switch), :params => gen_request(:refresh)) @@ -97,4 +97,87 @@ end end end + + describe "Physical Switches restart action" do + let(:action) { :restart } + + context "For multiple resources" do + context "With an invalid id and valid id" do + it "returns a HTTP status 200, perform the action for the valid resource and fail for the invalid" do + api_basic_authorize(action_identifier(:physical_switches, action, :resource_actions, :post)) + + post( + api_physical_switches_url, + :params => gen_request(action, [ + {"href" => api_physical_switch_url(nil, physical_switch)}, + {"href" => api_physical_switch_url(nil, 999_999)} + ]) + ) + + expected = { + "results" => a_collection_containing_exactly( + a_hash_including( + "message" => a_string_matching("Performing #{action} for Physical Switch id:#{physical_switch.id} name: '#{physical_switch.name}'"), + "success" => true, + "href" => api_physical_switch_url(nil, physical_switch) + ), + a_hash_including( + "success" => false + ) + ) + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:ok) + end + end + + context "With a valid request" do + it "performs the action succesfully" do + api_basic_authorize(action_identifier(:physical_switches, action, :resource_actions, :post)) + + post(api_physical_switches_url, :params => gen_request(action, [ + {"href" => api_physical_switch_url(nil, physical_switch)}, + ])) + + expected = { + "results" => a_collection_containing_exactly( + a_hash_including( + "message" => a_string_matching("Performing #{action} for Physical Switch id:#{physical_switch.id} name: '#{physical_switch.name}'"), + "success" => true, + "href" => api_physical_switch_url(nil, physical_switch) + ) + ) + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:ok) + end + end + end + + context "For a single resource" do + context "With an invalid id and valid id" do + it "it responds with 404 Not Found" do + api_basic_authorize(action_identifier(:physical_switches, action, :resource_actions, :post)) + + post(api_physical_switch_url(nil, 999_999), :params => gen_request(action)) + + expect(response).to have_http_status(:not_found) + end + end + + context "With a valid request" do + it "restarts the Physical Switch" do + api_basic_authorize(action_identifier(:physical_switches, action, :resource_actions, :post)) + + post(api_physical_switch_url(nil, physical_switch), :params => gen_request(action)) + + expect_single_action_result( + :success => true, + :message => a_string_matching("Performing #{action} for Physical Switch id:#{physical_switch.id} name: '#{physical_switch.name}'"), + :href => api_physical_switch_url(nil, physical_switch) + ) + end + end + end + end end