Remove Hipchat support from Watcher (#39374)
* Remove Hipchat support from Watcher (#39199) Hipchat has been shut down and has previously been deprecated in Watcher (#39160), therefore we should remove support for these actions. * Add migrate note
|
@ -75,3 +75,9 @@ Tribe node functionality has been removed in favor of
|
||||||
|
|
||||||
* The method `DiscoveryPlugin#getDiscoveryTypes()` was removed, so that plugins
|
* The method `DiscoveryPlugin#getDiscoveryTypes()` was removed, so that plugins
|
||||||
can no longer provide their own discovery implementations.
|
can no longer provide their own discovery implementations.
|
||||||
|
|
||||||
|
[float]
|
||||||
|
==== Watcher 'hipchat' action removed
|
||||||
|
|
||||||
|
Hipchat has been deprecated and shut down as a service. The `hipchat` action for
|
||||||
|
watches has been removed.
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
You configure {watcher} settings to set up {watcher} and send notifications via
|
You configure {watcher} settings to set up {watcher} and send notifications via
|
||||||
<<email-notification-settings,email>>,
|
<<email-notification-settings,email>>,
|
||||||
<<hipchat-notification-settings,HipChat>>,
|
|
||||||
<<slack-notification-settings,Slack>>, and
|
<<slack-notification-settings,Slack>>, and
|
||||||
<<pagerduty-notification-settings, PagerDuty>>.
|
<<pagerduty-notification-settings, PagerDuty>>.
|
||||||
|
|
||||||
|
@ -67,10 +66,10 @@ Specifies the maximum size an HTTP response is allowed to have, defaults to
|
||||||
|
|
||||||
`xpack.http.whitelist`::
|
`xpack.http.whitelist`::
|
||||||
A list of URLs, that the internal HTTP client is allowed to connect to. This
|
A list of URLs, that the internal HTTP client is allowed to connect to. This
|
||||||
client is used in the HTTP input, the webhook, the slack, pagerduty, hipchat
|
client is used in the HTTP input, the webhook, the slack, pagerduty,
|
||||||
and jira actions. This setting can be updated dynamically. It defaults to `*`
|
and jira actions. This setting can be updated dynamically. It defaults to `*`
|
||||||
allowing everything. Note: If you configure this setting and you are using one
|
allowing everything. Note: If you configure this setting and you are using one
|
||||||
of the slack/pagerduty/hipchat actions, you have to ensure that the
|
of the slack/pagerduty actions, you have to ensure that the
|
||||||
corresponding endpoints are whitelisted as well.
|
corresponding endpoints are whitelisted as well.
|
||||||
|
|
||||||
[[ssl-notification-settings]]
|
[[ssl-notification-settings]]
|
||||||
|
@ -207,54 +206,6 @@ HTML feature groups>>.
|
||||||
Set to `false` to completely disable HTML sanitation. Not recommended.
|
Set to `false` to completely disable HTML sanitation. Not recommended.
|
||||||
Defaults to `true`.
|
Defaults to `true`.
|
||||||
|
|
||||||
[float]
|
|
||||||
[[hipchat-notification-settings]]
|
|
||||||
==== HipChat Notification Settings
|
|
||||||
You can configure the following HipChat notification settings in
|
|
||||||
`elasticsearch.yml`. For more information about sending notifications
|
|
||||||
via HipChat, see {xpack-ref}/actions-hipchat.html#configuring-hipchat-actions[Configuring HipChat].
|
|
||||||
|
|
||||||
`xpack.notification.hipchat` ::
|
|
||||||
Specifies account information for sending notifications
|
|
||||||
via HipChat. You can specify the following HipChat account attributes:
|
|
||||||
|
|
||||||
[[hipchat-account-attributes]]
|
|
||||||
`profile`;;
|
|
||||||
The HipChat account profile to use: `integration`,
|
|
||||||
`user`, or `v1`. Required.
|
|
||||||
|
|
||||||
`secure_auth_token` (<<secure-settings,Secure>>);;
|
|
||||||
The authentication token to use to access the HipChat API. Required.
|
|
||||||
|
|
||||||
`host`;;
|
|
||||||
The HipChat server hostname. Defaults to `api.hipchat.com`.
|
|
||||||
|
|
||||||
`port`;;
|
|
||||||
The HipChat server port number. Defaults to 443.
|
|
||||||
|
|
||||||
`room`;;
|
|
||||||
The room you want to send messages to. Must be specified
|
|
||||||
if the `profile` is set to `integration`. Not valid for
|
|
||||||
the `user` or `vi` profiles.
|
|
||||||
|
|
||||||
`user`;;
|
|
||||||
The HipChat user account to use to send messages.
|
|
||||||
Specified as an email address. Must be specified if the
|
|
||||||
`profile` is set to `user`. Not valid for the `integration`
|
|
||||||
or `v1` profiles.
|
|
||||||
|
|
||||||
`message.format`;;
|
|
||||||
The format of the message: `text` or `html`.
|
|
||||||
Defaults to `html`.
|
|
||||||
|
|
||||||
`message.color`;;
|
|
||||||
The background color of the notification in the room.
|
|
||||||
Defaults to `yellow`.
|
|
||||||
`message.notify`;;
|
|
||||||
Indicates whether people in the room should be
|
|
||||||
actively notified. Defaults to `false`.
|
|
||||||
|
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
[[slack-notification-settings]]
|
[[slack-notification-settings]]
|
||||||
==== Slack Notification Settings
|
==== Slack Notification Settings
|
||||||
|
|
|
@ -16,8 +16,8 @@ serve as a model for a templated email body.
|
||||||
|
|
||||||
{watcher} supports the following types of actions:
|
{watcher} supports the following types of actions:
|
||||||
<<actions-email, email>>, <<actions-webhook, webhook>>, <<actions-index, index>>,
|
<<actions-email, email>>, <<actions-webhook, webhook>>, <<actions-index, index>>,
|
||||||
<<actions-logging, logging>>, <<actions-hipchat, hipchat>>, <<actions-slack,
|
<<actions-logging, logging>>, <<actions-slack, Slack>>,
|
||||||
Slack>>, and <<actions-pagerduty, pagerduty>>.
|
and <<actions-pagerduty, pagerduty>>.
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
[[actions-ack-throttle]]
|
[[actions-ack-throttle]]
|
||||||
|
@ -271,9 +271,6 @@ include::actions/index.asciidoc[]
|
||||||
:edit_url: https://github.com/elastic/elasticsearch/edit/{branch}/x-pack/docs/en/watcher/actions/logging.asciidoc
|
:edit_url: https://github.com/elastic/elasticsearch/edit/{branch}/x-pack/docs/en/watcher/actions/logging.asciidoc
|
||||||
include::actions/logging.asciidoc[]
|
include::actions/logging.asciidoc[]
|
||||||
|
|
||||||
:edit_url: https://github.com/elastic/elasticsearch/edit/{branch}/x-pack/docs/en/watcher/actions/hipchat.asciidoc
|
|
||||||
include::actions/hipchat.asciidoc[]
|
|
||||||
|
|
||||||
:edit_url: https://github.com/elastic/elasticsearch/edit/{branch}/x-pack/docs/en/watcher/actions/slack.asciidoc
|
:edit_url: https://github.com/elastic/elasticsearch/edit/{branch}/x-pack/docs/en/watcher/actions/slack.asciidoc
|
||||||
include::actions/slack.asciidoc[]
|
include::actions/slack.asciidoc[]
|
||||||
|
|
||||||
|
@ -292,7 +289,7 @@ that even despite the exact same version, an OpenJDK distribution contains
|
||||||
different parts under different Linux distributions.
|
different parts under different Linux distributions.
|
||||||
|
|
||||||
This can lead to issues with any action or input that uses TLS, like the `jira`,
|
This can lead to issues with any action or input that uses TLS, like the `jira`,
|
||||||
`pagerduty`, `slack`, `hipchat` or `webhook` one, because of missing CA certs.
|
`pagerduty`, `slack`, or `webhook` one, because of missing CA certs.
|
||||||
If you encounter TLS errors, when writing watches that connect to TLS endpoints,
|
If you encounter TLS errors, when writing watches that connect to TLS endpoints,
|
||||||
you should try to upgrade to the latest available OpenJDK distribution for your
|
you should try to upgrade to the latest available OpenJDK distribution for your
|
||||||
platform and if that does not help, try to upgrade to Oracle JDK.
|
platform and if that does not help, try to upgrade to Oracle JDK.
|
||||||
|
|
|
@ -1,393 +0,0 @@
|
||||||
[[actions-hipchat]]
|
|
||||||
=== HipChat Action
|
|
||||||
|
|
||||||
Use the `hipchat` action to send messages to https://www.hipchat.com[HipChat]
|
|
||||||
rooms or users. To send HipChat messages, you must
|
|
||||||
<<configuring-hipchat, configure at least one HipChat account>> in `elasticsearch.yml`.
|
|
||||||
|
|
||||||
[[configuring-hipchat-actions]]
|
|
||||||
==== Configuring HipChat Actions
|
|
||||||
|
|
||||||
You configure HipChat actions in a `actions` array. Action-specific attributes
|
|
||||||
are specified using the `hipchat` keyword. You must specify the `message`
|
|
||||||
attribute for all `hipchat` actions. If you omit the `account` attribute, the
|
|
||||||
message is sent using the default HipChat account configured in
|
|
||||||
`elasticsearch.yml`.
|
|
||||||
|
|
||||||
For example, the following action is configured to send messages using a HipChat
|
|
||||||
account that uses the <<hipchat-api-integration, integration>> profile. Because
|
|
||||||
this type of account can only send messages to a specific room, the only required
|
|
||||||
attribute is the message itself:
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
--------------------------------------------------
|
|
||||||
"actions" : {
|
|
||||||
"notify-hipchat" : {
|
|
||||||
"transform" : { ... },
|
|
||||||
"throttle_period" : "5m",
|
|
||||||
"hipchat" : {
|
|
||||||
"account" : "integration-account", <1>
|
|
||||||
"message" : {
|
|
||||||
"body" : "Encountered {{ctx.payload.hits.total.value}} errors in the last 5 minutes (facepalm)", <2>
|
|
||||||
"format" : "text",
|
|
||||||
"color" : "red",
|
|
||||||
"notify" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--------------------------------------------------
|
|
||||||
// NOTCONSOLE
|
|
||||||
<1> The name of a HipChat account configured in `elasticsearch.yml`.
|
|
||||||
<2> The message you want to send to HipChat.
|
|
||||||
|
|
||||||
To send messages with a HipChat account that uses the <<hipchat-api-user, user>>
|
|
||||||
profile, you need to specify what rooms and users you want to send the message to.
|
|
||||||
For example, the following action is configured to send messages to the
|
|
||||||
`mission-control` and `devops` rooms as well as the user `website-admin@example.com`.
|
|
||||||
(To send to multiple users or rooms, specify an array of strings):
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
--------------------------------------------------
|
|
||||||
"actions" : {
|
|
||||||
"notify-hipchat" : {
|
|
||||||
"transform" : { ... },
|
|
||||||
"throttle_period" : "5m",
|
|
||||||
"hipchat" : {
|
|
||||||
"account" : "user-account",
|
|
||||||
"message" : {
|
|
||||||
"room" : [ "mission-control", "devops" ],
|
|
||||||
"user" : "website-admin@example.com",
|
|
||||||
"body" : "Encountered {{ctx.payload.hits.total.value}} errors in the last 5 minutes (facepalm)",
|
|
||||||
"format" : "text",
|
|
||||||
"color" : "red",
|
|
||||||
"notify" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--------------------------------------------------
|
|
||||||
// NOTCONSOLE
|
|
||||||
|
|
||||||
To send messages with a HipChat account that uses the <<hipchat-api-v1, v1>>
|
|
||||||
profile, you need to specify what room or rooms you want to send the message to.
|
|
||||||
For example, the following action is configured to send messages to the
|
|
||||||
`server-status` room. (To send to multiple rooms, specify an array of strings.)
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
--------------------------------------------------
|
|
||||||
"actions" : {
|
|
||||||
"notify-hipchat" : {
|
|
||||||
"transform" : { ... },
|
|
||||||
"throttle_period" : "5m",
|
|
||||||
"hipchat" : {
|
|
||||||
"account" : "v1-account",
|
|
||||||
"message" : {
|
|
||||||
"from" : "Watcher",
|
|
||||||
"room" : [ "server-status", "infra-team" ],
|
|
||||||
"body" : "Encountered {{ctx.payload.hits.total.value}} errors in the last 5 minutes (facepalm)",
|
|
||||||
"format" : "text",
|
|
||||||
"color" : "red",
|
|
||||||
"notify" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--------------------------------------------------
|
|
||||||
// NOTCONSOLE
|
|
||||||
|
|
||||||
[[hipchat-action-attributes]]
|
|
||||||
==== HipChat Action Attributes
|
|
||||||
|
|
||||||
[cols=",^,,", options="header"]
|
|
||||||
|======
|
|
||||||
| Name |Required | Default | Description
|
|
||||||
|
|
||||||
| `account` | no | Default account | The HipChat account to use to send the message.
|
|
||||||
|
|
||||||
| `proxy.host` | no | - | The proxy host to use (only in combination with `proxy.port`)
|
|
||||||
|
|
||||||
| `proxy.port` | no | - | The proxy port to use (only in combination with `proxy.host`)
|
|
||||||
|
|
||||||
| `message.body` | yes | - | The message content. Can contain up to 1000 characters.
|
|
||||||
|
|
||||||
| `message.format` | no | html | The format of the message: `text` or `html`.
|
|
||||||
|
|
||||||
| `message.color` | no | yellow | The background color of the notification in the room:
|
|
||||||
`gray`, `green`, `purple`, `red`, `yellow`.
|
|
||||||
|
|
||||||
| `message.notify` | no | false | Indicates whether people in the room should be actively
|
|
||||||
notified
|
|
||||||
|
|
||||||
| `message.from` | no | the watch ID | The name that appears as the notification sender. Only
|
|
||||||
valid for accounts that use the v1 profile.
|
|
||||||
|
|
||||||
| `message.room` | no | - | The rooms that the notification should go to. Accepts
|
|
||||||
a string value or an array of string values. Must be
|
|
||||||
specified when using the v1 profile. At least one room
|
|
||||||
or user must be specified when using the `user` profile.
|
|
||||||
Not valid for the `integration` profile.
|
|
||||||
|
|
||||||
| `message.user` | no | - | The users that the notification should go to. Accepts
|
|
||||||
a string value or an array of string values. At least
|
|
||||||
one room or user must be specified when using the `user`
|
|
||||||
profile. Not valid for the `integration` or `v1` profiles.
|
|
||||||
|======
|
|
||||||
|
|
||||||
|
|
||||||
[[configuring-hipchat]]
|
|
||||||
==== Configuring HipChat Accounts
|
|
||||||
|
|
||||||
You configure the accounts {watcher} can use to communicate with HipChat in the
|
|
||||||
`xpack.notification.hipchat` namespace in `elasticsearch.yml`. Both
|
|
||||||
https://www.hipchat.com/docs/api[v1] and
|
|
||||||
https://www.hipchat.com/docs/apiv2[v2] HipChat APIs are supported.
|
|
||||||
|
|
||||||
{watcher} provides three HipChat API profiles:
|
|
||||||
|
|
||||||
<<hipchat-api-integration,integration>>::
|
|
||||||
Sends messages to a specific room using HipChat's v2 API
|
|
||||||
https://www.hipchat.com/docs/apiv2/method/send_room_notification[Send room
|
|
||||||
notification].
|
|
||||||
|
|
||||||
<<hipchat-api-user, user>>::
|
|
||||||
Sends messages as a particular user through the HipChat v2 API. Enables you to
|
|
||||||
send messages to arbitrary rooms or users.
|
|
||||||
|
|
||||||
<<hipchat-api-v1, v1>>::
|
|
||||||
Sends messages to rooms using HipChat's v1 API
|
|
||||||
https://www.hipchat.com/docs/api/method/rooms/message[rooms/message].
|
|
||||||
+
|
|
||||||
NOTE: The `v1` profile is provided because it is simple to set up and this API
|
|
||||||
is familiar to many users. That said, HipChat has deprecated the v1 API
|
|
||||||
and is encouraging users to migrate to v2. Both the `integration` and
|
|
||||||
`user` profiles are based on the HipChat v2 API.
|
|
||||||
|
|
||||||
If you configure multiple HipChat accounts, you either need to set a default
|
|
||||||
HipChat account or specify which account the notification should be sent with
|
|
||||||
in the <<actions-hipchat, hipchat>> action.
|
|
||||||
|
|
||||||
deprecated[Storing the `auth_token` in the configuration file or using via updating the settings now is deprecated, as you should use the keystore for this, see {ref}/secure-settings.html[secure settings]]
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
xpack.notification.hipchat:
|
|
||||||
default_account: team1
|
|
||||||
account:
|
|
||||||
team1:
|
|
||||||
...
|
|
||||||
team2:
|
|
||||||
...
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
[[hipchat-api-integration]]
|
|
||||||
===== Using the Hipchat Integration Profile
|
|
||||||
|
|
||||||
You can use the `integration` profile to send messages to specific rooms. When
|
|
||||||
you set an account's profile to `integration`, the messages are sent through
|
|
||||||
HipChat's v2 https://www.hipchat.com/docs/apiv2/method/send_room_notification[
|
|
||||||
Send room notification] API.
|
|
||||||
|
|
||||||
When you use the `integration` profile, you need to configure a separate HipChat
|
|
||||||
account for each room you want to send messages--the account configuration
|
|
||||||
contains a room-specific authentication token. Alternatively, you can use the
|
|
||||||
<<hipchat-api-user, `user`>> or <<hipchat-api-v1, `v1`>> profile to send messages
|
|
||||||
to multiple rooms.
|
|
||||||
|
|
||||||
NOTE: The `integration` profile only supports sending messages to rooms, it does
|
|
||||||
not support sending private messages. Use the <<hipchat-api-user, `user`>>
|
|
||||||
profile to notify a particular HipChat user.
|
|
||||||
|
|
||||||
You need a room-specific authentication token to configure an `integration`
|
|
||||||
account. To generate an authentication token:
|
|
||||||
|
|
||||||
. Log in to http://hipchat.com[hipchat.com] or your HipChat server as a group
|
|
||||||
administrator.
|
|
||||||
. Go to *Group admin > Rooms*.
|
|
||||||
. Click the name of the room you want to send messages to.
|
|
||||||
. Click the *Tokens* link.
|
|
||||||
. Enter a name for the token in the *Label* field.
|
|
||||||
+
|
|
||||||
image::images/hipchat-generate-room-token.jpg[]
|
|
||||||
. Select the *Send Notification* scope.
|
|
||||||
. Click *Create*.
|
|
||||||
. Copy the generated token so you can paste it into your HipChat account
|
|
||||||
configuration in `elasticsearch.yml`.
|
|
||||||
+
|
|
||||||
image::images/hipchat-copy-room-token.jpg[]
|
|
||||||
|
|
||||||
To configure a HipChat account that uses the `integration` profile:
|
|
||||||
|
|
||||||
. Set the `type` to `integration`.
|
|
||||||
. Set `room` to the name of the room you want to send messages to.
|
|
||||||
. Set `auth_token` to the room-specific authentication token.
|
|
||||||
|
|
||||||
For example, the following snippet configures an account called
|
|
||||||
`notify-monitoring` that sends messages to the `monitoring` room:
|
|
||||||
|
|
||||||
[source,shell]
|
|
||||||
--------------------------------------------------
|
|
||||||
bin/elasticsearch-keystore add xpack.notification.hipchat.account.notify-monitoring.secure_auth_token
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
xpack.notification.hipchat:
|
|
||||||
account:
|
|
||||||
notify-monitoring:
|
|
||||||
profile: integration
|
|
||||||
room: monitoring
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
You can also specify defaults for the {ref}/notification-settings.html#hipchat-account-attributes[
|
|
||||||
message attributes]:
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
xpack.notification.hipchat:
|
|
||||||
account:
|
|
||||||
notify-monitoring:
|
|
||||||
profile: integration
|
|
||||||
room: monitoring
|
|
||||||
message:
|
|
||||||
format: text
|
|
||||||
color: blue
|
|
||||||
notify: true
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
[[hipchat-api-user]]
|
|
||||||
===== Using the HipChat User Profile
|
|
||||||
|
|
||||||
You can use the `user` profile to send messages to rooms as well as individual
|
|
||||||
HipChat users. When you set an account's profile to `user`, {watcher} sends
|
|
||||||
messages as a particular user through the HipChat v2 API.
|
|
||||||
|
|
||||||
Before you can configure a `user` account, you need to:
|
|
||||||
|
|
||||||
. Add a HipChat user for {watcher}. When setting the user name, keep in mind that
|
|
||||||
the messages are sent on behalf of this user.
|
|
||||||
. Create an API token for the {watcher} user:
|
|
||||||
.. Log in to HipChat as the {watcher} user.
|
|
||||||
.. Go to `https://<hipchat-server>/account/api`. For example,
|
|
||||||
`https://www.hipchat.com/account/api`.
|
|
||||||
.. Confirm the user password.
|
|
||||||
.. Enter a name for the token in the *Label* field.
|
|
||||||
+
|
|
||||||
image::images/hipchat-generate-user-token.jpg[]
|
|
||||||
. Select the *Send Notification* and *Send Message* scopes.
|
|
||||||
. Click *Create*.
|
|
||||||
. Copy the generated token so you can paste it into your HipChat account
|
|
||||||
configuration in `elasticsearch.yml`.
|
|
||||||
+
|
|
||||||
image::images/hipchat-copy-room-token.jpg[]
|
|
||||||
|
|
||||||
To configure a HipChat account that uses the `user` profile:
|
|
||||||
|
|
||||||
. Set the `type` to `user`.
|
|
||||||
. Set `user` to the email address associated with the {watcher} user.
|
|
||||||
. Set `auth_token` to the {watcher} user's authentication token.
|
|
||||||
|
|
||||||
For example, the following configuration creates an account called
|
|
||||||
`notify-monitoring` that sends messages to the `monitoring` room:
|
|
||||||
|
|
||||||
[source,shell]
|
|
||||||
--------------------------------------------------
|
|
||||||
bin/elasticsearch-keystore add xpack.notification.hipchat.account.notify-monitoring.secure_auth_token
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
xpack.notification.hipchat:
|
|
||||||
account:
|
|
||||||
notify-monitoring:
|
|
||||||
profile: user
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
You can also specify defaults for the <{ref}/notification-settings.html#hipchat-account-attributes[
|
|
||||||
message attributes]:
|
|
||||||
|
|
||||||
[source,shell]
|
|
||||||
--------------------------------------------------
|
|
||||||
bin/elasticsearch-keystore add xpack.notification.hipchat.account.notify-monitoring.secure_auth_token
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
xpack.notification.hipchat:
|
|
||||||
account:
|
|
||||||
notify-monitoring:
|
|
||||||
profile: user
|
|
||||||
message:
|
|
||||||
format: text
|
|
||||||
color: blue
|
|
||||||
notify: true
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
[[hipchat-api-v1]]
|
|
||||||
===== Using the HipChat v1 Profile
|
|
||||||
|
|
||||||
You can use the `v1` profile to send messages to particular rooms. When you set
|
|
||||||
an account's profile to `v1`, messages are sent through HipChat's v1
|
|
||||||
https://www.hipchat.com/docs/api/method/rooms/message[rooms/message] API.
|
|
||||||
|
|
||||||
WARNING: The `v1` profile uses a deprecated API that is expected to be removed
|
|
||||||
by HipChat in the future.
|
|
||||||
|
|
||||||
The `v1` profile only supports sending messages to rooms, it does not support
|
|
||||||
sending private messages. Use the <<hipchat-api-user, `user`>> profile to send
|
|
||||||
private messages to HipChat users.
|
|
||||||
|
|
||||||
Before you can configure a `v1` account, you need to generate a `v1` API token:
|
|
||||||
|
|
||||||
. Log in to your HipChat server as a group admin.
|
|
||||||
. Go to `https://<hipchat-server>/admin/api`. For example,
|
|
||||||
`https://hipchat.com/admin/api`.
|
|
||||||
. Confirm your admin password.
|
|
||||||
. Select the *Notification* type.
|
|
||||||
+
|
|
||||||
image::images/hipchat-generate-v1-token.jpg[]
|
|
||||||
. Enter a name for the token in the *Label* field.
|
|
||||||
. Click *Create*.
|
|
||||||
. Copy the generated token so you can paste it into your HipChat account
|
|
||||||
configuration in `elasticsearch.yml`.
|
|
||||||
+
|
|
||||||
image::images/hipchat-copy-v1-token.jpg[]
|
|
||||||
|
|
||||||
To configure a HipChat account that uses the `v1` profile:
|
|
||||||
|
|
||||||
. Set the `type` to `v1`.
|
|
||||||
. Set `auth_token` to the v1 authentication token you generated.
|
|
||||||
|
|
||||||
For example, the following configuration creates an account called
|
|
||||||
`notify-monitoring`:
|
|
||||||
|
|
||||||
[source,shell]
|
|
||||||
--------------------------------------------------
|
|
||||||
bin/elasticsearch-keystore add xpack.notification.hipchat.account.notify-monitoring.secure_auth_token
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
xpack.notification.hipchat:
|
|
||||||
account:
|
|
||||||
notify-monitoring:
|
|
||||||
profile: v1
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
You can also specify defaults for the {ref}/notification-settings.html#hipchat-account-attributes[
|
|
||||||
message attributes].
|
|
||||||
|
|
||||||
[source,yaml]
|
|
||||||
--------------------------------------------------
|
|
||||||
xpack.notification.hipchat:
|
|
||||||
account:
|
|
||||||
notify-monitoring:
|
|
||||||
profile: v1
|
|
||||||
message:
|
|
||||||
format: text
|
|
||||||
color: blue
|
|
||||||
notify: true
|
|
||||||
--------------------------------------------------
|
|
|
@ -202,7 +202,7 @@ Actions are associated with a watch and are executed as part of the watch execut
|
||||||
only when the watch condition is met.
|
only when the watch condition is met.
|
||||||
|
|
||||||
{watcher} supports the following action types: <<actions-email, email>>,
|
{watcher} supports the following action types: <<actions-email, email>>,
|
||||||
<<actions-slack, slack>>, <<actions-hipchat, hipchat>>, <<actions-pagerduty, pagerduty>>,
|
<<actions-slack, slack>>, <<actions-pagerduty, pagerduty>>,
|
||||||
<<actions-index, index>>, <<actions-logging, logging>>, and <<actions-webhook, webhook>>.
|
<<actions-index, index>>, <<actions-logging, logging>>, and <<actions-webhook, webhook>>.
|
||||||
|
|
||||||
To use the `email` action, you need to <<configuring-email, configure an email account>>
|
To use the `email` action, you need to <<configuring-email, configure an email account>>
|
||||||
|
|
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 147 KiB |
|
@ -333,63 +333,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hipchat" : {
|
|
||||||
"type": "object",
|
|
||||||
"dynamic": true,
|
|
||||||
"properties": {
|
|
||||||
"account": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"sent_messages": {
|
|
||||||
"type": "nested",
|
|
||||||
"include_in_parent": true,
|
|
||||||
"dynamic": true,
|
|
||||||
"properties": {
|
|
||||||
"status": {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"reason": {
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
"request" : {
|
|
||||||
"type" : "object",
|
|
||||||
"enabled" : false
|
|
||||||
},
|
|
||||||
"response" : {
|
|
||||||
"type" : "object",
|
|
||||||
"enabled" : false
|
|
||||||
},
|
|
||||||
"room" : {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"user" : {
|
|
||||||
"type": "keyword"
|
|
||||||
},
|
|
||||||
"message" : {
|
|
||||||
"type" : "object",
|
|
||||||
"dynamic" : true,
|
|
||||||
"properties" : {
|
|
||||||
"message_format" : {
|
|
||||||
"type" : "keyword"
|
|
||||||
},
|
|
||||||
"color" : {
|
|
||||||
"type" : "keyword"
|
|
||||||
},
|
|
||||||
"notify" : {
|
|
||||||
"type" : "boolean"
|
|
||||||
},
|
|
||||||
"message" : {
|
|
||||||
"type" : "text"
|
|
||||||
},
|
|
||||||
"from" : {
|
|
||||||
"type" : "text"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"jira" : {
|
"jira" : {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"dynamic": true,
|
"dynamic": true,
|
||||||
|
|
|
@ -82,8 +82,6 @@ import org.elasticsearch.xpack.core.watcher.trigger.TriggerEvent;
|
||||||
import org.elasticsearch.xpack.core.watcher.watch.Watch;
|
import org.elasticsearch.xpack.core.watcher.watch.Watch;
|
||||||
import org.elasticsearch.xpack.watcher.actions.email.EmailAction;
|
import org.elasticsearch.xpack.watcher.actions.email.EmailAction;
|
||||||
import org.elasticsearch.xpack.watcher.actions.email.EmailActionFactory;
|
import org.elasticsearch.xpack.watcher.actions.email.EmailActionFactory;
|
||||||
import org.elasticsearch.xpack.watcher.actions.hipchat.HipChatAction;
|
|
||||||
import org.elasticsearch.xpack.watcher.actions.hipchat.HipChatActionFactory;
|
|
||||||
import org.elasticsearch.xpack.watcher.actions.index.IndexAction;
|
import org.elasticsearch.xpack.watcher.actions.index.IndexAction;
|
||||||
import org.elasticsearch.xpack.watcher.actions.index.IndexActionFactory;
|
import org.elasticsearch.xpack.watcher.actions.index.IndexActionFactory;
|
||||||
import org.elasticsearch.xpack.watcher.actions.jira.JiraAction;
|
import org.elasticsearch.xpack.watcher.actions.jira.JiraAction;
|
||||||
|
@ -135,7 +133,6 @@ import org.elasticsearch.xpack.watcher.notification.email.attachment.EmailAttach
|
||||||
import org.elasticsearch.xpack.watcher.notification.email.attachment.HttpEmailAttachementParser;
|
import org.elasticsearch.xpack.watcher.notification.email.attachment.HttpEmailAttachementParser;
|
||||||
import org.elasticsearch.xpack.watcher.notification.email.attachment.ReportingAttachmentParser;
|
import org.elasticsearch.xpack.watcher.notification.email.attachment.ReportingAttachmentParser;
|
||||||
import org.elasticsearch.xpack.watcher.notification.email.support.BodyPartSource;
|
import org.elasticsearch.xpack.watcher.notification.email.support.BodyPartSource;
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatService;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.jira.JiraService;
|
import org.elasticsearch.xpack.watcher.notification.jira.JiraService;
|
||||||
import org.elasticsearch.xpack.watcher.notification.pagerduty.PagerDutyService;
|
import org.elasticsearch.xpack.watcher.notification.pagerduty.PagerDutyService;
|
||||||
import org.elasticsearch.xpack.watcher.notification.slack.SlackService;
|
import org.elasticsearch.xpack.watcher.notification.slack.SlackService;
|
||||||
|
@ -277,13 +274,11 @@ public class Watcher extends Plugin implements ActionPlugin, ScriptPlugin, Reloa
|
||||||
|
|
||||||
// notification
|
// notification
|
||||||
EmailService emailService = new EmailService(settings, cryptoService, clusterService.getClusterSettings());
|
EmailService emailService = new EmailService(settings, cryptoService, clusterService.getClusterSettings());
|
||||||
HipChatService hipChatService = new HipChatService(settings, httpClient, clusterService.getClusterSettings());
|
|
||||||
JiraService jiraService = new JiraService(settings, httpClient, clusterService.getClusterSettings());
|
JiraService jiraService = new JiraService(settings, httpClient, clusterService.getClusterSettings());
|
||||||
SlackService slackService = new SlackService(settings, httpClient, clusterService.getClusterSettings());
|
SlackService slackService = new SlackService(settings, httpClient, clusterService.getClusterSettings());
|
||||||
PagerDutyService pagerDutyService = new PagerDutyService(settings, httpClient, clusterService.getClusterSettings());
|
PagerDutyService pagerDutyService = new PagerDutyService(settings, httpClient, clusterService.getClusterSettings());
|
||||||
|
|
||||||
reloadableServices.add(emailService);
|
reloadableServices.add(emailService);
|
||||||
reloadableServices.add(hipChatService);
|
|
||||||
reloadableServices.add(jiraService);
|
reloadableServices.add(jiraService);
|
||||||
reloadableServices.add(slackService);
|
reloadableServices.add(slackService);
|
||||||
reloadableServices.add(pagerDutyService);
|
reloadableServices.add(pagerDutyService);
|
||||||
|
@ -315,7 +310,6 @@ public class Watcher extends Plugin implements ActionPlugin, ScriptPlugin, Reloa
|
||||||
actionFactoryMap.put(WebhookAction.TYPE, new WebhookActionFactory(httpClient, templateEngine));
|
actionFactoryMap.put(WebhookAction.TYPE, new WebhookActionFactory(httpClient, templateEngine));
|
||||||
actionFactoryMap.put(IndexAction.TYPE, new IndexActionFactory(settings, client));
|
actionFactoryMap.put(IndexAction.TYPE, new IndexActionFactory(settings, client));
|
||||||
actionFactoryMap.put(LoggingAction.TYPE, new LoggingActionFactory(templateEngine));
|
actionFactoryMap.put(LoggingAction.TYPE, new LoggingActionFactory(templateEngine));
|
||||||
actionFactoryMap.put(HipChatAction.TYPE, new HipChatActionFactory(templateEngine, hipChatService));
|
|
||||||
actionFactoryMap.put(JiraAction.TYPE, new JiraActionFactory(templateEngine, jiraService));
|
actionFactoryMap.put(JiraAction.TYPE, new JiraActionFactory(templateEngine, jiraService));
|
||||||
actionFactoryMap.put(SlackAction.TYPE, new SlackActionFactory(templateEngine, slackService));
|
actionFactoryMap.put(SlackAction.TYPE, new SlackActionFactory(templateEngine, slackService));
|
||||||
actionFactoryMap.put(PagerDutyAction.TYPE, new PagerDutyActionFactory(templateEngine, pagerDutyService));
|
actionFactoryMap.put(PagerDutyAction.TYPE, new PagerDutyActionFactory(templateEngine, pagerDutyService));
|
||||||
|
@ -420,7 +414,7 @@ public class Watcher extends Plugin implements ActionPlugin, ScriptPlugin, Reloa
|
||||||
|
|
||||||
return Arrays.asList(registry, inputRegistry, historyStore, triggerService, triggeredWatchParser,
|
return Arrays.asList(registry, inputRegistry, historyStore, triggerService, triggeredWatchParser,
|
||||||
watcherLifeCycleService, executionService, triggerEngineListener, watcherService, watchParser,
|
watcherLifeCycleService, executionService, triggerEngineListener, watcherService, watchParser,
|
||||||
configuredTriggerEngine, triggeredWatchStore, watcherSearchTemplateService, slackService, pagerDutyService, hipChatService);
|
configuredTriggerEngine, triggeredWatchStore, watcherSearchTemplateService, slackService, pagerDutyService);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TriggerEngine getTriggerEngine(Clock clock, ScheduleRegistry scheduleRegistry) {
|
protected TriggerEngine getTriggerEngine(Clock clock, ScheduleRegistry scheduleRegistry) {
|
||||||
|
@ -481,7 +475,6 @@ public class Watcher extends Plugin implements ActionPlugin, ScriptPlugin, Reloa
|
||||||
settings.addAll(SlackService.getSettings());
|
settings.addAll(SlackService.getSettings());
|
||||||
settings.addAll(EmailService.getSettings());
|
settings.addAll(EmailService.getSettings());
|
||||||
settings.addAll(HtmlSanitizer.getSettings());
|
settings.addAll(HtmlSanitizer.getSettings());
|
||||||
settings.addAll(HipChatService.getSettings());
|
|
||||||
settings.addAll(JiraService.getSettings());
|
settings.addAll(JiraService.getSettings());
|
||||||
settings.addAll(PagerDutyService.getSettings());
|
settings.addAll(PagerDutyService.getSettings());
|
||||||
settings.add(ReportingAttachmentParser.RETRIES_SETTING);
|
settings.add(ReportingAttachmentParser.RETRIES_SETTING);
|
||||||
|
|
|
@ -6,19 +6,18 @@
|
||||||
package org.elasticsearch.xpack.watcher.actions;
|
package org.elasticsearch.xpack.watcher.actions;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
import org.elasticsearch.common.collect.MapBuilder;
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.email.EmailTemplate;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.pagerduty.IncidentEvent;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.slack.message.SlackMessage;
|
|
||||||
import org.elasticsearch.xpack.watcher.actions.email.EmailAction;
|
import org.elasticsearch.xpack.watcher.actions.email.EmailAction;
|
||||||
import org.elasticsearch.xpack.watcher.actions.hipchat.HipChatAction;
|
|
||||||
import org.elasticsearch.xpack.watcher.actions.index.IndexAction;
|
import org.elasticsearch.xpack.watcher.actions.index.IndexAction;
|
||||||
import org.elasticsearch.xpack.watcher.actions.jira.JiraAction;
|
import org.elasticsearch.xpack.watcher.actions.jira.JiraAction;
|
||||||
import org.elasticsearch.xpack.watcher.actions.logging.LoggingAction;
|
import org.elasticsearch.xpack.watcher.actions.logging.LoggingAction;
|
||||||
import org.elasticsearch.xpack.watcher.actions.pagerduty.PagerDutyAction;
|
import org.elasticsearch.xpack.watcher.actions.pagerduty.PagerDutyAction;
|
||||||
import org.elasticsearch.xpack.watcher.actions.slack.SlackAction;
|
import org.elasticsearch.xpack.watcher.actions.slack.SlackAction;
|
||||||
import org.elasticsearch.xpack.watcher.actions.webhook.WebhookAction;
|
import org.elasticsearch.xpack.watcher.actions.webhook.WebhookAction;
|
||||||
|
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
|
||||||
|
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
|
||||||
|
import org.elasticsearch.xpack.watcher.notification.email.EmailTemplate;
|
||||||
|
import org.elasticsearch.xpack.watcher.notification.pagerduty.IncidentEvent;
|
||||||
|
import org.elasticsearch.xpack.watcher.notification.slack.message.SlackMessage;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -63,22 +62,6 @@ public final class ActionBuilders {
|
||||||
return LoggingAction.builder(text);
|
return LoggingAction.builder(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HipChatAction.Builder hipchatAction(String message) {
|
|
||||||
return hipchatAction(new TextTemplate(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HipChatAction.Builder hipchatAction(String account, String body) {
|
|
||||||
return hipchatAction(account, new TextTemplate(body));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HipChatAction.Builder hipchatAction(TextTemplate body) {
|
|
||||||
return hipchatAction(null, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HipChatAction.Builder hipchatAction(String account, TextTemplate body) {
|
|
||||||
return HipChatAction.builder(account, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SlackAction.Builder slackAction(String account, SlackMessage.Template.Builder message) {
|
public static SlackAction.Builder slackAction(String account, SlackMessage.Template.Builder message) {
|
||||||
return slackAction(account, message.build());
|
return slackAction(account, message.build());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.actions.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.actions.Action;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.actions.ExecutableAction;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.watch.Payload;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatAccount;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatService;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.SentMessages;
|
|
||||||
import org.elasticsearch.xpack.watcher.support.Variables;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ExecutableHipChatAction extends ExecutableAction<HipChatAction> {
|
|
||||||
|
|
||||||
private final TextTemplateEngine templateEngine;
|
|
||||||
private final HipChatService hipchatService;
|
|
||||||
|
|
||||||
public ExecutableHipChatAction(HipChatAction action, Logger logger, HipChatService hipchatService,
|
|
||||||
TextTemplateEngine templateEngine) {
|
|
||||||
super(action, logger);
|
|
||||||
this.hipchatService = hipchatService;
|
|
||||||
this.templateEngine = templateEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Action.Result execute(final String actionId, WatchExecutionContext ctx, Payload payload) throws Exception {
|
|
||||||
|
|
||||||
HipChatAccount account = hipchatService.getAccount(action.account);
|
|
||||||
// lets validate the message again, in case the hipchat service were updated since the
|
|
||||||
// watch/action were created.
|
|
||||||
account.validateParsedTemplate(ctx.id().watchId(), actionId, action.message);
|
|
||||||
|
|
||||||
Map<String, Object> model = Variables.createCtxParamsMap(ctx, payload);
|
|
||||||
HipChatMessage message = account.render(ctx.id().watchId(), actionId, templateEngine, action.message, model);
|
|
||||||
|
|
||||||
if (ctx.simulateAction(actionId)) {
|
|
||||||
return new HipChatAction.Result.Simulated(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
SentMessages sentMessages = account.send(message, action.proxy);
|
|
||||||
return new HipChatAction.Result.Executed(sentMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,253 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.actions.hipchat;
|
|
||||||
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.ParseField;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.actions.Action;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.SentMessages;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class HipChatAction implements Action {
|
|
||||||
|
|
||||||
public static final String TYPE = "hipchat";
|
|
||||||
|
|
||||||
@Nullable final String account;
|
|
||||||
@Nullable final HttpProxy proxy;
|
|
||||||
final HipChatMessage.Template message;
|
|
||||||
|
|
||||||
public HipChatAction(@Nullable String account, HipChatMessage.Template message, @Nullable HttpProxy proxy) {
|
|
||||||
this.account = account;
|
|
||||||
this.message = message;
|
|
||||||
this.proxy = proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
HipChatAction that = (HipChatAction) o;
|
|
||||||
|
|
||||||
return Objects.equals(account, that.account) &&
|
|
||||||
Objects.equals(message, that.message) &&
|
|
||||||
Objects.equals(proxy, that.proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(account, message, proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
builder.startObject();
|
|
||||||
if (account != null) {
|
|
||||||
builder.field(Field.ACCOUNT.getPreferredName(), account);
|
|
||||||
}
|
|
||||||
if (proxy != null) {
|
|
||||||
proxy.toXContent(builder, params);
|
|
||||||
}
|
|
||||||
builder.field(Field.MESSAGE.getPreferredName(), message);
|
|
||||||
return builder.endObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HipChatAction parse(String watchId, String actionId, XContentParser parser) throws IOException {
|
|
||||||
String account = null;
|
|
||||||
HipChatMessage.Template message = null;
|
|
||||||
HttpProxy proxy = null;
|
|
||||||
|
|
||||||
String currentFieldName = null;
|
|
||||||
XContentParser.Token token;
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
|
||||||
currentFieldName = parser.currentName();
|
|
||||||
} else if (Field.ACCOUNT.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
if (token == XContentParser.Token.VALUE_STRING) {
|
|
||||||
account = parser.text();
|
|
||||||
} else {
|
|
||||||
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. expected [{}] to be of type string, but " +
|
|
||||||
"found [{}] instead", TYPE, watchId, actionId, Field.ACCOUNT.getPreferredName(), token);
|
|
||||||
}
|
|
||||||
} else if (Field.PROXY.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
proxy = HttpProxy.parse(parser);
|
|
||||||
} else if (Field.MESSAGE.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
try {
|
|
||||||
message = HipChatMessage.Template.parse(parser);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. failed to parse [{}] field", e, TYPE,
|
|
||||||
watchId, actionId, Field.MESSAGE.getPreferredName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. unexpected token [{}]", TYPE, watchId,
|
|
||||||
actionId, token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message == null) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse [{}] action [{}/{}]. missing required [{}] field", TYPE, watchId,
|
|
||||||
actionId, Field.MESSAGE.getPreferredName());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new HipChatAction(account, message, proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Builder builder(String account, TextTemplate body) {
|
|
||||||
return new Builder(account, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Result {
|
|
||||||
|
|
||||||
class Executed extends Action.Result implements Result {
|
|
||||||
|
|
||||||
private final SentMessages sentMessages;
|
|
||||||
|
|
||||||
public Executed(SentMessages sentMessages) {
|
|
||||||
super(TYPE, status(sentMessages));
|
|
||||||
this.sentMessages = sentMessages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SentMessages sentMessages() {
|
|
||||||
return sentMessages;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return builder.field(type, sentMessages, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Status status(SentMessages sentMessages) {
|
|
||||||
boolean hasSuccesses = false;
|
|
||||||
boolean hasFailures = false;
|
|
||||||
for (SentMessages.SentMessage message : sentMessages) {
|
|
||||||
if (message.isSuccess()) {
|
|
||||||
hasSuccesses = true;
|
|
||||||
} else {
|
|
||||||
hasFailures = true;
|
|
||||||
}
|
|
||||||
if (hasFailures && hasSuccesses) {
|
|
||||||
return Status.PARTIAL_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hasFailures ? Status.FAILURE : Status.SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Simulated extends Action.Result implements Result {
|
|
||||||
|
|
||||||
private final HipChatMessage message;
|
|
||||||
|
|
||||||
protected Simulated(HipChatMessage message) {
|
|
||||||
super(TYPE, Status.SIMULATED);
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HipChatMessage getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return builder.startObject(type)
|
|
||||||
.field(Field.MESSAGE.getPreferredName(), message, params)
|
|
||||||
.endObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder implements Action.Builder<HipChatAction> {
|
|
||||||
|
|
||||||
final String account;
|
|
||||||
final HipChatMessage.Template.Builder messageBuilder;
|
|
||||||
private HttpProxy proxy;
|
|
||||||
|
|
||||||
public Builder(String account, TextTemplate body) {
|
|
||||||
this.account = account;
|
|
||||||
this.messageBuilder = new HipChatMessage.Template.Builder(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder addRooms(TextTemplate... rooms) {
|
|
||||||
messageBuilder.addRooms(rooms);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder addRooms(String... rooms) {
|
|
||||||
TextTemplate[] templates = new TextTemplate[rooms.length];
|
|
||||||
for (int i = 0; i < rooms.length; i++) {
|
|
||||||
templates[i] = new TextTemplate(rooms[i]);
|
|
||||||
}
|
|
||||||
return addRooms(templates);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Builder addUsers(TextTemplate... users) {
|
|
||||||
messageBuilder.addUsers(users);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder addUsers(String... users) {
|
|
||||||
TextTemplate[] templates = new TextTemplate[users.length];
|
|
||||||
for (int i = 0; i < users.length; i++) {
|
|
||||||
templates[i] = new TextTemplate(users[i]);
|
|
||||||
}
|
|
||||||
return addUsers(templates);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setFrom(String from) {
|
|
||||||
messageBuilder.setFrom(from);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setFormat(HipChatMessage.Format format) {
|
|
||||||
messageBuilder.setFormat(format);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setColor(TextTemplate color) {
|
|
||||||
messageBuilder.setColor(color);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setColor(HipChatMessage.Color color) {
|
|
||||||
return setColor(color.asTemplate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setNotify(boolean notify) {
|
|
||||||
messageBuilder.setNotify(notify);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setProxy(HttpProxy proxy) {
|
|
||||||
this.proxy = proxy;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HipChatAction build() {
|
|
||||||
return new HipChatAction(account, messageBuilder.build(), proxy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Field {
|
|
||||||
ParseField ACCOUNT = new ParseField("account");
|
|
||||||
ParseField MESSAGE = new ParseField("message");
|
|
||||||
ParseField PROXY = new ParseField("proxy");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.actions.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.actions.ActionFactory;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatAccount;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatService;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class HipChatActionFactory extends ActionFactory {
|
|
||||||
|
|
||||||
private final TextTemplateEngine templateEngine;
|
|
||||||
private final HipChatService hipchatService;
|
|
||||||
|
|
||||||
public HipChatActionFactory(TextTemplateEngine templateEngine, HipChatService hipchatService) {
|
|
||||||
super(LogManager.getLogger(ExecutableHipChatAction.class));
|
|
||||||
this.templateEngine = templateEngine;
|
|
||||||
this.hipchatService = hipchatService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExecutableHipChatAction parseExecutable(String watchId, String actionId, XContentParser parser) throws IOException {
|
|
||||||
HipChatAction action = HipChatAction.parse(watchId, actionId, parser);
|
|
||||||
HipChatAccount account = hipchatService.getAccount(action.account);
|
|
||||||
account.validateParsedTemplate(watchId, actionId, action.message);
|
|
||||||
return new ExecutableHipChatAction(action, actionLogger, hipchatService, templateEngine);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -300,7 +300,7 @@ public class HttpClient implements Closeable {
|
||||||
Scheme.parse(HttpSettings.PROXY_SCHEME.get(settings)) : Scheme.HTTP;
|
Scheme.parse(HttpSettings.PROXY_SCHEME.get(settings)) : Scheme.HTTP;
|
||||||
int proxyPort = HttpSettings.PROXY_PORT.get(settings);
|
int proxyPort = HttpSettings.PROXY_PORT.get(settings);
|
||||||
if (proxyPort != 0 && Strings.hasText(proxyHost)) {
|
if (proxyPort != 0 && Strings.hasText(proxyHost)) {
|
||||||
logger.info("Using default proxy for http input and slack/hipchat/pagerduty/webhook actions [{}:{}]", proxyHost, proxyPort);
|
logger.info("Using default proxy for http input and slack/pagerduty/webhook actions [{}:{}]", proxyHost, proxyPort);
|
||||||
} else if (proxyPort != 0 ^ Strings.hasText(proxyHost)) {
|
} else if (proxyPort != 0 ^ Strings.hasText(proxyHost)) {
|
||||||
throw new IllegalArgumentException("HTTP proxy requires both settings: [" + HttpSettings.PROXY_HOST.getKey() + "] and [" +
|
throw new IllegalArgumentException("HTTP proxy requires both settings: [" + HttpSettings.PROXY_HOST.getKey() + "] and [" +
|
||||||
HttpSettings.PROXY_PORT.getKey() + "]");
|
HttpSettings.PROXY_PORT.getKey() + "]");
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.settings.SecureSetting;
|
|
||||||
import org.elasticsearch.common.settings.SecureString;
|
|
||||||
import org.elasticsearch.common.settings.Setting;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.settings.SettingsException;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public abstract class HipChatAccount {
|
|
||||||
|
|
||||||
public static final String ROOM_SETTING = HipChatMessage.Field.ROOM.getPreferredName();
|
|
||||||
public static final String DEFAULT_ROOM_SETTING = "message_defaults." + HipChatMessage.Field.ROOM.getPreferredName();
|
|
||||||
public static final String DEFAULT_USER_SETTING = "message_defaults." + HipChatMessage.Field.USER.getPreferredName();
|
|
||||||
public static final String DEFAULT_FROM_SETTING = "message_defaults." + HipChatMessage.Field.FROM.getPreferredName();
|
|
||||||
public static final String DEFAULT_FORMAT_SETTING = "message_defaults." + HipChatMessage.Field.FORMAT.getPreferredName();
|
|
||||||
public static final String DEFAULT_COLOR_SETTING = "message_defaults." + HipChatMessage.Field.COLOR.getPreferredName();
|
|
||||||
public static final String DEFAULT_NOTIFY_SETTING = "message_defaults." + HipChatMessage.Field.NOTIFY.getPreferredName();
|
|
||||||
|
|
||||||
static final Setting<SecureString> SECURE_AUTH_TOKEN_SETTING = SecureSetting.secureString("secure_auth_token", null);
|
|
||||||
|
|
||||||
protected final Logger logger;
|
|
||||||
protected final String name;
|
|
||||||
protected final Profile profile;
|
|
||||||
protected final HipChatServer server;
|
|
||||||
protected final HttpClient httpClient;
|
|
||||||
protected final String authToken;
|
|
||||||
|
|
||||||
protected HipChatAccount(String name, Profile profile, Settings settings, HipChatServer defaultServer, HttpClient httpClient,
|
|
||||||
Logger logger) {
|
|
||||||
this.name = name;
|
|
||||||
this.profile = profile;
|
|
||||||
this.server = new HipChatServer(settings, defaultServer);
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
this.authToken = getAuthToken(name, settings);
|
|
||||||
this.logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getAuthToken(String name, Settings settings) {
|
|
||||||
SecureString secureString = SECURE_AUTH_TOKEN_SETTING.get(settings);
|
|
||||||
if (secureString == null || secureString.length() < 1) {
|
|
||||||
throw new SettingsException(
|
|
||||||
"hipchat account [" + name + "] missing required [" + SECURE_AUTH_TOKEN_SETTING.getKey() + "] secure setting");
|
|
||||||
}
|
|
||||||
return secureString.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract String type();
|
|
||||||
|
|
||||||
public abstract void validateParsedTemplate(String watchId, String actionId, HipChatMessage.Template message) throws SettingsException;
|
|
||||||
|
|
||||||
public abstract HipChatMessage render(String watchId, String actionId, TextTemplateEngine engine, HipChatMessage.Template template,
|
|
||||||
Map<String, Object> model);
|
|
||||||
|
|
||||||
public abstract SentMessages send(HipChatMessage message, @Nullable HttpProxy proxy);
|
|
||||||
|
|
||||||
public enum Profile {
|
|
||||||
|
|
||||||
V1() {
|
|
||||||
@Override
|
|
||||||
HipChatAccount createAccount(String name, Settings settings, HipChatServer defaultServer, HttpClient httpClient,
|
|
||||||
Logger logger) {
|
|
||||||
return new V1Account(name, settings, defaultServer, httpClient, logger);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
INTEGRATION() {
|
|
||||||
@Override
|
|
||||||
HipChatAccount createAccount(String name, Settings settings, HipChatServer defaultServer, HttpClient httpClient,
|
|
||||||
Logger logger) {
|
|
||||||
return new IntegrationAccount(name, settings, defaultServer, httpClient, logger);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
USER() {
|
|
||||||
@Override
|
|
||||||
HipChatAccount createAccount(String name, Settings settings, HipChatServer defaultServer, HttpClient httpClient,
|
|
||||||
Logger logger) {
|
|
||||||
return new UserAccount(name, settings, defaultServer, httpClient, logger);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
abstract HipChatAccount createAccount(String name, Settings settings, HipChatServer defaultServer, HttpClient httpClient,
|
|
||||||
Logger logger);
|
|
||||||
|
|
||||||
public String value() {
|
|
||||||
return name().toLowerCase(Locale.ROOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Profile parse(XContentParser parser) throws IOException {
|
|
||||||
return Profile.valueOf(parser.text().toUpperCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Profile resolve(String value, Profile defaultValue) {
|
|
||||||
if (value == null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return Profile.valueOf(value.toUpperCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Profile resolve(Settings settings, String setting, Profile defaultValue) {
|
|
||||||
return resolve(settings.get(setting), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean validate(String value) {
|
|
||||||
try {
|
|
||||||
Profile.valueOf(value.toUpperCase(Locale.ROOT));
|
|
||||||
return true;
|
|
||||||
} catch (IllegalArgumentException ilae) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,457 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.ParseField;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class HipChatMessage implements ToXContentObject {
|
|
||||||
|
|
||||||
final String body;
|
|
||||||
@Nullable final String[] rooms;
|
|
||||||
@Nullable final String[] users;
|
|
||||||
@Nullable final String from;
|
|
||||||
@Nullable final Format format;
|
|
||||||
@Nullable final Color color;
|
|
||||||
@Nullable final Boolean notify;
|
|
||||||
|
|
||||||
public HipChatMessage(String body, String[] rooms, String[] users, String from, Format format, Color color, Boolean notify) {
|
|
||||||
this.body = body;
|
|
||||||
this.rooms = rooms;
|
|
||||||
this.users = users;
|
|
||||||
this.from = from;
|
|
||||||
this.format = format;
|
|
||||||
this.color = color;
|
|
||||||
this.notify = notify;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBody() {
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getRooms() {
|
|
||||||
return rooms;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String[] getUsers() {
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getFrom() {
|
|
||||||
return from;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Format getFormat() {
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Color getColor() {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Boolean getNotify() {
|
|
||||||
return notify;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
HipChatMessage that = (HipChatMessage) o;
|
|
||||||
return Objects.equals(body, that.body) &&
|
|
||||||
Objects.deepEquals(rooms, that.rooms) &&
|
|
||||||
Objects.deepEquals(users, that.users) &&
|
|
||||||
Objects.equals(from, that.from) &&
|
|
||||||
Objects.equals(format, that.format) &&
|
|
||||||
Objects.equals(color, that.color) &&
|
|
||||||
Objects.equals(notify, that.notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = body.hashCode();
|
|
||||||
result = 31 * result + (rooms != null ? Arrays.hashCode(rooms) : 0);
|
|
||||||
result = 31 * result + (users != null ? Arrays.hashCode(users) : 0);
|
|
||||||
result = 31 * result + (from != null ? from.hashCode() : 0);
|
|
||||||
result = 31 * result + (format != null ? format.hashCode() : 0);
|
|
||||||
result = 31 * result + (color != null ? color.hashCode() : 0);
|
|
||||||
result = 31 * result + (notify != null ? notify.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return toXContent(builder, params, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params, boolean includeTargets) throws IOException {
|
|
||||||
builder.startObject();
|
|
||||||
if (from != null) {
|
|
||||||
builder.field(Field.FROM.getPreferredName(), from);
|
|
||||||
}
|
|
||||||
if (includeTargets) {
|
|
||||||
if (rooms != null && rooms.length > 0) {
|
|
||||||
builder.array(Field.ROOM.getPreferredName(), rooms);
|
|
||||||
}
|
|
||||||
if (users != null && users.length > 0) {
|
|
||||||
builder.array(Field.USER.getPreferredName(), users);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.field(Field.BODY.getPreferredName(), body);
|
|
||||||
if (format != null) {
|
|
||||||
builder.field(Field.FORMAT.getPreferredName(), format.value());
|
|
||||||
}
|
|
||||||
if (color != null) {
|
|
||||||
builder.field(Field.COLOR.getPreferredName(), color.value());
|
|
||||||
}
|
|
||||||
if (notify != null) {
|
|
||||||
builder.field(Field.NOTIFY.getPreferredName(), notify);
|
|
||||||
}
|
|
||||||
return builder.endObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Template implements ToXContentObject {
|
|
||||||
|
|
||||||
final TextTemplate body;
|
|
||||||
@Nullable final TextTemplate[] rooms;
|
|
||||||
@Nullable final TextTemplate[] users;
|
|
||||||
@Nullable final String from;
|
|
||||||
@Nullable final Format format;
|
|
||||||
@Nullable final TextTemplate color;
|
|
||||||
@Nullable final Boolean notify;
|
|
||||||
|
|
||||||
public Template(TextTemplate body,
|
|
||||||
TextTemplate[] rooms,
|
|
||||||
TextTemplate[] users,
|
|
||||||
String from,
|
|
||||||
Format format,
|
|
||||||
TextTemplate color,
|
|
||||||
Boolean notify) {
|
|
||||||
this.rooms = rooms;
|
|
||||||
this.users = users;
|
|
||||||
this.body = body;
|
|
||||||
this.from = from;
|
|
||||||
this.format = format;
|
|
||||||
this.color = color;
|
|
||||||
this.notify = notify;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
Template template = (Template) o;
|
|
||||||
|
|
||||||
return Objects.equals(body, template.body) &&
|
|
||||||
Objects.deepEquals(rooms, template.rooms) &&
|
|
||||||
Objects.deepEquals(users, template.users) &&
|
|
||||||
Objects.equals(from, template.from) &&
|
|
||||||
Objects.equals(format, template.format) &&
|
|
||||||
Objects.equals(color, template.color) &&
|
|
||||||
Objects.equals(notify, template.notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(body, rooms, users, from, format, color, notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
builder.startObject();
|
|
||||||
if (from != null) {
|
|
||||||
builder.field(Field.FROM.getPreferredName(), from);
|
|
||||||
}
|
|
||||||
if (rooms != null && rooms.length > 0) {
|
|
||||||
builder.startArray(Field.ROOM.getPreferredName());
|
|
||||||
for (TextTemplate room : rooms) {
|
|
||||||
room.toXContent(builder, params);
|
|
||||||
}
|
|
||||||
builder.endArray();
|
|
||||||
}
|
|
||||||
if (users != null && users.length > 0) {
|
|
||||||
builder.startArray(Field.USER.getPreferredName());
|
|
||||||
for (TextTemplate user : users) {
|
|
||||||
user.toXContent(builder, params);
|
|
||||||
}
|
|
||||||
builder.endArray();
|
|
||||||
}
|
|
||||||
builder.field(Field.BODY.getPreferredName(), body, params);
|
|
||||||
if (format != null) {
|
|
||||||
builder.field(Field.FORMAT.getPreferredName(), format.value());
|
|
||||||
}
|
|
||||||
if (color != null) {
|
|
||||||
builder.field(Field.COLOR.getPreferredName(), color, params);
|
|
||||||
}
|
|
||||||
if (notify != null) {
|
|
||||||
builder.field(Field.NOTIFY.getPreferredName(), notify);
|
|
||||||
}
|
|
||||||
return builder.endObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Template parse(XContentParser parser) throws IOException {
|
|
||||||
TextTemplate body = null;
|
|
||||||
TextTemplate[] rooms = null;
|
|
||||||
TextTemplate[] users = null;
|
|
||||||
String from = null;
|
|
||||||
TextTemplate color = null;
|
|
||||||
Boolean notify = null;
|
|
||||||
HipChatMessage.Format messageFormat = null;
|
|
||||||
|
|
||||||
String currentFieldName = null;
|
|
||||||
XContentParser.Token token;
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
|
||||||
currentFieldName = parser.currentName();
|
|
||||||
} else if (Field.FROM.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
from = parser.text();
|
|
||||||
} else if (Field.ROOM.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
List<TextTemplate> templates = new ArrayList<>();
|
|
||||||
if (token == XContentParser.Token.START_ARRAY) {
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
|
||||||
try {
|
|
||||||
templates.add(TextTemplate.parse(parser));
|
|
||||||
} catch (ElasticsearchParseException epe) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [{}] field", epe,
|
|
||||||
Field.ROOM.getPreferredName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
templates.add(TextTemplate.parse(parser));
|
|
||||||
} catch (ElasticsearchParseException epe) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [{}] field", epe,
|
|
||||||
Field.ROOM.getPreferredName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rooms = templates.toArray(new TextTemplate[templates.size()]);
|
|
||||||
} else if (Field.USER.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
List<TextTemplate> templates = new ArrayList<>();
|
|
||||||
if (token == XContentParser.Token.START_ARRAY) {
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
|
||||||
try {
|
|
||||||
templates.add(TextTemplate.parse(parser));
|
|
||||||
} catch (ElasticsearchParseException epe) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [{}] field", epe,
|
|
||||||
Field.USER.getPreferredName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
templates.add(TextTemplate.parse(parser));
|
|
||||||
} catch (ElasticsearchParseException epe) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [{}] field", epe,
|
|
||||||
Field.USER.getPreferredName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
users = templates.toArray(new TextTemplate[templates.size()]);
|
|
||||||
} else if (Field.COLOR.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
try {
|
|
||||||
color = TextTemplate.parse(parser);
|
|
||||||
} catch (ElasticsearchParseException | IllegalArgumentException e) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [{}] field", e,
|
|
||||||
Field.COLOR.getPreferredName());
|
|
||||||
}
|
|
||||||
} else if (Field.NOTIFY.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
if (token == XContentParser.Token.VALUE_BOOLEAN) {
|
|
||||||
notify = parser.booleanValue();
|
|
||||||
} else {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [{}] field, expected a " +
|
|
||||||
"boolean value but found [{}]", Field.NOTIFY.getPreferredName(), token);
|
|
||||||
}
|
|
||||||
} else if (Field.BODY.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
try {
|
|
||||||
body = TextTemplate.parse(parser);
|
|
||||||
} catch (ElasticsearchParseException pe) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [{}] field", pe,
|
|
||||||
Field.BODY.getPreferredName());
|
|
||||||
}
|
|
||||||
} else if (Field.FORMAT.match(currentFieldName, parser.getDeprecationHandler())) {
|
|
||||||
try {
|
|
||||||
messageFormat = HipChatMessage.Format.parse(parser);
|
|
||||||
} catch (IllegalArgumentException ilae) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [{}] field", ilae,
|
|
||||||
Field.FORMAT.getPreferredName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. unexpected field [{}]", currentFieldName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body == null) {
|
|
||||||
throw new ElasticsearchParseException("failed to parse hipchat message. missing required [{}] field",
|
|
||||||
Field.BODY.getPreferredName());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new HipChatMessage.Template(body, rooms, users, from, messageFormat, color, notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder {
|
|
||||||
|
|
||||||
final TextTemplate body;
|
|
||||||
final List<TextTemplate> rooms = new ArrayList<>();
|
|
||||||
final List<TextTemplate> users = new ArrayList<>();
|
|
||||||
@Nullable String from;
|
|
||||||
@Nullable Format format;
|
|
||||||
@Nullable TextTemplate color;
|
|
||||||
@Nullable Boolean notify;
|
|
||||||
|
|
||||||
public Builder(TextTemplate body) {
|
|
||||||
this.body = body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder addRooms(TextTemplate... rooms) {
|
|
||||||
this.rooms.addAll(Arrays.asList(rooms));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder addUsers(TextTemplate... users) {
|
|
||||||
this.users.addAll(Arrays.asList(users));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setFrom(String from) {
|
|
||||||
this.from = from;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setFormat(Format format) {
|
|
||||||
this.format = format;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setColor(TextTemplate color) {
|
|
||||||
this.color = color;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setNotify(boolean notify) {
|
|
||||||
this.notify = notify;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Template build() {
|
|
||||||
return new Template(
|
|
||||||
body,
|
|
||||||
rooms.isEmpty() ? null : rooms.toArray(new TextTemplate[rooms.size()]),
|
|
||||||
users.isEmpty() ? null : users.toArray(new TextTemplate[users.size()]),
|
|
||||||
from,
|
|
||||||
format,
|
|
||||||
color,
|
|
||||||
notify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum Color {
|
|
||||||
YELLOW, GREEN, RED, PURPLE, GRAY, RANDOM;
|
|
||||||
|
|
||||||
private final TextTemplate template = new TextTemplate(name());
|
|
||||||
|
|
||||||
public TextTemplate asTemplate() {
|
|
||||||
return template;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String value() {
|
|
||||||
return name().toLowerCase(Locale.ROOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Color parse(XContentParser parser) throws IOException {
|
|
||||||
return Color.valueOf(parser.text().toUpperCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Color resolve(String value, Color defaultValue) {
|
|
||||||
if (value == null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return Color.valueOf(value.toUpperCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Color resolve(Settings settings, String setting, Color defaultValue) {
|
|
||||||
return resolve(settings.get(setting), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean validate(String value) {
|
|
||||||
try {
|
|
||||||
Color.valueOf(value.toUpperCase(Locale.ROOT));
|
|
||||||
return true;
|
|
||||||
} catch (IllegalArgumentException ilae) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Format {
|
|
||||||
|
|
||||||
TEXT,
|
|
||||||
HTML;
|
|
||||||
|
|
||||||
private final TextTemplate template = new TextTemplate(name());
|
|
||||||
|
|
||||||
public TextTemplate asTemplate() {
|
|
||||||
return template;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String value() {
|
|
||||||
return name().toLowerCase(Locale.ROOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Format parse(XContentParser parser) throws IOException {
|
|
||||||
return Format.valueOf(parser.text().toUpperCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Format resolve(String value, Format defaultValue) {
|
|
||||||
if (value == null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return Format.valueOf(value.toUpperCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Format resolve(Settings settings, String setting, Format defaultValue) {
|
|
||||||
return resolve(settings.get(setting), defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean validate(String value) {
|
|
||||||
try {
|
|
||||||
Format.valueOf(value.toUpperCase(Locale.ROOT));
|
|
||||||
return true;
|
|
||||||
} catch (IllegalArgumentException ilae) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Field {
|
|
||||||
ParseField ROOM = new ParseField("room");
|
|
||||||
ParseField USER = new ParseField("user");
|
|
||||||
ParseField BODY = new ParseField("body");
|
|
||||||
ParseField FROM = new ParseField("from");
|
|
||||||
ParseField COLOR = new ParseField("color");
|
|
||||||
ParseField NOTIFY = new ParseField("notify");
|
|
||||||
ParseField FORMAT = new ParseField("format");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
|
|
||||||
public class HipChatServer {
|
|
||||||
|
|
||||||
public static final String HOST_SETTING = "host";
|
|
||||||
public static final String PORT_SETTING = "port";
|
|
||||||
|
|
||||||
public static final HipChatServer DEFAULT = new HipChatServer("api.hipchat.com", 443, null);
|
|
||||||
|
|
||||||
private final String host;
|
|
||||||
private final int port;
|
|
||||||
private final HipChatServer fallback;
|
|
||||||
|
|
||||||
public HipChatServer(Settings settings) {
|
|
||||||
this(settings, DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HipChatServer(Settings settings, HipChatServer fallback) {
|
|
||||||
this(settings.get(HOST_SETTING, null), settings.getAsInt(PORT_SETTING, -1), fallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HipChatServer(String host, int port, HipChatServer fallback) {
|
|
||||||
this.host = host;
|
|
||||||
this.port = port;
|
|
||||||
this.fallback = fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String host() {
|
|
||||||
return host != null ? host : fallback.host();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int port() {
|
|
||||||
return port > 0 ? port : fallback.port();
|
|
||||||
}
|
|
||||||
|
|
||||||
public HipChatServer fallback() {
|
|
||||||
return fallback != null ? fallback : DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HipChatServer rebuild(Settings settings, HipChatServer fallback) {
|
|
||||||
return new HipChatServer(settings.get(HOST_SETTING, host), settings.getAsInt(PORT_SETTING, port), fallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized HttpRequest.Builder httpRequest() {
|
|
||||||
return HttpRequest.builder(host(), port());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.common.settings.ClusterSettings;
|
|
||||||
import org.elasticsearch.common.settings.SecureSetting;
|
|
||||||
import org.elasticsearch.common.settings.SecureString;
|
|
||||||
import org.elasticsearch.common.settings.Setting;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.settings.SettingsException;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.NotificationService;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A component to store hipchat credentials.
|
|
||||||
*/
|
|
||||||
public class HipChatService extends NotificationService<HipChatAccount> {
|
|
||||||
|
|
||||||
private static final Setting<String> SETTING_DEFAULT_ACCOUNT =
|
|
||||||
Setting.simpleString("xpack.notification.hipchat.default_account", Setting.Property.Dynamic, Setting.Property.NodeScope);
|
|
||||||
|
|
||||||
static final Setting<String> SETTING_DEFAULT_HOST =
|
|
||||||
Setting.simpleString("xpack.notification.hipchat.host", Setting.Property.Dynamic, Setting.Property.NodeScope);
|
|
||||||
|
|
||||||
static final Setting<Integer> SETTING_DEFAULT_PORT =
|
|
||||||
Setting.intSetting("xpack.notification.hipchat.port", 443, Setting.Property.Dynamic, Setting.Property.NodeScope);
|
|
||||||
|
|
||||||
private static final Setting.AffixSetting<SecureString> SETTING_AUTH_TOKEN_SECURE =
|
|
||||||
Setting.affixKeySetting("xpack.notification.hipchat.account.", "secure_auth_token",
|
|
||||||
(key) -> SecureSetting.secureString(key, null));
|
|
||||||
|
|
||||||
private static final Setting.AffixSetting<String> SETTING_PROFILE =
|
|
||||||
Setting.affixKeySetting("xpack.notification.hipchat.account.", "profile",
|
|
||||||
(key) -> Setting.simpleString(key, Setting.Property.Dynamic, Setting.Property.NodeScope));
|
|
||||||
|
|
||||||
private static final Setting.AffixSetting<String> SETTING_ROOM =
|
|
||||||
Setting.affixKeySetting("xpack.notification.hipchat.account.", "room",
|
|
||||||
(key) -> Setting.simpleString(key, Setting.Property.Dynamic, Setting.Property.NodeScope));
|
|
||||||
|
|
||||||
private static final Setting.AffixSetting<String> SETTING_HOST =
|
|
||||||
Setting.affixKeySetting("xpack.notification.hipchat.account.", "host",
|
|
||||||
(key) -> Setting.simpleString(key, Setting.Property.Dynamic, Setting.Property.NodeScope));
|
|
||||||
|
|
||||||
private static final Setting.AffixSetting<Integer> SETTING_PORT =
|
|
||||||
Setting.affixKeySetting("xpack.notification.hipchat.account.", "port",
|
|
||||||
(key) -> Setting.intSetting(key, 443, Setting.Property.Dynamic, Setting.Property.NodeScope));
|
|
||||||
|
|
||||||
private static final Setting.AffixSetting<Settings> SETTING_MESSAGE_DEFAULTS =
|
|
||||||
Setting.affixKeySetting("xpack.notification.hipchat.account.", "message",
|
|
||||||
(key) -> Setting.groupSetting(key + ".", Setting.Property.Dynamic, Setting.Property.NodeScope));
|
|
||||||
|
|
||||||
private static final Logger logger = LogManager.getLogger(HipChatService.class);
|
|
||||||
|
|
||||||
private final HttpClient httpClient;
|
|
||||||
private HipChatServer defaultServer;
|
|
||||||
|
|
||||||
public HipChatService(Settings settings, HttpClient httpClient, ClusterSettings clusterSettings) {
|
|
||||||
super("hipchat", settings, clusterSettings, HipChatService.getDynamicSettings(), HipChatService.getSecureSettings());
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
// ensure logging of setting changes
|
|
||||||
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_ACCOUNT, (s) -> {});
|
|
||||||
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_HOST, (s) -> {});
|
|
||||||
clusterSettings.addSettingsUpdateConsumer(SETTING_DEFAULT_PORT, (s) -> {});
|
|
||||||
clusterSettings.addAffixUpdateConsumer(SETTING_PROFILE, (s, o) -> {}, (s, o) -> {});
|
|
||||||
clusterSettings.addAffixUpdateConsumer(SETTING_ROOM, (s, o) -> {}, (s, o) -> {});
|
|
||||||
clusterSettings.addAffixUpdateConsumer(SETTING_HOST, (s, o) -> {}, (s, o) -> {});
|
|
||||||
clusterSettings.addAffixUpdateConsumer(SETTING_PORT, (s, o) -> {}, (s, o) -> {});
|
|
||||||
clusterSettings.addAffixUpdateConsumer(SETTING_MESSAGE_DEFAULTS, (s, o) -> {}, (s, o) -> {});
|
|
||||||
// do an initial load
|
|
||||||
reload(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void reload(Settings settings) {
|
|
||||||
defaultServer = new HipChatServer(settings.getByPrefix("xpack.notification.hipchat."));
|
|
||||||
super.reload(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected HipChatAccount createAccount(String name, Settings accountSettings) {
|
|
||||||
HipChatAccount.Profile profile = HipChatAccount.Profile.resolve(accountSettings, "profile", null);
|
|
||||||
if (profile == null) {
|
|
||||||
throw new SettingsException("missing [profile] setting for hipchat account [" + name + "]");
|
|
||||||
}
|
|
||||||
return profile.createAccount(name, accountSettings, defaultServer, httpClient, logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Setting<?>> getDynamicSettings() {
|
|
||||||
return Arrays.asList(SETTING_DEFAULT_ACCOUNT, SETTING_PROFILE, SETTING_ROOM, SETTING_MESSAGE_DEFAULTS,
|
|
||||||
SETTING_DEFAULT_HOST, SETTING_DEFAULT_PORT, SETTING_HOST, SETTING_PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Setting<?>> getSecureSettings() {
|
|
||||||
return Arrays.asList(SETTING_AUTH_TOKEN_SECURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Setting<?>> getSettings() {
|
|
||||||
List<Setting<?>> allSettings = new ArrayList<Setting<?>>(getDynamicSettings());
|
|
||||||
allSettings.addAll(getSecureSettings());
|
|
||||||
return allSettings;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.settings.SettingsException;
|
|
||||||
import org.elasticsearch.xpack.watcher.actions.hipchat.HipChatAction;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.Scheme;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage.Color;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage.Format;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class IntegrationAccount extends HipChatAccount {
|
|
||||||
|
|
||||||
public static final String TYPE = "integration";
|
|
||||||
|
|
||||||
final String room;
|
|
||||||
final Defaults defaults;
|
|
||||||
|
|
||||||
public IntegrationAccount(String name, Settings settings, HipChatServer defaultServer, HttpClient httpClient, Logger logger) {
|
|
||||||
super(name, Profile.INTEGRATION, settings, defaultServer, httpClient, logger);
|
|
||||||
List<String> rooms = settings.getAsList(ROOM_SETTING, null);
|
|
||||||
if (rooms == null || rooms.isEmpty()) {
|
|
||||||
throw new SettingsException("invalid hipchat account [" + name + "]. missing required [" + ROOM_SETTING + "] setting for [" +
|
|
||||||
TYPE + "] account profile");
|
|
||||||
}
|
|
||||||
if (rooms.size() > 1) {
|
|
||||||
throw new SettingsException("invalid hipchat account [" + name + "]. [" + ROOM_SETTING + "] setting for [" + TYPE + "] " +
|
|
||||||
"account must only be set with a single value");
|
|
||||||
}
|
|
||||||
this.room = rooms.get(0);
|
|
||||||
defaults = new Defaults(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validateParsedTemplate(String watchId, String actionId, HipChatMessage.Template template) throws SettingsException {
|
|
||||||
if (template.rooms != null) {
|
|
||||||
throw new ElasticsearchParseException("invalid [" + HipChatAction.TYPE + "] action for [" + watchId + "/" + actionId + "] " +
|
|
||||||
"action. [" + name + "] hipchat account doesn't support custom rooms");
|
|
||||||
}
|
|
||||||
if (template.users != null) {
|
|
||||||
throw new ElasticsearchParseException("invalid [" + HipChatAction.TYPE + "] action for [" + watchId + "/" + actionId + "] " +
|
|
||||||
"action. [" + name + "] hipchat account doesn't support user private messages");
|
|
||||||
}
|
|
||||||
if (template.from != null) {
|
|
||||||
throw new ElasticsearchParseException("invalid [" + HipChatAction.TYPE + "] action for [" + watchId + "/" + actionId + "] " +
|
|
||||||
"action. [" + name + "] hipchat account doesn't support custom `from` fields");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HipChatMessage render(String watchId, String actionId, TextTemplateEngine engine, HipChatMessage.Template template,
|
|
||||||
Map<String, Object> model) {
|
|
||||||
String message = engine.render(template.body, model);
|
|
||||||
Color color = template.color != null ? Color.resolve(engine.render(template.color, model), defaults.color) : defaults.color;
|
|
||||||
Boolean notify = template.notify != null ? template.notify : defaults.notify;
|
|
||||||
Format messageFormat = template.format != null ? template.format : defaults.format;
|
|
||||||
return new HipChatMessage(message, null, null, null, messageFormat, color, notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SentMessages send(HipChatMessage message, @Nullable HttpProxy proxy) {
|
|
||||||
List<SentMessages.SentMessage> sentMessages = new ArrayList<>();
|
|
||||||
HttpRequest request = buildRoomRequest(room, message, proxy);
|
|
||||||
try {
|
|
||||||
HttpResponse response = httpClient.execute(request);
|
|
||||||
sentMessages.add(SentMessages.SentMessage.responded(room, SentMessages.SentMessage.TargetType.ROOM, message, request,
|
|
||||||
response));
|
|
||||||
} catch (Exception e) {
|
|
||||||
sentMessages.add(SentMessages.SentMessage.error(room, SentMessages.SentMessage.TargetType.ROOM, message, e));
|
|
||||||
}
|
|
||||||
return new SentMessages(name, sentMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpRequest buildRoomRequest(String room, final HipChatMessage message, HttpProxy proxy) {
|
|
||||||
String urlEncodedRoom = HttpRequest.encodeUrl(room);
|
|
||||||
HttpRequest.Builder builder = server.httpRequest()
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v2/room/" + urlEncodedRoom + "/notification")
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setHeader("Authorization", "Bearer " + authToken)
|
|
||||||
.body(Strings.toString((xbuilder, params) -> {
|
|
||||||
xbuilder.field("message", message.body);
|
|
||||||
if (message.format != null) {
|
|
||||||
xbuilder.field("message_format", message.format.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
xbuilder.field("notify", message.notify);
|
|
||||||
}
|
|
||||||
if (message.color != null) {
|
|
||||||
xbuilder.field("color", String.valueOf(message.color.value()));
|
|
||||||
}
|
|
||||||
return xbuilder;
|
|
||||||
}));
|
|
||||||
if (proxy != null) {
|
|
||||||
builder.proxy(proxy);
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Defaults {
|
|
||||||
|
|
||||||
@Nullable final Format format;
|
|
||||||
@Nullable final Color color;
|
|
||||||
@Nullable final Boolean notify;
|
|
||||||
|
|
||||||
Defaults(Settings settings) {
|
|
||||||
this.format = Format.resolve(settings, DEFAULT_FORMAT_SETTING, null);
|
|
||||||
this.color = Color.resolve(settings, DEFAULT_COLOR_SETTING, null);
|
|
||||||
this.notify = settings.getAsBoolean(DEFAULT_NOTIFY_SETTING, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,153 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.ParseField;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.support.xcontent.WatcherParams;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class SentMessages implements ToXContentObject, Iterable<SentMessages.SentMessage> {
|
|
||||||
|
|
||||||
private static final ParseField ACCOUNT = new ParseField("account");
|
|
||||||
private static final ParseField SENT_MESSAGES = new ParseField("sent_messages");
|
|
||||||
|
|
||||||
private String accountName;
|
|
||||||
private List<SentMessage> messages;
|
|
||||||
|
|
||||||
public SentMessages(String accountName, List<SentMessage> messages) {
|
|
||||||
this.accountName = accountName;
|
|
||||||
this.messages = messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAccountName() {
|
|
||||||
return accountName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<SentMessage> iterator() {
|
|
||||||
return messages.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int count() {
|
|
||||||
return messages.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SentMessage> asList() {
|
|
||||||
return Collections.unmodifiableList(messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
builder.startObject();
|
|
||||||
builder.field(ACCOUNT.getPreferredName(), accountName);
|
|
||||||
builder.startArray(SENT_MESSAGES.getPreferredName());
|
|
||||||
for (SentMessage message : messages) {
|
|
||||||
message.toXContent(builder, params);
|
|
||||||
}
|
|
||||||
builder.endArray();
|
|
||||||
return builder.endObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SentMessage implements ToXContentObject {
|
|
||||||
|
|
||||||
private static final ParseField STATUS = new ParseField("status");
|
|
||||||
private static final ParseField REQUEST = new ParseField("request");
|
|
||||||
private static final ParseField RESPONSE = new ParseField("response");
|
|
||||||
private static final ParseField MESSAGE = new ParseField("message");
|
|
||||||
|
|
||||||
public enum TargetType {
|
|
||||||
ROOM, USER;
|
|
||||||
|
|
||||||
final String fieldName = new String(name().toLowerCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
final String targetName;
|
|
||||||
final TargetType targetType;
|
|
||||||
final HipChatMessage message;
|
|
||||||
@Nullable final HttpRequest request;
|
|
||||||
@Nullable final HttpResponse response;
|
|
||||||
@Nullable final Exception exception;
|
|
||||||
|
|
||||||
public static SentMessage responded(String targetName, TargetType targetType, HipChatMessage message, HttpRequest request,
|
|
||||||
HttpResponse response) {
|
|
||||||
return new SentMessage(targetName, targetType, message, request, response, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SentMessage error(String targetName, TargetType targetType, HipChatMessage message, Exception e) {
|
|
||||||
return new SentMessage(targetName, targetType, message, null, null, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SentMessage(String targetName, TargetType targetType, HipChatMessage message, HttpRequest request, HttpResponse response,
|
|
||||||
Exception exception) {
|
|
||||||
this.targetName = targetName;
|
|
||||||
this.targetType = targetType;
|
|
||||||
this.message = message;
|
|
||||||
this.request = request;
|
|
||||||
this.response = response;
|
|
||||||
this.exception = exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpRequest getRequest() {
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpResponse getResponse() {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Exception getException() {
|
|
||||||
return exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSuccess() {
|
|
||||||
return response != null && response.status() >= 200 && response.status() < 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
builder.startObject();
|
|
||||||
boolean success = isSuccess();
|
|
||||||
builder.field(STATUS.getPreferredName(), success ? "success" : "failure");
|
|
||||||
if (success == false) {
|
|
||||||
if (request != null) {
|
|
||||||
if (WatcherParams.hideSecrets(params)) {
|
|
||||||
// this writes out the request to the byte array output stream with the correct excludes for hipchat
|
|
||||||
try (InputStream is = HttpRequest.filterToXContent(request, builder.contentType().xContent(),
|
|
||||||
params, "params.auth_token")) {
|
|
||||||
builder.rawField(REQUEST.getPreferredName(), is, builder.contentType());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
builder.field(REQUEST.getPreferredName());
|
|
||||||
request.toXContent(builder, params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (response != null) {
|
|
||||||
builder.field(RESPONSE.getPreferredName());
|
|
||||||
response.toXContent(builder, params);
|
|
||||||
}
|
|
||||||
if (exception != null) {
|
|
||||||
ElasticsearchException.generateFailureXContent(builder, params, exception, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.field(targetType.fieldName, targetName);
|
|
||||||
builder.field(MESSAGE.getPreferredName());
|
|
||||||
message.toXContent(builder, params, false);
|
|
||||||
return builder.endObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,192 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.settings.SettingsException;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.Scheme;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage.Color;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage.Format;
|
|
||||||
import org.elasticsearch.xpack.watcher.actions.hipchat.HipChatAction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class UserAccount extends HipChatAccount {
|
|
||||||
|
|
||||||
public static final String TYPE = "user";
|
|
||||||
|
|
||||||
final Defaults defaults;
|
|
||||||
|
|
||||||
public UserAccount(String name, Settings settings, HipChatServer defaultServer, HttpClient httpClient, Logger logger) {
|
|
||||||
super(name, Profile.USER, settings, defaultServer, httpClient, logger);
|
|
||||||
defaults = new Defaults(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validateParsedTemplate(String watchId, String actionId, HipChatMessage.Template template) throws SettingsException {
|
|
||||||
if (template.from != null) {
|
|
||||||
throw new ElasticsearchParseException("invalid [" + HipChatAction.TYPE + "] action for [" + watchId + "/" + actionId + "]. ["
|
|
||||||
+ name + "] hipchat account doesn't support custom `from` fields");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HipChatMessage render(String watchId, String actionId, TextTemplateEngine engine, HipChatMessage.Template template,
|
|
||||||
Map<String, Object> model) {
|
|
||||||
String[] rooms = defaults.rooms;
|
|
||||||
if (template.rooms != null) {
|
|
||||||
rooms = new String[template.rooms.length];
|
|
||||||
for (int i = 0; i < template.rooms.length; i++) {
|
|
||||||
rooms[i] = engine.render(template.rooms[i], model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String[] users = defaults.users;
|
|
||||||
if (template.users != null) {
|
|
||||||
users = new String[template.users.length];
|
|
||||||
for (int i = 0; i < template.users.length; i++) {
|
|
||||||
users[i] = engine.render(template.users[i], model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String message = engine.render(template.body, model);
|
|
||||||
Color color = Color.resolve(engine.render(template.color, model), defaults.color);
|
|
||||||
Boolean notify = template.notify != null ? template.notify : defaults.notify;
|
|
||||||
Format messageFormat = template.format != null ? template.format : defaults.format;
|
|
||||||
return new HipChatMessage(message, rooms, users, null, messageFormat, color, notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SentMessages send(HipChatMessage message, HttpProxy proxy) {
|
|
||||||
List<SentMessages.SentMessage> sentMessages = new ArrayList<>();
|
|
||||||
if (message.rooms != null) {
|
|
||||||
for (String room : message.rooms) {
|
|
||||||
HttpRequest request = buildRoomRequest(room, message, proxy);
|
|
||||||
try {
|
|
||||||
HttpResponse response = httpClient.execute(request);
|
|
||||||
sentMessages.add(SentMessages.SentMessage.responded(room, SentMessages.SentMessage.TargetType.ROOM, message, request,
|
|
||||||
response));
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error("failed to execute hipchat api http request", e);
|
|
||||||
sentMessages.add(SentMessages.SentMessage.error(room, SentMessages.SentMessage.TargetType.ROOM, message, e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (message.users != null) {
|
|
||||||
for (String user : message.users) {
|
|
||||||
HttpRequest request = buildUserRequest(user, message, proxy);
|
|
||||||
try {
|
|
||||||
HttpResponse response = httpClient.execute(request);
|
|
||||||
sentMessages.add(SentMessages.SentMessage.responded(user, SentMessages.SentMessage.TargetType.USER, message, request,
|
|
||||||
response));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("failed to execute hipchat api http request", e);
|
|
||||||
sentMessages.add(SentMessages.SentMessage.error(user, SentMessages.SentMessage.TargetType.USER, message, e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new SentMessages(name, sentMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpRequest buildRoomRequest(String room, final HipChatMessage message, HttpProxy proxy) {
|
|
||||||
String urlEncodedRoom = encodeRoom(room);
|
|
||||||
HttpRequest.Builder builder = server.httpRequest()
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v2/room/" + urlEncodedRoom + "/notification")
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setHeader("Authorization", "Bearer " + authToken)
|
|
||||||
.body(Strings.toString((xbuilder, params) -> {
|
|
||||||
xbuilder.field("message", message.body);
|
|
||||||
if (message.format != null) {
|
|
||||||
xbuilder.field("message_format", message.format.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
xbuilder.field("notify", message.notify);
|
|
||||||
}
|
|
||||||
if (message.color != null) {
|
|
||||||
xbuilder.field("color", String.valueOf(message.color.value()));
|
|
||||||
}
|
|
||||||
return xbuilder;
|
|
||||||
}));
|
|
||||||
if (proxy != null) {
|
|
||||||
builder.proxy(proxy);
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// this specific hipchat API does not accept application-form encoding, but requires real URL encoding
|
|
||||||
// spaces must not be replaced with a plus, but rather with %20
|
|
||||||
// this workaround ensures, that this happens
|
|
||||||
private String encodeRoom(String text) {
|
|
||||||
try {
|
|
||||||
return new URI("//", "", "", text, null).getRawQuery();
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
throw new IllegalArgumentException("failed to URL encode text [" + text + "]", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpRequest buildUserRequest(String user, final HipChatMessage message, HttpProxy proxy) {
|
|
||||||
HttpRequest.Builder builder = server.httpRequest()
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v2/user/" + user + "/message")
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setHeader("Authorization", "Bearer " + authToken)
|
|
||||||
.body(Strings.toString((xbuilder, params) -> {
|
|
||||||
xbuilder.field("message", message.body);
|
|
||||||
if (message.format != null) {
|
|
||||||
xbuilder.field("message_format", message.format.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
xbuilder.field("notify", message.notify);
|
|
||||||
}
|
|
||||||
return xbuilder;
|
|
||||||
}));
|
|
||||||
if (proxy != null) {
|
|
||||||
builder.proxy(proxy);
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Defaults {
|
|
||||||
|
|
||||||
@Nullable final String[] rooms;
|
|
||||||
@Nullable final String[] users;
|
|
||||||
@Nullable final Format format;
|
|
||||||
@Nullable final Color color;
|
|
||||||
@Nullable final Boolean notify;
|
|
||||||
|
|
||||||
Defaults(Settings settings) {
|
|
||||||
List<String> rooms = settings.getAsList(DEFAULT_ROOM_SETTING, null);
|
|
||||||
this.rooms = rooms == null ? null : rooms.toArray(Strings.EMPTY_ARRAY);
|
|
||||||
List<String> users = settings.getAsList(DEFAULT_USER_SETTING, null);
|
|
||||||
this.users = users == null ? null : users.toArray(Strings.EMPTY_ARRAY);
|
|
||||||
this.format = Format.resolve(settings, DEFAULT_FORMAT_SETTING, null);
|
|
||||||
this.color = Color.resolve(settings, DEFAULT_COLOR_SETTING, null);
|
|
||||||
this.notify = settings.getAsBoolean(DEFAULT_NOTIFY_SETTING, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.Scheme;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage.Color;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage.Format;
|
|
||||||
import org.elasticsearch.xpack.watcher.actions.hipchat.HipChatAction;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class V1Account extends HipChatAccount {
|
|
||||||
|
|
||||||
public static final String TYPE = "v1";
|
|
||||||
|
|
||||||
final Defaults defaults;
|
|
||||||
|
|
||||||
public V1Account(String name, Settings settings, HipChatServer defaultServer, HttpClient httpClient, Logger logger) {
|
|
||||||
super(name, Profile.V1, settings, defaultServer, httpClient, logger);
|
|
||||||
defaults = new Defaults(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validateParsedTemplate(String watchId, String actionId,
|
|
||||||
HipChatMessage.Template template) throws ElasticsearchParseException {
|
|
||||||
if (template.users != null) {
|
|
||||||
throw new ElasticsearchParseException("invalid [" + HipChatAction.TYPE + "] action for [" + watchId + "/" + actionId + "]. ["
|
|
||||||
+ name + "] hipchat account doesn't support user private messaging");
|
|
||||||
}
|
|
||||||
if ((template.rooms == null || template.rooms.length == 0) && (defaults.rooms == null || defaults.rooms.length == 0)) {
|
|
||||||
throw new ElasticsearchParseException("invalid [" + HipChatAction.TYPE + "] action for [" + watchId + "/" + actionId + "]. " +
|
|
||||||
"missing required [" + HipChatMessage.Field.ROOM + "] field for [" + name + "] hipchat account");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HipChatMessage render(String watchId, String actionId, TextTemplateEngine engine, HipChatMessage.Template template,
|
|
||||||
Map<String, Object> model) {
|
|
||||||
String message = engine.render(template.body, model);
|
|
||||||
String[] rooms = defaults.rooms;
|
|
||||||
if (template.rooms != null) {
|
|
||||||
rooms = new String[template.rooms.length];
|
|
||||||
for (int i = 0; i < template.rooms.length; i++) {
|
|
||||||
rooms[i] = engine.render(template.rooms[i], model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String from = template.from != null ? template.from : defaults.from != null ? defaults.from : watchId;
|
|
||||||
Color color = Color.resolve(engine.render(template.color, model), defaults.color);
|
|
||||||
Boolean notify = template.notify != null ? template.notify : defaults.notify;
|
|
||||||
Format messageFormat = template.format != null ? template.format : defaults.format;
|
|
||||||
return new HipChatMessage(message, rooms, null, from, messageFormat, color, notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SentMessages send(HipChatMessage message, @Nullable HttpProxy proxy) {
|
|
||||||
List<SentMessages.SentMessage> sentMessages = new ArrayList<>();
|
|
||||||
if (message.rooms != null) {
|
|
||||||
for (String room : message.rooms) {
|
|
||||||
HttpRequest request = buildRoomRequest(room, message, proxy);
|
|
||||||
try {
|
|
||||||
HttpResponse response = httpClient.execute(request);
|
|
||||||
sentMessages.add(SentMessages.SentMessage.responded(room, SentMessages.SentMessage.TargetType.ROOM, message, request,
|
|
||||||
response));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("failed to execute hipchat api http request", e);
|
|
||||||
sentMessages.add(SentMessages.SentMessage.error(room, SentMessages.SentMessage.TargetType.ROOM, message, e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new SentMessages(name, sentMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpRequest buildRoomRequest(String room, HipChatMessage message, HttpProxy proxy) {
|
|
||||||
HttpRequest.Builder builder = server.httpRequest();
|
|
||||||
builder.method(HttpMethod.POST);
|
|
||||||
builder.scheme(Scheme.HTTPS);
|
|
||||||
builder.path("/v1/rooms/message");
|
|
||||||
builder.setHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
||||||
builder.setParam("format", "json");
|
|
||||||
builder.setParam("auth_token", authToken);
|
|
||||||
if (proxy != null) {
|
|
||||||
builder.proxy(proxy);
|
|
||||||
}
|
|
||||||
StringBuilder body = new StringBuilder();
|
|
||||||
body.append("room_id=").append(HttpRequest.encodeUrl(room));
|
|
||||||
body.append("&from=").append(HttpRequest.encodeUrl(message.from));
|
|
||||||
body.append("&message=").append(HttpRequest.encodeUrl(message.body));
|
|
||||||
if (message.format != null) {
|
|
||||||
body.append("&message_format=").append(message.format.value());
|
|
||||||
}
|
|
||||||
if (message.color != null) {
|
|
||||||
body.append("&color=").append(message.color.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
body.append("¬ify=").append(message.notify ? "1" : "0");
|
|
||||||
}
|
|
||||||
builder.body(body.toString());
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Defaults {
|
|
||||||
|
|
||||||
@Nullable final String[] rooms;
|
|
||||||
@Nullable final String from;
|
|
||||||
@Nullable final Format format;
|
|
||||||
@Nullable final Color color;
|
|
||||||
@Nullable final Boolean notify;
|
|
||||||
|
|
||||||
Defaults(Settings settings) {
|
|
||||||
List<String> rooms = settings.getAsList(DEFAULT_ROOM_SETTING, null);
|
|
||||||
this.rooms = rooms == null ? null : rooms.toArray(Strings.EMPTY_ARRAY);
|
|
||||||
this.from = settings.get(DEFAULT_FROM_SETTING);
|
|
||||||
this.format = Format.resolve(settings, DEFAULT_FORMAT_SETTING, null);
|
|
||||||
this.color = Color.resolve(settings, DEFAULT_COLOR_SETTING, null);
|
|
||||||
this.notify = settings.getAsBoolean(DEFAULT_NOTIFY_SETTING, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.actions.hipchat;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.ClusterSettings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatAccount;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatService;
|
|
||||||
import org.junit.Before;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
||||||
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.hipchatAction;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
public class HipChatActionFactoryTests extends ESTestCase {
|
|
||||||
private HipChatActionFactory factory;
|
|
||||||
private HipChatService hipchatService;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() throws Exception {
|
|
||||||
hipchatService = mock(HipChatService.class);
|
|
||||||
factory = new HipChatActionFactory(mock(TextTemplateEngine.class), hipchatService);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testParseAction() throws Exception {
|
|
||||||
HipChatAccount account = mock(HipChatAccount.class);
|
|
||||||
when(hipchatService.getAccount("_account1")).thenReturn(account);
|
|
||||||
|
|
||||||
HipChatAction action = hipchatAction("_account1", "_body").build();
|
|
||||||
XContentBuilder jsonBuilder = jsonBuilder().value(action);
|
|
||||||
XContentParser parser = createParser(jsonBuilder);
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
ExecutableHipChatAction parsedAction = factory.parseExecutable("_w1", "_a1", parser);
|
|
||||||
assertThat(parsedAction.action(), is(action));
|
|
||||||
|
|
||||||
verify(account, times(1)).validateParsedTemplate("_w1", "_a1", action.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testParseActionUnknownAccount() throws Exception {
|
|
||||||
hipchatService = new HipChatService(Settings.EMPTY, null, new ClusterSettings(Settings.EMPTY,
|
|
||||||
new HashSet<>(HipChatService.getSettings())));
|
|
||||||
factory = new HipChatActionFactory(mock(TextTemplateEngine.class), hipchatService);
|
|
||||||
HipChatAction action = hipchatAction("_unknown", "_body").build();
|
|
||||||
XContentBuilder jsonBuilder = jsonBuilder().value(action);
|
|
||||||
XContentParser parser = createParser(jsonBuilder);
|
|
||||||
parser.nextToken();
|
|
||||||
expectThrows(IllegalArgumentException.class, () -> factory.parseExecutable("_w1", "_a1", parser));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,296 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.actions.hipchat;
|
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
|
||||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
|
||||||
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.actions.Action;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.execution.Wid;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.watch.Payload;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatAccount;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatMessage;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.HipChatService;
|
|
||||||
import org.elasticsearch.xpack.watcher.notification.hipchat.SentMessages;
|
|
||||||
import org.junit.Before;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.time.ZoneOffset;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static java.util.Collections.singletonMap;
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
||||||
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContextBuilder;
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
|
||||||
import static org.hamcrest.Matchers.sameInstance;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
public class HipChatActionTests extends ESTestCase {
|
|
||||||
private HipChatService service;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() throws Exception {
|
|
||||||
service = mock(HipChatService.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testExecute() throws Exception {
|
|
||||||
final String accountName = "account1";
|
|
||||||
|
|
||||||
TextTemplateEngine templateEngine = mock(TextTemplateEngine.class);
|
|
||||||
|
|
||||||
TextTemplate body = new TextTemplate("_body");
|
|
||||||
HipChatMessage.Template.Builder messageBuilder = new HipChatMessage.Template.Builder(body);
|
|
||||||
|
|
||||||
HipChatMessage.Template messageTemplate = messageBuilder.build();
|
|
||||||
|
|
||||||
HipChatAction action = new HipChatAction(accountName, messageTemplate, null);
|
|
||||||
ExecutableHipChatAction executable = new ExecutableHipChatAction(action, logger, service, templateEngine);
|
|
||||||
|
|
||||||
Map<String, Object> data = new HashMap<>();
|
|
||||||
Payload payload = new Payload.Simple(data);
|
|
||||||
|
|
||||||
Map<String, Object> metadata = MapBuilder.<String, Object>newMapBuilder().put("_key", "_val").map();
|
|
||||||
|
|
||||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
|
||||||
JodaCompatibleZonedDateTime jodaJavaNow = new JodaCompatibleZonedDateTime(now.toInstant(), ZoneOffset.UTC);
|
|
||||||
|
|
||||||
Wid wid = new Wid(randomAlphaOfLength(5), now);
|
|
||||||
WatchExecutionContext ctx = mockExecutionContextBuilder(wid.watchId())
|
|
||||||
.wid(wid)
|
|
||||||
.payload(payload)
|
|
||||||
.time(wid.watchId(), now)
|
|
||||||
.metadata(metadata)
|
|
||||||
.buildMock();
|
|
||||||
|
|
||||||
Map<String, Object> triggerModel = new HashMap<>();
|
|
||||||
triggerModel.put("triggered_time", jodaJavaNow);
|
|
||||||
triggerModel.put("scheduled_time", jodaJavaNow);
|
|
||||||
Map<String, Object> ctxModel = new HashMap<>();
|
|
||||||
ctxModel.put("id", ctx.id().value());
|
|
||||||
ctxModel.put("watch_id", wid.watchId());
|
|
||||||
ctxModel.put("payload", data);
|
|
||||||
ctxModel.put("metadata", metadata);
|
|
||||||
ctxModel.put("execution_time", jodaJavaNow);
|
|
||||||
ctxModel.put("trigger", triggerModel);
|
|
||||||
ctxModel.put("vars", Collections.emptyMap());
|
|
||||||
Map<String, Object> expectedModel = singletonMap("ctx", ctxModel);
|
|
||||||
|
|
||||||
if (body != null) {
|
|
||||||
when(templateEngine.render(body, expectedModel)).thenReturn(body.getTemplate());
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] rooms = new String[] { "_r1" };
|
|
||||||
HipChatMessage message = new HipChatMessage(body.getTemplate(), rooms, null, null, null, null, null);
|
|
||||||
HipChatAccount account = mock(HipChatAccount.class);
|
|
||||||
when(account.render(wid.watchId(), "_id", templateEngine, messageTemplate, expectedModel)).thenReturn(message);
|
|
||||||
boolean responseFailure = randomBoolean();
|
|
||||||
HttpResponse response = new HttpResponse(responseFailure ? 404 : 200);
|
|
||||||
HttpRequest request = HttpRequest.builder("localhost", 12345).path("/").build();
|
|
||||||
SentMessages sentMessages = new SentMessages(accountName, Arrays.asList(
|
|
||||||
SentMessages.SentMessage.responded("_r1", SentMessages.SentMessage.TargetType.ROOM, message, request, response)
|
|
||||||
));
|
|
||||||
when(account.send(message, null)).thenReturn(sentMessages);
|
|
||||||
when(service.getAccount(accountName)).thenReturn(account);
|
|
||||||
|
|
||||||
Action.Result result = executable.execute("_id", ctx, payload);
|
|
||||||
|
|
||||||
assertThat(result, notNullValue());
|
|
||||||
assertThat(result, instanceOf(HipChatAction.Result.Executed.class));
|
|
||||||
if (responseFailure) {
|
|
||||||
assertThat(result.status(), equalTo(Action.Result.Status.FAILURE));
|
|
||||||
} else {
|
|
||||||
assertThat(result.status(), equalTo(Action.Result.Status.SUCCESS));
|
|
||||||
}
|
|
||||||
assertThat(((HipChatAction.Result.Executed) result).sentMessages(), sameInstance(sentMessages));
|
|
||||||
assertValidToXContent(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testParser() throws Exception {
|
|
||||||
XContentBuilder builder = jsonBuilder().startObject();
|
|
||||||
|
|
||||||
String accountName = randomAlphaOfLength(10);
|
|
||||||
builder.field("account", accountName);
|
|
||||||
builder.startObject("message");
|
|
||||||
|
|
||||||
TextTemplate body = new TextTemplate("_body");
|
|
||||||
builder.field("body", body);
|
|
||||||
|
|
||||||
TextTemplate[] rooms = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
TextTemplate r1 = new TextTemplate("_r1");
|
|
||||||
TextTemplate r2 = new TextTemplate("_r2");
|
|
||||||
rooms = new TextTemplate[] { r1, r2 };
|
|
||||||
builder.array("room", r1, r2);
|
|
||||||
}
|
|
||||||
TextTemplate[] users = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
TextTemplate u1 = new TextTemplate("_u1");
|
|
||||||
TextTemplate u2 = new TextTemplate("_u2");
|
|
||||||
users = new TextTemplate[] { u1, u2 };
|
|
||||||
builder.array("user", u1, u2);
|
|
||||||
}
|
|
||||||
String from = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
from = randomAlphaOfLength(10);
|
|
||||||
builder.field("from", from);
|
|
||||||
}
|
|
||||||
HipChatMessage.Format format = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
format = randomFrom(HipChatMessage.Format.values());
|
|
||||||
builder.field("format", format.value());
|
|
||||||
}
|
|
||||||
TextTemplate color = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
color = new TextTemplate(randomFrom(HipChatMessage.Color.values()).value());
|
|
||||||
builder.field("color", color);
|
|
||||||
}
|
|
||||||
Boolean notify = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
notify = randomBoolean();
|
|
||||||
builder.field("notify", notify);
|
|
||||||
}
|
|
||||||
builder.endObject();
|
|
||||||
HttpProxy proxy = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
proxy = new HttpProxy("localhost", 8080);
|
|
||||||
builder.startObject("proxy").field("host", "localhost").field("port", 8080).endObject();
|
|
||||||
}
|
|
||||||
builder.endObject();
|
|
||||||
|
|
||||||
BytesReference bytes = BytesReference.bytes(builder);
|
|
||||||
logger.info("hipchat action json [{}]", bytes.utf8ToString());
|
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
HipChatAction action = HipChatAction.parse("_watch", "_action", parser);
|
|
||||||
|
|
||||||
assertThat(action, notNullValue());
|
|
||||||
assertThat(action.account, is(accountName));
|
|
||||||
assertThat(action.proxy, is(proxy));
|
|
||||||
assertThat(action.message, notNullValue());
|
|
||||||
assertThat(action.message, is(new HipChatMessage.Template(body, rooms, users, from, format, color, notify)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testParserSelfGenerated() throws Exception {
|
|
||||||
String accountName = randomAlphaOfLength(10);
|
|
||||||
TextTemplate body = new TextTemplate("_body");
|
|
||||||
HipChatMessage.Template.Builder templateBuilder = new HipChatMessage.Template.Builder(body);
|
|
||||||
|
|
||||||
XContentBuilder builder = jsonBuilder().startObject();
|
|
||||||
builder.field("account", accountName);
|
|
||||||
|
|
||||||
HttpProxy proxy = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
proxy = new HttpProxy("localhost", 8080);
|
|
||||||
builder.startObject("proxy").field("host", "localhost").field("port", 8080).endObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.startObject("message");
|
|
||||||
builder.field("body", body);
|
|
||||||
|
|
||||||
if (randomBoolean()) {
|
|
||||||
TextTemplate r1 = new TextTemplate("_r1");
|
|
||||||
TextTemplate r2 = new TextTemplate("_r2");
|
|
||||||
templateBuilder.addRooms(r1, r2);
|
|
||||||
builder.array("room", r1, r2);
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
TextTemplate u1 = new TextTemplate("_u1");
|
|
||||||
TextTemplate u2 = new TextTemplate("_u2");
|
|
||||||
templateBuilder.addUsers(u1, u2);
|
|
||||||
builder.array("user", u1, u2);
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
String from = randomAlphaOfLength(10);
|
|
||||||
templateBuilder.setFrom(from);
|
|
||||||
builder.field("from", from);
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
HipChatMessage.Format format = randomFrom(HipChatMessage.Format.values());
|
|
||||||
templateBuilder.setFormat(format);
|
|
||||||
builder.field("format", format.value());
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
TextTemplate color = new TextTemplate(randomFrom(HipChatMessage.Color.values()).value());
|
|
||||||
templateBuilder.setColor(color);
|
|
||||||
builder.field("color", color);
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
boolean notify = randomBoolean();
|
|
||||||
templateBuilder.setNotify(notify);
|
|
||||||
builder.field("notify", notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.endObject();
|
|
||||||
builder.endObject();
|
|
||||||
|
|
||||||
HipChatMessage.Template template = templateBuilder.build();
|
|
||||||
|
|
||||||
HipChatAction action = new HipChatAction(accountName, template, proxy);
|
|
||||||
|
|
||||||
XContentBuilder jsonBuilder = jsonBuilder();
|
|
||||||
action.toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS);
|
|
||||||
BytesReference bytes = BytesReference.bytes(builder);
|
|
||||||
logger.info("{}", bytes.utf8ToString());
|
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
HipChatAction parsedAction = HipChatAction.parse("_watch", "_action", parser);
|
|
||||||
|
|
||||||
assertThat(parsedAction, notNullValue());
|
|
||||||
assertThat(parsedAction, is(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testParserInvalid() throws Exception {
|
|
||||||
XContentBuilder builder = jsonBuilder().startObject().field("unknown_field", "value").endObject();
|
|
||||||
XContentParser parser = createParser(builder);
|
|
||||||
parser.nextToken();
|
|
||||||
try {
|
|
||||||
HipChatAction.parse("_watch", "_action", parser);
|
|
||||||
fail("Expected ElasticsearchParseException");
|
|
||||||
} catch (ElasticsearchParseException e) {
|
|
||||||
assertThat(e.getMessage(), is("failed to parse [hipchat] action [_watch/_action]. unexpected token [VALUE_STRING]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure that toXContent can be serialized and read again
|
|
||||||
private void assertValidToXContent(Action.Result result) throws IOException {
|
|
||||||
try (XContentBuilder builder = jsonBuilder()) {
|
|
||||||
builder.startObject();
|
|
||||||
result.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
|
||||||
builder.endObject();
|
|
||||||
Strings.toString(builder);
|
|
||||||
try (XContentParser parser = XContentType.JSON.xContent()
|
|
||||||
.createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, Strings.toString(builder))) {
|
|
||||||
parser.map();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.ClusterSettings;
|
|
||||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
public class HipChatAccountsTests extends ESTestCase {
|
|
||||||
private HttpClient httpClient;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() throws Exception {
|
|
||||||
httpClient = mock(HttpClient.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testProxy() throws Exception {
|
|
||||||
Settings.Builder builder = Settings.builder()
|
|
||||||
.put("xpack.notification.hipchat.default_account", "account1");
|
|
||||||
addAccountSettings("account1", builder);
|
|
||||||
HipChatService service = new HipChatService(builder.build(), httpClient, new ClusterSettings(Settings.EMPTY,
|
|
||||||
new HashSet<>(HipChatService.getSettings())));
|
|
||||||
HipChatAccount account = service.getAccount("account1");
|
|
||||||
|
|
||||||
HipChatMessage hipChatMessage = new HipChatMessage("body", new String[]{"rooms"}, null, "from", null, null, null);
|
|
||||||
|
|
||||||
ArgumentCaptor<HttpRequest> argumentCaptor = ArgumentCaptor.forClass(HttpRequest.class);
|
|
||||||
when(httpClient.execute(argumentCaptor.capture())).thenReturn(new HttpResponse(200));
|
|
||||||
|
|
||||||
HttpProxy proxy = new HttpProxy("localhost", 8080);
|
|
||||||
account.send(hipChatMessage, proxy);
|
|
||||||
|
|
||||||
HttpRequest request = argumentCaptor.getValue();
|
|
||||||
assertThat(request.proxy(), is(proxy));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addAccountSettings(String name, Settings.Builder builder) {
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString("xpack.notification.hipchat.account." + name + ".secure_auth_token", randomAlphaOfLength(50));
|
|
||||||
HipChatAccount.Profile profile = randomFrom(HipChatAccount.Profile.values());
|
|
||||||
builder.put("xpack.notification.hipchat.account." + name + ".profile", profile.value());
|
|
||||||
builder.setSecureSettings(secureSettings);
|
|
||||||
if (profile == HipChatAccount.Profile.INTEGRATION) {
|
|
||||||
builder.put("xpack.notification.hipchat.account." + name + ".room", randomAlphaOfLength(10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,325 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
|
||||||
import org.elasticsearch.common.xcontent.DeprecationHandler;
|
|
||||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.support.xcontent.WatcherParams;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
|
||||||
import static org.hamcrest.CoreMatchers.nullValue;
|
|
||||||
import static org.hamcrest.Matchers.arrayContaining;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
|
||||||
|
|
||||||
public class HipChatMessageTests extends ESTestCase {
|
|
||||||
|
|
||||||
public void testToXContent() throws Exception {
|
|
||||||
String message = randomAlphaOfLength(10);
|
|
||||||
String[] rooms = generateRandomStringArray(3, 10, true);
|
|
||||||
String[] users = generateRandomStringArray(3, 10, true);
|
|
||||||
String from = randomBoolean() ? null : randomAlphaOfLength(10);
|
|
||||||
HipChatMessage.Format format = rarely() ? null : randomFrom(HipChatMessage.Format.values());
|
|
||||||
HipChatMessage.Color color = rarely() ? null : randomFrom(HipChatMessage.Color.values());
|
|
||||||
Boolean notify = rarely() ? null : randomBoolean();
|
|
||||||
HipChatMessage msg = new HipChatMessage(message, rooms, users, from, format, color, notify);
|
|
||||||
|
|
||||||
XContentBuilder builder = jsonBuilder();
|
|
||||||
boolean includeTarget = randomBoolean();
|
|
||||||
if (includeTarget && randomBoolean()) {
|
|
||||||
msg.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
|
||||||
} else {
|
|
||||||
msg.toXContent(builder, ToXContent.EMPTY_PARAMS, includeTarget);
|
|
||||||
}
|
|
||||||
BytesReference bytes = BytesReference.bytes(builder);
|
|
||||||
|
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
assertThat(parser.currentToken(), is(XContentParser.Token.START_OBJECT));
|
|
||||||
|
|
||||||
message = null;
|
|
||||||
rooms = null;
|
|
||||||
users = null;
|
|
||||||
from = null;
|
|
||||||
format = null;
|
|
||||||
color = null;
|
|
||||||
notify = null;
|
|
||||||
XContentParser.Token token = null;
|
|
||||||
String currentFieldName = null;
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
|
||||||
currentFieldName = parser.currentName();
|
|
||||||
} else if ("body".equals(currentFieldName)) {
|
|
||||||
message = parser.text();
|
|
||||||
} else if ("room".equals(currentFieldName)) {
|
|
||||||
rooms = parser.list().stream().map(Object::toString).toArray(String[]::new);
|
|
||||||
} else if ("user".equals(currentFieldName)) {
|
|
||||||
users = parser.list().stream().map(Object::toString).toArray(String[]::new);
|
|
||||||
} else if ("from".equals(currentFieldName)) {
|
|
||||||
from = parser.text();
|
|
||||||
} else if ("format".equals(currentFieldName)) {
|
|
||||||
format = HipChatMessage.Format.parse(parser);
|
|
||||||
} else if ("color".equals(currentFieldName)) {
|
|
||||||
color = HipChatMessage.Color.parse(parser);
|
|
||||||
} else if ("notify".equals(currentFieldName)) {
|
|
||||||
notify = parser.booleanValue();
|
|
||||||
} else {
|
|
||||||
fail("unexpected xcontent field [" + currentFieldName + "] in hipchat message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertThat(message, notNullValue());
|
|
||||||
assertThat(message, is(msg.body));
|
|
||||||
if (includeTarget) {
|
|
||||||
if (msg.rooms == null || msg.rooms.length == 0) {
|
|
||||||
assertThat(rooms, nullValue());
|
|
||||||
} else {
|
|
||||||
assertThat(rooms, arrayContaining(msg.rooms));
|
|
||||||
}
|
|
||||||
if (msg.users == null || msg.users.length == 0) {
|
|
||||||
assertThat(users, nullValue());
|
|
||||||
} else {
|
|
||||||
assertThat(users, arrayContaining(msg.users));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertThat(from, is(msg.from));
|
|
||||||
assertThat(format, is(msg.format));
|
|
||||||
assertThat(color, is(msg.color));
|
|
||||||
assertThat(notify, is(msg.notify));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testEquals() throws Exception {
|
|
||||||
String message = randomAlphaOfLength(10);
|
|
||||||
String[] rooms = generateRandomStringArray(3, 10, true);
|
|
||||||
String[] users = generateRandomStringArray(3, 10, true);
|
|
||||||
String from = randomBoolean() ? null : randomAlphaOfLength(10);
|
|
||||||
HipChatMessage.Format format = rarely() ? null : randomFrom(HipChatMessage.Format.values());
|
|
||||||
HipChatMessage.Color color = rarely() ? null : randomFrom(HipChatMessage.Color.values());
|
|
||||||
Boolean notify = rarely() ? null : randomBoolean();
|
|
||||||
HipChatMessage msg1 = new HipChatMessage(message, rooms, users, from, format, color, notify);
|
|
||||||
|
|
||||||
boolean equals = randomBoolean();
|
|
||||||
if (!equals) {
|
|
||||||
equals = true;
|
|
||||||
if (rarely()) {
|
|
||||||
equals = false;
|
|
||||||
message = "another message";
|
|
||||||
}
|
|
||||||
if (rarely()) {
|
|
||||||
equals = false;
|
|
||||||
rooms = rooms == null ? new String[] { "roomX" } : randomBoolean() ? null : new String[] { "roomX" , "roomY"};
|
|
||||||
}
|
|
||||||
if (rarely()) {
|
|
||||||
equals = false;
|
|
||||||
users = users == null ? new String[] { "userX" } : randomBoolean() ? null : new String[] { "userX", "userY" };
|
|
||||||
}
|
|
||||||
if (rarely()) {
|
|
||||||
equals = false;
|
|
||||||
from = from == null ? "fromX" : randomBoolean() ? null : "fromY";
|
|
||||||
}
|
|
||||||
if (rarely()) {
|
|
||||||
equals = false;
|
|
||||||
format = format == null ?
|
|
||||||
randomFrom(HipChatMessage.Format.values()) :
|
|
||||||
randomBoolean() ?
|
|
||||||
null :
|
|
||||||
randomFromWithExcludes(HipChatMessage.Format.values(), format);
|
|
||||||
}
|
|
||||||
if (rarely()) {
|
|
||||||
equals = false;
|
|
||||||
color = color == null ?
|
|
||||||
randomFrom(HipChatMessage.Color.values()) :
|
|
||||||
randomBoolean() ?
|
|
||||||
null :
|
|
||||||
randomFromWithExcludes(HipChatMessage.Color.values(), color);
|
|
||||||
}
|
|
||||||
if (rarely()) {
|
|
||||||
equals = false;
|
|
||||||
notify = notify == null ? (Boolean) randomBoolean() : randomBoolean() ? null : !notify;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HipChatMessage msg2 = new HipChatMessage(message, rooms, users, from, format, color, notify);
|
|
||||||
assertThat(msg1.equals(msg2), is(equals));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTemplateParse() throws Exception {
|
|
||||||
XContentBuilder jsonBuilder = jsonBuilder();
|
|
||||||
jsonBuilder.startObject();
|
|
||||||
|
|
||||||
TextTemplate body = new TextTemplate(randomAlphaOfLength(200));
|
|
||||||
jsonBuilder.field("body", body, ToXContent.EMPTY_PARAMS);
|
|
||||||
TextTemplate[] rooms = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
jsonBuilder.startArray("room");
|
|
||||||
rooms = new TextTemplate[randomIntBetween(1, 3)];
|
|
||||||
for (int i = 0; i < rooms.length; i++) {
|
|
||||||
rooms[i] = new TextTemplate(randomAlphaOfLength(10));
|
|
||||||
rooms[i].toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS);
|
|
||||||
}
|
|
||||||
jsonBuilder.endArray();
|
|
||||||
}
|
|
||||||
TextTemplate[] users = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
jsonBuilder.startArray("user");
|
|
||||||
users = new TextTemplate[randomIntBetween(1, 3)];
|
|
||||||
for (int i = 0; i < users.length; i++) {
|
|
||||||
users[i] = new TextTemplate(randomAlphaOfLength(10));
|
|
||||||
users[i].toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS);
|
|
||||||
}
|
|
||||||
jsonBuilder.endArray();
|
|
||||||
}
|
|
||||||
String from = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
from = randomAlphaOfLength(10);
|
|
||||||
jsonBuilder.field("from", from);
|
|
||||||
}
|
|
||||||
TextTemplate color = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
color = new TextTemplate(randomAlphaOfLength(10));
|
|
||||||
jsonBuilder.field("color", color, ToXContent.EMPTY_PARAMS);
|
|
||||||
}
|
|
||||||
HipChatMessage.Format format = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
format = randomFrom(HipChatMessage.Format.values());
|
|
||||||
jsonBuilder.field("format", format.value());
|
|
||||||
}
|
|
||||||
Boolean notify = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
notify = randomBoolean();
|
|
||||||
jsonBuilder.field("notify", notify);
|
|
||||||
}
|
|
||||||
|
|
||||||
BytesReference bytes = BytesReference.bytes(jsonBuilder.endObject());
|
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
HipChatMessage.Template template = HipChatMessage.Template.parse(parser);
|
|
||||||
|
|
||||||
assertThat(template, notNullValue());
|
|
||||||
assertThat(template.body, is(body));
|
|
||||||
if (rooms == null) {
|
|
||||||
assertThat(template.rooms, nullValue());
|
|
||||||
} else {
|
|
||||||
assertThat(template.rooms, arrayContaining(rooms));
|
|
||||||
}
|
|
||||||
if (users == null) {
|
|
||||||
assertThat(template.users, nullValue());
|
|
||||||
} else {
|
|
||||||
assertThat(template.users, arrayContaining(users));
|
|
||||||
}
|
|
||||||
assertThat(template.from, is(from));
|
|
||||||
assertThat(template.color, is(color));
|
|
||||||
assertThat(template.format, is(format));
|
|
||||||
assertThat(template.notify, is(notify));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTemplateParseSelfGenerated() throws Exception {
|
|
||||||
TextTemplate body = new TextTemplate(randomAlphaOfLength(10));
|
|
||||||
HipChatMessage.Template.Builder templateBuilder = new HipChatMessage.Template.Builder(body);
|
|
||||||
|
|
||||||
if (randomBoolean()) {
|
|
||||||
int count = randomIntBetween(1, 3);
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
templateBuilder.addRooms(new TextTemplate(randomAlphaOfLength(10)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
int count = randomIntBetween(1, 3);
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
templateBuilder.addUsers(new TextTemplate(randomAlphaOfLength(10)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
templateBuilder.setFrom(randomAlphaOfLength(10));
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
templateBuilder.setColor(new TextTemplate(randomAlphaOfLength(5)));
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
templateBuilder.setFormat(randomFrom(HipChatMessage.Format.values()));
|
|
||||||
}
|
|
||||||
if (randomBoolean()) {
|
|
||||||
templateBuilder.setNotify(randomBoolean());
|
|
||||||
}
|
|
||||||
HipChatMessage.Template template = templateBuilder.build();
|
|
||||||
|
|
||||||
XContentBuilder jsonBuilder = jsonBuilder();
|
|
||||||
template.toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS);
|
|
||||||
BytesReference bytes = BytesReference.bytes(jsonBuilder);
|
|
||||||
|
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
|
|
||||||
parser.nextToken();
|
|
||||||
|
|
||||||
HipChatMessage.Template parsed = HipChatMessage.Template.parse(parser);
|
|
||||||
|
|
||||||
assertThat(parsed, equalTo(template));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAuthTokenParamIsFiltered() throws Exception {
|
|
||||||
HttpResponse response = new HttpResponse(500);
|
|
||||||
String token = randomAlphaOfLength(20);
|
|
||||||
HttpRequest request = HttpRequest.builder("localhost", 1234).setParam("auth_token", token).build();
|
|
||||||
|
|
||||||
// String body, String[] rooms, String[] users, String from, Format format, Color color, Boolean notify
|
|
||||||
HipChatMessage hipChatMessage = new HipChatMessage("body", new String[]{"room"}, null, "from",
|
|
||||||
HipChatMessage.Format.TEXT, HipChatMessage.Color.RED, false);
|
|
||||||
SentMessages.SentMessage sentMessage = SentMessages.SentMessage.responded("targetName", SentMessages.SentMessage.TargetType.ROOM,
|
|
||||||
hipChatMessage, request, response);
|
|
||||||
|
|
||||||
|
|
||||||
try (XContentBuilder builder = jsonBuilder()) {
|
|
||||||
WatcherParams params = WatcherParams.builder().hideSecrets(false).build();
|
|
||||||
sentMessage.toXContent(builder, params);
|
|
||||||
assertThat(Strings.toString(builder), containsString(token));
|
|
||||||
|
|
||||||
try (XContentParser parser = builder.contentType().xContent()
|
|
||||||
.createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
|
|
||||||
Strings.toString(builder))) {
|
|
||||||
parser.map();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try (XContentBuilder builder = jsonBuilder()) {
|
|
||||||
sentMessage.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
|
||||||
assertThat(Strings.toString(builder), not(containsString(token)));
|
|
||||||
|
|
||||||
try (XContentParser parser = builder.contentType().xContent()
|
|
||||||
.createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
|
|
||||||
Strings.toString(builder))) {
|
|
||||||
parser.map();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static <E extends Enum> E randomFromWithExcludes(E[] values, E... exclude) {
|
|
||||||
List<E> excludes = Arrays.asList(exclude);
|
|
||||||
List<E> includes = new ArrayList<>();
|
|
||||||
for (E value : values) {
|
|
||||||
if (!excludes.contains(value)) {
|
|
||||||
includes.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return randomFrom(includes);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,279 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.ClusterSettings;
|
|
||||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.settings.SettingsException;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.junit.Before;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.arrayContaining;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.hamcrest.Matchers.sameInstance;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
public class HipChatServiceTests extends ESTestCase {
|
|
||||||
private HttpClient httpClient;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() throws Exception {
|
|
||||||
httpClient = mock(HttpClient.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSingleAccountV1() throws Exception {
|
|
||||||
String accountName = randomAlphaOfLength(10);
|
|
||||||
String host = randomBoolean() ? null : "_host";
|
|
||||||
int port = randomBoolean() ? -1 : randomIntBetween(300, 400);
|
|
||||||
String defaultRoom = randomBoolean() ? null : "_r1, _r2";
|
|
||||||
String defaultFrom = randomBoolean() ? null : "_from";
|
|
||||||
HipChatMessage.Color defaultColor = randomBoolean() ? null : randomFrom(HipChatMessage.Color.values());
|
|
||||||
HipChatMessage.Format defaultFormat = randomBoolean() ? null : randomFrom(HipChatMessage.Format.values());
|
|
||||||
Boolean defaultNotify = randomBoolean() ? null : (Boolean) randomBoolean();
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString("xpack.notification.hipchat.account." + accountName + ".secure_auth_token", "_token");
|
|
||||||
Settings.Builder settingsBuilder = Settings.builder()
|
|
||||||
.put("xpack.notification.hipchat.account." + accountName + ".profile", HipChatAccount.Profile.V1.value())
|
|
||||||
.setSecureSettings(secureSettings);
|
|
||||||
if (host != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".host", host);
|
|
||||||
}
|
|
||||||
if (port > 0) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".port", port);
|
|
||||||
}
|
|
||||||
buildMessageDefaults(accountName, settingsBuilder, defaultRoom, null, defaultFrom, defaultColor, defaultFormat, defaultNotify);
|
|
||||||
HipChatService service = new HipChatService(settingsBuilder.build(), httpClient,
|
|
||||||
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings())));
|
|
||||||
|
|
||||||
HipChatAccount account = service.getAccount(accountName);
|
|
||||||
assertThat(account, notNullValue());
|
|
||||||
assertThat(account.name, is(accountName));
|
|
||||||
assertThat(account.authToken, is("_token"));
|
|
||||||
assertThat(account.profile, is(HipChatAccount.Profile.V1));
|
|
||||||
assertThat(account.httpClient, is(httpClient));
|
|
||||||
assertThat(account.server, notNullValue());
|
|
||||||
assertThat(account.server.host(), is(host != null ? host : HipChatServer.DEFAULT.host()));
|
|
||||||
assertThat(account.server.port(), is(port > 0 ? port : HipChatServer.DEFAULT.port()));
|
|
||||||
assertThat(account, instanceOf(V1Account.class));
|
|
||||||
if (defaultRoom == null) {
|
|
||||||
assertThat(((V1Account) account).defaults.rooms, nullValue());
|
|
||||||
} else {
|
|
||||||
assertThat(((V1Account) account).defaults.rooms, arrayContaining("_r1", "_r2"));
|
|
||||||
}
|
|
||||||
assertThat(((V1Account) account).defaults.from, is(defaultFrom));
|
|
||||||
assertThat(((V1Account) account).defaults.color, is(defaultColor));
|
|
||||||
assertThat(((V1Account) account).defaults.format, is(defaultFormat));
|
|
||||||
assertThat(((V1Account) account).defaults.notify, is(defaultNotify));
|
|
||||||
|
|
||||||
// with a single account defined, making sure that that account is set to the default one.
|
|
||||||
assertThat(service.getAccount(null), sameInstance(account));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSingleAccountIntegration() throws Exception {
|
|
||||||
String accountName = randomAlphaOfLength(10);
|
|
||||||
String host = randomBoolean() ? null : "_host";
|
|
||||||
int port = randomBoolean() ? -1 : randomIntBetween(300, 400);
|
|
||||||
String room = randomAlphaOfLength(10);
|
|
||||||
String defaultFrom = randomBoolean() ? null : "_from";
|
|
||||||
HipChatMessage.Color defaultColor = randomBoolean() ? null : randomFrom(HipChatMessage.Color.values());
|
|
||||||
HipChatMessage.Format defaultFormat = randomBoolean() ? null : randomFrom(HipChatMessage.Format.values());
|
|
||||||
Boolean defaultNotify = randomBoolean() ? null : (Boolean) randomBoolean();
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString("xpack.notification.hipchat.account." + accountName + ".secure_auth_token", "_token");
|
|
||||||
Settings.Builder settingsBuilder = Settings.builder()
|
|
||||||
.put("xpack.notification.hipchat.account." + accountName + ".profile",
|
|
||||||
HipChatAccount.Profile.INTEGRATION.value())
|
|
||||||
.setSecureSettings(secureSettings)
|
|
||||||
.put("xpack.notification.hipchat.account." + accountName + ".room", room);
|
|
||||||
if (host != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".host", host);
|
|
||||||
}
|
|
||||||
if (port > 0) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".port", port);
|
|
||||||
}
|
|
||||||
buildMessageDefaults(accountName, settingsBuilder, null, null, defaultFrom, defaultColor, defaultFormat, defaultNotify);
|
|
||||||
HipChatService service = new HipChatService(settingsBuilder.build(), httpClient,
|
|
||||||
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings())));
|
|
||||||
|
|
||||||
HipChatAccount account = service.getAccount(accountName);
|
|
||||||
assertThat(account, notNullValue());
|
|
||||||
assertThat(account.name, is(accountName));
|
|
||||||
assertThat(account.authToken, is("_token"));
|
|
||||||
assertThat(account.profile, is(HipChatAccount.Profile.INTEGRATION));
|
|
||||||
assertThat(account.httpClient, is(httpClient));
|
|
||||||
assertThat(account.server, notNullValue());
|
|
||||||
assertThat(account.server.host(), is(host != null ? host : HipChatServer.DEFAULT.host()));
|
|
||||||
assertThat(account.server.port(), is(port > 0 ? port : HipChatServer.DEFAULT.port()));
|
|
||||||
assertThat(account, instanceOf(IntegrationAccount.class));
|
|
||||||
assertThat(((IntegrationAccount) account).room, is(room));
|
|
||||||
assertThat(((IntegrationAccount) account).defaults.color, is(defaultColor));
|
|
||||||
assertThat(((IntegrationAccount) account).defaults.format, is(defaultFormat));
|
|
||||||
assertThat(((IntegrationAccount) account).defaults.notify, is(defaultNotify));
|
|
||||||
|
|
||||||
// with a single account defined, making sure that that account is set to the default one.
|
|
||||||
assertThat(service.getAccount(null), sameInstance(account));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSingleAccountIntegrationNoRoomSetting() throws Exception {
|
|
||||||
String accountName = randomAlphaOfLength(10);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString("xpack.notification.hipchat.account." + accountName + ".secure_auth_token", "_token");
|
|
||||||
Settings.Builder settingsBuilder = Settings.builder()
|
|
||||||
.put("xpack.notification.hipchat.account." + accountName + ".profile",
|
|
||||||
HipChatAccount.Profile.INTEGRATION.value())
|
|
||||||
.setSecureSettings(secureSettings);
|
|
||||||
SettingsException e = expectThrows(SettingsException.class, () ->
|
|
||||||
new HipChatService(settingsBuilder.build(), httpClient,
|
|
||||||
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings()))).getAccount(null));
|
|
||||||
assertThat(e.getMessage(), containsString("missing required [room] setting for [integration] account profile"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSingleAccountUser() throws Exception {
|
|
||||||
String accountName = randomAlphaOfLength(10);
|
|
||||||
String host = randomBoolean() ? null : "_host";
|
|
||||||
int port = randomBoolean() ? -1 : randomIntBetween(300, 400);
|
|
||||||
String defaultRoom = randomBoolean() ? null : "_r1, _r2";
|
|
||||||
String defaultUser = randomBoolean() ? null : "_u1, _u2";
|
|
||||||
HipChatMessage.Color defaultColor = randomBoolean() ? null : randomFrom(HipChatMessage.Color.values());
|
|
||||||
HipChatMessage.Format defaultFormat = randomBoolean() ? null : randomFrom(HipChatMessage.Format.values());
|
|
||||||
Boolean defaultNotify = randomBoolean() ? null : (Boolean) randomBoolean();
|
|
||||||
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString("xpack.notification.hipchat.account." + accountName + ".secure_auth_token", "_token");
|
|
||||||
Settings.Builder settingsBuilder = Settings.builder()
|
|
||||||
.put("xpack.notification.hipchat.account." + accountName + ".profile", HipChatAccount.Profile.USER.value())
|
|
||||||
.setSecureSettings(secureSettings);
|
|
||||||
if (host != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".host", host);
|
|
||||||
}
|
|
||||||
if (port > 0) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + accountName + ".port", port);
|
|
||||||
}
|
|
||||||
buildMessageDefaults(accountName, settingsBuilder, defaultRoom, defaultUser, null, defaultColor, defaultFormat, defaultNotify);
|
|
||||||
HipChatService service = new HipChatService(settingsBuilder.build(), httpClient,
|
|
||||||
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings())));
|
|
||||||
|
|
||||||
HipChatAccount account = service.getAccount(accountName);
|
|
||||||
assertThat(account, notNullValue());
|
|
||||||
assertThat(account.name, is(accountName));
|
|
||||||
assertThat(account.authToken, is("_token"));
|
|
||||||
assertThat(account.profile, is(HipChatAccount.Profile.USER));
|
|
||||||
assertThat(account.httpClient, is(httpClient));
|
|
||||||
assertThat(account.server, notNullValue());
|
|
||||||
assertThat(account.server.host(), is(host != null ? host : HipChatServer.DEFAULT.host()));
|
|
||||||
assertThat(account.server.port(), is(port > 0 ? port : HipChatServer.DEFAULT.port()));
|
|
||||||
assertThat(account, instanceOf(UserAccount.class));
|
|
||||||
if (defaultRoom == null) {
|
|
||||||
assertThat(((UserAccount) account).defaults.rooms, nullValue());
|
|
||||||
} else {
|
|
||||||
assertThat(((UserAccount) account).defaults.rooms, arrayContaining("_r1", "_r2"));
|
|
||||||
}
|
|
||||||
if (defaultUser == null) {
|
|
||||||
assertThat(((UserAccount) account).defaults.users, nullValue());
|
|
||||||
} else {
|
|
||||||
assertThat(((UserAccount) account).defaults.users, arrayContaining("_u1", "_u2"));
|
|
||||||
}
|
|
||||||
assertThat(((UserAccount) account).defaults.color, is(defaultColor));
|
|
||||||
assertThat(((UserAccount) account).defaults.format, is(defaultFormat));
|
|
||||||
assertThat(((UserAccount) account).defaults.notify, is(defaultNotify));
|
|
||||||
|
|
||||||
// with a single account defined, making sure that that account is set to the default one.
|
|
||||||
assertThat(service.getAccount(null), sameInstance(account));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testMultipleAccounts() throws Exception {
|
|
||||||
HipChatMessage.Color defaultColor = randomBoolean() ? null : randomFrom(HipChatMessage.Color.values());
|
|
||||||
HipChatMessage.Format defaultFormat = randomBoolean() ? null : randomFrom(HipChatMessage.Format.values());
|
|
||||||
Boolean defaultNotify = randomBoolean() ? null : (Boolean) randomBoolean();
|
|
||||||
Settings.Builder settingsBuilder = Settings.builder();
|
|
||||||
String defaultAccount = "_a" + randomIntBetween(0, 4);
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.default_account", defaultAccount);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
settingsBuilder.setSecureSettings(secureSettings);
|
|
||||||
|
|
||||||
final boolean customGlobalServer = randomBoolean();
|
|
||||||
if (customGlobalServer) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.host", "_host_global");
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.port", 299);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
String name = "_a" + i;
|
|
||||||
String prefix = "xpack.notification.hipchat.account." + name;
|
|
||||||
HipChatAccount.Profile profile = randomFrom(HipChatAccount.Profile.values());
|
|
||||||
settingsBuilder.put(prefix + ".profile", profile);
|
|
||||||
secureSettings.setString(prefix + ".secure_auth_token", "_token" + i);
|
|
||||||
if (profile == HipChatAccount.Profile.INTEGRATION) {
|
|
||||||
settingsBuilder.put(prefix + ".room", "_room" + i);
|
|
||||||
}
|
|
||||||
if (i % 2 == 0) {
|
|
||||||
settingsBuilder.put(prefix + ".host", "_host" + i);
|
|
||||||
settingsBuilder.put(prefix + ".port", 300 + i);
|
|
||||||
}
|
|
||||||
buildMessageDefaults(name, settingsBuilder, null, null, null, defaultColor, defaultFormat, defaultNotify);
|
|
||||||
}
|
|
||||||
|
|
||||||
HipChatService service = new HipChatService(settingsBuilder.build(), httpClient,
|
|
||||||
new ClusterSettings(settingsBuilder.build(), new HashSet<>(HipChatService.getSettings())));
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
String name = "_a" + i;
|
|
||||||
HipChatAccount account = service.getAccount(name);
|
|
||||||
assertThat(account, notNullValue());
|
|
||||||
assertThat(account.name, is(name));
|
|
||||||
assertThat(account.authToken, is("_token" + i));
|
|
||||||
assertThat(account.profile, notNullValue());
|
|
||||||
if (account.profile == HipChatAccount.Profile.INTEGRATION) {
|
|
||||||
assertThat(account, instanceOf(IntegrationAccount.class));
|
|
||||||
assertThat(((IntegrationAccount) account).room, is("_room" + i));
|
|
||||||
}
|
|
||||||
assertThat(account.httpClient, is(httpClient));
|
|
||||||
assertThat(account.server, notNullValue());
|
|
||||||
if (i % 2 == 0) {
|
|
||||||
assertThat(account.server.host(), is("_host" + i));
|
|
||||||
assertThat(account.server.port(), is(300 + i));
|
|
||||||
} else if (customGlobalServer) {
|
|
||||||
assertThat(account.server.host(), is("_host_global"));
|
|
||||||
assertThat(account.server.port(), is(299));
|
|
||||||
} else {
|
|
||||||
assertThat(account.server.host(), is(HipChatServer.DEFAULT.host()));
|
|
||||||
assertThat(account.server.port(), is(HipChatServer.DEFAULT.port()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertThat(service.getAccount(null), sameInstance(service.getAccount(defaultAccount)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildMessageDefaults(String account, Settings.Builder settingsBuilder, String room, String user, String from,
|
|
||||||
HipChatMessage.Color color, HipChatMessage.Format format, Boolean notify) {
|
|
||||||
if (room != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + account + ".message_defaults.room", room);
|
|
||||||
}
|
|
||||||
if (user != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + account + ".message_defaults.user", user);
|
|
||||||
}
|
|
||||||
if (from != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + account + ".message_defaults.from", from);
|
|
||||||
}
|
|
||||||
if (color != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + account + ".message_defaults.color", color.value());
|
|
||||||
}
|
|
||||||
if (format != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + account + ".message_defaults.format", format);
|
|
||||||
}
|
|
||||||
if (notify != null) {
|
|
||||||
settingsBuilder.put("xpack.notification.hipchat.account." + account + ".message_defaults.notify", notify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,181 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.settings.SettingsException;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.Scheme;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
public class IntegrationAccountTests extends ESTestCase {
|
|
||||||
|
|
||||||
public void testSettings() throws Exception {
|
|
||||||
String accountName = "_name";
|
|
||||||
|
|
||||||
Settings.Builder sb = Settings.builder();
|
|
||||||
|
|
||||||
String authToken = randomAlphaOfLength(50);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
|
|
||||||
sb.setSecureSettings(secureSettings);
|
|
||||||
|
|
||||||
String host = HipChatServer.DEFAULT.host();
|
|
||||||
if (randomBoolean()) {
|
|
||||||
host = randomAlphaOfLength(10);
|
|
||||||
sb.put("host", host);
|
|
||||||
}
|
|
||||||
int port = HipChatServer.DEFAULT.port();
|
|
||||||
if (randomBoolean()) {
|
|
||||||
port = randomIntBetween(300, 400);
|
|
||||||
sb.put("port", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
String room = randomAlphaOfLength(10);
|
|
||||||
sb.put(IntegrationAccount.ROOM_SETTING, room);
|
|
||||||
|
|
||||||
HipChatMessage.Format defaultFormat = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultFormat = randomFrom(HipChatMessage.Format.values());
|
|
||||||
sb.put(HipChatAccount.DEFAULT_FORMAT_SETTING, defaultFormat);
|
|
||||||
}
|
|
||||||
HipChatMessage.Color defaultColor = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultColor = randomFrom(HipChatMessage.Color.values());
|
|
||||||
sb.put(HipChatAccount.DEFAULT_COLOR_SETTING, defaultColor);
|
|
||||||
}
|
|
||||||
Boolean defaultNotify = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultNotify = randomBoolean();
|
|
||||||
sb.put(HipChatAccount.DEFAULT_NOTIFY_SETTING, defaultNotify);
|
|
||||||
}
|
|
||||||
Settings settings = sb.build();
|
|
||||||
|
|
||||||
IntegrationAccount account = new IntegrationAccount(accountName, settings, HipChatServer.DEFAULT, mock(HttpClient.class),
|
|
||||||
mock(Logger.class));
|
|
||||||
|
|
||||||
assertThat(account.profile, is(HipChatAccount.Profile.INTEGRATION));
|
|
||||||
assertThat(account.name, equalTo(accountName));
|
|
||||||
assertThat(account.server.host(), is(host));
|
|
||||||
assertThat(account.server.port(), is(port));
|
|
||||||
assertThat(account.authToken, is(authToken));
|
|
||||||
assertThat(account.room, is(room));
|
|
||||||
assertThat(account.defaults.format, is(defaultFormat));
|
|
||||||
assertThat(account.defaults.color, is(defaultColor));
|
|
||||||
assertThat(account.defaults.notify, is(defaultNotify));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSettingsNoAuthToken() throws Exception {
|
|
||||||
Settings.Builder sb = Settings.builder();
|
|
||||||
sb.put(IntegrationAccount.ROOM_SETTING, randomAlphaOfLength(10));
|
|
||||||
try {
|
|
||||||
new IntegrationAccount("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
|
|
||||||
fail("Expected SettingsException");
|
|
||||||
} catch (SettingsException e) {
|
|
||||||
assertThat(e.getMessage(), is("hipchat account [_name] missing required [secure_auth_token] secure setting"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSettingsWithoutRoom() throws Exception {
|
|
||||||
Settings.Builder sb = Settings.builder();
|
|
||||||
String authToken = randomAlphaOfLength(50);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
|
|
||||||
sb.setSecureSettings(secureSettings);
|
|
||||||
try {
|
|
||||||
new IntegrationAccount("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
|
|
||||||
fail("Expected SettingsException");
|
|
||||||
} catch (SettingsException e) {
|
|
||||||
assertThat(e.getMessage(), containsString("missing required [room] setting for [integration] account profile"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSettingsWithoutMultipleRooms() throws Exception {
|
|
||||||
Settings.Builder sb = Settings.builder();
|
|
||||||
String authToken = randomAlphaOfLength(50);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
|
|
||||||
sb.setSecureSettings(secureSettings);
|
|
||||||
sb.put(IntegrationAccount.ROOM_SETTING, "_r1,_r2");
|
|
||||||
try {
|
|
||||||
new IntegrationAccount("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
|
|
||||||
fail("Expected SettingsException");
|
|
||||||
} catch (SettingsException e) {
|
|
||||||
assertThat(e.getMessage(), containsString("[room] setting for [integration] account must only be set with a single value"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSend() throws Exception {
|
|
||||||
String token = randomAlphaOfLength(10);
|
|
||||||
HttpClient httpClient = mock(HttpClient.class);
|
|
||||||
String room = "Room with Spaces";
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), token);
|
|
||||||
IntegrationAccount account = new IntegrationAccount("_name", Settings.builder()
|
|
||||||
.put("host", "_host")
|
|
||||||
.put("port", "443")
|
|
||||||
.setSecureSettings(secureSettings)
|
|
||||||
.put("room", room)
|
|
||||||
.build(), HipChatServer.DEFAULT, httpClient, mock(Logger.class));
|
|
||||||
|
|
||||||
HipChatMessage.Format format = randomFrom(HipChatMessage.Format.values());
|
|
||||||
HipChatMessage.Color color = randomFrom(HipChatMessage.Color.values());
|
|
||||||
Boolean notify = randomBoolean();
|
|
||||||
final HipChatMessage message = new HipChatMessage("_body", null, null, null, format, color, notify);
|
|
||||||
|
|
||||||
HttpRequest req = HttpRequest.builder("_host", 443)
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
// url encoded already
|
|
||||||
.path("/v2/room/Room+with+Spaces/notification")
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setHeader("Authorization", "Bearer " + token)
|
|
||||||
.body(Strings.toString((builder, params) -> {
|
|
||||||
builder.field("message", message.body);
|
|
||||||
if (message.format != null) {
|
|
||||||
builder.field("message_format", message.format.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
builder.field("notify", message.notify);
|
|
||||||
}
|
|
||||||
if (message.color != null) {
|
|
||||||
builder.field("color", String.valueOf(message.color.value()));
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse res = mock(HttpResponse.class);
|
|
||||||
when(res.status()).thenReturn(200);
|
|
||||||
when(httpClient.execute(req)).thenReturn(res);
|
|
||||||
|
|
||||||
SentMessages sentMessages = account.send(message, null);
|
|
||||||
verify(httpClient).execute(req);
|
|
||||||
assertThat(sentMessages.asList(), hasSize(1));
|
|
||||||
try (XContentBuilder builder = jsonBuilder()) {
|
|
||||||
sentMessages.asList().get(0).toXContent(builder, ToXContent.EMPTY_PARAMS);
|
|
||||||
assertThat(Strings.toString(builder), not(containsString(token)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,313 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
|
||||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.settings.SettingsException;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpProxy;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.Scheme;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
|
|
||||||
import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
||||||
import static org.hamcrest.Matchers.arrayContaining;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
public class UserAccountTests extends ESTestCase {
|
|
||||||
|
|
||||||
public void testSettings() throws Exception {
|
|
||||||
String accountName = "_name";
|
|
||||||
|
|
||||||
Settings.Builder sb = Settings.builder();
|
|
||||||
|
|
||||||
String authToken = randomAlphaOfLength(50);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(UserAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
|
|
||||||
sb.setSecureSettings(secureSettings);
|
|
||||||
|
|
||||||
String host = HipChatServer.DEFAULT.host();
|
|
||||||
if (randomBoolean()) {
|
|
||||||
host = randomAlphaOfLength(10);
|
|
||||||
sb.put("host", host);
|
|
||||||
}
|
|
||||||
int port = HipChatServer.DEFAULT.port();
|
|
||||||
if (randomBoolean()) {
|
|
||||||
port = randomIntBetween(300, 400);
|
|
||||||
sb.put("port", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] defaultRooms = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultRooms = new String[] { "_r1", "_r2" };
|
|
||||||
sb.put(HipChatAccount.DEFAULT_ROOM_SETTING, "_r1,_r2");
|
|
||||||
}
|
|
||||||
String[] defaultUsers = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultUsers = new String[] { "_u1", "_u2" };
|
|
||||||
sb.put(HipChatAccount.DEFAULT_USER_SETTING, "_u1,_u2");
|
|
||||||
}
|
|
||||||
HipChatMessage.Format defaultFormat = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultFormat = randomFrom(HipChatMessage.Format.values());
|
|
||||||
sb.put(HipChatAccount.DEFAULT_FORMAT_SETTING, defaultFormat);
|
|
||||||
}
|
|
||||||
HipChatMessage.Color defaultColor = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultColor = randomFrom(HipChatMessage.Color.values());
|
|
||||||
sb.put(HipChatAccount.DEFAULT_COLOR_SETTING, defaultColor);
|
|
||||||
}
|
|
||||||
Boolean defaultNotify = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultNotify = randomBoolean();
|
|
||||||
sb.put(HipChatAccount.DEFAULT_NOTIFY_SETTING, defaultNotify);
|
|
||||||
}
|
|
||||||
Settings settings = sb.build();
|
|
||||||
|
|
||||||
UserAccount account = new UserAccount(accountName, settings, HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
|
|
||||||
|
|
||||||
assertThat(account.profile, is(HipChatAccount.Profile.USER));
|
|
||||||
assertThat(account.name, equalTo(accountName));
|
|
||||||
assertThat(account.server.host(), is(host));
|
|
||||||
assertThat(account.server.port(), is(port));
|
|
||||||
assertThat(account.authToken, is(authToken));
|
|
||||||
if (defaultRooms != null) {
|
|
||||||
assertThat(account.defaults.rooms, arrayContaining(defaultRooms));
|
|
||||||
} else {
|
|
||||||
assertThat(account.defaults.rooms, nullValue());
|
|
||||||
}
|
|
||||||
if (defaultUsers != null) {
|
|
||||||
assertThat(account.defaults.users, arrayContaining(defaultUsers));
|
|
||||||
} else {
|
|
||||||
assertThat(account.defaults.users, nullValue());
|
|
||||||
}
|
|
||||||
assertThat(account.defaults.format, is(defaultFormat));
|
|
||||||
assertThat(account.defaults.color, is(defaultColor));
|
|
||||||
assertThat(account.defaults.notify, is(defaultNotify));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSettingsNoAuthToken() throws Exception {
|
|
||||||
Settings.Builder sb = Settings.builder();
|
|
||||||
try {
|
|
||||||
new UserAccount("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
|
|
||||||
fail("Expected SettingsException");
|
|
||||||
} catch (SettingsException e) {
|
|
||||||
assertThat(e.getMessage(), is("hipchat account [_name] missing required [secure_auth_token] secure setting"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSend() throws Exception {
|
|
||||||
HttpClient httpClient = mock(HttpClient.class);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "_token");
|
|
||||||
UserAccount account = new UserAccount("_name", Settings.builder()
|
|
||||||
.put("host", "_host")
|
|
||||||
.put("port", "443")
|
|
||||||
.setSecureSettings(secureSettings)
|
|
||||||
.build(), HipChatServer.DEFAULT, httpClient, mock(Logger.class));
|
|
||||||
|
|
||||||
HipChatMessage.Format format = randomFrom(HipChatMessage.Format.values());
|
|
||||||
HipChatMessage.Color color = randomFrom(HipChatMessage.Color.values());
|
|
||||||
Boolean notify = randomBoolean();
|
|
||||||
final HipChatMessage message = new HipChatMessage("_body", new String[] { "_r1", "_r2" }, new String[] { "_u1", "_u2" }, null,
|
|
||||||
format, color, notify);
|
|
||||||
|
|
||||||
HttpRequest reqR1 = HttpRequest.builder("_host", 443)
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v2/room/_r1/notification")
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setHeader("Authorization", "Bearer _token")
|
|
||||||
.body(Strings.toString((builder, params) -> {
|
|
||||||
builder.field("message", message.body);
|
|
||||||
if (message.format != null) {
|
|
||||||
builder.field("message_format", message.format.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
builder.field("notify", message.notify);
|
|
||||||
}
|
|
||||||
if (message.color != null) {
|
|
||||||
builder.field("color", String.valueOf(message.color.value()));
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
logger.info("expected (r1): {}", BytesReference.bytes(jsonBuilder().value(reqR1)).utf8ToString());
|
|
||||||
|
|
||||||
HttpResponse resR1 = mock(HttpResponse.class);
|
|
||||||
when(resR1.status()).thenReturn(200);
|
|
||||||
when(httpClient.execute(reqR1)).thenReturn(resR1);
|
|
||||||
|
|
||||||
HttpRequest reqR2 = HttpRequest.builder("_host", 443)
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v2/room/_r2/notification")
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setHeader("Authorization", "Bearer _token")
|
|
||||||
.body(Strings.toString((builder, params) -> {
|
|
||||||
builder.field("message", message.body);
|
|
||||||
if (message.format != null) {
|
|
||||||
builder.field("message_format", message.format.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
builder.field("notify", message.notify);
|
|
||||||
}
|
|
||||||
if (message.color != null) {
|
|
||||||
builder.field("color", String.valueOf(message.color.value()));
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
logger.info("expected (r2): {}", BytesReference.bytes(jsonBuilder().value(reqR1)).utf8ToString());
|
|
||||||
|
|
||||||
HttpResponse resR2 = mock(HttpResponse.class);
|
|
||||||
when(resR2.status()).thenReturn(200);
|
|
||||||
when(httpClient.execute(reqR2)).thenReturn(resR2);
|
|
||||||
|
|
||||||
HttpRequest reqU1 = HttpRequest.builder("_host", 443)
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v2/user/_u1/message")
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setHeader("Authorization", "Bearer _token")
|
|
||||||
.body(Strings.toString((builder, params) -> {
|
|
||||||
builder.field("message", message.body);
|
|
||||||
if (message.format != null) {
|
|
||||||
builder.field("message_format", message.format.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
builder.field("notify", message.notify);
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
logger.info("expected (u1): {}", BytesReference.bytes(jsonBuilder().value(reqU1)).utf8ToString());
|
|
||||||
|
|
||||||
HttpResponse resU1 = mock(HttpResponse.class);
|
|
||||||
when(resU1.status()).thenReturn(200);
|
|
||||||
when(httpClient.execute(reqU1)).thenReturn(resU1);
|
|
||||||
|
|
||||||
HttpRequest reqU2 = HttpRequest.builder("_host", 443)
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v2/user/_u2/message")
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setHeader("Authorization", "Bearer _token")
|
|
||||||
.body(Strings.toString((builder, params) -> {
|
|
||||||
builder.field("message", message.body);
|
|
||||||
if (message.format != null) {
|
|
||||||
builder.field("message_format", message.format.value());
|
|
||||||
}
|
|
||||||
if (message.notify != null) {
|
|
||||||
builder.field("notify", message.notify);
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
logger.info("expected (u2): {}", BytesReference.bytes(jsonBuilder().value(reqU2)).utf8ToString());
|
|
||||||
|
|
||||||
HttpResponse resU2 = mock(HttpResponse.class);
|
|
||||||
when(resU2.status()).thenReturn(200);
|
|
||||||
when(httpClient.execute(reqU2)).thenReturn(resU2);
|
|
||||||
|
|
||||||
account.send(message, null);
|
|
||||||
|
|
||||||
verify(httpClient).execute(reqR1);
|
|
||||||
verify(httpClient).execute(reqR2);
|
|
||||||
verify(httpClient).execute(reqU2);
|
|
||||||
verify(httpClient).execute(reqU2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testColorIsOptional() throws Exception {
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "awesome-auth-token");
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put("user", "testuser")
|
|
||||||
.setSecureSettings(secureSettings)
|
|
||||||
.build();
|
|
||||||
UserAccount userAccount = createUserAccount(settings);
|
|
||||||
|
|
||||||
TextTemplate body = new TextTemplate("body");
|
|
||||||
TextTemplate[] rooms = new TextTemplate[] { new TextTemplate("room")};
|
|
||||||
HipChatMessage.Template template =
|
|
||||||
new HipChatMessage.Template(body, rooms, null, "sender", HipChatMessage.Format.TEXT, null, true);
|
|
||||||
|
|
||||||
HipChatMessage message = userAccount.render("watchId", "actionId", new MockTextTemplateEngine(), template, new HashMap<>());
|
|
||||||
assertThat(message.color, is(nullValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testFormatIsOptional() throws Exception {
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "awesome-auth-token");
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put("user", "testuser")
|
|
||||||
.setSecureSettings(secureSettings)
|
|
||||||
.build();
|
|
||||||
UserAccount userAccount = createUserAccount(settings);
|
|
||||||
|
|
||||||
TextTemplate body = new TextTemplate("body");
|
|
||||||
TextTemplate[] rooms = new TextTemplate[] { new TextTemplate("room") };
|
|
||||||
HipChatMessage.Template template = new HipChatMessage.Template(body, rooms, null, "sender", null,
|
|
||||||
new TextTemplate("yellow"), true);
|
|
||||||
|
|
||||||
HipChatMessage message = userAccount.render("watchId", "actionId", new MockTextTemplateEngine(), template, new HashMap<>());
|
|
||||||
assertThat(message.format, is(nullValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRoomNameIsUrlEncoded() throws Exception {
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "awesome-auth-token");
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put("user", "testuser")
|
|
||||||
.setSecureSettings(secureSettings)
|
|
||||||
.build();
|
|
||||||
HipChatServer hipChatServer = mock(HipChatServer.class);
|
|
||||||
HttpClient httpClient = mock(HttpClient.class);
|
|
||||||
UserAccount account = new UserAccount("notify-monitoring", settings, hipChatServer, httpClient, logger);
|
|
||||||
|
|
||||||
TextTemplate[] rooms = new TextTemplate[] { new TextTemplate("Room with Spaces")};
|
|
||||||
HipChatMessage.Template template =
|
|
||||||
new HipChatMessage.Template(new TextTemplate("body"), rooms, null, "sender", HipChatMessage.Format.TEXT, null, true);
|
|
||||||
|
|
||||||
HipChatMessage message = account.render("watchId", "actionId", new MockTextTemplateEngine(), template, new HashMap<>());
|
|
||||||
account.send(message, HttpProxy.NO_PROXY);
|
|
||||||
|
|
||||||
ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
|
|
||||||
verify(httpClient).execute(captor.capture());
|
|
||||||
assertThat(captor.getAllValues(), hasSize(1));
|
|
||||||
assertThat(captor.getValue().path(), not(containsString("Room with Spaces")));
|
|
||||||
assertThat(captor.getValue().path(), containsString("Room%20with%20Spaces"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private UserAccount createUserAccount(Settings settings) {
|
|
||||||
HipChatServer hipChatServer = mock(HipChatServer.class);
|
|
||||||
HttpClient httpClient = mock(HttpClient.class);
|
|
||||||
return new UserAccount("notify-monitoring", settings, hipChatServer, httpClient, logger);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,174 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.watcher.notification.hipchat;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
|
||||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.settings.SettingsException;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpClient;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpMethod;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpRequest;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.HttpResponse;
|
|
||||||
import org.elasticsearch.xpack.watcher.common.http.Scheme;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
|
||||||
import static org.hamcrest.Matchers.arrayContaining;
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
public class V1AccountTests extends ESTestCase {
|
|
||||||
public void testSettings() throws Exception {
|
|
||||||
String accountName = "_name";
|
|
||||||
|
|
||||||
Settings.Builder sb = Settings.builder();
|
|
||||||
|
|
||||||
String authToken = randomAlphaOfLength(50);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(V1Account.SECURE_AUTH_TOKEN_SETTING.getKey(), authToken);
|
|
||||||
sb.setSecureSettings(secureSettings);
|
|
||||||
|
|
||||||
String host = HipChatServer.DEFAULT.host();
|
|
||||||
if (randomBoolean()) {
|
|
||||||
host = randomAlphaOfLength(10);
|
|
||||||
sb.put("host", host);
|
|
||||||
}
|
|
||||||
int port = HipChatServer.DEFAULT.port();
|
|
||||||
if (randomBoolean()) {
|
|
||||||
port = randomIntBetween(300, 400);
|
|
||||||
sb.put("port", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] defaultRooms = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultRooms = new String[] { "_r1", "_r2" };
|
|
||||||
sb.put(HipChatAccount.DEFAULT_ROOM_SETTING, "_r1,_r2");
|
|
||||||
}
|
|
||||||
String defaultFrom = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultFrom = randomAlphaOfLength(10);
|
|
||||||
sb.put(HipChatAccount.DEFAULT_FROM_SETTING, defaultFrom);
|
|
||||||
}
|
|
||||||
HipChatMessage.Format defaultFormat = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultFormat = randomFrom(HipChatMessage.Format.values());
|
|
||||||
sb.put(HipChatAccount.DEFAULT_FORMAT_SETTING, defaultFormat);
|
|
||||||
}
|
|
||||||
HipChatMessage.Color defaultColor = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultColor = randomFrom(HipChatMessage.Color.values());
|
|
||||||
sb.put(HipChatAccount.DEFAULT_COLOR_SETTING, defaultColor);
|
|
||||||
}
|
|
||||||
Boolean defaultNotify = null;
|
|
||||||
if (randomBoolean()) {
|
|
||||||
defaultNotify = randomBoolean();
|
|
||||||
sb.put(HipChatAccount.DEFAULT_NOTIFY_SETTING, defaultNotify);
|
|
||||||
}
|
|
||||||
Settings settings = sb.build();
|
|
||||||
|
|
||||||
V1Account account = new V1Account(accountName, settings, HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
|
|
||||||
|
|
||||||
assertThat(account.profile, is(HipChatAccount.Profile.V1));
|
|
||||||
assertThat(account.name, equalTo(accountName));
|
|
||||||
assertThat(account.server.host(), is(host));
|
|
||||||
assertThat(account.server.port(), is(port));
|
|
||||||
assertThat(account.authToken, is(authToken));
|
|
||||||
if (defaultRooms != null) {
|
|
||||||
assertThat(account.defaults.rooms, arrayContaining(defaultRooms));
|
|
||||||
} else {
|
|
||||||
assertThat(account.defaults.rooms, nullValue());
|
|
||||||
}
|
|
||||||
assertThat(account.defaults.from, is(defaultFrom));
|
|
||||||
assertThat(account.defaults.format, is(defaultFormat));
|
|
||||||
assertThat(account.defaults.color, is(defaultColor));
|
|
||||||
assertThat(account.defaults.notify, is(defaultNotify));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSettingsNoAuthToken() throws Exception {
|
|
||||||
Settings.Builder sb = Settings.builder();
|
|
||||||
try {
|
|
||||||
new V1Account("_name", sb.build(), HipChatServer.DEFAULT, mock(HttpClient.class), mock(Logger.class));
|
|
||||||
fail("Expected SettingsException");
|
|
||||||
} catch (SettingsException e) {
|
|
||||||
assertThat(e.getMessage(), is("hipchat account [_name] missing required [secure_auth_token] secure setting"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSend() throws Exception {
|
|
||||||
HttpClient httpClient = mock(HttpClient.class);
|
|
||||||
String authToken = randomAlphaOfLength(50);
|
|
||||||
final MockSecureSettings secureSettings = new MockSecureSettings();
|
|
||||||
secureSettings.setString(IntegrationAccount.SECURE_AUTH_TOKEN_SETTING.getKey(), "_token");
|
|
||||||
V1Account account = new V1Account("_name", Settings.builder()
|
|
||||||
.put("host", "_host")
|
|
||||||
.put("port", "443")
|
|
||||||
.setSecureSettings(secureSettings)
|
|
||||||
.build(), HipChatServer.DEFAULT, httpClient, mock(Logger.class));
|
|
||||||
|
|
||||||
HipChatMessage.Format format = randomFrom(HipChatMessage.Format.values());
|
|
||||||
HipChatMessage.Color color = randomFrom(HipChatMessage.Color.values());
|
|
||||||
Boolean notify = randomBoolean();
|
|
||||||
HipChatMessage message = new HipChatMessage("_body", new String[] { "Room with Spaces", "_r2" }, null, "_from", format,
|
|
||||||
color, notify);
|
|
||||||
|
|
||||||
HttpRequest req1 = HttpRequest.builder("_host", 443)
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v1/rooms/message")
|
|
||||||
.setHeader("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
.setParam("format", "json")
|
|
||||||
.setParam("auth_token", "_token")
|
|
||||||
.body(new StringBuilder()
|
|
||||||
.append("room_id=").append("Room+with+Spaces&")
|
|
||||||
.append("from=").append("_from&")
|
|
||||||
.append("message=").append("_body&")
|
|
||||||
.append("message_format=").append(format.value()).append("&")
|
|
||||||
.append("color=").append(color.value()).append("&")
|
|
||||||
.append("notify=").append(notify ? "1" : "0")
|
|
||||||
.toString())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
logger.info("expected (r1): {}", BytesReference.bytes(jsonBuilder().value(req1)).utf8ToString());
|
|
||||||
|
|
||||||
HttpResponse res1 = mock(HttpResponse.class);
|
|
||||||
when(res1.status()).thenReturn(200);
|
|
||||||
when(httpClient.execute(req1)).thenReturn(res1);
|
|
||||||
|
|
||||||
HttpRequest req2 = HttpRequest.builder("_host", 443)
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.scheme(Scheme.HTTPS)
|
|
||||||
.path("/v1/rooms/message")
|
|
||||||
.setHeader("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
.setParam("format", "json")
|
|
||||||
.setParam("auth_token", "_token")
|
|
||||||
.body(new StringBuilder()
|
|
||||||
.append("room_id=").append("_r2&")
|
|
||||||
.append("from=").append("_from&")
|
|
||||||
.append("message=").append("_body&")
|
|
||||||
.append("message_format=").append(format.value()).append("&")
|
|
||||||
.append("color=").append(color.value()).append("&")
|
|
||||||
.append("notify=").append(notify ? "1" : "0")
|
|
||||||
.toString())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
logger.info("expected (r2): {}", BytesReference.bytes(jsonBuilder().value(req2)).utf8ToString());
|
|
||||||
|
|
||||||
HttpResponse res2 = mock(HttpResponse.class);
|
|
||||||
when(res2.status()).thenReturn(200);
|
|
||||||
when(httpClient.execute(req2)).thenReturn(res2);
|
|
||||||
|
|
||||||
account.send(message, null);
|
|
||||||
|
|
||||||
verify(httpClient).execute(req1);
|
|
||||||
verify(httpClient).execute(req2);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
apply plugin: 'elasticsearch.standalone-rest-test'
|
|
||||||
apply plugin: 'elasticsearch.rest-test'
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
testCompile "org.elasticsearch.plugin:x-pack-core:${version}"
|
|
||||||
testCompile project(path: xpackModule('watcher'), configuration: 'runtime')
|
|
||||||
}
|
|
||||||
|
|
||||||
String integrationAccount = System.getenv('hipchat_auth_token_integration')
|
|
||||||
String userAccount = System.getenv('hipchat_auth_token_user')
|
|
||||||
String v1Account = System.getenv('hipchat_auth_token_v1')
|
|
||||||
|
|
||||||
integTestCluster {
|
|
||||||
setting 'xpack.security.enabled', 'false'
|
|
||||||
setting 'xpack.monitoring.enabled', 'false'
|
|
||||||
setting 'xpack.ml.enabled', 'false'
|
|
||||||
setting 'xpack.license.self_generated.type', 'trial'
|
|
||||||
setting 'logger.org.elasticsearch.xpack.watcher', 'DEBUG'
|
|
||||||
setting 'xpack.notification.hipchat.account.integration_account.profile', 'integration'
|
|
||||||
setting 'xpack.notification.hipchat.account.integration_account.room', 'test-watcher'
|
|
||||||
setting 'xpack.notification.hipchat.account.user_account.profile', 'user'
|
|
||||||
setting 'xpack.notification.hipchat.account.v1_account.profile', 'v1'
|
|
||||||
keystoreSetting 'xpack.notification.hipchat.account.integration_account.secure_auth_token', integrationAccount
|
|
||||||
keystoreSetting 'xpack.notification.hipchat.account.user_account.secure_auth_token', userAccount
|
|
||||||
keystoreSetting 'xpack.notification.hipchat.account.v1_account.secure_auth_token', v1Account
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!integrationAccount && !userAccount && !v1Account) {
|
|
||||||
integTest.enabled = false
|
|
||||||
testingConventions.enabled = false
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.smoketest;
|
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestResponse;
|
|
||||||
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
|
||||||
import org.elasticsearch.xpack.core.watcher.support.WatcherIndexTemplateRegistryField;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static java.util.Collections.emptyMap;
|
|
||||||
import static java.util.Collections.singletonMap;
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
|
|
||||||
/** Runs rest tests against external cluster */
|
|
||||||
public class WatcherHipchatYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
|
||||||
|
|
||||||
public WatcherHipchatYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
|
||||||
super(testCandidate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParametersFactory
|
|
||||||
public static Iterable<Object[]> parameters() throws Exception {
|
|
||||||
return ESClientYamlSuiteTestCase.createParameters();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void startWatcher() throws Exception {
|
|
||||||
final List<String> watcherTemplates = Arrays.asList(WatcherIndexTemplateRegistryField.TEMPLATE_NAMES);
|
|
||||||
assertBusy(() -> {
|
|
||||||
try {
|
|
||||||
getAdminExecutionContext().callApi("watcher.start", emptyMap(), emptyList(), emptyMap());
|
|
||||||
|
|
||||||
for (String template : watcherTemplates) {
|
|
||||||
ClientYamlTestResponse templateExistsResponse = getAdminExecutionContext().callApi("indices.exists_template",
|
|
||||||
singletonMap("name", template), emptyList(), emptyMap());
|
|
||||||
assertThat(templateExistsResponse.getStatusCode(), is(200));
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientYamlTestResponse response =
|
|
||||||
getAdminExecutionContext().callApi("watcher.stats", emptyMap(), emptyList(), emptyMap());
|
|
||||||
String state = (String) response.evaluate("stats.0.watcher_state");
|
|
||||||
assertThat(state, is("started"));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new AssertionError(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void stopWatcher() throws Exception {
|
|
||||||
assertBusy(() -> {
|
|
||||||
try {
|
|
||||||
getAdminExecutionContext().callApi("watcher.stop", emptyMap(), emptyList(), emptyMap());
|
|
||||||
ClientYamlTestResponse response =
|
|
||||||
getAdminExecutionContext().callApi("watcher.stats", emptyMap(), emptyList(), emptyMap());
|
|
||||||
String state = (String) response.evaluate("stats.0.watcher_state");
|
|
||||||
assertThat(state, is("stopped"));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new AssertionError(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,279 +0,0 @@
|
||||||
---
|
|
||||||
"Test Hipchat v1 account Action":
|
|
||||||
- do:
|
|
||||||
cluster.health:
|
|
||||||
wait_for_status: yellow
|
|
||||||
|
|
||||||
- do:
|
|
||||||
watcher.put_watch:
|
|
||||||
id: "hipchat_v1_watch"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"trigger": {
|
|
||||||
"schedule": {
|
|
||||||
"interval": "1d"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"simple": {
|
|
||||||
"foo": "something from input"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"my_hipchat_action": {
|
|
||||||
"hipchat": {
|
|
||||||
"account": "v1_account",
|
|
||||||
"message": {
|
|
||||||
"from" : "watcher-tests",
|
|
||||||
"room" : ["test-watcher", "test-watcher-2", "test watcher with spaces"],
|
|
||||||
"body": "From input {{ctx.payload.foo}}, and some tests (facepalm) in the v1 account",
|
|
||||||
"format": "text",
|
|
||||||
"color": "red",
|
|
||||||
"notify": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
watcher.execute_watch:
|
|
||||||
id: "hipchat_v1_watch"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"record_execution": true
|
|
||||||
}
|
|
||||||
|
|
||||||
- match: { watch_record.trigger_event.type: "manual" }
|
|
||||||
- match: { watch_record.state: "executed" }
|
|
||||||
- match: { watch_record.result.actions.0.id: "my_hipchat_action" }
|
|
||||||
- match: { watch_record.result.actions.0.type: "hipchat" }
|
|
||||||
- match: { watch_record.result.actions.0.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.account: "v1_account" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.0.room: "test-watcher" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.1.room: "test-watcher-2" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.2.room: "test watcher with spaces" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.0.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.1.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.2.status: "success" }
|
|
||||||
|
|
||||||
# Waits for the watcher history index to be available
|
|
||||||
- do:
|
|
||||||
cluster.health:
|
|
||||||
index: ".watcher-history-*"
|
|
||||||
wait_for_no_relocating_shards: true
|
|
||||||
timeout: 60s
|
|
||||||
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
search:
|
|
||||||
rest_total_hits_as_int: true
|
|
||||||
index: ".watcher-history-*"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"query" : {
|
|
||||||
"term" : {
|
|
||||||
"watch_id" : "hipchat_v1_watch"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0._source.state: "executed" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.id: "my_hipchat_action" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.type: "hipchat" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.status: "success" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.account: "v1_account" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.0.room: "test-watcher" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.1.room: "test-watcher-2" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.2.room: "test watcher with spaces" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.0.status: "success" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.1.status: "success" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.2.status: "success" }
|
|
||||||
|
|
||||||
---
|
|
||||||
"Test Hipchat integration account Action":
|
|
||||||
- do:
|
|
||||||
cluster.health:
|
|
||||||
wait_for_status: yellow
|
|
||||||
|
|
||||||
# custom rooms, custom users and custom from are not allowed for this account type to be configured
|
|
||||||
- do:
|
|
||||||
watcher.put_watch:
|
|
||||||
id: "hipchat_integration_account_watch"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"trigger": {
|
|
||||||
"schedule": {
|
|
||||||
"interval": "1d"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"simple": {
|
|
||||||
"foo": "something from input"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"my_hipchat_action": {
|
|
||||||
"hipchat": {
|
|
||||||
"account": "integration_account",
|
|
||||||
"message": {
|
|
||||||
"body": "From input {{ctx.payload.foo}}, and some tests (facepalm) in the integration account",
|
|
||||||
"format": "text",
|
|
||||||
"color": "red",
|
|
||||||
"notify": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
watcher.execute_watch:
|
|
||||||
id: "hipchat_integration_account_watch"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"record_execution": true
|
|
||||||
}
|
|
||||||
|
|
||||||
- match: { watch_record.trigger_event.type: "manual" }
|
|
||||||
- match: { watch_record.state: "executed" }
|
|
||||||
- match: { watch_record.result.actions.0.id: "my_hipchat_action" }
|
|
||||||
- match: { watch_record.result.actions.0.type: "hipchat" }
|
|
||||||
- match: { watch_record.result.actions.0.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.account: "integration_account" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.0.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.0.room: "test-watcher" }
|
|
||||||
|
|
||||||
# Waits for the watcher history index to be available
|
|
||||||
- do:
|
|
||||||
cluster.health:
|
|
||||||
index: ".watcher-history-*"
|
|
||||||
wait_for_no_relocating_shards: true
|
|
||||||
timeout: 60s
|
|
||||||
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
search:
|
|
||||||
rest_total_hits_as_int: true
|
|
||||||
index: ".watcher-history-*"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"query" : {
|
|
||||||
"term" : {
|
|
||||||
"watch_id" : "hipchat_integration_account_watch"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0._source.state: "executed" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.id: "my_hipchat_action" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.type: "hipchat" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.status: "success" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.account: "integration_account" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.0.room: "test-watcher" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.0.status: "success" }
|
|
||||||
|
|
||||||
---
|
|
||||||
"Test Hipchat user account Action":
|
|
||||||
- do:
|
|
||||||
cluster.health:
|
|
||||||
wait_for_status: yellow
|
|
||||||
|
|
||||||
- do:
|
|
||||||
watcher.put_watch:
|
|
||||||
id: "hipchat_user_account_watch"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"trigger": {
|
|
||||||
"schedule": {
|
|
||||||
"interval": "1d"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"simple": {
|
|
||||||
"foo": "something from input"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"actions": {
|
|
||||||
"my_hipchat_action": {
|
|
||||||
"hipchat": {
|
|
||||||
"account": "user_account",
|
|
||||||
"message": {
|
|
||||||
"user" : [ "watcher@elastic.co" ],
|
|
||||||
"room" : ["test-watcher", "test-watcher-2", "test watcher with spaces"],
|
|
||||||
"body": "From input {{ctx.payload.foo}}, and some tests (facepalm) in the user_account test. <b>bold</b>",
|
|
||||||
"format": "html"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
watcher.execute_watch:
|
|
||||||
id: "hipchat_user_account_watch"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"record_execution": true
|
|
||||||
}
|
|
||||||
|
|
||||||
- match: { watch_record.trigger_event.type: "manual" }
|
|
||||||
- match: { watch_record.state: "executed" }
|
|
||||||
- match: { watch_record.result.actions.0.id: "my_hipchat_action" }
|
|
||||||
- match: { watch_record.result.actions.0.type: "hipchat" }
|
|
||||||
- match: { watch_record.result.actions.0.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.account: "user_account" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.0.room: "test-watcher" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.1.room: "test-watcher-2" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.2.room: "test watcher with spaces" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.3.user: "watcher@elastic.co" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.0.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.1.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.2.status: "success" }
|
|
||||||
- match: { watch_record.result.actions.0.hipchat.sent_messages.3.status: "success" }
|
|
||||||
|
|
||||||
# Waits for the watcher history index to be available
|
|
||||||
- do:
|
|
||||||
cluster.health:
|
|
||||||
index: ".watcher-history-*"
|
|
||||||
wait_for_no_relocating_shards: true
|
|
||||||
timeout: 60s
|
|
||||||
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
search:
|
|
||||||
rest_total_hits_as_int: true
|
|
||||||
index: ".watcher-history-*"
|
|
||||||
body: >
|
|
||||||
{
|
|
||||||
"query" : {
|
|
||||||
"term" : {
|
|
||||||
"watch_id" : "hipchat_user_account_watch"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0._source.state: "executed" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.id: "my_hipchat_action" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.type: "hipchat" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.status: "success" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.account: "user_account" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.0.room: "test-watcher" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.1.room: "test-watcher-2" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.2.room: "test watcher with spaces" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.3.user: "watcher@elastic.co" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.0.status: "success" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.1.status: "success" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.2.status: "success" }
|
|
||||||
- match: { hits.hits.0._source.result.actions.0.hipchat.sent_messages.1.status: "success" }
|
|
||||||
|
|
||||||
|
|