
[[input-http]]
==== HTTP Input
An <<input, input>> that enables you to query an HTTP endpoint and load theresponse into a watch's execution context as the initial payload. See <<http-input-attributes>> for the supported attributes. 

For example, you can use the `http` input to:

* Query an external Elasticsearch cluster. The query that one can define in the <<input-search,`search`>> input can also defined 
  in the `http` input. This in particular interesting as one can query clusters that are version wise incompatible with the 
  cluster where _Watcher_ is running on. With the `search` input these cluster would otherwise not be accessible. Also with 
  the `http` input it is straight forward to run a dedicated _Watcher_ cluster that queries other clusters.

* Query Elasticsearch APIs other than the search API. For example, the {ref}/cluster-nodes-stats.html[Nodes Stats], 
  {ref}/cluster-health.html[Cluster Health] or {ref}/cluster-state.html[Cluster State] APIs.

* Query an external webservice. Any service that exposes an HTTP endpoint can be queried by the `http` input. This can be very useful when you need to bridge between an Elasticsearch cluster and other systems.

Conditions, transforms, and actions can access the JSON response through the watch execution context. For example, if 
the response contains a `message` object, you could use `ctx.payload.message` to get the message from the payload.


NOTE:   If the body of the response from the HTTP endpoint is in the JSON or YAML format it will be parsed and used as the initial payload. Any
        other value that is returned will be assigned and accessible to/via the `_value` variable of the payload.

[[http-input-attributes]]
.HTTP Input Attributes
[options="header"]
|======
| Name                                          |Required   | Default     | Description
| `request.scheme`                              | no        | http        | Url scheme. Valid values are: `http` or `https`.
| `request.host`                                | yes       | -           | The host to connect to.
| `request.port`                                | yes       | -           | The port the http service is listening on.
| `request.path`                                | no        | -           | The URL path. The path can be static text or contain `mustache` <<templates, templates>>. URL query string parameters must be specified via the `request.params` attribute.
| `request.method`                              | no        | get         | The HTTP method. Supported values are: `head`, `get`, `post`, `put` and `delete`.
| `request.headers`                             | no        | -           | The HTTP request headers. The header values can be static text or include `mustache` <<templates, templates>>.
| `request.params`                              | no        | -           | The URL query string parameters. The parameter values can be static text or contain `mustache` <<templates, templates>>.
| `request.auth`                                | no        | -           | Authentication related HTTP headers. Currently, only basic authentication is supported.
| `request.connection_timeout`                  | no        | 10s         | The timeout for setting up the http connection. If the connection could not be set up within this time, the input will timeout and fail. It is
                                                                            also possible to <<configuring-default-http-timeouts, configure>> the default connection timeout for all http connection timeouts.
| `request.read_timeout`                        | no        | 10s         | The timeout for reading data from http connection. If no response was received within this time, the input will timeout and fail. It is
                                                                            also possible to <<configuring-default-http-timeouts, configure>> the default read timeout for all http connection timeouts.
| `request.body`                                | no        | -           | The HTTP request body. The body can be static text or include `mustache` <<templates, templates>>.
| `extract`                                     | no        | -           | A array of JSON keys to extract from the input response and use as payload. In cases when an input generates a large response this can be used to filter the relevant piece of the response to be used as payload.
| `response_content_type`                       | no        | json        | The expected content type the response body will contain. Supported values are `json`, `yaml` and `text`. If the format is `text` the `extract` attribute cannot exist. Note that any content type set by the http headers in the response will override this setting. If this is set to `text` the body of the response will be assigned and accessible to/via the `_value` variable of the payload.
|======

You can reference the following variables in the execution context when specifying the `path`, `params`, `headers` and `body` values:

[options="header"]
|======
| Name                                  | Description
| `ctx.watch_id`                        | The id of the watch that is currently executing.
| `ctx.execution_time`                  | The time execution of this watch started.
| `ctx.trigger.triggered_time`          | The time this watch was triggered.
| `ctx.trigger.scheduled_time`          | The time this watch was supposed to be triggered.
| `ctx.metadata.*`                      | Any metadata associated with the watch.
|======

===== Querying External Elasticsearch Clusters

The following snippet shows a basic `http` input that searches for all documents in the `idx` index in
an external cluster:

[source,json]
--------------------------------------------------
"input" : {
  "http" : {
    "request" : {
      "host" : "example.com",
      "port" : 9200,
      "path" : "/idx/_search"
    }
  }
}
--------------------------------------------------

You can use the full Elasticsearch {ref}/query-dsl.html[Query DSL] to perform more sophisticated searches. For example, the following snippet retrieves all documents that contain `event` in the `category` field.

[source,json]
--------------------------------------------------
"input" : {
  "http" : {
    "request" : {
      "host" : "host.domain",
      "port" : 9200,
      "path" : "/idx/_search",
      "body" :  "{\"query\" :  {  \"match\" : { \"category\" : \"event\"}}}"        
    }
  }
}
--------------------------------------------------

===== Using Templates 

The `http` input supports templating. You can use <<templates, templates>> when specifying 
the `path`, `body`, header values, and parameter values. 

For example, the following snippet uses templates to specify what 
index to query and restrict the results to documents added  
within the last five minutes. 

[source,json]
--------------------------------------------------
"input" : {
  "http" : {
    "request" : {
      "host" : "host.domain",
      "port" : 9200,
      "path" : "/{{ctx.watch_id}}/_search",
      "body" : "{\"query\" : {\"range\": {\"@timestamp\" : {\"from\": \"{{ctx.trigger.triggered_time}}||-5m\",\"to\": \"{{ctx.trigger.triggered_time}}\"}}}}"
      }
    }
  }
--------------------------------------------------

===== Calling Elasticsearch APIs

You can use `http` input load the data returned by any Elasticsearch API. For example, the following snippet calls the
 {ref}/cluster-stats.html[Cluster Stats] API and passes in the `human` query string argument.

[source,json]
.Http Input
--------------------------------------------------
"input" : {
  "http" : {
    "request" : {
      "host" : "host.domain",
      "port" : "9200",
      "path" : "/_cluster/stats",
      "params" : {
        "human" : "true" <1>
      }
    }
  }
}
--------------------------------------------------

<1> Enabling this attribute returns the `bytes` values in the response in human readable format.

===== Calling External Webservices

You can use `http` input to get data from any external webservice. The `http` input
supports basic authentication. For example, the following snippet calls `myservice` and uses basic authentication:

[[input-http-auth-basic-example]]
[source,json]
.Http Input
--------------------------------------------------
"input" : {
  "http" : {
    "request" : {
      "host" : "host.domain",
      "port" : "9200",
      "path" : "/myservice",
      "auth" : {
        "basic" : {
          "username" : "user",
          "password" : "pass"
        }
      }
    }
  }
}
--------------------------------------------------
