Skip to content

Commit

Permalink
Document the new configuration format for event pusher
Browse files Browse the repository at this point in the history
  • Loading branch information
chrzaszcz committed Mar 25, 2022
1 parent 24e6ce8 commit 35b1320
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 131 deletions.
3 changes: 2 additions & 1 deletion doc/migrations/5.0.0_5.1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ The rules for overriding global options in the `host_config` section have been s
### Extension modules

* `mod_auth_token` has a new configuration format - if you are using this module, amend the [`validity_period`](../modules/mod_auth_token.md#modulesmod_auth_tokenvalidity_period) option.
* `mod_event_pusher` has an updated configuration format - the `backend` subsection is removed and the `http` backend has a new `handlers` option. Adjust your configuration according to [`mod_event_pusher`](../modules/mod_event_pusher.md) documentation.
* `mod_mam_meta` does not have the `rdbms_message_format` and `simple` options anymore. Use [`db_jid_format`](../modules/mod_mam.md#modulesmod_mam_metadb_jid_format) and [`db_message_format`](../modules/mod_mam.md#modulesmod_mam_metadb_message_format) instead.
* `mod_vcard` LDAP options are moved into an LDAP subsection.
* `mod_shared_roster_ldap` all options have their `ldap_` prefix dropped.
* `mod_vcard` LDAP options are moved into an LDAP subsection.

## Async workers

Expand Down
67 changes: 34 additions & 33 deletions doc/modules/mod_event_pusher.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,52 @@
## Module Description

This module is a generic interface for event-pushing backends.
It defines a single callback, `push_event/3` that forwards the event to all registered backends.
It defines a single callback, `push_event/2` that forwards the event to all registered backends.
Each backend decides how and if to handle the event in its `push_event/2` implementation.

Currently supported backends include [http], [push], [rabbit] and [sns].
Refer to their specific documentation to learn more about their functions and configuration options.

### How it works

The events are standardized as records that can be found in the `mod_event_pusher_events.hrl` file.
Common events like user presence changes (offline and online), chat and groupchat messages (incoming
and outgoing) are already hooked up to the frontend via `mod_event_pusher_hook_translator`, a
`mod_event_pusher` dependency, which is a proxy between various hooks and the `push_event/3` hook
handler.
and outgoing) are already handled in the `mod_event_pusher_hook_translator` module, which is a proxy between various hooks and the `push_event/2` handler.

!!! warning
!!! Warning
This module does not support [dynamic domains](../configuration/general.md#generalhost_types).

## Options
## Configuration

### `modules.mod_event_pusher.backend`
* **Syntax:** Array of TOML tables. See description.
* **Default:** see description
* **Example:** see description
Each backend is configured in a corresponding subsection.
The example below enables all backends.
The `[modules.mod_event_pusher]` section itself is omitted - this is allowed in TOML, because the presence of a subsection implies that the corresponding parent section is also present.

Specifies backends to register with the frontend, along with arguments that will be passed to the backend.
Currently supported backends include [sns], [push], [http_notification] and [rabbit].
Refer to their specific documentation to learn more about their functions and configuration options.

## Example configuration
!!! Note
Some backends require configuring connection pools in the `outgoing_pools` section.
See the detailed documentation for each backend.

```toml
[modules.mod_event_pusher]
backend.sns.access_key_id = "AKIAIOSFODNN7EXAMPLE"
backend.sns.secret_access_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
# ...

backend.push.backend = "mnesia"
backend.push.wpool.workers = 200
# ...

backend.http.pool_name = "http_pool"
backend.http.path = "/notifications"
# ...

backend.rabbit.presence_exchange.name ="presence"
backend.rabbit.presence_exchange.type = "topic"
# ...
[modules.mod_event_pusher.sns]
presence_updates_topic = "user_presence_updated"
pm_messages_topic = "user_message_sent"
muc_messages_topic = "user_messagegroup_sent"
sns_host = "eu-west-1.amazonaws.com"
region = "eu-west-1"
access_key_id = "AKIAIOSFODNN7EXAMPLE"
secret_access_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
account_id = "123456789012"

[modules.mod_event_pusher.push]
wpool.workers = 200

[modules.mod_event_pusher.http]
handlers = [{path = "/notifications"}]

[modules.mod_event_pusher.rabbit]
```

[sns]: ./mod_event_pusher_sns.md
[http]: ./mod_event_pusher_http.md
[push]: ./mod_event_pusher_push.md
[http_notification]: ./mod_event_pusher_http.md
[rabbit]: ./mod_event_pusher_rabbit.md
[sns]: ./mod_event_pusher_sns.md
54 changes: 28 additions & 26 deletions doc/modules/mod_event_pusher_http.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,47 +12,41 @@ When the hook is triggered, the module:
* runs a callback module's `prepare_body/7`
* sends a POST request composed of `{Host::binary(), Sender::binary(), Receiver::binary(), Message::binary()}` to the http notification server

You can make multiple configuration entries for this backend to handle more complicated pushing scenarios (e.g. sending various types of messages to different backends).

### Callback module


To find out what and how to send MongooseIM calls the following callback module's functions:
`Mod:should_make_req(Acc::mongoose_acc:t(), Dir::in|out, Packet::xmlel(), From::jid(), To::jid(), Opts :: [{atom(), term()}])`.

`Mod:prepare_headers(Acc::mongoose_acc:t(), Dir::in|out, Host::jid:lserver(), Message::binary(), Sender::jid:luser(), Receiver::luser(), Opts :: [{atom(), term()}])`.

`Mod:prepare_body(Acc::mongoose_acc:t(), Dir::in|out, Host::jid:lserver(), Message::binary(), Sender::jid:luser(), Receiver::luser(), Opts :: [{atom(), term()}])`.

By default it uses the function in `mod_event_pusher_http` itself, which ships all non-empty chat messages.
You can configure multiple handlers e.g. for sending various types of messages to different HTTP servers.

## Prerequisites

This module uses a connection pool created by mongoose_http_client.
This module uses a connection pool created by `mongoose_http_client`.
It must be defined in the [`outgoing_pools` settings](../configuration/outgoing-connections.md#http-options).

## Options

### `modules.mod_event_pusher_http.pool_name`
### `modules.mod_event_pusher.http.handlers`
* **Syntax:** array of TOML tables with the keys described below
* **Default:** empty list

A list of handler definitions. All handlers are applied for each event.

#### `modules.mod_event_pusher.http.handlers.pool_name`
* **Syntax:** non-empty string
* **Default:** `"http_pool"`
* **Example:** `pool_name = "http_pool"`

Name of the pool to use (as defined in outgoing_pools).
Name of the pool to use to connect to the HTTP server (as defined in `outgoing_pools`).

### `modules.mod_event_pusher_http.path`
#### `modules.mod_event_pusher.http.handlers.path`
* **Syntax:** string
* **Default:** `""`
* **Example:** `path = "/notifications"`

Path part of an URL to which a request should be sent (will be appended to the pool's prefix path).

### `modules.mod_event_pusher_http.callback_module`
#### `modules.mod_event_pusher.http.handlers.callback_module`
* **Syntax:** string
* **Default:** `"mod_event_pusher_http_defaults"`
* **Example:** `callback_module = "mod_event_pusher_http_notifications"`

Name of a module which should be used to check whether a notification should be sent.
Name of a module which should be used to check whether a notification should be sent. The default callback module, `mod_event_pusher_http_defaults`, sends notifications for all non-empty chat messages. You can use this module as a starting point for developing a custom one.

## Example configuration

Expand All @@ -62,24 +56,32 @@ Name of a module which should be used to check whether a notification should be
workers = 50

[outgoing_pools.http.http_pool.connection]
host = "https://localhost:8000"
host = "http://localhost:8000"
path_prefix = "/webservice"
request_timeout = 2000

[modules.mod_event_pusher.backend.http]
[modules.mod_event_pusher.http]
handlers = [{pool_name = "http_pool", path = "/notifications"}]
```

Notifications will be POSTed to `http://localhost:8000/webservice/notifications`.
TOML also allows to specify the handler in its own subsection.

```toml
[[modules.mod_event_pusher.http.handlers]]
pool_name = "http_pool"
path = "/notifications"
```

Notifications will be POSTed to `http://localhost:8000/webservice/notifications`.
This alternative syntax is useful for specifying multiple handlers with options:

```toml
[[modules.mod_event_pusher.backend.http]]
[[modules.mod_event_pusher.http.handlers]]
pool_name = "http_pool"
path = "/notifications"
callback_module = "mod_event_pusher_http_notifications"

[[modules.mod_event_pusher.backend.http]]
[[modules.mod_event_pusher.http.handlers]]
pool_name = "http_pool"
path = "/alerts"
callback_module = "mod_event_pusher_http_alerts"
Expand All @@ -90,9 +92,9 @@ Here, some notifications will be POSTed to `http://localhost:8000/webservice/not
## Default payload format
The default HTTP event pusher sends a POST request with Content-Type `application/x-www-form-urlencoded`. The form has the following fields:

* `author`: username of the user who authored the message
* `author`: name of the user who authored the message
* `server`: name of the server from where the message originates
* `receiver`: username of the user who the message is for
* `receiver`: name of the user who the message is for
* `message`: content of `<body>` element of the message

The contents of the author, server and receiver fields are processed by `stringprep`.
Expand Down
27 changes: 13 additions & 14 deletions doc/modules/mod_event_pusher_push.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,37 @@ This module is very easy to enable, just paste the following to your MongooseIM

```toml
[modules.mod_event_pusher]
backend.push.wpool.workers = 100
push.wpool.workers = 100
```

And that's basically it. You have just enabled the push notification support
with 100 asynchronous workers that will handle all push notification related work.


## Options

### `modules.mod_event_pusher_push.backend`
### `modules.mod_event_pusher.push.backend`
* **Syntax:** string, one of `"mnesia"`, `"rdbms"`
* **Default:** `"mnesia"`
* **Example:** `backend = "rdbms"`

Backend to use for storing the registrations.

### `modules.mod_event_pusher_push.wpool`
### `modules.mod_event_pusher.push.wpool`
* **Syntax:** TOML table with worker pool options
* **Default:** `{}`
* **Default:** see description
* **Example:** `wpool.workers = 200`

Array of options that will be passed to the `worker_pool` library that handles all the requests. The options allowed here are the same as for the [outgoing connection pools](../configuration/outgoing-connections.md#worker-pool-options).
Pool options that will be passed to the `worker_pool` library that handles all the requests. The options allowed here are the same as for the [outgoing connection pools](../configuration/outgoing-connections.md#worker-pool-options). The only difference is that the default `strategy` is `"available_worker"`.

### `modules.mod_event_pusher_push.plugin_module`
### `modules.mod_event_pusher.push.plugin_module`
* **Syntax:** non-empty string
* **Default:** `"mod_event_pusher_push_plugin_defaults"`
* **Example:** `plugin_module = "mod_event_pusher_push_plugin_defaults"`

The module implementing `mod_event_pusher_push_plugin` behaviour, used for dynamic configuration of push notifications.
See the [relevant section](#plugin-module) for more details.

### `modules.mod_event_pusher_push.virtual_pubsub_hosts`
### `modules.mod_event_pusher.push.virtual_pubsub_hosts`
* **Syntax:** array of strings
* **Default:** `[]`
* **Example:** `virtual_pubsub_hosts = ["host1", "host2"]`
Expand All @@ -61,7 +60,7 @@ See the [relevant section](#virtual-pubsub-hosts) for more details.
If a notification is published to one of the configured domains, the internal push notification hook
is executed in MongooseIM instead of the XEP-0357 typical behaviour. If an existing PubSub domain
is added to this list, it will be shadowed in the push notifications context. To ensure complete
shadowing of all the PubSub subdomains we must use the `@HOST@` pattern, otherwise only the
shadowing of all the PubSub subdomains you must use the `@HOST@` pattern, otherwise only the
subdomain of the user is shadowed. It enables easy migration from PubSub-full deployments to
PubSub-less variants.

Expand All @@ -76,11 +75,11 @@ option. `"pubsub.@HOST@"` is the default domain for `mod_pubsub`.
[modules.mod_pubsub]
plugins = ["push"] # mandatory minimal config

[modules.mod_event_pusher]
backend.push.backend = "mnesia" # optional
backend.push.wpool.workers = 200 # optional
backend.push.plugin_module = "mod_event_pusher_push_plugin_defaults" # optional
backend.push.virtual_pubsub_hosts = ["pubsub.@HOST@"]
[modules.mod_event_pusher.push]
backend = "mnesia" # optional
wpool.workers = 200 # optional
plugin_module = "mod_event_pusher_push_plugin_defaults" # optional
virtual_pubsub_hosts = ["pubsub.@HOST@"]
```

#### Advantages
Expand Down
38 changes: 19 additions & 19 deletions doc/modules/mod_event_pusher_rabbit.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ section before enabling the module.

## Presence exchange options

### `modules.mod_event_pusher.backend.rabbit.presence_exchange.name`
### `modules.mod_event_pusher.rabbit.presence_exchange.name`
* **Syntax:** non-empty string
* **Default:** `"presence"`
* **Example:** `name = "custom_presence_name"`

Defines RabbitMQ presence exchange name.

### `modules.mod_event_pusher.backend.rabbit.presence_exchange.type`
### `modules.mod_event_pusher.rabbit.presence_exchange.type`
* **Syntax:** non-empty string
* **Default:** `"topic"`
* **Example:** `type = "custom_presence_topic"`
Expand All @@ -45,28 +45,28 @@ Defines RabbitMQ presence exchange type.

## Chat message options

### `modules.mod_event_pusher.backend.rabbit.chat_msg_exchange.name`
### `modules.mod_event_pusher.rabbit.chat_msg_exchange.name`
* **Syntax:** non-empty string
* **Default:** `"chat_msg"`
* **Example:** `name = "custom_msg_name"`

Defines RabbitMQ chat message exchange name.

### `modules.mod_event_pusher.backend.rabbit.chat_msg_exchange.type`
### `modules.mod_event_pusher.rabbit.chat_msg_exchange.type`
* **Syntax:** non-empty string
* **Default:** `"topic"`
* **Example:** `type = "custom_msg_topic"`

Defines RabbitMQ chat message exchange type.

### `modules.mod_event_pusher.backend.rabbit.chat_msg_exchange.sent_topic`
### `modules.mod_event_pusher.rabbit.chat_msg_exchange.sent_topic`
* **Syntax:** non-empty string
* **Default:** `"chat_msg_sent"`
* **Example:** `sent_topic = "custom_sent_topic"`

Defines RabbitMQ chat message sent topic name.

### `modules.mod_event_pusher.backend.rabbit.chat_msg_exchange.recv_topic`
### `modules.mod_event_pusher.rabbit.chat_msg_exchange.recv_topic`
* **Syntax:** non-empty string
* **Default:** `"chat_msg_recv"`
* **Example:** `recv_topic = "custom_recv_topic"`
Expand All @@ -75,28 +75,28 @@ Defines RabbitMQ chat message received topic name.

## Group chat message options

### `modules.mod_event_pusher.backend.rabbit.groupchat_msg_exchange.name`
### `modules.mod_event_pusher.rabbit.groupchat_msg_exchange.name`
* **Syntax:** non-empty string
* **Default:** `"groupchat_msg"`
* **Example:** `name = "custom_group_msg_name"`

Defines RabbitMQ group chat message exchange name.

### `modules.mod_event_pusher.backend.rabbit.groupchat_msg_exchange.type`
### `modules.mod_event_pusher.rabbit.groupchat_msg_exchange.type`
* **Syntax:** non-empty string
* **Default:** `"topic"`
* **Example:** `type = "custom_group_msg_topic"`

Defines RabbitMQ group chat message exchange type.

### `modules.mod_event_pusher.backend.rabbit.groupchat_msg_exchange.sent_topic`
### `modules.mod_event_pusher.rabbit.groupchat_msg_exchange.sent_topic`
* **Syntax:** non-empty string
* **Default:** `"groupchat_msg_sent"`
* **Example:** `sent_topic = "custom_group_sent_topic"`

Defines RabbitMQ group chat message sent topic name.

### `modules.mod_event_pusher.backend.rabbit.groupchat_msg_exchange.recv_topic`
### `modules.mod_event_pusher.rabbit.groupchat_msg_exchange.recv_topic`
* **Syntax:** non-empty string
* **Default:** `"groupchat_msg_recv"`
* **Example:** `recv_topic = "custom_group_recv_topic"`
Expand All @@ -106,15 +106,15 @@ Defines RabbitMQ group chat message received topic name.
## Example configuration

```toml
[modules.mod_event_pusher]
backend.rabbit.presence_exchange.name ="presence"
backend.rabbit.presence_exchange.type = "topic"
backend.rabbit.chat_msg_exchange.name = "chat_msg"
backend.rabbit.chat_msg_exchange.sent_topic = "chat_msg_sent"
backend.rabbit.chat_msg_exchange.recv_topic = "chat_msg_recv"
backend.rabbit.groupchat_msg_exchange.name = "groupchat_msg"
backend.rabbit.groupchat_msg_exchange.sent_topic = "groupchat_msg_sent"
backend.rabbit.groupchat_msg_exchange.recv_topic = "groupchat_msg_recv"
[modules.mod_event_pusher.rabbit]
presence_exchange.name ="presence"
presence_exchange.type = "topic"
chat_msg_exchange.name = "chat_msg"
chat_msg_exchange.sent_topic = "chat_msg_sent"
chat_msg_exchange.recv_topic = "chat_msg_recv"
groupchat_msg_exchange.name = "groupchat_msg"
groupchat_msg_exchange.sent_topic = "groupchat_msg_sent"
groupchat_msg_exchange.recv_topic = "groupchat_msg_recv"
```

## JSON Schema examples
Expand Down
Loading

0 comments on commit 35b1320

Please sign in to comment.