Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add alert actions api #13325

Merged
merged 1 commit into from
Jan 24, 2017
Merged

Conversation

moolitayer
Copy link

@moolitayer moolitayer commented Dec 29, 2016

Adds retrieval and creation of alert_actions as a sub resource of alerts.

Route Body
GET /api/alerts/:id/alert_actions/ [1]
GET /api/alerts/:id/alert_actions/:id [2]
POST /api/alerts/:id/alert_actions/ [3]

[1] :
Response:

{
    "name": "alert_actions",
    "count": 3,
    "subcount": 3,
    "resources": [
        {
            "href": "http://localhost:3000/api/alerts/6/alert_actions/8"
        },
        {
            "href": "http://localhost:3000/api/alerts/6/alert_actions/9"
        },
        {
            "href": "http://localhost:3000/api/alerts/6/alert_actions/10"
        }
    ],
    "actions": [
        {
            "name": "create",
            "method": "post",
            "href": "http://localhost:3000/api/alerts/6/alert_actions"
        }
    ]
}

[2] :
Response:

{
    "href": "http://localhost:3000/api/alerts/6/alert_actions/9",
    "id": 9,
    "action_type": "assign",
    "user_id": 1,
    "assignee_id": 1,
    "miq_alert_status_id": 6,
    "created_at": "2017-01-22T12:29:29Z",
    "updated_at": "2017-01-22T12:29:29Z"
}

[3] :
Request:

{
  "action_type": "comment",
  "user_id": 1,
  "comment": "comment text"
}

Response:

{
    "results": [
        {
            "id": 11,
            "action_type": "comment",
            "user_id": 1,
            "comment": "comment text",
            "miq_alert_status_id": 6,
            "created_at": "2017-01-22T12:36:54Z",
            "updated_at": "2017-01-22T12:36:54Z"
        }
    ]
}

@moolitayer
Copy link
Author

@miq-bot add_label wip, enhancement, api

@chessbyte chessbyte added the wip label Jan 3, 2017
@moolitayer moolitayer changed the title [WIP] Add alert actions api Add alert actions api Jan 11, 2017
@moolitayer
Copy link
Author

@miq-bot remove_label wip

@moolitayer
Copy link
Author

@abellotti can you start reviewing 530fdbb9e46ccc7734ded66aa05e8b5afb93c8c7 even though the dependent patch hasn't been merged yet?

It's critical to have all of those patches merged by the end of the week to have the API in place for the next week for other people's work

@moolitayer
Copy link
Author

@abellotti PTAL

@abellotti
Copy link
Member

Could you add a description entry showing the expected usage, i.e.

GET /api/alerts
GET /api/alerts/:id/alert_actions
POST /api/alerts/:id/alert_actions  with action names ...
...

It would help us to better review.

Copy link
Member

@abellotti abellotti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments above.

/cc @imtayadeway for more input. Thanks!!

module Subcollections
module Alerts
def alerts_query_resource(object)
object.try(:miq_alert_statuses).to_a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could just be:

object.miq_alert_statuses || []

- :name: read
:identifier: alert_status_action_show_list
:post:
- :name: create
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it make sense to allow creates as both /api/alert_actions as well as /api/alerts/:id/alert_actions ? Doesn't the former need a relationship to the /api/alerts resource ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, should be supported only for /api/alerts/:id/alert_actions now

expect(response.parsed_body["results"].count).to eq(1)
expect(response.parsed_body["results"][0]).to include(specification)
end
# TODO: add tests for sub collection (only related for alert returned, id is ignored and taken from parent etc)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'd need this test added too.

run_post(alert_actions_url, specification)
expect(response).to have_http_status(:ok)
expect(response.parsed_body["results"].count).to eq(1)
expect(response.parsed_body["results"][0]).to include(specification)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

32/33 could be a single expect.

- :name: Add
:description: Display Individual Alert Status
:feature_type: control
:identifier: alert_status_action_new
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @h-kataria need your 👀 on above miq_product_features.yml changes. Thanks!!

@miq-bot
Copy link
Member

miq-bot commented Jan 19, 2017

This pull request is not mergeable. Please rebase and repush.

@moolitayer
Copy link
Author

moolitayer commented Jan 22, 2017

/cc @h-kataria need your on above miq_product_features.yml changes. Thanks!!

@h-kataria could you please take a look at the product features for added here?
this is part of the API needed for "Monitor" added here does it make sense to have separate features?

@imtayadeway @abellotti addressed comments, and made some changes based on the review of #13025 can you take a look? Thanks

@moolitayer
Copy link
Author

@imtayadeway @abellotti Please review, Feedback appriciated

