How To : EMQ plugin development

EMQ is a MQTT broker written in Erlang. The broker is opensource and licensed under Apache 2.

EMQ broker has plugin support to extend features of the broker. Such that, EMQ broker has a web dashboard to handle administrative task which is actually a EMQ plugin developed out of EMQ broker. So if you want to add such custom feature to broker you can develop plugin for that by yourself. The tutorial will follow the steps which is need to develop a EMQ plugin.

EMQ broker's internal program flow can be intercepted in two ways. One is by module directly and another is by hook.
Such as, Authentication & Authorization can be handled by registering module.
And client connect, disconnect, publish, subscribe, acknowledged, delivered etc by hooks.

First of all create an Erlang project using rebar3.

// Our plugin name is emq_custom_plugin
// It will be used across the the tutorial
rebar3 new app emq_custom_plugin

Then in root folder add two more files erlang.mk & Makefile.

Checkout this for erlang.mk file content

And Makefile content will be,

Create a folder named etc and add a file emq_custom_plugin.config having content,

[
  {emq_custom_plugin, [
    {"version", "1.0"}
  ]}
].

Ok, We are ready to go.
Now to intercept Authentication [auth] & Authorization [acl] we have to register module having few function which structure is predefined by EMQ.

// Init function
init(Opts)->
   {ok, Opts}.
// Authentication function
check(#mqtt_client{client_id = ClientId, username = Username}, Password, _Opts) ->
  ok.
// Authorization
check_acl({Client, PubSub, Topic}, Opts) ->
  allow.
// Reloading authorization
reload_acl(_Opts) ->
  ok.
// To provide module description
description() ->
  "EMQ Custom Plugin".

These functions must be public.
Assume our module name is emq_custom_plugin.erl having these functions.
And

-behaviour(emqttd_auth_mod).

-include_lib("emqttd/include/emqttd.hrl").
-include_lib("emqttd/include/emqttd_cli.hrl").

these are at top.

Now to register it we have to add below lines in emq_custom_plugin_app.erl in start function,

ok = emqttd_access_control:register_mod(auth, emq_custom_plugin, []),
ok = emqttd_access_control:register_mod(acl, emq_custom_plugin, [])

in stop function,

ok = emqttd_access_control:unregister_mod(auth, emq_auth_demo),
ok = emqttd_access_control:unregister_mod(acl, emq_acl_demo),

Now you will get callback for auth and acl in emq_custom_plugin module in respective functions.

Lets play with hooks,
Assume we have another module named mod_hook_handler.erl then it should have this definitions depending on your requirements,

And in emq_custom_plugin.erl in start function add,

mod_hook_handler:load(application:get_all_env())

in stop function,

emq_plugin_template:unload().

Well your plugin is ready. Now we will deploy it to broker. For that,
Clone https://github.com/emqtt/emq-relx in your system and enter into the emq-relx folder. Then in plugin section of relx.config add,

{emq_custom_plugin, load}

In Makefile concat emq_custom_plugin with DEPS
and add,

dep_emq_custom_plugin = git git_url branch_name

Finally execute, make clean && make && make rel.
If everything goes ok then start the broker.
Move to _rel/emqttd/bin and
execute emqttd_ctl plugins load emq_custom_plugin

Your plugin is now running in the system.
To stop it execute emqttd_ctl plugins unload emq_custom_plugin.

You can also start and stop plugin from web dashboard.

References,