module Subcollections
module AlertActions
def alert_actions_query_resource(object)
MiqAlertStatusAction.where(:miq_alert_status_id => object.id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do alert statuses not have alert status actions? i.e. something like object.miq_alert_status_actions?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will change

end

def alert_actions_create_resource(object, type, _id, data)
data['miq_alert_status_id'] = object.id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changing the data that's passed into this method - perhaps you could dup the data before you do this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe using merge would be cleaner?

api_basic_authorize subcollection_action_identifier(:alerts, :alert_actions, :create, :post)
run_post(actions_subcollection_url, attributes)
expect(response).to have_http_status(:ok)
alert_action = MiqAlertStatusAction.find(response.parsed_body["results"].first["id"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the attributes not sent back in the response? Can you not put the expectation on those?

@moolitayer
Copy link
Author

moolitayer commented Jan 23, 2017

@imtayadeway addressed comments, thanks

api_basic_authorize subcollection_action_identifier(:alerts, :alert_actions, :create, :post)
run_post(actions_subcollection_url, attributes)
expect(response).to have_http_status(:ok)
expect(response.parsed_body["results"].first).to have_attributes(attributes)
Copy link
Contributor

@imtayadeway imtayadeway Jan 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but in the case that it breaks you may get a NoMethodError on nil, instead of a diff. So it may be better to write these and others like it something like:

expected = {
  "results" => [
    a_hash_including(attributes)
  ]
}
expected(response.parsed_body). to include(expected)

"comment" => "comment text",
)
expect(response).to have_http_status(:bad_request)
expect(response.parsed_body["error"]["message"]).to eq(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a helper that you can use here that will better handle the case outlined above:

expect(response).to have_error_with_message("Failed etc...")

@imtayadeway
Copy link
Contributor

@moolitayer this looks good, just some minor nits about tests. @abellotti any thoughts?

@moolitayer moolitayer force-pushed the alert_actions_api branch 2 times, most recently from 260c760 to b5c1c0e Compare January 23, 2017 19:57
@moolitayer
Copy link
Author

Thanks @imtayadeway!
Addressed comments, @abellotti please review

Good night 🌔 💤

Copy link
Member

@abellotti abellotti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, other than the user reference support, minor changes needed. Thanks!!

)
if alert_action.invalid?
raise BadRequestError, "Failed to add a new alert action resource" \
" - #{alert_action.errors.full_messages.join(', ')}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would prefer:

          raise BadRequestError,
                "Failed to add a new alert action resource - #{alert_action.errors.full_messages.join(', ')}"

should still be good rubucop line length limit-wise.

expect(response).to have_http_status(:forbidden)
end

it "creats an alert action under an alert" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

creats -> creates

user = FactoryGirl.create(:user)
attributes = {
"action_type" => "comment",
"user_id" => user.id,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should support user reference signatures in addition to user_id,

i.e. support:

   "user" : { "id" : ### }

as well as:

  "user" : { "href" : "http://localhost:3000/api/users/###" }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and the related tests for both additional signatures.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I Hope I understood. I should not accept a parameter named user_id anymore?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keep support for user_id as you do today (that's what is sent to the model), but the API should support the user reference and generate the user_id accordingly, see what was done for arbitration_rules creation for specifying arbitration_profile (we define the arbitration_profile_id if the arbitration_profile reference is specified, using parse_id) https://github.com/ManageIQ/manageiq/pull/13525/files

Copy link
Author

@moolitayer moolitayer Jan 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification.

Now that I think about it

  • the user should always be the current user
  • your comment should be applied on assignee_id

user_id === who created this action
assignee_id === assignment target, if this is an assignment action

I'm working on it, let me know if that does not make sense

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if user_id is always who created this action, why is it passed in below as part of attributes in the run_post (line 102). Maybe it should not and the API forces it to be User.current_user.id before sending to model ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is should be the situation now. I wrote a test to show a user_id is always ignored in favor of the current user ("creates an alert action on the current user")

"subcount" => 1,
"resources" => [
{
"href" => "http://www.example.com/api/alerts/#{alert.id}/alert_actions/#{alert_action.id}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would prefer:

  "resources" = [
     {
         "href" => a_string_matching("#{alerts_url(alert.id)}/alert_actions/#{alert_action.id}")
     }

including the ones in the alerts_spec.rb, but those can be a different PR.

run_get("#{actions_subcollection_url}/#{alert_action.id}")
expect(response).to have_http_status(:ok)
expect(response.parsed_body).to have_attributes(
"href" => "http://www.example.com/api/alerts/#{alert.id}/alert_actions/#{alert_action.id}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above, would prefer the a_string_matching, leveraging alerts_url.

@moolitayer
Copy link
Author

moolitayer commented Jan 24, 2017

@abellotti addressed comments, added tests for the new functionalities
(assignee can be refrenced by either id or href, user value should be ignored and always set to the current user)
please take a look

@miq-bot
Copy link
Member

miq-bot commented Jan 24, 2017

Checked commit moolitayer@6bb0bf1 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0
4 files checked, 1 offense detected

spec/requests/api/alerts_spec.rb

@abellotti
Copy link
Member

LGTM!! Thanks @moolitayer for the API Enhancement.

@abellotti abellotti merged commit 1d00c06 into ManageIQ:master Jan 24, 2017
@abellotti abellotti added this to the Sprint 53 Ending Jan 30, 2017 milestone Jan 24, 2017
@moolitayer
Copy link
Author

Awesome @abellotti @imtayadeway Thanks for reviewing & improving my work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants