chore(apps): Sync again with 4.3.0
This commit is contained in:
commit
db792ec577
|
@ -0,0 +1,25 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_auth_http.d
|
||||||
|
data
|
||||||
|
ct.cover.spec
|
||||||
|
cover/
|
||||||
|
ct.coverdata
|
||||||
|
eunit.coverdata
|
||||||
|
logs/
|
||||||
|
erlang.mk
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
rebar3.crashdump
|
||||||
|
etc/emqx_auth_http.conf.rendered
|
||||||
|
.rebar3/
|
||||||
|
*.swp
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,162 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## HTTP Auth/ACL Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Authentication request.
|
||||||
|
|
||||||
|
## HTTP URL API path for authentication request
|
||||||
|
##
|
||||||
|
## Value: URL
|
||||||
|
##
|
||||||
|
## Examples: http://127.0.0.1:8991/mqtt/auth, https://[::1]:8991/mqtt/auth
|
||||||
|
auth.http.auth_req = http://127.0.0.1:8991/mqtt/auth
|
||||||
|
|
||||||
|
## Value: post | get
|
||||||
|
auth.http.auth_req.method = post
|
||||||
|
|
||||||
|
## It only works when method=post
|
||||||
|
## Value: json | x-www-form-urlencoded
|
||||||
|
auth.http.auth_req.content_type = x-www-form-urlencoded
|
||||||
|
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %a: ipaddress
|
||||||
|
## - %r: protocol
|
||||||
|
## - %P: password
|
||||||
|
## - %p: sockport of server accepted
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
##
|
||||||
|
## Value: Params
|
||||||
|
auth.http.auth_req.params = clientid=%c,username=%u,password=%P
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Superuser request.
|
||||||
|
|
||||||
|
## HTTP URL API path for Superuser request
|
||||||
|
##
|
||||||
|
## Value: URL
|
||||||
|
##
|
||||||
|
## Examples: http://127.0.0.1:8991/mqtt/superuser, https://[::1]:8991/mqtt/superuser
|
||||||
|
#auth.http.super_req = http://127.0.0.1:8991/mqtt/superuser
|
||||||
|
|
||||||
|
## Value: post | get
|
||||||
|
#auth.http.super_req.method = post
|
||||||
|
|
||||||
|
## It only works when method=pos
|
||||||
|
## Value: json | x-www-form-urlencoded
|
||||||
|
#auth.http.super_req.content_type = x-www-form-urlencoded
|
||||||
|
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %a: ipaddress
|
||||||
|
## - %r: protocol
|
||||||
|
## - %P: password
|
||||||
|
## - %p: sockport of server accepted
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
##
|
||||||
|
## Value: Params
|
||||||
|
#auth.http.super_req.params = clientid=%c,username=%u
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## ACL request.
|
||||||
|
|
||||||
|
## HTTP URL API path for ACL request
|
||||||
|
##
|
||||||
|
## Value: URL
|
||||||
|
##
|
||||||
|
## Examples: http://127.0.0.1:8991/mqtt/acl, https://[::1]:8991/mqtt/acl
|
||||||
|
auth.http.acl_req = http://127.0.0.1:8991/mqtt/acl
|
||||||
|
|
||||||
|
## Value: post | get
|
||||||
|
auth.http.acl_req.method = get
|
||||||
|
|
||||||
|
## It only works when method=post
|
||||||
|
## Value: json | x-www-form-urlencoded
|
||||||
|
auth.http.acl_req.content_type = x-www-form-urlencoded
|
||||||
|
|
||||||
|
## Variables:
|
||||||
|
## - %A: 1 | 2, 1 = sub, 2 = pub
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %a: ipaddress
|
||||||
|
## - %r: protocol
|
||||||
|
## - %m: mountpoint
|
||||||
|
## - %t: topic
|
||||||
|
##
|
||||||
|
## Value: Params
|
||||||
|
auth.http.acl_req.params = access=%A,username=%u,clientid=%c,ipaddr=%a,topic=%t,mountpoint=%m
|
||||||
|
|
||||||
|
##------------------------------------------------------------------------------
|
||||||
|
## Http Reqeust options
|
||||||
|
|
||||||
|
## Time-out time for the http request, 0 is never timeout.
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
## -h: hour, e.g. '2h' for 2 hours
|
||||||
|
## -m: minute, e.g. '5m' for 5 minutes
|
||||||
|
## -s: second, e.g. '30s' for 30 seconds
|
||||||
|
##
|
||||||
|
## Default: 0
|
||||||
|
## auth.http.request.timeout = 0
|
||||||
|
|
||||||
|
## Connection time-out time, used during the initial request
|
||||||
|
## when the client is connecting to the server
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
##
|
||||||
|
## Default is same with the timeout option
|
||||||
|
## auth.http.request.connect_timeout = 0
|
||||||
|
|
||||||
|
## Re-send http reuqest times
|
||||||
|
##
|
||||||
|
## Value: integer
|
||||||
|
##
|
||||||
|
## Default: 3
|
||||||
|
auth.http.request.retry_times = 3
|
||||||
|
|
||||||
|
## The interval for re-sending the http request
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
##
|
||||||
|
## Default: 1s
|
||||||
|
auth.http.request.retry_interval = 1s
|
||||||
|
|
||||||
|
## The 'Exponential Backoff' mechanism for re-sending request. The actually
|
||||||
|
## re-send time interval is `interval * backoff ^ times`
|
||||||
|
##
|
||||||
|
## Value: float
|
||||||
|
##
|
||||||
|
## Default: 2.0
|
||||||
|
auth.http.request.retry_backoff = 2.0
|
||||||
|
|
||||||
|
##------------------------------------------------------------------------------
|
||||||
|
## SSL options
|
||||||
|
|
||||||
|
## Path to the file containing PEM-encoded CA certificates. The CA certificates
|
||||||
|
## are used during server authentication and when building the client certificate chain.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.http.ssl.cacertfile = {{ platform_etc_dir }}/certs/ca.pem
|
||||||
|
|
||||||
|
## The path to a file containing the client's certificate.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.http.ssl.certfile = {{ platform_etc_dir }}/certs/client-cert.pem
|
||||||
|
|
||||||
|
## Path to a file containing the client's private PEM-encoded key.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.http.ssl.keyfile = {{ platform_etc_dir }}/certs/client-key.pem
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## HTTP Request Headers
|
||||||
|
##
|
||||||
|
## Example: auth.http.header.Accept-Encoding = *
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.http.header.Accept = */*
|
|
@ -24,4 +24,3 @@
|
||||||
]}
|
]}
|
||||||
]}
|
]}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_auth_jwt.d
|
||||||
|
data/
|
||||||
|
.DS_Store
|
||||||
|
cover/
|
||||||
|
ct.coverdata
|
||||||
|
eunit.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
emq_auth_jwt.d
|
||||||
|
erlang.mk
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
rebar3.crashdump
|
||||||
|
etc/emqx_auth_jwt.conf.rendered
|
||||||
|
.rebar3/
|
||||||
|
*.swp
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,39 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## JWT Auth Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## HMAC Hash Secret.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.jwt.secret = emqxsecret
|
||||||
|
|
||||||
|
## From where the JWT string can be got
|
||||||
|
##
|
||||||
|
## Value: username | password
|
||||||
|
## Default: password
|
||||||
|
auth.jwt.from = password
|
||||||
|
|
||||||
|
## RSA or ECDSA public key file.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.jwt.pubkey = etc/certs/jwt_public_key.pem
|
||||||
|
|
||||||
|
## Enable to verify claims fields
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
auth.jwt.verify_claims = off
|
||||||
|
|
||||||
|
## The checklist of claims to validate
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.jwt.verify_claims.$name = expected
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
# auth.jwt.verify_claims.username = %u
|
||||||
|
|
||||||
|
## The Signature format
|
||||||
|
## - `der`: The erlang default format
|
||||||
|
## - `raw`: Compatible with others platform maybe
|
||||||
|
#auth.jwt.signature_format = der
|
|
@ -0,0 +1,25 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_auth_ldap.d
|
||||||
|
data/
|
||||||
|
cover/
|
||||||
|
ct.coverdata
|
||||||
|
eunit.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
.DS_Store
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
erlang.mk
|
||||||
|
rebar3.crashdump
|
||||||
|
.rebar3/
|
||||||
|
etc/emqx_auth_ldap.conf.rendered
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,78 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## LDAP Auth Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## LDAP server list, seperated by ','.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.ldap.servers = 127.0.0.1
|
||||||
|
|
||||||
|
## LDAP server port.
|
||||||
|
##
|
||||||
|
## Value: Port
|
||||||
|
auth.ldap.port = 389
|
||||||
|
|
||||||
|
## LDAP pool size
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.ldap.pool = 8
|
||||||
|
|
||||||
|
## LDAP Bind DN.
|
||||||
|
##
|
||||||
|
## Value: DN
|
||||||
|
auth.ldap.bind_dn = cn=root,dc=emqx,dc=io
|
||||||
|
|
||||||
|
## LDAP Bind Password.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.ldap.bind_password = public
|
||||||
|
|
||||||
|
## LDAP query timeout.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
auth.ldap.timeout = 30s
|
||||||
|
|
||||||
|
## Device DN.
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
##
|
||||||
|
## Value: DN
|
||||||
|
auth.ldap.device_dn = ou=device,dc=emqx,dc=io
|
||||||
|
|
||||||
|
## Specified ObjectClass
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
##
|
||||||
|
## Value: string
|
||||||
|
auth.ldap.match_objectclass = mqttUser
|
||||||
|
|
||||||
|
## attributetype for username
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
##
|
||||||
|
## Value: string
|
||||||
|
auth.ldap.username.attributetype = uid
|
||||||
|
|
||||||
|
## attributetype for password
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
##
|
||||||
|
## Value: string
|
||||||
|
auth.ldap.password.attributetype = userPassword
|
||||||
|
|
||||||
|
## Whether to enable SSL.
|
||||||
|
##
|
||||||
|
## Value: true | false
|
||||||
|
auth.ldap.ssl = false
|
||||||
|
|
||||||
|
#auth.ldap.ssl.certfile = etc/certs/cert.pem
|
||||||
|
|
||||||
|
#auth.ldap.ssl.keyfile = etc/certs/key.pem
|
||||||
|
|
||||||
|
#auth.ldap.ssl.cacertfile = etc/certs/cacert.pem
|
||||||
|
|
||||||
|
#auth.ldap.ssl.verify = verify_peer
|
||||||
|
|
||||||
|
#auth.ldap.ssl.fail_if_no_peer_cert = true
|
||||||
|
|
||||||
|
#auth.ldap.ssl.server_name_indication = your_server_name
|
|
@ -0,0 +1,26 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_auth_mnesia.d
|
||||||
|
data/
|
||||||
|
_build/
|
||||||
|
.DS_Store
|
||||||
|
cover/
|
||||||
|
ct.coverdata
|
||||||
|
eunit.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
rebar.lock
|
||||||
|
rebar3.crashdump
|
||||||
|
erlang.mk
|
||||||
|
.*.swp
|
||||||
|
.rebar3/
|
||||||
|
etc/emqx_auth_mnesia.conf.rendered
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -1,8 +1,5 @@
|
||||||
{minimum_otp_vsn, "21"}.
|
|
||||||
|
|
||||||
{deps,
|
{deps,
|
||||||
[{emqx_passwd, {git, "https://github.com/emqx/emqx-passwd.git", {tag, "v1.1.1"}}},
|
[
|
||||||
{minirest, {git, "https://github.com/emqx/minirest.git", {tag, "0.3.0"}}}
|
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{profiles,
|
{profiles,
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.DS_Store
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_auth_mongo.d
|
||||||
|
ct.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
data/
|
||||||
|
cover/
|
||||||
|
eunit.coverdata
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
erlang.mk
|
||||||
|
etc/emqx_auth_mongo.conf.rendered
|
||||||
|
.rebar3
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,172 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## MongoDB Auth/ACL Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## MongoDB Topology Type.
|
||||||
|
##
|
||||||
|
## Value: single | unknown | sharded | rs
|
||||||
|
auth.mongo.type = single
|
||||||
|
|
||||||
|
## The set name if type is rs.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.mongo.rs_set_name =
|
||||||
|
|
||||||
|
## MongoDB server list.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
##
|
||||||
|
## Examples: 127.0.0.1:27017,127.0.0.2:27017...
|
||||||
|
auth.mongo.server = 127.0.0.1:27017
|
||||||
|
|
||||||
|
## MongoDB pool size
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
auth.mongo.pool = 8
|
||||||
|
|
||||||
|
## MongoDB login user.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.mongo.login =
|
||||||
|
|
||||||
|
## MongoDB password.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.mongo.password =
|
||||||
|
|
||||||
|
## MongoDB AuthSource
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## Default: mqtt
|
||||||
|
## auth.mongo.auth_source = admin
|
||||||
|
|
||||||
|
## MongoDB database
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.mongo.database = mqtt
|
||||||
|
|
||||||
|
## MongoDB query timeout
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
## auth.mongo.query_timeout = 5s
|
||||||
|
|
||||||
|
## Whether to enable SSL connection.
|
||||||
|
##
|
||||||
|
## Value: true | false
|
||||||
|
## auth.mongo.ssl = false
|
||||||
|
|
||||||
|
## SSL keyfile.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.mongo.ssl_opts.keyfile =
|
||||||
|
|
||||||
|
## SSL certfile.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.mongo.ssl_opts.certfile =
|
||||||
|
|
||||||
|
## SSL cacertfile.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.mongo.ssl_opts.cacertfile =
|
||||||
|
|
||||||
|
## MongoDB write mode.
|
||||||
|
##
|
||||||
|
## Value: unsafe | safe
|
||||||
|
## auth.mongo.w_mode =
|
||||||
|
|
||||||
|
## Mongo read mode.
|
||||||
|
##
|
||||||
|
## Value: master | slave_ok
|
||||||
|
## auth.mongo.r_mode =
|
||||||
|
|
||||||
|
## MongoDB topology options.
|
||||||
|
auth.mongo.topology.pool_size = 1
|
||||||
|
auth.mongo.topology.max_overflow = 0
|
||||||
|
## auth.mongo.topology.overflow_ttl = 1000
|
||||||
|
## auth.mongo.topology.overflow_check_period = 1000
|
||||||
|
## auth.mongo.topology.local_threshold_ms = 1000
|
||||||
|
## auth.mongo.topology.connect_timeout_ms = 20000
|
||||||
|
## auth.mongo.topology.socket_timeout_ms = 100
|
||||||
|
## auth.mongo.topology.server_selection_timeout_ms = 30000
|
||||||
|
## auth.mongo.topology.wait_queue_timeout_ms = 1000
|
||||||
|
## auth.mongo.topology.heartbeat_frequency_ms = 10000
|
||||||
|
## auth.mongo.topology.min_heartbeat_frequency_ms = 1000
|
||||||
|
|
||||||
|
## -------------------------------------------------
|
||||||
|
## Auth Query
|
||||||
|
## -------------------------------------------------
|
||||||
|
## Password hash.
|
||||||
|
##
|
||||||
|
## Value: plain | md5 | sha | sha256 | bcrypt
|
||||||
|
auth.mongo.auth_query.password_hash = sha256
|
||||||
|
|
||||||
|
## sha256 with salt suffix
|
||||||
|
## auth.mongo.auth_query.password_hash = sha256,salt
|
||||||
|
|
||||||
|
## sha256 with salt prefix
|
||||||
|
## auth.mongo.auth_query.password_hash = salt,sha256
|
||||||
|
|
||||||
|
## bcrypt with salt prefix
|
||||||
|
## auth.mongo.auth_query.password_hash = salt,bcrypt
|
||||||
|
|
||||||
|
## pbkdf2 with macfun iterations dklen
|
||||||
|
## macfun: md4, md5, ripemd160, sha, sha224, sha256, sha384, sha512
|
||||||
|
## auth.mongo.auth_query.password_hash = pbkdf2,sha256,1000,20
|
||||||
|
|
||||||
|
## Authentication query.
|
||||||
|
auth.mongo.auth_query.collection = mqtt_user
|
||||||
|
|
||||||
|
## Password mainly fields
|
||||||
|
##
|
||||||
|
## Value: password | password,salt
|
||||||
|
auth.mongo.auth_query.password_field = password
|
||||||
|
|
||||||
|
## Authentication Selector.
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
##
|
||||||
|
## auth.mongo.auth_query.selector = {Field}={Placeholder}
|
||||||
|
auth.mongo.auth_query.selector = username=%u
|
||||||
|
|
||||||
|
## -------------------------------------------------
|
||||||
|
## Super User Query
|
||||||
|
## -------------------------------------------------
|
||||||
|
auth.mongo.super_query.collection = mqtt_user
|
||||||
|
auth.mongo.super_query.super_field = is_superuser
|
||||||
|
#auth.mongo.super_query.selector = username=%u, clientid=%c
|
||||||
|
auth.mongo.super_query.selector = username=%u
|
||||||
|
|
||||||
|
## ACL Selector.
|
||||||
|
##
|
||||||
|
## Multiple selectors could be combined with '$or'
|
||||||
|
## when query acl from mongo.
|
||||||
|
##
|
||||||
|
## e.g.
|
||||||
|
##
|
||||||
|
## With following 2 selectors configured:
|
||||||
|
##
|
||||||
|
## auth.mongo.acl_query.selector.1 = username=%u
|
||||||
|
## auth.mongo.acl_query.selector.2 = username=$all
|
||||||
|
##
|
||||||
|
## And if a client connected using username 'ilyas',
|
||||||
|
## then the following mongo command will be used to
|
||||||
|
## retrieve acl entries:
|
||||||
|
##
|
||||||
|
## db.mqtt_acl.find({$or: [{username: "ilyas"}, {username: "$all"}]});
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
##
|
||||||
|
## Examples:
|
||||||
|
##
|
||||||
|
## auth.mongo.acl_query.selector.1 = username=%u,clientid=%c
|
||||||
|
## auth.mongo.acl_query.selector.2 = username=$all
|
||||||
|
## auth.mongo.acl_query.selector.3 = clientid=$all
|
||||||
|
auth.mongo.acl_query.collection = mqtt_acl
|
||||||
|
auth.mongo.acl_query.selector = username=%u
|
|
@ -1,5 +1,6 @@
|
||||||
{deps,
|
{deps,
|
||||||
[{mongodb, {git,"https://github.com/emqx/mongodb-erlang", {tag, "v3.0.7"}}}]}.
|
[{mongodb, {git,"https://github.com/emqx/mongodb-erlang", {tag, "v3.0.7"}}}
|
||||||
|
]}.
|
||||||
|
|
||||||
{edoc_opts, [{preprocess, true}]}.
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
{erl_opts, [warn_unused_vars,
|
{erl_opts, [warn_unused_vars,
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.so
|
||||||
|
.iml
|
||||||
|
.idea
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_auth_mysql.d
|
||||||
|
ct.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
test/*.beam
|
||||||
|
cover/
|
||||||
|
eunit.coverdata
|
||||||
|
data
|
||||||
|
.placeholder
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
erlang.mk
|
||||||
|
rebar3.crashdump
|
||||||
|
etc/emqx_auth_mysql.conf.rendered
|
||||||
|
.rebar3/
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,116 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## MySQL Auth/ACL Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## MySQL server address.
|
||||||
|
##
|
||||||
|
## Value: Port | IP:Port
|
||||||
|
##
|
||||||
|
## Examples: 3306, 127.0.0.1:3306, localhost:3306
|
||||||
|
auth.mysql.server = 127.0.0.1:3306
|
||||||
|
|
||||||
|
## MySQL pool size.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
auth.mysql.pool = 8
|
||||||
|
|
||||||
|
## MySQL username.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.mysql.username =
|
||||||
|
|
||||||
|
## MySQL password.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.mysql.password =
|
||||||
|
|
||||||
|
## MySQL database.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.mysql.database = mqtt
|
||||||
|
|
||||||
|
## MySQL query timeout
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
## auth.mysql.query_timeout = 5s
|
||||||
|
|
||||||
|
## Variables: %u = username, %c = clientid
|
||||||
|
|
||||||
|
## Authentication query.
|
||||||
|
##
|
||||||
|
## Note that column names should be 'password' and 'salt' (if used).
|
||||||
|
## In case column names differ in your DB - please use aliases,
|
||||||
|
## e.g. "my_column_name as password".
|
||||||
|
##
|
||||||
|
## Value: SQL
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
##
|
||||||
|
auth.mysql.auth_query = select password from mqtt_user where username = '%u' limit 1
|
||||||
|
## auth.mysql.auth_query = select password_hash as password from mqtt_user where username = '%u' limit 1
|
||||||
|
|
||||||
|
## Password hash.
|
||||||
|
##
|
||||||
|
## Value: plain | md5 | sha | sha256 | bcrypt
|
||||||
|
auth.mysql.password_hash = sha256
|
||||||
|
|
||||||
|
## sha256 with salt prefix
|
||||||
|
## auth.mysql.password_hash = salt,sha256
|
||||||
|
|
||||||
|
## bcrypt with salt only prefix
|
||||||
|
## auth.mysql.password_hash = salt,bcrypt
|
||||||
|
|
||||||
|
## sha256 with salt suffix
|
||||||
|
## auth.mysql.password_hash = sha256,salt
|
||||||
|
|
||||||
|
## pbkdf2 with macfun iterations dklen
|
||||||
|
## macfun: md4, md5, ripemd160, sha, sha224, sha256, sha384, sha512
|
||||||
|
## auth.mysql.password_hash = pbkdf2,sha256,1000,20
|
||||||
|
|
||||||
|
## Superuser query.
|
||||||
|
##
|
||||||
|
## Value: SQL
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
##
|
||||||
|
auth.mysql.super_query = select is_superuser from mqtt_user where username = '%u' limit 1
|
||||||
|
|
||||||
|
## ACL query.
|
||||||
|
##
|
||||||
|
## Value: SQL
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %a: ipaddr
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
##
|
||||||
|
## Note: You can add the 'ORDER BY' statement to control the rules match order
|
||||||
|
auth.mysql.acl_query = select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'
|
||||||
|
|
||||||
|
## Mysql ssl configuration.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
auth.mysql.ssl = off
|
||||||
|
|
||||||
|
## CA certificate.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.mysql.ssl.cafile = path to your ca file
|
||||||
|
|
||||||
|
## Client ssl certificate.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.mysql.ssl.certfile = path to your clientcert file
|
||||||
|
|
||||||
|
## Client ssl keyfile.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.mysql.ssl.keyfile = path to your clientkey file
|
|
@ -0,0 +1,20 @@
|
||||||
|
ebin
|
||||||
|
.rebar
|
||||||
|
.eunit
|
||||||
|
.DS_Store
|
||||||
|
.erlang.mk/
|
||||||
|
deps/
|
||||||
|
emqx_auth_pgsql.d
|
||||||
|
ct.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
test/*.beam
|
||||||
|
data/
|
||||||
|
.DS_Store
|
||||||
|
cover/
|
||||||
|
eunit.coverdata
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
erlang.mk
|
||||||
|
*.conf.rendered
|
||||||
|
.rebar3/
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,110 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## PostgreSQL Auth/ACL Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## PostgreSQL server address.
|
||||||
|
##
|
||||||
|
## Value: Port | IP:Port
|
||||||
|
##
|
||||||
|
## Examples: 5432, 127.0.0.1:5432, localhost:5432
|
||||||
|
auth.pgsql.server = 127.0.0.1:5432
|
||||||
|
|
||||||
|
## PostgreSQL pool size.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
auth.pgsql.pool = 8
|
||||||
|
|
||||||
|
## PostgreSQL username.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.pgsql.username = root
|
||||||
|
|
||||||
|
## PostgreSQL password.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.pgsql.password =
|
||||||
|
|
||||||
|
## PostgreSQL database.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.pgsql.database = mqtt
|
||||||
|
|
||||||
|
## PostgreSQL database encoding.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
auth.pgsql.encoding = utf8
|
||||||
|
|
||||||
|
## Whether to enable SSL connection.
|
||||||
|
##
|
||||||
|
## Value: true | false
|
||||||
|
auth.pgsql.ssl = false
|
||||||
|
|
||||||
|
## SSL keyfile.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.pgsql.ssl_opts.keyfile =
|
||||||
|
|
||||||
|
## SSL certfile.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.pgsql.ssl_opts.certfile =
|
||||||
|
|
||||||
|
## SSL cacertfile.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## auth.pgsql.ssl_opts.cacertfile =
|
||||||
|
|
||||||
|
## Authentication query.
|
||||||
|
##
|
||||||
|
## Value: SQL
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
##
|
||||||
|
auth.pgsql.auth_query = select password from mqtt_user where username = '%u' limit 1
|
||||||
|
|
||||||
|
## Password hash.
|
||||||
|
##
|
||||||
|
## Value: plain | md5 | sha | sha256 | bcrypt
|
||||||
|
auth.pgsql.password_hash = sha256
|
||||||
|
|
||||||
|
## sha256 with salt prefix
|
||||||
|
## auth.pgsql.password_hash = salt,sha256
|
||||||
|
|
||||||
|
## sha256 with salt suffix
|
||||||
|
## auth.pgsql.password_hash = sha256,salt
|
||||||
|
|
||||||
|
## bcrypt with salt prefix
|
||||||
|
## auth.pgsql.password_hash = salt,bcrypt
|
||||||
|
|
||||||
|
## pbkdf2 with macfun iterations dklen
|
||||||
|
## macfun: md4, md5, ripemd160, sha, sha224, sha256, sha384, sha512
|
||||||
|
## auth.pgsql.password_hash = pbkdf2,sha256,1000,20
|
||||||
|
|
||||||
|
## Superuser query.
|
||||||
|
##
|
||||||
|
## Value: SQL
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
##
|
||||||
|
auth.pgsql.super_query = select is_superuser from mqtt_user where username = '%u' limit 1
|
||||||
|
|
||||||
|
## ACL query. Comment this query, the ACL will be disabled.
|
||||||
|
##
|
||||||
|
## Value: SQL
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %a: ipaddress
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
##
|
||||||
|
## Note: You can add the 'ORDER BY' statement to control the rules match order
|
||||||
|
auth.pgsql.acl_query = select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
.rebar/
|
||||||
|
.eunit/
|
||||||
|
.erlang.mk/
|
||||||
|
emqttd_auth_redis.d
|
||||||
|
deps/
|
||||||
|
ct.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
ebin/
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
data
|
||||||
|
emqx_auth_redis.d
|
||||||
|
cover/
|
||||||
|
eunit.coverdata
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
erlang.mk
|
||||||
|
*.conf.rendered
|
||||||
|
.rebar3/
|
||||||
|
*.swp
|
||||||
|
rebar.lock
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,116 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Redis Auth/ACL Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Redis Server cluster type
|
||||||
|
## single Single redis server
|
||||||
|
## sentinel Redis cluster through sentinel
|
||||||
|
## cluster Redis through cluster
|
||||||
|
auth.redis.type = single
|
||||||
|
|
||||||
|
## Redis server address.
|
||||||
|
##
|
||||||
|
## Value: Port | IP:Port
|
||||||
|
##
|
||||||
|
## Single Redis Server: 127.0.0.1:6379, localhost:6379
|
||||||
|
## Redis Sentinel: 127.0.0.1:26379,127.0.0.2:26379,127.0.0.3:26379
|
||||||
|
## Redis Cluster: 127.0.0.1:6379,127.0.0.2:6379,127.0.0.3:6379
|
||||||
|
auth.redis.server = 127.0.0.1:6379
|
||||||
|
|
||||||
|
## Redis sentinel cluster name.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.redis.sentinel = mymaster
|
||||||
|
|
||||||
|
## Redis pool size.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
auth.redis.pool = 8
|
||||||
|
|
||||||
|
## Redis database no.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
auth.redis.database = 0
|
||||||
|
|
||||||
|
## Redis password.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## auth.redis.password =
|
||||||
|
|
||||||
|
## Redis query timeout
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
## auth.redis.query_timeout = 5s
|
||||||
|
|
||||||
|
## Authentication query command.
|
||||||
|
##
|
||||||
|
## Value: Redis cmd
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
##
|
||||||
|
## Examples:
|
||||||
|
## - HGET mqtt_user:%u password
|
||||||
|
## - HMGET mqtt_user:%u password
|
||||||
|
## - HMGET mqtt_user:%u password salt
|
||||||
|
auth.redis.auth_cmd = HMGET mqtt_user:%u password
|
||||||
|
|
||||||
|
## Password hash.
|
||||||
|
##
|
||||||
|
## Value: plain | md5 | sha | sha256 | bcrypt
|
||||||
|
auth.redis.password_hash = plain
|
||||||
|
|
||||||
|
## sha256 with salt prefix
|
||||||
|
## auth.redis.password_hash = salt,sha256
|
||||||
|
|
||||||
|
## sha256 with salt suffix
|
||||||
|
## auth.redis.password_hash = sha256,salt
|
||||||
|
|
||||||
|
## bcrypt with salt prefix
|
||||||
|
## auth.redis.password_hash = salt,bcrypt
|
||||||
|
|
||||||
|
## pbkdf2 with macfun iterations dklen
|
||||||
|
## macfun: md4, md5, ripemd160, sha, sha224, sha256, sha384, sha512
|
||||||
|
## auth.redis.password_hash = pbkdf2,sha256,1000,20
|
||||||
|
|
||||||
|
## Superuser query command.
|
||||||
|
##
|
||||||
|
## Value: Redis cmd
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
## - %C: common name of client TLS cert
|
||||||
|
## - %d: subject of client TLS cert
|
||||||
|
auth.redis.super_cmd = HGET mqtt_user:%u is_superuser
|
||||||
|
|
||||||
|
## ACL query command.
|
||||||
|
##
|
||||||
|
## Value: Redis cmd
|
||||||
|
##
|
||||||
|
## Variables:
|
||||||
|
## - %u: username
|
||||||
|
## - %c: clientid
|
||||||
|
auth.redis.acl_cmd = HGETALL mqtt_acl:%u
|
||||||
|
|
||||||
|
## Redis ssl configuration.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
#auth.redis.ssl = off
|
||||||
|
|
||||||
|
## CA certificate.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
#auth.redis.cafile = path/to/your/cafile
|
||||||
|
|
||||||
|
## Client ssl certificate.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
#auth.redis.certfile = path/to/your/certfile
|
||||||
|
|
||||||
|
## Client ssl keyfile.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
#auth.redis.keyfile = path/to/your/keyfile
|
|
@ -0,0 +1,29 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIE5jCCAs4CCQCc1DzEYETfKTANBgkqhkiG9w0BAQsFADA1MRMwEQYDVQQKDApS
|
||||||
|
ZWRpcyBUZXN0MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjAx
|
||||||
|
MDI5MDEzNDE2WhcNMzAxMDI3MDEzNDE2WjA1MRMwEQYDVQQKDApSZWRpcyBUZXN0
|
||||||
|
MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4ICDwAwggIKAoICAQC/RxC/zQ6+ThI2l+LT5tpuvljE7CPca5erahTjv1Pq
|
||||||
|
mbmHYIVlige9jvZKR/AaaHuhNRT6C4PDpD98TgrhSLSgMMFImoFMSnmFEOVave3O
|
||||||
|
y1qV9vtoHLMB9hO+t7P98KRi1sCoMdPIE/o5uEGSd4YgWbk3NllAV6me108UniWU
|
||||||
|
yZMCSEKmV9OpfQ+YfHFolESV92ajdViDbtRBjfDNwD7qb8zgigxIJvBzEnWF4RZl
|
||||||
|
4+KIiyoJ55AQ3omdEi0QwiRRRONFtB6kRSqjGS8genGnycX1ZNPRB8JeG3ESuFj9
|
||||||
|
1WQUD0EMBXFB5agHoZjvtFwxOkUkA4XbcnpKddHGKRt4BAbm+YcizJaT7mRytGWZ
|
||||||
|
UoTrDWz8/Cc0BlwAfPEk6ogU/sLSZpdxjxwprCNB89UOI+q7ng7CYiFnxY9HHZeg
|
||||||
|
GCJxYfvpKM/eOT9mSLUug8EGITd0j2cusflO4Q243clPyRbTSSr39Pcpy8rfKApF
|
||||||
|
HkUuGIpa/qgAbez+lPlIydzpbrTgrnHvL1P6fCYTnHkcgSn8glBIKv3vh4zQd6df
|
||||||
|
JvcLv3WEka9+lyoCvJ0QH+/ITqrToyWa8g9fR3ajTlyMANesKxQejo80zCwk/0ns
|
||||||
|
SFKRIJc6vfnUJ12Vdxpmm1LeoJZnCYODNUeeksL1ahHCBGq4M8UJ+ycUM6N4ndWE
|
||||||
|
6QIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQAg0BaIi7lzrNb7xC42c+GJVrBq8Qf8
|
||||||
|
7CBzP8SXYGUavQIYNRrtH8UgTOwaju9vOn3zoY8L59N6e+Icyt+Oh1FENcQMCZ2l
|
||||||
|
SP79iaY9A/dRV56p6NqNd3VWH+EuRGbQVatLdhJf3l5+W1z3Dum1YXmIn26acawF
|
||||||
|
GZVqLalgvLqPzPHHWEqz9RnmcvTu3w9YVb4NgbmY4byCb6mB2avt0iWQrY/fZSMe
|
||||||
|
FvRXurr0jwyIXBncqnXu97sCeccNc+fo3qZC1xxH9iXOIzrRg0ud7VGMTKcNLTTc
|
||||||
|
GqnbjNT8BC96Qp2Bs8J+JGZa3mT/usKBq2TT/3q6oKevuc23u/a5s1rztnqZgIe5
|
||||||
|
RzfevJ79xdva6DMSq/8Yyd3I8hrs3oZKJbAce6ux01RsrCcY2O7gi4dAMoEGumxW
|
||||||
|
CS9XLchNy7QxQ+J2AKBZXd6AZjvTvloDGz/yC5EbdK/MnLz8oApK5Z8U/huEilFa
|
||||||
|
AymVWQWpmlX2KxW0nkCperlb7lcbPS+ZuH0+Zd9HOvqr9cpYMrwpF54q4vnzUQkR
|
||||||
|
Hsxoapv/FBsVoxtcOqrcxwGpYWCsV0VBnv9+1fzzZ83aK7CHDIeGVuKPyjkhHzLy
|
||||||
|
v7Ljuqg400wH0WB9pyEdK+O3F+xO3zJgf4o0JptOKOFBVVSkZWTrqlDjjbcnXBmh
|
||||||
|
dwgj2xYeigqHJA==
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,51 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIJKAIBAAKCAgEAv0cQv80Ovk4SNpfi0+babr5YxOwj3GuXq2oU479T6pm5h2CF
|
||||||
|
ZYoHvY72SkfwGmh7oTUU+guDw6Q/fE4K4Ui0oDDBSJqBTEp5hRDlWr3tzstalfb7
|
||||||
|
aByzAfYTvrez/fCkYtbAqDHTyBP6ObhBkneGIFm5NzZZQFepntdPFJ4llMmTAkhC
|
||||||
|
plfTqX0PmHxxaJRElfdmo3VYg27UQY3wzcA+6m/M4IoMSCbwcxJ1heEWZePiiIsq
|
||||||
|
CeeQEN6JnRItEMIkUUTjRbQepEUqoxkvIHpxp8nF9WTT0QfCXhtxErhY/dVkFA9B
|
||||||
|
DAVxQeWoB6GY77RcMTpFJAOF23J6SnXRxikbeAQG5vmHIsyWk+5kcrRlmVKE6w1s
|
||||||
|
/PwnNAZcAHzxJOqIFP7C0maXcY8cKawjQfPVDiPqu54OwmIhZ8WPRx2XoBgicWH7
|
||||||
|
6SjP3jk/Zki1LoPBBiE3dI9nLrH5TuENuN3JT8kW00kq9/T3KcvK3ygKRR5FLhiK
|
||||||
|
Wv6oAG3s/pT5SMnc6W604K5x7y9T+nwmE5x5HIEp/IJQSCr974eM0HenXyb3C791
|
||||||
|
hJGvfpcqArydEB/vyE6q06MlmvIPX0d2o05cjADXrCsUHo6PNMwsJP9J7EhSkSCX
|
||||||
|
Or351CddlXcaZptS3qCWZwmDgzVHnpLC9WoRwgRquDPFCfsnFDOjeJ3VhOkCAwEA
|
||||||
|
AQKCAgBF1jSPUtcnNGoB9MKki40FEgpnG7CcMcxWkYy++oQxC59phhwuTo807pWN
|
||||||
|
2WYYvj0lRrQ59ypMrBNh1zyxtFH+is6HK6I5sJddtiWHVAEXl7ejOWHhSVkyRh4/
|
||||||
|
a+MTvGDIlZAR2N9yFZkuqc+HIoyeEyREvFsp2tfbXtFIvdUK1e4Oz0NGaJqnLzoa
|
||||||
|
epUNkdTYzFN1Ksr+ceCdbq2U8bQG9HrhIIYLcewol3zBPMVoviNfpy/aHenDvvyP
|
||||||
|
lKtPixKneXdhY7osT/SZSACk4w/MKydTyVRs5WBZ67sFErmrM9YuXMNrGDGZ1bfb
|
||||||
|
0Wx9WGSwtI258G9XCB0OQqYsq6WTMaEei+z8l0iarZi1l2bz2F89J+IBYM8RqSsa
|
||||||
|
E30F8AtEG32QJUfK3F6k6N4uLx6JZduJgLyzsSh6q51ghAJ8kD1vUkEeXffCzynp
|
||||||
|
hzwRHUw5O1jNLEBdKYHpSyszlFX6qbzR1YXypzZs/aehZi5d89eBKN8X/Fnbi9a2
|
||||||
|
Q0MqpZ5J/1hH7zadJFibNyuOCP4CNO3Hm18PjyEFRrCMbSF293kY9GoiOlQiwNAT
|
||||||
|
MqrsyLYgHPCXKXpG/R60lyHEfWKO9sOjyh+mSbv3QfNZS32Fweuo0R/vGYmkmtGn
|
||||||
|
wpn2IeSmX8ychdQrSemJjwzjUl/EUN0lGRAlHEt4ZDf52vHZ4QKCAQEA9k7b2vpU
|
||||||
|
g3S3GRCMzhl8GKZloNSbnR/ZHE8b9PVNahp0bQcZj+1yimF35p27VZR662ZBoKLy
|
||||||
|
/MLyPT+ZyynykwypcTVA5U9CABpSlyZMeezLnFlBXeHHMeoXcBZfFqHeXSsNYbhW
|
||||||
|
OStf4BGwKf7m/V0P/QL9mNsA/iq2uugC1gHoyp422YUIQQvKkBiFyMl34Zp2URsX
|
||||||
|
yIwb9aVyg2GogKDtbDPIwW89l3BCBiwalvjR6UotbXh3PQgYbsv62rTJ8AN+E+XH
|
||||||
|
eSQPnmPR6EXtX2nDuov996qlbja+JQE3SAls4EXLbrLyjSlObjcvkA59r+kZgNIY
|
||||||
|
g88hv7e9ublfqwKCAQEAxs3d9Zmjh9ByCT6jOUVnRMqw0+lVyVOs0kp7nOCb4HKM
|
||||||
|
CnupZuJQHQVQt7VhgD7FrALmYwkpt2e/WllN9bPFHRJcsw+SylOqyPil9G4DO5XZ
|
||||||
|
YPvk6PeQ/c0cbREKhsYNXqj5fWdq5pRd8rE72rK82mhdGQtAAN7NOEW5fo5tqHDK
|
||||||
|
D079SZmpcgd8Wz9luNpnZRpNhO3ccKV5yf0S1LZOZBbG9t875OVNhxlQY5wwIBXv
|
||||||
|
8ab13zcFKG21tWvLzz80vgkMIp0A9xh0XznIRnH3NnBZB80Yubg4sIaWvX7bqZ4X
|
||||||
|
EE9HGeiamw6c6Sm/Lvh/H659ri95l7C9TgAfAA7puwKCAQEAgJ/N0BzJ5ZwdwckS
|
||||||
|
vs4wL+81QzfDy9nF1zK4tsMjGjWWdxkuECs/lWQw6Q2VtqtDRYqw2uI9YiGrvrBn
|
||||||
|
7+CH/KKwGZ5ltVoebU9Rsf0eEs3FxnAV4qD1FOvaMX59SaReKulAo7dPz6sG9kxG
|
||||||
|
YqfqmITwxH+7TwePDSvhINnoITn+B1F38z+1f8JYlcc4lhIfuIChKNmtId2I/E7Z
|
||||||
|
7iIhjIp9cfPY8qrUzzCgSfjeKdjmRZ2m+3PdUNHZcIK1DWE700r/nARylqBuR5h5
|
||||||
|
FYLu4tSokdJpXdyPZ27O/SQValkBslzAT57Da1QW0RegjuoCWMqxtsQAaVTRmvyo
|
||||||
|
50QW4QKCAQBLJFbn1MmFtRjVO7KwG/Z7fu01O7WsIg9pcLOmSRNB06nw8GrIM3Q6
|
||||||
|
c97dgRY4RgGrEXGJL1ZwNyuRd73Kx8cSRPV6zMEb7mHYEnuPluFr7Si7ypnsIF7S
|
||||||
|
P2umIdHLvSIijFW4u5UhUCTubWUFNZfCKb4+kA0CBzSkN150Yls6Vl9ZR+7emdD9
|
||||||
|
A61SQ/Ur2IlKIpX4T3uJrFILMbejZMDefel4OEpIKw+Rp9TFwaxDBGer/AJk+0Pc
|
||||||
|
0xLiXrsrO2WxCnRmxNcvjjO2Jn33em4JSo+sLi5RTDtJJaXmPAPE6bcn9/8U4OFH
|
||||||
|
CE/wpVHY7B4ImIhyhQk9d5Ul3U/aUsivAoIBAG8zk3CnFAnii1ENxhPtE8GCinvs
|
||||||
|
NdsluVtvUgMcA8gNzvqLHLQCoIy/b1wkqxPVsdTq1gZ7+FX9D9LzW9JxrWeEZqVV
|
||||||
|
jrUQIbls6HZei7i5x0tPwh1shOZiijgY24I6HDX9QRKZ7H7lLw0HfJI9YBI1Hl8E
|
||||||
|
naOtCuzFiaYEPfbGQACL8/UuoOZaD31JQda2EGYysGRxxJ2ZNPJIphCrwRb/nQBG
|
||||||
|
7WwCSCzu0peFNhZPVvkWHaFN73Uv/MmgFkp8RZzw9TEENB05wluCZB1TYJAOe65n
|
||||||
|
HnRWSDvWYR4lzMtq5WASFLC0WrFTiJKRCuKPljjoTptbXsJKyskW/t/+XPM=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1 @@
|
||||||
|
BFFAA2A065DFA6FC
|
|
@ -0,0 +1,23 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID1zCCAb8CCQC/+qKgZd+m/DANBgkqhkiG9w0BAQsFADA1MRMwEQYDVQQKDApS
|
||||||
|
ZWRpcyBUZXN0MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjAx
|
||||||
|
MDI5MDEzNDE2WhcNMjExMDI5MDEzNDE2WjAmMRMwEQYDVQQKDApSZWRpcyBUZXN0
|
||||||
|
MQ8wDQYDVQQDDAZTZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
|
AQDSs3bQ9sYi2AhFuHU75Ryk1HHSgfzA6pQAJilmJdTy0s5vyiWe1HQJaWkMcS5V
|
||||||
|
GVzGMK+c+OBqtXtDDninL3betg1YPMjSCOjPMOTC1H9K7+effwf7Iwpnw9Zro8mb
|
||||||
|
TEmMslIYhhcDedzT9Owli4QAgbgTn4l1BYuKX9CLrrKFtnr21miKu3ydViy9q7T1
|
||||||
|
pib3eigvAyk7X2fadHFArGEttsXrD6cetPPkSF/1OLWNlqzUKXzhSyrBXzO44Kks
|
||||||
|
fwR/EpTiES9g4dNOL2wvKS/YE1fNKhiCENrNxTXQo1l0yOdm2+MeyOeHFzRuS0b/
|
||||||
|
+uGDFOPPi04KXeO6dQ5olBCPAgMBAAEwDQYJKoZIhvcNAQELBQADggIBADn0E2vG
|
||||||
|
iQWe8/I7VbBdPhPNupVNcLvew10eIHxY2g5vSruCSVRQTgk8itVMRmDQxbb7gdDW
|
||||||
|
jnCRbxykxbLjM9iCRljnOCsIcTi7qO7JRl8niV8dtEpPOs9lZxEdNXjIV1iZoWf3
|
||||||
|
arBbPQSyQZvTQHG6qbFnyCdMMyyXGGvEPGQDaBiKH+Ko1qeAbCi0zupChYvxmtZ8
|
||||||
|
hSTPlMFezDT9bKoNY0pkJSELfokEPU/Pn6Lz/NVbdzmCMjVa/xmF3s31g+DGhz95
|
||||||
|
4AyOnCr6o0aydPVVV3pB/BCezNXPUxpp53BG0w/K2f2DnKYCvGvJbqDAaJ8bG/J1
|
||||||
|
EFSOmwobdwVxJz3KNubmo1qJ6xOl/YT7yyqPRQRM1SY8nZW+YcoJSZjOe8wJVlob
|
||||||
|
d0bOwN1C3HQwomyMWes187bEQP6Y36HuEbR1fK8yIOzGsGDKRFAFwQwMgw2M91lr
|
||||||
|
EJIP5NRD3OZRuiYDiVfVhDZDaNahrAMZUcPCgeCAwc4YG6Gp2sDtdorOl4kIJYWE
|
||||||
|
BbBZ0Jplq9+g6ciu5ChjAW8iFl0Ae5U24MxPGXnrxiRF4WWxLeZMVLXLDvlPqReD
|
||||||
|
CHII5ifyvGEt5+RhqtZC/L+HimL+5wQgOlntqhUdLb6yWRz7YW37PFMnUXU3MXe9
|
||||||
|
uY7m73ZLluXiLojcZxU2+cx89u5FOJxrYtrj
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,8 @@
|
||||||
|
-----BEGIN DH PARAMETERS-----
|
||||||
|
MIIBCAKCAQEAo2dgOzTnLK7c8AjkiTXxdmo2MJsyzTlNXUDxLfl2hgwic6benyQ3
|
||||||
|
9iL95wKjYg2YpMhzbwux50D+9XeVkRatf1pRi/N9H911f90MO6penzUx/dxfOepN
|
||||||
|
qoGK/T9xO8e6aFCYOoQjJaZzQYC0HixJVadZd7wRlHkZ3siNKUU5QK68KaN3JE3J
|
||||||
|
R3yZ9A7MU/TVdwZyVIyoWF2+WJMQW+qaezoqiuVKZXXzzoqbj14ZrtPRmO26vMV/
|
||||||
|
bmMuHwPsk9dL7tKnTWEOrs6NVHIQW+RxJuRE9wGa0qqzHAzysEQ8q9QYPRvGo5y+
|
||||||
|
XRWosl1bHG4+EmvXsCCs35bcbKToi3NFWwIBAg==
|
||||||
|
-----END DH PARAMETERS-----
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpgIBAAKCAQEA0rN20PbGItgIRbh1O+UcpNRx0oH8wOqUACYpZiXU8tLOb8ol
|
||||||
|
ntR0CWlpDHEuVRlcxjCvnPjgarV7Qw54py923rYNWDzI0gjozzDkwtR/Su/nn38H
|
||||||
|
+yMKZ8PWa6PJm0xJjLJSGIYXA3nc0/TsJYuEAIG4E5+JdQWLil/Qi66yhbZ69tZo
|
||||||
|
irt8nVYsvau09aYm93ooLwMpO19n2nRxQKxhLbbF6w+nHrTz5Ehf9Ti1jZas1Cl8
|
||||||
|
4UsqwV8zuOCpLH8EfxKU4hEvYOHTTi9sLykv2BNXzSoYghDazcU10KNZdMjnZtvj
|
||||||
|
Hsjnhxc0bktG//rhgxTjz4tOCl3junUOaJQQjwIDAQABAoIBAQCP7CJ27nm9B0/v
|
||||||
|
P+ZkeUWtmaf+IOhjZlieGXMh4SmqjDCSz8QO0BRK8YPeCdmaK27huhPa521ztm9y
|
||||||
|
CIqFuLg7vKM06KBMR+Wu0TkRlFE3ANR4cC8lbnQHGRB4CjMGL3/16UCGm+FQcIdV
|
||||||
|
CPHdW4VZS0JPtSQRmS4N4RD0uOocxqGcVbCRqnJoNp1zyXhookgHfZsC3b3cgzC7
|
||||||
|
qvI9F1oY4Yg4b9Lw5sNi3JXWtFth8JFOPyImRcE0ngcGZK4iWjiufNKWVeTmSmVy
|
||||||
|
njMZfj8xKSpfqO3sOTbJMdrH1v5pMrAR/Ed748HheXuL15Ur9n88683hMMATZInn
|
||||||
|
YzIqNSrBAoGBAO94YBB1hN+jSKw+2FbAhuuM0gWHREmLQuaF2vjeVXL3r6YofFmf
|
||||||
|
+oJNgoOWXsv4KO2MgKDv4qrz7RohhhQpOFm5PpapSH/di7u6KsbJLYSxv/TEqQFE
|
||||||
|
NPyGywwNDIkn1wPlnX3LXp26puj2Gtn21Z0trUrpgsDM99BaTBbqTR2xAoGBAOE+
|
||||||
|
tw0GHD/6CRPfoBIgVilS/sUJ5VJYTTKo/y6ozovCAq4bt5LkYmAOy6q8paHb58Oc
|
||||||
|
J890+LEPhelM/ZJDDz9oQFfq5LvuzgNfzDRyIhgDSpghtFrdDxQZP1X1lSdh+MFW
|
||||||
|
gx0k9h8VuIPksBsIgcmUtyCYitxLFep/0tAA/GI/AoGBAMxexEVntjWSScROgh1P
|
||||||
|
hBXlAZycO4g0ZK0OEboRLYXHos1AghePM6Ee+0LIAzE6IdvR7DjtYVoagQCrGZ19
|
||||||
|
LE1Ojf7QjEIr1kQpdrZeHQ3BERyY9c9R4ZKeiw1G2ar4KEV4Ifeop6AfGrF4z6Oz
|
||||||
|
R80znVBwhxl6FAhp98QaxCORAoGBAInkc/nEKN09u/rvpzYRl83aol+MDFjZ+ACw
|
||||||
|
lvBApZnHnw5pp3uE13jI9gRDUv8A+iS1X2XQzULQJwHJgV7eMOJ3dxSbl4Y5zuMf
|
||||||
|
7YqZ6KdctHjoAVqzBD0gq7Z7DuG6R6hMxx27d/VVvcz43preHV6D7YxF9pSgXv1d
|
||||||
|
XXi7ccbPAoGBAIeLzCYd+JGufHwbq7oNvSyXJjGMjsAQuErUQ0xXwo7VAyOere2P
|
||||||
|
Dwk67wq6vsmn38EAs7IkXDgIoTD9z69DNtcjr/3fARYfmDSWyHscRwyUaJ15WQcZ
|
||||||
|
TCXAPf70Vf0KGBpRkgD+Qnq+lMZ3dr1uINGdalI4AWsXje0dPKpd+W8U
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,21 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin/*.beam
|
||||||
|
rel
|
||||||
|
_build
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk
|
||||||
|
data
|
||||||
|
ebin
|
||||||
|
emqx_bridge_mqtt.d
|
||||||
|
*.rendered
|
||||||
|
.rebar3/
|
||||||
|
*.coverdata
|
||||||
|
rebar.lock
|
||||||
|
.DS_Store
|
||||||
|
Mnesia.*/
|
|
@ -0,0 +1,191 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Copyright 2019, GilbertWong <gilbertwong96@icloud.com>.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
##====================================================================
|
||||||
|
## Configuration for EMQ X MQTT Broker Bridge
|
||||||
|
##====================================================================
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Bridges to aws
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## Bridge address: node name for local bridge, host:port for remote.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## Example: emqx@127.0.0.1, 127.0.0.1:1883
|
||||||
|
bridge.mqtt.aws.address = 127.0.0.1:1883
|
||||||
|
|
||||||
|
## Protocol version of the bridge.
|
||||||
|
##
|
||||||
|
## Value: Enum
|
||||||
|
## - mqttv5
|
||||||
|
## - mqttv4
|
||||||
|
## - mqttv3
|
||||||
|
bridge.mqtt.aws.proto_ver = mqttv4
|
||||||
|
|
||||||
|
## Start type of the bridge.
|
||||||
|
##
|
||||||
|
## Value: enum
|
||||||
|
## manual
|
||||||
|
## auto
|
||||||
|
bridge.mqtt.aws.start_type = manual
|
||||||
|
|
||||||
|
## Whether to enable bridge mode for mqtt bridge
|
||||||
|
##
|
||||||
|
## This option is prepared for the mqtt broker which does not
|
||||||
|
## support bridge_mode such as the mqtt-plugin of the rabbitmq
|
||||||
|
##
|
||||||
|
## Value: boolean
|
||||||
|
#bridge.mqtt.aws.bridge_mode = false
|
||||||
|
|
||||||
|
## The ClientId of a remote bridge.
|
||||||
|
##
|
||||||
|
## Placeholders:
|
||||||
|
## ${node}: Node name
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
bridge.mqtt.aws.clientid = bridge_aws
|
||||||
|
|
||||||
|
## The Clean start flag of a remote bridge.
|
||||||
|
##
|
||||||
|
## Value: boolean
|
||||||
|
## Default: true
|
||||||
|
##
|
||||||
|
## NOTE: Some IoT platforms require clean_start
|
||||||
|
## must be set to 'true'
|
||||||
|
bridge.mqtt.aws.clean_start = true
|
||||||
|
|
||||||
|
## The username for a remote bridge.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
bridge.mqtt.aws.username = user
|
||||||
|
|
||||||
|
## The password for a remote bridge.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
bridge.mqtt.aws.password = passwd
|
||||||
|
|
||||||
|
## Topics that need to be forward to AWS IoTHUB
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## Example: topic1/#,topic2/#
|
||||||
|
bridge.mqtt.aws.forwards = topic1/#,topic2/#
|
||||||
|
|
||||||
|
## Forward messages to the mountpoint of an AWS IoTHUB
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
bridge.mqtt.aws.forward_mountpoint = bridge/aws/${node}/
|
||||||
|
|
||||||
|
## Need to subscribe to AWS topics
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## bridge.mqtt.aws.subscription.1.topic = cmd/topic1
|
||||||
|
|
||||||
|
## Need to subscribe to AWS topics QoS.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
## bridge.mqtt.aws.subscription.1.qos = 1
|
||||||
|
|
||||||
|
## A mountpoint that receives messages from AWS IoTHUB
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## bridge.mqtt.aws.receive_mountpoint = receive/aws/
|
||||||
|
|
||||||
|
|
||||||
|
## Bribge to remote server via SSL.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
bridge.mqtt.aws.ssl = off
|
||||||
|
|
||||||
|
## PEM-encoded CA certificates of the bridge.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
bridge.mqtt.aws.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem
|
||||||
|
|
||||||
|
## Client SSL Certfile of the bridge.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
bridge.mqtt.aws.certfile = {{ platform_etc_dir }}/certs/client-cert.pem
|
||||||
|
|
||||||
|
## Client SSL Keyfile of the bridge.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
bridge.mqtt.aws.keyfile = {{ platform_etc_dir }}/certs/client-key.pem
|
||||||
|
|
||||||
|
## SSL Ciphers used by the bridge.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
bridge.mqtt.aws.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA
|
||||||
|
|
||||||
|
## Ciphers for TLS PSK.
|
||||||
|
## Note that 'bridge.${BridgeName}.ciphers' and 'bridge.${BridgeName}.psk_ciphers' cannot
|
||||||
|
## be configured at the same time.
|
||||||
|
## See 'https://tools.ietf.org/html/rfc4279#section-2'.
|
||||||
|
#bridge.mqtt.aws.psk_ciphers = PSK-AES128-CBC-SHA,PSK-AES256-CBC-SHA,PSK-3DES-EDE-CBC-SHA,PSK-RC4-SHA
|
||||||
|
|
||||||
|
## Ping interval of a down bridge.
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
## Default: 10 seconds
|
||||||
|
bridge.mqtt.aws.keepalive = 60s
|
||||||
|
|
||||||
|
## TLS versions used by the bridge.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
bridge.mqtt.aws.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
|
## Bridge reconnect time.
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
## Default: 30 seconds
|
||||||
|
bridge.mqtt.aws.reconnect_interval = 30s
|
||||||
|
|
||||||
|
## Retry interval for bridge QoS1 message delivering.
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
bridge.mqtt.aws.retry_interval = 20s
|
||||||
|
|
||||||
|
## Publish messages in batches, only RPC Bridge supports
|
||||||
|
##
|
||||||
|
## Value: Integer
|
||||||
|
## default: 32
|
||||||
|
bridge.mqtt.aws.batch_size = 32
|
||||||
|
|
||||||
|
## Inflight size.
|
||||||
|
##
|
||||||
|
## Value: Integer
|
||||||
|
bridge.mqtt.aws.max_inflight_size = 32
|
||||||
|
|
||||||
|
## Base directory for replayq to store messages on disk
|
||||||
|
## If this config entry is missing or set to undefined,
|
||||||
|
## replayq works in a mem-only manner.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
bridge.mqtt.aws.queue.replayq_dir = {{ platform_data_dir }}/replayq/emqx_aws_bridge/
|
||||||
|
|
||||||
|
## Replayq segment size
|
||||||
|
##
|
||||||
|
## Value: Bytesize
|
||||||
|
bridge.mqtt.aws.queue.replayq_seg_bytes = 10MB
|
||||||
|
|
||||||
|
## Replayq max total size
|
||||||
|
##
|
||||||
|
## Value: Bytesize
|
||||||
|
bridge.mqtt.aws.queue.max_total_size = 5GB
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
deps/
|
||||||
|
ebin/
|
||||||
|
_rel/
|
||||||
|
.erlang.mk/
|
||||||
|
*.d
|
||||||
|
*.o
|
||||||
|
*.exe
|
||||||
|
data/
|
||||||
|
*.iml
|
||||||
|
.idea/
|
||||||
|
logs/
|
||||||
|
*.beam
|
||||||
|
emqx_coap.d
|
||||||
|
intergration_test/emqx-rel/
|
||||||
|
intergration_test/libcoap/
|
||||||
|
intergration_test/case*.txt
|
||||||
|
.DS_Store
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
rebar3.crashdump
|
||||||
|
*.swp
|
||||||
|
erlang.mk
|
||||||
|
.rebar3/
|
||||||
|
etc/emqx_coap.conf.rendered
|
||||||
|
.tags*
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,82 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## CoAP Gateway
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## The IP and UDP port that CoAP bind with.
|
||||||
|
##
|
||||||
|
## Default: 0.0.0.0:5683
|
||||||
|
##
|
||||||
|
## Examples:
|
||||||
|
## coap.bind.udp.x = 0.0.0.0:5683 | :::5683 | 127.0.0.1:5683 | ::1:5683
|
||||||
|
##
|
||||||
|
coap.bind.udp.1 = 0.0.0.0:5683
|
||||||
|
##coap.bind.udp.2 = 0.0.0.0:6683
|
||||||
|
|
||||||
|
## Whether to enable statistics for CoAP clients.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
coap.enable_stats = off
|
||||||
|
|
||||||
|
|
||||||
|
##------------------------------------------------------------------------------
|
||||||
|
## DTLS options
|
||||||
|
|
||||||
|
## The DTLS port that CoAP is listening on.
|
||||||
|
##
|
||||||
|
## Default: 0.0.0.0:5684
|
||||||
|
##
|
||||||
|
## Examples:
|
||||||
|
## coap.bind.dtls.x = 0.0.0.0:5684 | :::5684 | 127.0.0.1:5684 | ::1:5684
|
||||||
|
##
|
||||||
|
coap.bind.dtls.1 = 0.0.0.0:5684
|
||||||
|
##coap.bind.dtls.2 = 0.0.0.0:6684
|
||||||
|
|
||||||
|
## A server only does x509-path validation in mode verify_peer,
|
||||||
|
## as it then sends a certificate request to the client (this
|
||||||
|
## message is not sent if the verify option is verify_none).
|
||||||
|
## You can then also want to specify option fail_if_no_peer_cert.
|
||||||
|
## More information at: http://erlang.org/doc/man/ssl.html
|
||||||
|
##
|
||||||
|
## Value: verify_peer | verify_none
|
||||||
|
## coap.dtls.verify = verify_peer
|
||||||
|
|
||||||
|
## Private key file for DTLS
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
coap.dtls.keyfile = {{ platform_etc_dir }}/certs/key.pem
|
||||||
|
|
||||||
|
## Server certificate for DTLS.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
coap.dtls.certfile = {{ platform_etc_dir }}/certs/cert.pem
|
||||||
|
|
||||||
|
## PEM-encoded CA certificates for DTLS
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## coap.dtls.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem
|
||||||
|
|
||||||
|
## Used together with {verify, verify_peer} by an SSL server. If set to true,
|
||||||
|
## the server fails if the client does not have a certificate to send, that is,
|
||||||
|
## sends an empty certificate.
|
||||||
|
##
|
||||||
|
## Value: true | false
|
||||||
|
## coap.dtls.fail_if_no_peer_cert = false
|
||||||
|
|
||||||
|
## This is the single most important configuration option of an Erlang SSL
|
||||||
|
## application. Ciphers (and their ordering) define the way the client and
|
||||||
|
## server encrypt information over the wire, from the initial Diffie-Helman
|
||||||
|
## key exchange, the session key encryption ## algorithm and the message
|
||||||
|
## digest algorithm. Selecting a good cipher suite is critical for the
|
||||||
|
## application’s data security, confidentiality and performance.
|
||||||
|
##
|
||||||
|
## The cipher list above offers:
|
||||||
|
##
|
||||||
|
## A good balance between compatibility with older browsers.
|
||||||
|
## It can get stricter for Machine-To-Machine scenarios.
|
||||||
|
## Perfect Forward Secrecy.
|
||||||
|
## No old/insecure encryption and HMAC algorithms
|
||||||
|
##
|
||||||
|
## Most of it was copied from Mozilla’s Server Side TLS article
|
||||||
|
##
|
||||||
|
## Value: Ciphers
|
||||||
|
coap.dtls.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA
|
|
@ -0,0 +1,129 @@
|
||||||
|
.PHONY: clean, clean_result, start_broker stop_broker case1 case2 case3
|
||||||
|
|
||||||
|
RELX_CONF = emqx-rel/relx.config
|
||||||
|
LIBCOAP_GIT = libcoap/README.md
|
||||||
|
|
||||||
|
all: clean_result $(RELX_CONF) $(LIBCOAP_GIT) start_broker clean_result case1 case2 case3 case4 stop_broker
|
||||||
|
@echo " "
|
||||||
|
@echo " test complete"
|
||||||
|
@echo " "
|
||||||
|
|
||||||
|
clean_result:
|
||||||
|
-rm -f case*.txt
|
||||||
|
|
||||||
|
|
||||||
|
start_broker:
|
||||||
|
-rm -f emqx-rel/_rel/emqx/log/*
|
||||||
|
-emqx-rel/_rel/emqx/bin/emqx stop
|
||||||
|
sleep 1
|
||||||
|
emqx-rel/_rel/emqx/bin/emqx start
|
||||||
|
sleep 1
|
||||||
|
emqx-rel/_rel/emqx/bin/emqx_ctl plugins load emqx_coap
|
||||||
|
|
||||||
|
stop_broker:
|
||||||
|
-emqx-rel/_rel/emqx/bin/emqx stop
|
||||||
|
|
||||||
|
case1:
|
||||||
|
libcoap/examples/coap-client -m get -s 5 "coap://127.0.0.1/mqtt/topic1?c=client1&u=tom&p=secret" > case1_output.txt &
|
||||||
|
sleep 1
|
||||||
|
libcoap/examples/coap-client -m put -e w123G45 "coap://127.0.0.1/mqtt/topic1?c=client2&u=mike&p=pw12"
|
||||||
|
sleep 6
|
||||||
|
python check_result.py case1 case1_output.txt==w123G45
|
||||||
|
|
||||||
|
case2:
|
||||||
|
# subscribe to topic="x/y"
|
||||||
|
libcoap/examples/coap-client -m get -s 5 "coap://127.0.0.1/mqtt/x%2Fy?c=client3&u=tom&p=secret" > case2_output1.txt &
|
||||||
|
# subscribe to topic="+/z"
|
||||||
|
libcoap/examples/coap-client -m get -s 5 "coap://127.0.0.1/mqtt/%2B%2Fz?c=client4&u=mike&p=pw12" > case2_output2.txt &
|
||||||
|
sleep 1
|
||||||
|
# publish to topic="x/y"
|
||||||
|
libcoap/examples/coap-client -m put -e big9wolf "coap://127.0.0.1/mqtt/x%2Fy?c=client5&u=sun&p=pw3"
|
||||||
|
# publish to topic="p/z"
|
||||||
|
libcoap/examples/coap-client -m put -e black2ant "coap://127.0.0.1/mqtt/p%2Fz?c=client5&u=sun&p=pw3"
|
||||||
|
sleep 6
|
||||||
|
python check_result.py case2 case2_output1.txt==big9wolf case2_output1.txt!=black2ant case2_output2.txt!=big9wolf case2_output2.txt==black2ant
|
||||||
|
|
||||||
|
case3:
|
||||||
|
libcoap/examples/coap-client -m get -T tk12 -s 5 "coap://127.0.0.1/mqtt/a%2Fb?c=client3&u=tom&p=secret" > case3_output1.txt &
|
||||||
|
libcoap/examples/coap-client -m get -T tk34 -s 5 "coap://127.0.0.1/mqtt/c%2Fd?c=client3&u=tom&p=secret" > case3_output2.txt &
|
||||||
|
sleep 1
|
||||||
|
libcoap/examples/coap-client -m put -e big9wolf "coap://127.0.0.1/mqtt/c%2Fd?c=client5&u=sun&p=pw3"
|
||||||
|
libcoap/examples/coap-client -m put -e black2ant "coap://127.0.0.1/mqtt/a%2Fb?c=client5&u=sun&p=pw3"
|
||||||
|
sleep 6
|
||||||
|
python check_result.py case3 case3_output1.txt==black2ant case3_output2.txt==big9wolf case3_output2.txt!=black2ant
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case4:
|
||||||
|
# reload emqx_coap, does it work as expected?
|
||||||
|
sleep 1
|
||||||
|
emqx-rel/_rel/emqx/bin/emqx_ctl plugins unload emqx_coap
|
||||||
|
sleep 1
|
||||||
|
emqx-rel/_rel/emqx/bin/emqx_ctl plugins load emqx_coap
|
||||||
|
sleep 1
|
||||||
|
libcoap/examples/coap-client -m get -s 5 "coap://127.0.0.1/mqtt/topic1?c=client1&u=tom&p=secret" > case4_output.txt &
|
||||||
|
sleep 1
|
||||||
|
libcoap/examples/coap-client -m put -e w6J3G45 "coap://127.0.0.1/mqtt/topic1?c=client2&u=mike&p=pw12"
|
||||||
|
sleep 6
|
||||||
|
python check_result.py case4 case4_output.txt==w6J3G45
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$(RELX_CONF):
|
||||||
|
git clone https://github.com/emqx/emqx-rel.git
|
||||||
|
git clone https://github.com/emqx/emq-coap.git
|
||||||
|
@echo "update emq-coap with this development code"
|
||||||
|
mv emq-coap emqx_coap
|
||||||
|
-rm -rf emqx_coap/etc
|
||||||
|
-rm -rf emqx_coap/include
|
||||||
|
-rm -rf emqx_coap/priv
|
||||||
|
-rm -rf emqx_coap/src
|
||||||
|
-rm -rf emqx_coap/Makefile
|
||||||
|
cp -rf ../etc emqx_coap/
|
||||||
|
cp -rf ../include emqx_coap/
|
||||||
|
cp -rf ../priv emqx_coap/
|
||||||
|
cp -rf ../src emqx_coap/
|
||||||
|
cp -rf ../Makefile emqx_coap/Makefile
|
||||||
|
-mkdir emqx-rel/deps
|
||||||
|
mv emqx_coap emqx-rel/deps/
|
||||||
|
@echo "start building ..."
|
||||||
|
make -C emqx-rel -f Makefile
|
||||||
|
|
||||||
|
|
||||||
|
coap: $(LIBCOAP_GIT)
|
||||||
|
@echo "make coap"
|
||||||
|
|
||||||
|
$(LIBCOAP_GIT):
|
||||||
|
git clone -b v4.1.2 http://github.com/obgm/libcoap
|
||||||
|
cd libcoap && ./autogen.sh && ./configure --enable-documentation=no --enable-tests=no
|
||||||
|
make -C libcoap -f Makefile
|
||||||
|
|
||||||
|
r: rebuild_emq
|
||||||
|
# r short for rebuild_emq
|
||||||
|
@echo " rebuild complete "
|
||||||
|
|
||||||
|
rebuild_emq:
|
||||||
|
-emqx-rel/_rel/emqx/bin/emqx stop
|
||||||
|
-rm -rf emqx-rel/deps/emqx_coap/etc
|
||||||
|
-rm -rf emqx-rel/deps/emqx_coap/include
|
||||||
|
-rm -rf emqx-rel/deps/emqx_coap/priv
|
||||||
|
-rm -rf emqx-rel/deps/emqx_coap/src
|
||||||
|
-rm -rf emqx-rel/deps/emqx_coap/Makefile
|
||||||
|
cp -rf ../etc emqx-rel/deps/emqx_coap/
|
||||||
|
cp -rf ../include emqx-rel/deps/emqx_coap/
|
||||||
|
cp -rf ../priv emqx-rel/deps/emqx_coap/
|
||||||
|
cp -rf ../src emqx-rel/deps/emqx_coap/
|
||||||
|
cp -rf ../Makefile emqx-rel/deps/emqx_coap/Makefile
|
||||||
|
make -C emqx-rel -f Makefile
|
||||||
|
|
||||||
|
clean: clean_result
|
||||||
|
-rm -f client/*.exe
|
||||||
|
-rm -f client/*.o
|
||||||
|
-rm -rf emqx-rel
|
||||||
|
-rm -rf libcoap
|
||||||
|
|
||||||
|
lazy: clean_result start_broker case2 stop_broker
|
||||||
|
# custom your command here
|
||||||
|
@echo "you are so lazy"
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
ct.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
data/
|
||||||
|
.DS_Store
|
||||||
|
emqx_dashboard.d
|
||||||
|
cover/
|
||||||
|
eunit.coverdata
|
||||||
|
.DS_Store
|
||||||
|
erlang.mk
|
||||||
|
rebar.lock
|
||||||
|
_build/
|
||||||
|
*.conf.rendered
|
||||||
|
.rebar3/
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,129 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## EMQ X Dashboard
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## Default user's login name.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
dashboard.default_user.login = admin
|
||||||
|
|
||||||
|
## Default user's password.
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
dashboard.default_user.password = public
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## HTTP Listener
|
||||||
|
|
||||||
|
## The port that the Dashboard HTTP listener will bind.
|
||||||
|
##
|
||||||
|
## Value: Port
|
||||||
|
##
|
||||||
|
## Examples: 18083
|
||||||
|
dashboard.listener.http = 18083
|
||||||
|
|
||||||
|
## The acceptor pool for external Dashboard HTTP listener.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
dashboard.listener.http.acceptors = 4
|
||||||
|
|
||||||
|
## Maximum number of concurrent Dashboard HTTP connections.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
dashboard.listener.http.max_clients = 512
|
||||||
|
|
||||||
|
## Set up the socket for IPv6.
|
||||||
|
##
|
||||||
|
## Value: false | true
|
||||||
|
dashboard.listener.http.inet6 = false
|
||||||
|
|
||||||
|
## Listen on IPv4 and IPv6 (false) or only on IPv6 (true). Use with inet6.
|
||||||
|
##
|
||||||
|
## Value: false | true
|
||||||
|
dashboard.listener.http.ipv6_v6only = false
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## HTTPS Listener
|
||||||
|
|
||||||
|
## The port that the Dashboard HTTPS listener will bind.
|
||||||
|
##
|
||||||
|
## Value: Port
|
||||||
|
##
|
||||||
|
## Examples: 18084
|
||||||
|
## dashboard.listener.https = 18084
|
||||||
|
|
||||||
|
## The acceptor pool for external Dashboard HTTPS listener.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
## dashboard.listener.https.acceptors = 2
|
||||||
|
|
||||||
|
## Maximum number of concurrent Dashboard HTTPS connections.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
## dashboard.listener.https.max_clients = 512
|
||||||
|
|
||||||
|
## Set up the socket for IPv6.
|
||||||
|
##
|
||||||
|
## Value: false | true
|
||||||
|
## dashboard.listener.https.inet6 = false
|
||||||
|
|
||||||
|
## Listen on IPv4 and IPv6 (false) or only on IPv6 (true). Use with inet6.
|
||||||
|
##
|
||||||
|
## Value: false | true
|
||||||
|
## dashboard.listener.https.ipv6_v6only = false
|
||||||
|
|
||||||
|
## Path to the file containing the user's private PEM-encoded key.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## dashboard.listener.https.keyfile = etc/certs/key.pem
|
||||||
|
|
||||||
|
## Path to a file containing the user certificate.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## dashboard.listener.https.certfile = etc/certs/cert.pem
|
||||||
|
|
||||||
|
## Path to the file containing PEM-encoded CA certificates.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## dashboard.listener.https.cacertfile = etc/certs/cacert.pem
|
||||||
|
|
||||||
|
## See: 'listener.ssl.<name>.dhfile' in emq.conf
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
## dashboard.listener.https.dhfile = {{ platform_etc_dir }}/certs/dh-params.pem
|
||||||
|
|
||||||
|
## See: 'listener.ssl.<name>.vefify' in emq.conf
|
||||||
|
##
|
||||||
|
## Value: vefify_peer | verify_none
|
||||||
|
## dashboard.listener.https.verify = verify_peer
|
||||||
|
|
||||||
|
## See: 'listener.ssl.<name>.fail_if_no_peer_cert' in emq.conf
|
||||||
|
##
|
||||||
|
## Value: false | true
|
||||||
|
## dashboard.listener.https.fail_if_no_peer_cert = true
|
||||||
|
|
||||||
|
## TLS versions only to protect from POODLE attack.
|
||||||
|
##
|
||||||
|
## Value: String, seperated by ','
|
||||||
|
## dashboard.listener.https.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
|
## See: 'listener.ssl.<name>.ciphers' in emq.conf
|
||||||
|
##
|
||||||
|
## Value: Ciphers
|
||||||
|
## dashboard.listener.https.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA
|
||||||
|
|
||||||
|
## See: 'listener.ssl.<name>.secure_renegotiate' in emq.conf
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
## dashboard.listener.https.secure_renegotiate = off
|
||||||
|
|
||||||
|
## See: 'listener.ssl.<name>.reuse_sessions' in emq.conf
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
## dashboard.listener.https.reuse_sessions = on
|
||||||
|
|
||||||
|
## See: 'listener.ssl.<name>.honor_cipher_order' in emq.conf
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
## dashboard.listener.https.honor_cipher_order = on
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
.rebar3
|
||||||
|
_*
|
||||||
|
.eunit
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
.erlang.cookie
|
||||||
|
ebin
|
||||||
|
log
|
||||||
|
erl_crash.dump
|
||||||
|
.rebar
|
||||||
|
logs
|
||||||
|
_build
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
rebar3.crashdump
|
||||||
|
*~
|
||||||
|
rebar.lock
|
||||||
|
data/
|
||||||
|
*.conf.rendered
|
||||||
|
*.pyc
|
||||||
|
.DS_Store
|
||||||
|
*.class
|
|
@ -0,0 +1,191 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Copyright 2020, JianBo He <heeejianbo@gmail.com>.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
`emqx-extension-hook` 插件用于提供钩子(Hook)的多语言支持。它能够允许其他的语言,例如:Python,Java 等,能够直接表达如何挂载钩子,和处理相应的钩子事件。
|
||||||
|
|
||||||
|
该插件给 EMQ X 带来的扩展性十分的强大,甚至于所有基于钩子的插件都可以通过其他编程语言实现。唯一不同的是在性能上肯定有一定的降低。
|
||||||
|
|
||||||
|
目前,一些常见的场景有:
|
||||||
|
|
||||||
|
- 通过 `client.authenticate` 钩子,使用其他编程语言查询数据库,判断该客户端是否具有接入的权限。
|
||||||
|
- 通过 `client.check_acl` 钩子,使用其他编程语言查询数据库,实现发布/订阅的权限控制逻辑。
|
||||||
|
- 通过 `message` 类的钩子,实现消息收发的控制和数据格式转换。
|
||||||
|
- 获取客户端所有的事件,将其存储进三方的日志、或数据平台中。
|
||||||
|
|
||||||
|
**声明:当前仅实现了 Python、Java 的支持**
|
||||||
|
|
||||||
|
**声明:message 类钩子功能仅包含在企业版当中**
|
||||||
|
|
||||||
|
### 要求
|
||||||
|
|
||||||
|
EMQ X 发行包中不包含其他语言的运行环境。它要求:
|
||||||
|
|
||||||
|
- 宿主机需包含其他编程语言对应的执行环境。
|
||||||
|
- 必须将源码(或编译后的代码)、资源文件等,放到 `emqx-extension-hook` 指示的路径。
|
||||||
|
- 代码的实现,若包含三方依赖、库等,它应该包含在 `emqx-extension-hook` 对其的搜索路径中。
|
||||||
|
|
||||||
|
|
||||||
|
### 架构
|
||||||
|
|
||||||
|
`emqx-extension-hook` 是 EMQ X 的一个插件,它主要包括:
|
||||||
|
|
||||||
|
1. 驱动的管理。例如:如何启动/停止某个驱动。
|
||||||
|
2. 事件的分发。例如:根据各个驱动所注册的钩子列表的不同,向各个驱动分发事件,传递返回值等。
|
||||||
|
3. 预置了驱动的实现。包括 Python 和 Java 驱动的实现,和方便用户集成开发的 SDK 代码包。
|
||||||
|
|
||||||
|
其架构图如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
EMQ X Third-party Runtimes
|
||||||
|
+========================+ +====================+
|
||||||
|
| Extension | | |
|
||||||
|
| +----------------+ | Hooks | Python scripts / |
|
||||||
|
| | Drivers | ------------------> | Java Classes / |
|
||||||
|
| +----------------+ | (pipe) | Others ... |
|
||||||
|
| | | |
|
||||||
|
+========================+ +====================+
|
||||||
|
```
|
||||||
|
|
||||||
|
图中表明,由 Client 产生的所有的事件,例如:连接、发布、订阅等,都会由 `emqx-extension-hook`插件分发给下面的各个 `驱动(Driver)`;而,驱动则负责如何与三方运行时的进行通信。
|
||||||
|
|
||||||
|
广义上的驱动(Driver)可以分为两类:
|
||||||
|
|
||||||
|
1. 编程语言类。
|
||||||
|
2. 服务类。例如:HTTP 就属于此类。
|
||||||
|
|
||||||
|
`emqx-extension-hook` 并不关心驱动实际的类型和实现,只要其实现了对应的接口即可。
|
||||||
|
|
||||||
|
|
||||||
|
#### 驱动
|
||||||
|
|
||||||
|
本文中,只有未经限定说明的驱动,都是指编程语言类的驱动。
|
||||||
|
|
||||||
|
编程语言类驱动是基于 [Erlang - Port](http://erlang.org/doc/tutorial/c_port.html) 进行实现。它本质上是由 `emqx-extension-hook` 是启动一个其他语言的程序,并使用管道(Pipe)实现两个进程间的通信。
|
||||||
|
|
||||||
|
|
||||||
|
此类驱动的实现包括两部分的内容:
|
||||||
|
|
||||||
|
1. Erlang 侧的实现,它包含如何启动其他语言的运行时系统、和分发请求、处理结果等。
|
||||||
|
2. 其他语言侧的实现。它包含如何和 Erlang 虚拟机通信,如何执行函数调用等。
|
||||||
|
|
||||||
|
如:
|
||||||
|
|
||||||
|
```
|
||||||
|
Erlang VM Third Runtimes (e.g: Java VM)
|
||||||
|
+===========+=========+ +=========+================+
|
||||||
|
| Extension | Driver | <=====> | Driver | User's Codes |
|
||||||
|
+===========+=========+ +=========+================+
|
||||||
|
```
|
||||||
|
|
||||||
|
而,对于基于服务的驱动,原理就很简单了。以 HTTP 为例,它的实现仅需要一个 HTTP 客户端、和指定服务端返回的数据格式即可。
|
||||||
|
|
||||||
|
### 集成与调试
|
||||||
|
|
||||||
|
参见 SDK 规范、和对应语言的开发手册
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
## SDK 规范
|
||||||
|
|
||||||
|
### 动机
|
||||||
|
|
||||||
|
SDK 的目的在于方便用户使用 IDE 集成开发、和模拟调试。
|
||||||
|
|
||||||
|
### 位置
|
||||||
|
|
||||||
|
```
|
||||||
|
+------------------+
|
||||||
|
| User's Codes |
|
||||||
|
+------------------+
|
||||||
|
| SDK | <==== The SDK Located
|
||||||
|
+------------------+
|
||||||
|
| Raw APIs |
|
||||||
|
+------------------+
|
||||||
|
| Driver |
|
||||||
|
+==================+
|
||||||
|
||
|
||||||
|
+==================+
|
||||||
|
| EMQ X Plugin |
|
||||||
|
+------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
因此,SDK 的作用在于封装底层的比较晦涩的数据格式和方法,屏蔽底层细节。直接提供优化 API 供用户使用。
|
||||||
|
|
||||||
|
|
||||||
|
### 实现要求
|
||||||
|
|
||||||
|
**声明:** stdin, stdout 已用于和 EMQ X 通信,请不要使用。stderr 用于日志输出。
|
||||||
|
|
||||||
|
#### 基础项
|
||||||
|
|
||||||
|
1. 必须将原始的 `init` `deinit`函数进行封装,方便用户:
|
||||||
|
- 配置需要挂载的钩子列表
|
||||||
|
- 定义用户自己的初始化和销毁的内容
|
||||||
|
2. 必须将回调函数的各个松散的数据类型,封装成类或某种结构化类型。
|
||||||
|
3. 必须要有对应的开发、部署文档说明
|
||||||
|
|
||||||
|
#### 高级项
|
||||||
|
|
||||||
|
1. 应能方便用户能在 IDE 中进行,集成和开发
|
||||||
|
2. 应提供集成测试用的模拟代码。
|
||||||
|
- 例如,生成模拟的数据,发送至用户的程序,方便直接断点调试
|
||||||
|
|
||||||
|
|
||||||
|
### 部署结构
|
||||||
|
|
||||||
|
#### 代码依赖结构
|
||||||
|
|
||||||
|
从部署的角度看,代码的依赖关系为:
|
||||||
|
|
||||||
|
1. 用户代码:
|
||||||
|
* 一定会依赖 SDK
|
||||||
|
* 可能会依赖 某个位置的三方/系统库
|
||||||
|
2. SDK 代码:
|
||||||
|
* 只能依赖 erlport
|
||||||
|
3. 基础通信库
|
||||||
|
* 无依赖
|
||||||
|
|
||||||
|
#### 部署
|
||||||
|
|
||||||
|
从文件存放的位置来看,一个标准的部署结构为:
|
||||||
|
|
||||||
|
```
|
||||||
|
emqx
|
||||||
|
|
|
||||||
|
|--- data
|
||||||
|
|------- extension
|
||||||
|
|---------- <some-sdk-package-name>
|
||||||
|
|--------------- <some-classes/scripts-in-sdk>
|
||||||
|
|---------- <user's classes/scripts>
|
||||||
|
|
|
||||||
|
|---------- <another-sdk-package-name>
|
||||||
|
|--------------- <some-classes/scripts-in-sdk>
|
||||||
|
|---------- <user's classes/scripts>
|
||||||
|
```
|
||||||
|
|
||||||
|
它表达了:在 `data/extension` 目录下安装了两个 SDK,并且用户都基于 SDK 编写了其回调的代码模块。
|
|
@ -0,0 +1,24 @@
|
||||||
|
##====================================================================
|
||||||
|
## EMQ X Hooks
|
||||||
|
##====================================================================
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Driver confs
|
||||||
|
|
||||||
|
## Setup the supported drivers
|
||||||
|
##
|
||||||
|
## Value: python3 | java
|
||||||
|
exhook.drivers = python3
|
||||||
|
|
||||||
|
## Search path for scripts/library
|
||||||
|
##
|
||||||
|
exhook.drivers.python3.path = {{ platform_data_dir }}/extension/
|
||||||
|
|
||||||
|
## Call timeout
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
##exhook.drivers.python3.call_timeout = 5s
|
||||||
|
|
||||||
|
## Initial module name
|
||||||
|
##
|
||||||
|
##exhook.drivers.python3.init_module = main
|
|
@ -0,0 +1,22 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-ifndef(EMQX_EXTENSION_HOOK_HRL).
|
||||||
|
-define(EMQX_EXTENSION_HOOK_HRL, true).
|
||||||
|
|
||||||
|
-define(APP, emqx_extension_hook).
|
||||||
|
|
||||||
|
-endif.
|
|
@ -0,0 +1,43 @@
|
||||||
|
%%-*- mode: erlang -*-
|
||||||
|
|
||||||
|
{mapping, "exhook.drivers", "emqx_extension_hook.drivers", [
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{mapping, "exhook.drivers.$name.$key", "emqx_extension_hook.drivers", [
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{translation, "emqx_extension_hook.drivers", fun(Conf) ->
|
||||||
|
|
||||||
|
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
||||||
|
|
||||||
|
Duration = fun(S) ->
|
||||||
|
case cuttlefish_duration:parse(S, ms) of
|
||||||
|
Ms when is_integer(Ms) -> Ms;
|
||||||
|
{error, R} -> error(R)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
Integer = fun(S) -> list_to_integer(S) end,
|
||||||
|
|
||||||
|
Atom = fun(S) -> list_to_atom(S) end,
|
||||||
|
|
||||||
|
Python = fun(Prefix) ->
|
||||||
|
[{init_module, Atom(cuttlefish:conf_get(Prefix ++ ".init_module", Conf, "main"))}, %% dirver
|
||||||
|
{python_path, cuttlefish:conf_get(Prefix ++ ".path", Conf, undefined)},
|
||||||
|
{call_timeout, Duration(cuttlefish:conf_get(Prefix ++ ".call_timeout", Conf, "5s"))}]
|
||||||
|
end,
|
||||||
|
|
||||||
|
Java = fun(Prefix) ->
|
||||||
|
[{init_module, Atom(cuttlefish:conf_get(Prefix ++ ".init_module", Conf, "Main"))}, %% dirver
|
||||||
|
{java_path, cuttlefish:conf_get(Prefix ++ ".path", Conf, undefined)},
|
||||||
|
{call_timeout, Duration(cuttlefish:conf_get(Prefix ++ ".call_timeout", Conf, "5s"))}]
|
||||||
|
end,
|
||||||
|
|
||||||
|
Options = fun(python) -> Filter(Python("exhook.drivers.python"));
|
||||||
|
(python3) -> Filter(Python("exhook.drivers.python3"));
|
||||||
|
(java) -> Filter(Java("exhook.drivers.java"));
|
||||||
|
(_) -> error(not_supported_drivers_type)
|
||||||
|
end,
|
||||||
|
[{Atom(Name), Options(Atom(Name))} || Name <- string:tokens(cuttlefish:conf_get("exhook.drivers", Conf), ",")]
|
||||||
|
end}.
|
|
@ -0,0 +1,12 @@
|
||||||
|
# SDKs
|
||||||
|
|
||||||
|
A specific language SDK is a suite of codes for user-oriented friendly.
|
||||||
|
|
||||||
|
Even it does not need it for you to develop the Multiple language support plugins, but it provides more friendly APIs and Abstract for you
|
||||||
|
|
||||||
|
|
||||||
|
Now, we provide the following SDKs:
|
||||||
|
|
||||||
|
- Java: https://github.com/emqx/emqx-extension-java-sdk
|
||||||
|
- Python: https://github.com/emqx/emqx-extension-python-sdk
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
{application, emqx_extension_hook,
|
||||||
|
[{description, "EMQ X Extension for Hook"},
|
||||||
|
{vsn, "git"},
|
||||||
|
{modules, []},
|
||||||
|
{registered, []},
|
||||||
|
{mod, {emqx_extension_hook_app, []}},
|
||||||
|
{applications, [kernel, stdlib, ecpool, erlport]},
|
||||||
|
{env,[]},
|
||||||
|
{licenses, ["Apache-2.0"]},
|
||||||
|
{maintainers, ["EMQ X Team <contact@emqx.io>"]},
|
||||||
|
{links, [{"Homepage", "https://emqx.io/"},
|
||||||
|
{"Github", "https://github.com/emqx/emqx-extension-hook"}
|
||||||
|
]}
|
||||||
|
]}.
|
|
@ -0,0 +1,136 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_extension_hook).
|
||||||
|
|
||||||
|
-include("emqx_extension_hook.hrl").
|
||||||
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
|
-logger_header("[ExHook]").
|
||||||
|
|
||||||
|
%% Mgmt APIs
|
||||||
|
-export([ enable/2
|
||||||
|
, disable/1
|
||||||
|
, disable_all/0
|
||||||
|
, list/0
|
||||||
|
]).
|
||||||
|
|
||||||
|
-export([ cast/2
|
||||||
|
, call_fold/4
|
||||||
|
]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Mgmt APIs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec list() -> [emqx_extension_hook_driver:driver()].
|
||||||
|
list() ->
|
||||||
|
[state(Name) || Name <- running()].
|
||||||
|
|
||||||
|
-spec enable(atom(), list()) -> ok | {error, term()}.
|
||||||
|
enable(Name, Opts) ->
|
||||||
|
case lists:member(Name, running()) of
|
||||||
|
true ->
|
||||||
|
{error, already_started};
|
||||||
|
_ ->
|
||||||
|
case emqx_extension_hook_driver:load(Name, Opts) of
|
||||||
|
{ok, DriverState} ->
|
||||||
|
save(Name, DriverState);
|
||||||
|
{error, Reason} ->
|
||||||
|
?LOG(error, "Load driver ~p failed: ~p", [Name, Reason]),
|
||||||
|
{error, Reason}
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec disable(atom()) -> ok | {error, term()}.
|
||||||
|
disable(Name) ->
|
||||||
|
case state(Name) of
|
||||||
|
undefined -> {error, not_running};
|
||||||
|
Driver ->
|
||||||
|
ok = emqx_extension_hook_driver:unload(Driver),
|
||||||
|
unsave(Name)
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec disable_all() -> [atom()].
|
||||||
|
disable_all() ->
|
||||||
|
[begin disable(Name), Name end || Name <- running()].
|
||||||
|
|
||||||
|
%%----------------------------------------------------------
|
||||||
|
%% Dispatch APIs
|
||||||
|
%%----------------------------------------------------------
|
||||||
|
|
||||||
|
-spec cast(atom(), list()) -> ok.
|
||||||
|
cast(Name, Args) ->
|
||||||
|
cast(Name, Args, running()).
|
||||||
|
|
||||||
|
cast(_, _, []) ->
|
||||||
|
ok;
|
||||||
|
cast(Name, Args, [DriverName|More]) ->
|
||||||
|
emqx_extension_hook_driver:run_hook(Name, Args, state(DriverName)),
|
||||||
|
cast(Name, Args, More).
|
||||||
|
|
||||||
|
-spec call_fold(atom(), list(), term(), function()) -> ok | {stop, term()}.
|
||||||
|
call_fold(Name, InfoArgs, AccArg, Validator) ->
|
||||||
|
call_fold(Name, InfoArgs, AccArg, Validator, running()).
|
||||||
|
|
||||||
|
call_fold(_, _, _, _, []) ->
|
||||||
|
ok;
|
||||||
|
call_fold(Name, InfoArgs, AccArg, Validator, [NameDriver|More]) ->
|
||||||
|
Driver = state(NameDriver),
|
||||||
|
case emqx_extension_hook_driver:run_hook_fold(Name, InfoArgs, AccArg, Driver) of
|
||||||
|
ok -> call_fold(Name, InfoArgs, AccArg, Validator, More);
|
||||||
|
{error, _} -> call_fold(Name, InfoArgs, AccArg, Validator, More);
|
||||||
|
{ok, NAcc} ->
|
||||||
|
case Validator(NAcc) of
|
||||||
|
true ->
|
||||||
|
{stop, NAcc};
|
||||||
|
_ ->
|
||||||
|
?LOG(error, "Got invalid return type for calling ~p on ~p",
|
||||||
|
[Name, emqx_extension_hook_driver:name(Driver)]),
|
||||||
|
call_fold(Name, InfoArgs, AccArg, Validator, More)
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%----------------------------------------------------------
|
||||||
|
%% Storage
|
||||||
|
|
||||||
|
-compile({inline, [save/2]}).
|
||||||
|
save(Name, DriverState) ->
|
||||||
|
Saved = persistent_term:get(?APP, []),
|
||||||
|
persistent_term:put(?APP, lists:reverse([Name | Saved])),
|
||||||
|
persistent_term:put({?APP, Name}, DriverState).
|
||||||
|
|
||||||
|
-compile({inline, [unsave/1]}).
|
||||||
|
unsave(Name) ->
|
||||||
|
case persistent_term:get(?APP, []) of
|
||||||
|
[] ->
|
||||||
|
persistent_term:erase(?APP);
|
||||||
|
Saved ->
|
||||||
|
persistent_term:put(?APP, lists:delete(Name, Saved))
|
||||||
|
end,
|
||||||
|
persistent_term:erase({?APP, Name}),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
-compile({inline, [running/0]}).
|
||||||
|
running() ->
|
||||||
|
persistent_term:get(?APP, []).
|
||||||
|
|
||||||
|
-compile({inline, [state/1]}).
|
||||||
|
state(Name) ->
|
||||||
|
case catch persistent_term:get({?APP, Name}) of
|
||||||
|
{'EXIT', {badarg,_}} -> undefined;
|
||||||
|
State -> State
|
||||||
|
end.
|
|
@ -0,0 +1,108 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_extension_hook_app).
|
||||||
|
|
||||||
|
-behaviour(application).
|
||||||
|
|
||||||
|
-include("emqx_extension_hook.hrl").
|
||||||
|
|
||||||
|
-emqx_plugin(?MODULE).
|
||||||
|
|
||||||
|
-export([ start/2
|
||||||
|
, stop/1
|
||||||
|
, prep_stop/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Application callbacks
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
start(_StartType, _StartArgs) ->
|
||||||
|
{ok, Sup} = emqx_extension_hook_sup:start_link(),
|
||||||
|
|
||||||
|
%% Load all dirvers
|
||||||
|
load_all_drivers(),
|
||||||
|
|
||||||
|
%% Register all hooks
|
||||||
|
load_exhooks(),
|
||||||
|
|
||||||
|
%% Register CLI
|
||||||
|
emqx_ctl:register_command(exhook, {emqx_extension_hook_cli, cli}, []),
|
||||||
|
{ok, Sup}.
|
||||||
|
|
||||||
|
prep_stop(State) ->
|
||||||
|
emqx_ctl:unregister_command(exhook),
|
||||||
|
unload_exhooks(),
|
||||||
|
unload_all_drivers(),
|
||||||
|
State.
|
||||||
|
|
||||||
|
stop(_State) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Internal funcs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
load_all_drivers() ->
|
||||||
|
load_all_drivers(application:get_env(?APP, drivers, [])).
|
||||||
|
|
||||||
|
load_all_drivers([]) ->
|
||||||
|
ok;
|
||||||
|
load_all_drivers([{Name, Opts}|Drivers]) ->
|
||||||
|
ok = emqx_extension_hook:enable(Name, Opts),
|
||||||
|
load_all_drivers(Drivers).
|
||||||
|
|
||||||
|
unload_all_drivers() ->
|
||||||
|
emqx_extension_hook:disable_all().
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Exhooks
|
||||||
|
|
||||||
|
load_exhooks() ->
|
||||||
|
[emqx:hook(Name, {M, F, A}) || {Name, {M, F, A}} <- search_exhooks()].
|
||||||
|
|
||||||
|
unload_exhooks() ->
|
||||||
|
[emqx:unhook(Name, {M, F}) || {Name, {M, F, _A}} <- search_exhooks()].
|
||||||
|
|
||||||
|
search_exhooks() ->
|
||||||
|
search_exhooks(ignore_lib_apps(application:loaded_applications())).
|
||||||
|
search_exhooks(Apps) ->
|
||||||
|
lists:flatten([ExHooks || App <- Apps, {_App, _Mod, ExHooks} <- find_attrs(App, exhooks)]).
|
||||||
|
|
||||||
|
ignore_lib_apps(Apps) ->
|
||||||
|
LibApps = [kernel, stdlib, sasl, appmon, eldap, erts,
|
||||||
|
syntax_tools, ssl, crypto, mnesia, os_mon,
|
||||||
|
inets, goldrush, gproc, runtime_tools,
|
||||||
|
snmp, otp_mibs, public_key, asn1, ssh, hipe,
|
||||||
|
common_test, observer, webtool, xmerl, tools,
|
||||||
|
test_server, compiler, debugger, eunit, et,
|
||||||
|
wx],
|
||||||
|
[AppName || {AppName, _, _} <- Apps, not lists:member(AppName, LibApps)].
|
||||||
|
|
||||||
|
find_attrs(App, Def) ->
|
||||||
|
[{App, Mod, Attr} || {ok, Modules} <- [application:get_key(App, modules)],
|
||||||
|
Mod <- Modules,
|
||||||
|
{Name, Attrs} <- module_attributes(Mod), Name =:= Def,
|
||||||
|
Attr <- Attrs].
|
||||||
|
|
||||||
|
module_attributes(Module) ->
|
||||||
|
try Module:module_info(attributes)
|
||||||
|
catch
|
||||||
|
error:undef -> [];
|
||||||
|
error:Reason -> error(Reason)
|
||||||
|
end.
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_extension_hook_cli).
|
||||||
|
|
||||||
|
-include("emqx_extension_hook.hrl").
|
||||||
|
|
||||||
|
-export([cli/1]).
|
||||||
|
|
||||||
|
cli(["drivers", "list"]) ->
|
||||||
|
if_enabled(fun() ->
|
||||||
|
Drivers = emqx_extension_hook:list(),
|
||||||
|
[emqx_ctl:print("Driver(~s)~n", [emqx_extension_hook_driver:format(Driver)]) || Driver <- Drivers]
|
||||||
|
end);
|
||||||
|
|
||||||
|
cli(["drivers", "enable", Name0]) ->
|
||||||
|
if_enabled(fun() ->
|
||||||
|
Name = list_to_atom(Name0),
|
||||||
|
case proplists:get_value(Name, application:get_env(?APP, drivers, [])) of
|
||||||
|
undefined ->
|
||||||
|
emqx_ctl:print("not_found~n");
|
||||||
|
Opts ->
|
||||||
|
print(emqx_extension_hook:enable(Name, Opts))
|
||||||
|
end
|
||||||
|
end);
|
||||||
|
|
||||||
|
cli(["drivers", "disable", Name]) ->
|
||||||
|
if_enabled(fun() ->
|
||||||
|
print(emqx_extension_hook:disable(list_to_atom(Name)))
|
||||||
|
end);
|
||||||
|
|
||||||
|
cli(["drivers", "stats"]) ->
|
||||||
|
if_enabled(fun() ->
|
||||||
|
[emqx_ctl:print("~-35s:~w~n", [Name, N]) || {Name, N} <- stats()]
|
||||||
|
end);
|
||||||
|
|
||||||
|
cli(_) ->
|
||||||
|
emqx_ctl:usage([{"exhook drivers list", "List all running drivers"},
|
||||||
|
{"exhook drivers enable <Name>", "Enable a driver with configurations"},
|
||||||
|
{"exhook drivers disable <Name>", "Disable a driver"},
|
||||||
|
{"exhook drivers stats", "Print drivers statistic"}]).
|
||||||
|
|
||||||
|
print(ok) ->
|
||||||
|
emqx_ctl:print("ok~n");
|
||||||
|
print({error, Reason}) ->
|
||||||
|
emqx_ctl:print("~p~n", [Reason]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Internal funcs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
if_enabled(Fun) ->
|
||||||
|
case lists:keymember(?APP, 1, application:which_applications()) of
|
||||||
|
true -> Fun();
|
||||||
|
_ -> hint()
|
||||||
|
end.
|
||||||
|
|
||||||
|
hint() ->
|
||||||
|
emqx_ctl:print("Please './bin/emqx_ctl plugins load emqx_extension_hook' first.~n").
|
||||||
|
|
||||||
|
stats() ->
|
||||||
|
lists:foldr(fun({K, N}, Acc) ->
|
||||||
|
case atom_to_list(K) of
|
||||||
|
"exhook." ++ Key -> [{Key, N}|Acc];
|
||||||
|
_ -> Acc
|
||||||
|
end
|
||||||
|
end, [], emqx_metrics:all()).
|
|
@ -0,0 +1,305 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_extension_hook_driver).
|
||||||
|
|
||||||
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
|
-logger_header("[ExHook Driver]").
|
||||||
|
|
||||||
|
%% Load/Unload
|
||||||
|
-export([ load/2
|
||||||
|
, unload/1
|
||||||
|
, connect/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
%% APIs
|
||||||
|
-export([ run_hook/3
|
||||||
|
, run_hook_fold/4]).
|
||||||
|
|
||||||
|
%% Infos
|
||||||
|
-export([ name/1
|
||||||
|
, format/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-record(driver, {
|
||||||
|
%% Driver name (equal to ecpool name)
|
||||||
|
name :: driver_name(),
|
||||||
|
%% Driver type
|
||||||
|
type :: driver_type(),
|
||||||
|
%% Initial Module name
|
||||||
|
init :: atom(),
|
||||||
|
%% Hook Spec
|
||||||
|
hookspec :: hook_spec(),
|
||||||
|
%% Metric fun
|
||||||
|
incfun :: function(),
|
||||||
|
%% low layer state
|
||||||
|
state
|
||||||
|
}).
|
||||||
|
|
||||||
|
-type driver_name() :: python | python3 | java | webhook | lua | atom().
|
||||||
|
-type driver_type() :: python | webhok | java | atom().
|
||||||
|
-type driver() :: #driver{}.
|
||||||
|
|
||||||
|
-type hook_spec() :: #{hookname() => [{callback_m(), callback_f(), spec()}]}.
|
||||||
|
-type hookname() :: client_connect
|
||||||
|
| client_connack
|
||||||
|
| client_connected
|
||||||
|
| client_disconnected
|
||||||
|
| client_authenticate
|
||||||
|
| client_check_acl
|
||||||
|
| client_subscribe
|
||||||
|
| client_unsubscribe
|
||||||
|
| session_created
|
||||||
|
| session_subscribed
|
||||||
|
| session_unsubscribed
|
||||||
|
| session_resumed
|
||||||
|
| session_discarded
|
||||||
|
| session_takeovered
|
||||||
|
| session_terminated
|
||||||
|
| message_publish
|
||||||
|
| message_delivered
|
||||||
|
| message_acked
|
||||||
|
| message_dropped.
|
||||||
|
|
||||||
|
-type callback_m() :: atom().
|
||||||
|
|
||||||
|
-type callback_f() :: atom().
|
||||||
|
|
||||||
|
-type spec() :: #{
|
||||||
|
topic => binary() %% for `message` hook only
|
||||||
|
}.
|
||||||
|
|
||||||
|
-export_type([driver/0]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Load/Unload APIs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec load(atom(), list()) -> {ok, driver()} | {error, term()} .
|
||||||
|
load(Name, Opts0) ->
|
||||||
|
case lists:keytake(init_module, 1, Opts0) of
|
||||||
|
false -> {error, not_found_initial_module};
|
||||||
|
{value, {_,InitM}, Opts} ->
|
||||||
|
Spec = pool_spec(Name, Opts),
|
||||||
|
{ok, _} = emqx_extension_hook_sup:start_driver_pool(Spec),
|
||||||
|
do_init(Name, InitM)
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec unload(driver()) -> ok.
|
||||||
|
unload(#driver{name = Name, init = InitM}) ->
|
||||||
|
do_deinit(Name, InitM),
|
||||||
|
emqx_extension_hook_sup:stop_driver_pool(Name).
|
||||||
|
|
||||||
|
do_deinit(Name, InitM) ->
|
||||||
|
_ = raw_call(type(Name), Name, InitM, 'deinit', []),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
do_init(Name, InitM) ->
|
||||||
|
Type = type(Name),
|
||||||
|
case raw_call(Type, Name, InitM, 'init', []) of
|
||||||
|
{ok, {HookSpec, State}} ->
|
||||||
|
NHookSpec = resovle_hook_spec(HookSpec),
|
||||||
|
%% Reigster metrics
|
||||||
|
Prefix = "exhook." ++ atom_to_list(Name) ++ ".",
|
||||||
|
ensure_metrics(Prefix, NHookSpec),
|
||||||
|
{ok, #driver{type = Type,
|
||||||
|
name = Name,
|
||||||
|
init = InitM,
|
||||||
|
state = State,
|
||||||
|
hookspec = NHookSpec,
|
||||||
|
incfun = incfun(Prefix) }};
|
||||||
|
{error, Reason} ->
|
||||||
|
emqx_extension_hook_sup:stop_driver_pool(Name),
|
||||||
|
{error, Reason}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
pool_spec(Name, Opts) ->
|
||||||
|
NOpts = lists:keystore(pool_size, 1, Opts, {pool_size, 1}),
|
||||||
|
ecpool:pool_spec(Name, Name, ?MODULE, [{name, Name} | NOpts]).
|
||||||
|
|
||||||
|
resovle_hook_spec(HookSpec) ->
|
||||||
|
Atom = fun(B) -> list_to_atom(B) end,
|
||||||
|
HookSpec1 = lists:map(fun({Name, Module, Func}) ->
|
||||||
|
{Name, Module, Func, []};
|
||||||
|
(Other) -> Other
|
||||||
|
end, HookSpec),
|
||||||
|
lists:foldr(
|
||||||
|
fun({Name, Module, Func, Spec}, Acc) ->
|
||||||
|
NameAtom = Atom(Name),
|
||||||
|
Acc#{NameAtom => [{Atom(Module), Atom(Func), maps:from_list(Spec)} | maps:get(NameAtom, Acc, [])]}
|
||||||
|
end, #{}, HookSpec1).
|
||||||
|
|
||||||
|
ensure_metrics(Prefix, HookSpec) ->
|
||||||
|
Keys = [ list_to_atom(Prefix ++ atom_to_list(K)) || K <- maps:keys(HookSpec)],
|
||||||
|
lists:foreach(fun emqx_metrics:ensure/1, Keys).
|
||||||
|
|
||||||
|
incfun(Prefix) ->
|
||||||
|
fun(Name) ->
|
||||||
|
emqx_metrics:inc(list_to_atom(Prefix ++ atom_to_list(Name)))
|
||||||
|
end.
|
||||||
|
|
||||||
|
format(#driver{name = Name, init = InitM, hookspec = Hooks}) ->
|
||||||
|
io_lib:format("name=~p, init_module=~p, hooks=~0p", [Name, InitM, maps:keys(Hooks)]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% ecpool callback
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec connect(list()) -> {ok, pid()} | {error, any()}.
|
||||||
|
connect(Opts0) ->
|
||||||
|
case lists:keytake(name, 1, lists:keydelete(ecpool_worker_id, 1, Opts0)) of
|
||||||
|
{_,{_, Name}, Opts}
|
||||||
|
when Name =:= python;
|
||||||
|
Name =:= python3 ->
|
||||||
|
NOpts = resovle_search_path(python, Opts),
|
||||||
|
python:start_link([{python, atom_to_list(Name)} | NOpts]);
|
||||||
|
{_,{_, Name}, Opts}
|
||||||
|
when Name =:= java ->
|
||||||
|
NOpts = resovle_search_path(java, Opts),
|
||||||
|
java:start_link([{java, atom_to_list(Name)} | NOpts])
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
resovle_search_path(java, Opts) ->
|
||||||
|
case proplists:get_value(java_path, Opts) of
|
||||||
|
undefined -> Opts;
|
||||||
|
Path ->
|
||||||
|
Solved = lists:flatten(
|
||||||
|
lists:join(pathsep(),
|
||||||
|
[expand_jar_packages(filename:absname(P))
|
||||||
|
|| P <- re:split(Path, pathsep(), [{return, list}]), P /= ""])),
|
||||||
|
lists:keystore(java_path, 1, Opts, {java_path, Solved})
|
||||||
|
end;
|
||||||
|
|
||||||
|
resovle_search_path(_, Opts) ->
|
||||||
|
Opts.
|
||||||
|
|
||||||
|
expand_jar_packages(Path) ->
|
||||||
|
IsJarPkgs = fun(Name) ->
|
||||||
|
Ext = filename:extension(Name),
|
||||||
|
Ext == ".jar" orelse Ext == ".zip"
|
||||||
|
end,
|
||||||
|
case file:list_dir(Path) of
|
||||||
|
{ok, []} -> [Path];
|
||||||
|
{error, _} -> [Path];
|
||||||
|
{ok, Names} ->
|
||||||
|
lists:join(pathsep(),
|
||||||
|
[Path] ++ [filename:join([Path, Name]) || Name <- Names, IsJarPkgs(Name)])
|
||||||
|
end.
|
||||||
|
|
||||||
|
pathsep() ->
|
||||||
|
case os:type() of
|
||||||
|
{win32, _} ->
|
||||||
|
";";
|
||||||
|
_ ->
|
||||||
|
":"
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% APIs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
name(#driver{name = Name}) ->
|
||||||
|
Name.
|
||||||
|
|
||||||
|
-spec run_hook(atom(), list(), driver())
|
||||||
|
-> ok
|
||||||
|
| {ok, term()}
|
||||||
|
| {error, term()}.
|
||||||
|
run_hook(Name, Args, Driver = #driver{hookspec = HookSpec, incfun = IncFun}) ->
|
||||||
|
case maps:get(Name, HookSpec, []) of
|
||||||
|
[] -> ok;
|
||||||
|
Cbs ->
|
||||||
|
lists:foldl(fun({M, F, Opts}, _) ->
|
||||||
|
case match_topic_filter(Name, proplists:get_value(topic, Args, null), maps:get(topics, Opts, [])) of
|
||||||
|
true ->
|
||||||
|
IncFun(Name),
|
||||||
|
call(M, F, Args, Driver);
|
||||||
|
_ -> ok
|
||||||
|
end
|
||||||
|
end, ok, Cbs)
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec run_hook_fold(atom(), list(), any(), driver())
|
||||||
|
-> ok
|
||||||
|
| {ok, term()}
|
||||||
|
| {error, term()}.
|
||||||
|
run_hook_fold(Name, Args, Acc0, Driver = #driver{hookspec = HookSpec, incfun = IncFun}) ->
|
||||||
|
case maps:get(Name, HookSpec, []) of
|
||||||
|
[] -> ok;
|
||||||
|
Cbs ->
|
||||||
|
lists:foldl(fun({M, F, Opts}, Acc) ->
|
||||||
|
case match_topic_filter(Name, proplists:get_value(topic, Args, null), maps:get(topics, Opts, [])) of
|
||||||
|
true ->
|
||||||
|
IncFun(Name),
|
||||||
|
call(M, F, Args ++ [Acc], Driver);
|
||||||
|
_ -> ok
|
||||||
|
end
|
||||||
|
end, Acc0, Cbs)
|
||||||
|
end.
|
||||||
|
|
||||||
|
-compile({inline, [match_topic_filter/3]}).
|
||||||
|
match_topic_filter(_Name, null, _TopicFilter) ->
|
||||||
|
true;
|
||||||
|
match_topic_filter(Name, TopicName, TopicFilter)
|
||||||
|
when Name =:= message_publish;
|
||||||
|
Name =:= message_delivered;
|
||||||
|
Name =:= message_dropped;
|
||||||
|
Name =:= message_acked ->
|
||||||
|
lists:any(fun(F) -> emqx_topic:match(TopicName, F) end, TopicFilter);
|
||||||
|
match_topic_filter(_, _, _) ->
|
||||||
|
true.
|
||||||
|
|
||||||
|
-spec call(atom(), atom(), list(), driver()) -> ok | {ok, term()} | {error, term()}.
|
||||||
|
call(Mod, Fun, Args, #driver{name = Name, type = Type, state = State}) ->
|
||||||
|
with_pool(Name, fun(C) ->
|
||||||
|
do_call(Type, C, Mod, Fun, Args ++ [State])
|
||||||
|
end).
|
||||||
|
|
||||||
|
raw_call(Type, Name, Mod, Fun, Args) when is_list(Args) ->
|
||||||
|
with_pool(Name, fun(C) ->
|
||||||
|
do_call(Type, C, Mod, Fun, Args)
|
||||||
|
end).
|
||||||
|
|
||||||
|
do_call(Type, C, M, F, A) ->
|
||||||
|
case catch apply(Type, call, [C, M, F, A]) of
|
||||||
|
ok -> ok;
|
||||||
|
undefined -> ok;
|
||||||
|
{_Ok = 0, Return} -> {ok, Return};
|
||||||
|
{_Err = 1, Reason} -> {error, Reason};
|
||||||
|
{'EXIT', Reason, Stk} ->
|
||||||
|
?LOG(error, "CALL ~p ~p:~p(~p), exception: ~p, stacktrace ~0p",
|
||||||
|
[Type, M, F, A, Reason, Stk]),
|
||||||
|
{error, Reason};
|
||||||
|
_X ->
|
||||||
|
?LOG(error, "CALL ~p ~p:~p(~p), unknown return: ~0p",
|
||||||
|
[Type, M, F, A, _X]),
|
||||||
|
{error, unknown_return_format}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Internal funcs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
with_pool(Name, Fun) ->
|
||||||
|
ecpool:with_client(Name, Fun).
|
||||||
|
|
||||||
|
type(python3) -> python;
|
||||||
|
type(python) -> python;
|
||||||
|
type(Name) -> Name.
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_extension_hook_handler).
|
||||||
|
|
||||||
|
-include("emqx_extension_hook.hrl").
|
||||||
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
|
-logger_header("[ExHook]").
|
||||||
|
|
||||||
|
-export([ on_client_connect/2
|
||||||
|
, on_client_connack/3
|
||||||
|
, on_client_connected/2
|
||||||
|
, on_client_disconnected/3
|
||||||
|
, on_client_authenticate/2
|
||||||
|
, on_client_check_acl/4
|
||||||
|
, on_client_subscribe/3
|
||||||
|
, on_client_unsubscribe/3
|
||||||
|
]).
|
||||||
|
|
||||||
|
%% Session Lifecircle Hooks
|
||||||
|
-export([ on_session_created/2
|
||||||
|
, on_session_subscribed/3
|
||||||
|
, on_session_unsubscribed/3
|
||||||
|
, on_session_resumed/2
|
||||||
|
, on_session_discarded/2
|
||||||
|
, on_session_takeovered/2
|
||||||
|
, on_session_terminated/3
|
||||||
|
]).
|
||||||
|
|
||||||
|
%% Utils
|
||||||
|
-export([ message/1
|
||||||
|
, validator/1
|
||||||
|
, assign_to_message/2
|
||||||
|
, clientinfo/1
|
||||||
|
, stringfy/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-import(emqx_extension_hook,
|
||||||
|
[ cast/2
|
||||||
|
, call_fold/4
|
||||||
|
]).
|
||||||
|
|
||||||
|
-exhooks([ {'client.connect', {?MODULE, on_client_connect, []}}
|
||||||
|
, {'client.connack', {?MODULE, on_client_connack, []}}
|
||||||
|
, {'client.connected', {?MODULE, on_client_connected, []}}
|
||||||
|
, {'client.disconnected', {?MODULE, on_client_disconnected, []}}
|
||||||
|
, {'client.authenticate', {?MODULE, on_client_authenticate, []}}
|
||||||
|
, {'client.check_acl', {?MODULE, on_client_check_acl, []}}
|
||||||
|
, {'client.subscribe', {?MODULE, on_client_subscribe, []}}
|
||||||
|
, {'client.unsubscribe', {?MODULE, on_client_unsubscribe, []}}
|
||||||
|
, {'session.created', {?MODULE, on_session_created, []}}
|
||||||
|
, {'session.subscribed', {?MODULE, on_session_subscribed, []}}
|
||||||
|
, {'session.unsubscribed',{?MODULE, on_session_unsubscribed, []}}
|
||||||
|
, {'session.resumed', {?MODULE, on_session_resumed, []}}
|
||||||
|
, {'session.discarded', {?MODULE, on_session_discarded, []}}
|
||||||
|
, {'session.takeovered', {?MODULE, on_session_takeovered, []}}
|
||||||
|
, {'session.terminated', {?MODULE, on_session_terminated, []}}
|
||||||
|
]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Clients
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
on_client_connect(ConnInfo, _Props) ->
|
||||||
|
cast('client_connect', [conninfo(ConnInfo), props(_Props)]).
|
||||||
|
|
||||||
|
on_client_connack(ConnInfo, Rc, _Props) ->
|
||||||
|
cast('client_connack', [conninfo(ConnInfo), Rc, props(_Props)]).
|
||||||
|
|
||||||
|
on_client_connected(ClientInfo, _ConnInfo) ->
|
||||||
|
cast('client_connected', [clientinfo(ClientInfo)]).
|
||||||
|
|
||||||
|
on_client_disconnected(ClientInfo, {shutdown, Reason}, ConnInfo) when is_atom(Reason) ->
|
||||||
|
on_client_disconnected(ClientInfo, Reason, ConnInfo);
|
||||||
|
on_client_disconnected(ClientInfo, Reason, _ConnInfo) ->
|
||||||
|
cast('client_disconnected', [clientinfo(ClientInfo), stringfy(Reason)]).
|
||||||
|
|
||||||
|
on_client_authenticate(ClientInfo, AuthResult) ->
|
||||||
|
AccArg = maps:get(auth_result, AuthResult, undefined) == success,
|
||||||
|
Name = 'client_authenticate',
|
||||||
|
case call_fold(Name, [clientinfo(ClientInfo)], AccArg, validator(Name)) of
|
||||||
|
{stop, Bool} when is_boolean(Bool) ->
|
||||||
|
Result = case Bool of true -> success; _ -> not_authorized end,
|
||||||
|
{stop, AuthResult#{auth_result => Result, anonymous => false}};
|
||||||
|
_ ->
|
||||||
|
{ok, AuthResult}
|
||||||
|
end.
|
||||||
|
|
||||||
|
on_client_check_acl(ClientInfo, PubSub, Topic, Result) ->
|
||||||
|
AccArg = Result == allow,
|
||||||
|
Name = 'client_check_acl',
|
||||||
|
case call_fold(Name, [clientinfo(ClientInfo), PubSub, Topic], AccArg, validator(Name)) of
|
||||||
|
{stop, Bool} when is_boolean(Bool) ->
|
||||||
|
NResult = case Bool of true -> allow; _ -> deny end,
|
||||||
|
{stop, NResult};
|
||||||
|
_ -> {ok, Result}
|
||||||
|
end.
|
||||||
|
|
||||||
|
on_client_subscribe(ClientInfo, Props, TopicFilters) ->
|
||||||
|
cast('client_subscribe', [clientinfo(ClientInfo), props(Props), topicfilters(TopicFilters)]).
|
||||||
|
|
||||||
|
on_client_unsubscribe(Clientinfo, Props, TopicFilters) ->
|
||||||
|
cast('client_unsubscribe', [clientinfo(Clientinfo), props(Props), topicfilters(TopicFilters)]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Session
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
on_session_created(ClientInfo, _SessInfo) ->
|
||||||
|
cast('session_created', [clientinfo(ClientInfo)]).
|
||||||
|
|
||||||
|
on_session_subscribed(Clientinfo, Topic, SubOpts) ->
|
||||||
|
cast('session_subscribed', [clientinfo(Clientinfo), Topic, props(SubOpts)]).
|
||||||
|
|
||||||
|
on_session_unsubscribed(ClientInfo, Topic, _SubOpts) ->
|
||||||
|
cast('session_unsubscribed', [clientinfo(ClientInfo), Topic]).
|
||||||
|
|
||||||
|
on_session_resumed(ClientInfo, _SessInfo) ->
|
||||||
|
cast('session_resumed', [clientinfo(ClientInfo)]).
|
||||||
|
|
||||||
|
on_session_discarded(ClientInfo, _SessInfo) ->
|
||||||
|
cast('session_discarded', [clientinfo(ClientInfo)]).
|
||||||
|
|
||||||
|
on_session_takeovered(ClientInfo, _SessInfo) ->
|
||||||
|
cast('session_takeovered', [clientinfo(ClientInfo)]).
|
||||||
|
|
||||||
|
on_session_terminated(ClientInfo, Reason, _SessInfo) ->
|
||||||
|
cast('session_terminated', [clientinfo(ClientInfo), stringfy(Reason)]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Types
|
||||||
|
|
||||||
|
props(undefined) -> [];
|
||||||
|
props(M) when is_map(M) -> maps:to_list(M).
|
||||||
|
|
||||||
|
conninfo(_ConnInfo =
|
||||||
|
#{clientid := ClientId, username := Username, peername := {Peerhost, _},
|
||||||
|
sockname := {_, SockPort}, proto_name := ProtoName, proto_ver := ProtoVer,
|
||||||
|
keepalive := Keepalive}) ->
|
||||||
|
[{node, node()},
|
||||||
|
{clientid, ClientId},
|
||||||
|
{username, maybe(Username)},
|
||||||
|
{peerhost, ntoa(Peerhost)},
|
||||||
|
{sockport, SockPort},
|
||||||
|
{proto_name, ProtoName},
|
||||||
|
{proto_ver, ProtoVer},
|
||||||
|
{keepalive, Keepalive}].
|
||||||
|
|
||||||
|
clientinfo(ClientInfo =
|
||||||
|
#{clientid := ClientId, username := Username, peerhost := PeerHost,
|
||||||
|
sockport := SockPort, protocol := Protocol, mountpoint := Mountpoiont}) ->
|
||||||
|
[{node, node()},
|
||||||
|
{clientid, ClientId},
|
||||||
|
{username, maybe(Username)},
|
||||||
|
{password, maybe(maps:get(password, ClientInfo, undefined))},
|
||||||
|
{peerhost, ntoa(PeerHost)},
|
||||||
|
{sockport, SockPort},
|
||||||
|
{protocol, Protocol},
|
||||||
|
{mountpoint, maybe(Mountpoiont)},
|
||||||
|
{is_superuser, maps:get(is_superuser, ClientInfo, false)},
|
||||||
|
{anonymous, maps:get(anonymous, ClientInfo, true)}].
|
||||||
|
|
||||||
|
message(#message{id = Id, qos = Qos, from = From, topic = Topic, payload = Payload, timestamp = Ts}) ->
|
||||||
|
[{node, node()},
|
||||||
|
{id, hexstr(Id)},
|
||||||
|
{qos, Qos},
|
||||||
|
{from, From},
|
||||||
|
{topic, Topic},
|
||||||
|
{payload, Payload},
|
||||||
|
{timestamp, Ts}].
|
||||||
|
|
||||||
|
topicfilters(Tfs = [{_, _}|_]) ->
|
||||||
|
[{Topic, Qos} || {Topic, #{qos := Qos}} <- Tfs];
|
||||||
|
topicfilters(Tfs) ->
|
||||||
|
Tfs.
|
||||||
|
|
||||||
|
ntoa({0,0,0,0,0,16#ffff,AB,CD}) ->
|
||||||
|
list_to_binary(inet_parse:ntoa({AB bsr 8, AB rem 256, CD bsr 8, CD rem 256}));
|
||||||
|
ntoa(IP) ->
|
||||||
|
list_to_binary(inet_parse:ntoa(IP)).
|
||||||
|
|
||||||
|
maybe(undefined) -> <<"">>;
|
||||||
|
maybe(B) -> B.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
stringfy(Term) when is_binary(Term) ->
|
||||||
|
Term;
|
||||||
|
stringfy(Term) when is_atom(Term) ->
|
||||||
|
atom_to_binary(Term, utf8);
|
||||||
|
stringfy(Term) when is_tuple(Term) ->
|
||||||
|
iolist_to_binary(io_lib:format("~p", [Term])).
|
||||||
|
|
||||||
|
hexstr(B) ->
|
||||||
|
iolist_to_binary([io_lib:format("~2.16.0B", [X]) || X <- binary_to_list(B)]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Validator funcs
|
||||||
|
|
||||||
|
validator(Name) ->
|
||||||
|
fun(V) -> validate_acc_arg(Name, V) end.
|
||||||
|
|
||||||
|
validate_acc_arg('client_authenticate', V) when is_boolean(V) -> true;
|
||||||
|
validate_acc_arg('client_check_acl', V) when is_boolean(V) -> true;
|
||||||
|
validate_acc_arg('message_publish', V) when is_list(V) -> validate_msg(V, true);
|
||||||
|
validate_acc_arg(_, _) -> false.
|
||||||
|
|
||||||
|
validate_msg([], Bool) ->
|
||||||
|
Bool;
|
||||||
|
validate_msg(_, false) ->
|
||||||
|
false;
|
||||||
|
validate_msg([{topic, T} | More], _) ->
|
||||||
|
validate_msg(More, is_binary(T));
|
||||||
|
validate_msg([{payload, P} | More], _) ->
|
||||||
|
validate_msg(More, is_binary(P));
|
||||||
|
validate_msg([{qos, Q} | More], _) ->
|
||||||
|
validate_msg(More, Q =< 2 andalso Q >= 0);
|
||||||
|
validate_msg([{timestamp, T} | More], _) ->
|
||||||
|
validate_msg(More, is_integer(T));
|
||||||
|
validate_msg([_ | More], _) ->
|
||||||
|
validate_msg(More, true).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Misc
|
||||||
|
|
||||||
|
assign_to_message([], Message) ->
|
||||||
|
Message;
|
||||||
|
assign_to_message([{topic, Topic}|More], Message) ->
|
||||||
|
assign_to_message(More, Message#message{topic = Topic});
|
||||||
|
assign_to_message([{qos, Qos}|More], Message) ->
|
||||||
|
assign_to_message(More, Message#message{qos = Qos});
|
||||||
|
assign_to_message([{payload, Payload}|More], Message) ->
|
||||||
|
assign_to_message(More, Message#message{payload = Payload});
|
||||||
|
assign_to_message([_|More], Message) ->
|
||||||
|
assign_to_message(More, Message).
|
|
@ -0,0 +1,50 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_extension_hook_sup).
|
||||||
|
|
||||||
|
-behaviour(supervisor).
|
||||||
|
|
||||||
|
-export([ start_link/0
|
||||||
|
, init/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-export([ start_driver_pool/1
|
||||||
|
, stop_driver_pool/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Supervisor APIs & Callbacks
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
start_link() ->
|
||||||
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
|
init([]) ->
|
||||||
|
{ok, {{one_for_one, 10, 100}, []}}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% APIs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec start_driver_pool(map()) -> {ok, pid()} | {error, term()}.
|
||||||
|
start_driver_pool(Spec) ->
|
||||||
|
supervisor:start_child(?MODULE, Spec).
|
||||||
|
|
||||||
|
-spec stop_driver_pool(atom()) -> ok.
|
||||||
|
stop_driver_pool(Name) ->
|
||||||
|
ok = supervisor:terminate_child(?MODULE, Name),
|
||||||
|
ok = supervisor:delete_child(?MODULE, Name).
|
|
@ -0,0 +1,139 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_extension_hook_SUITE).
|
||||||
|
|
||||||
|
-compile(export_all).
|
||||||
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Setups
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
|
init_per_suite(Cfg) ->
|
||||||
|
emqx_ct_helpers:start_apps([emqx_extension_hook], fun set_special_cfgs/1),
|
||||||
|
emqx_logger:set_log_level(warning),
|
||||||
|
Cfg.
|
||||||
|
|
||||||
|
end_per_suite(_) ->
|
||||||
|
emqx_ct_helpers:stop_apps([emqx_extension_hook]).
|
||||||
|
|
||||||
|
set_special_cfgs(emqx) ->
|
||||||
|
application:set_env(emqx, allow_anonymous, false),
|
||||||
|
application:set_env(emqx, enable_acl_cache, false),
|
||||||
|
application:set_env(emqx, plugins_loaded_file,
|
||||||
|
emqx_ct_helpers:deps_path(emqx, "test/emqx_SUITE_data/loaded_plugins"));
|
||||||
|
set_special_cfgs(emqx_extension_hook) ->
|
||||||
|
application:set_env(emqx_extension_hook, drivers, []),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
reload_plugin_with(_DriverName = python3) ->
|
||||||
|
application:stop(emqx_extension_hook),
|
||||||
|
Path = emqx_ct_helpers:deps_path(emqx_extension_hook, "test/scripts"),
|
||||||
|
Drivers = [{python3, [{init_module, main},
|
||||||
|
{python_path, Path},
|
||||||
|
{call_timeout, 5000}]}],
|
||||||
|
application:set_env(emqx_extension_hook, drivers, Drivers),
|
||||||
|
application:ensure_all_started(emqx_extension_hook);
|
||||||
|
|
||||||
|
reload_plugin_with(_DriverName = java) ->
|
||||||
|
application:stop(emqx_extension_hook),
|
||||||
|
|
||||||
|
ErlPortJar = emqx_ct_helpers:deps_path(erlport, "priv/java/_pkgs/erlport.jar"),
|
||||||
|
Path = emqx_ct_helpers:deps_path(emqx_extension_hook, "test/scripts"),
|
||||||
|
Drivers = [{java, [{init_module, 'Main'},
|
||||||
|
{java_path, Path},
|
||||||
|
{call_timeout, 5000}]}],
|
||||||
|
|
||||||
|
%% Compile it
|
||||||
|
ct:pal(os:cmd(lists:concat(["cd ", Path, " && ",
|
||||||
|
"rm -rf Main.class State.class && ",
|
||||||
|
"javac -cp ", ErlPortJar, " Main.java"]))),
|
||||||
|
|
||||||
|
application:set_env(emqx_extension_hook, drivers, Drivers),
|
||||||
|
application:ensure_all_started(emqx_extension_hook).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Test cases
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
t_python3(_) ->
|
||||||
|
reload_plugin_with(python3),
|
||||||
|
schedule_all_hooks().
|
||||||
|
|
||||||
|
t_java(_) ->
|
||||||
|
reload_plugin_with(java),
|
||||||
|
schedule_all_hooks().
|
||||||
|
|
||||||
|
schedule_all_hooks() ->
|
||||||
|
ok = emqx_extension_hook_handler:on_client_connect(conninfo(), #{}),
|
||||||
|
ok = emqx_extension_hook_handler:on_client_connack(conninfo(), success,#{}),
|
||||||
|
ok = emqx_extension_hook_handler:on_client_connected(clientinfo(), conninfo()),
|
||||||
|
ok = emqx_extension_hook_handler:on_client_disconnected(clientinfo(), takeovered, conninfo()),
|
||||||
|
{stop, #{auth_result := success,
|
||||||
|
anonymous := false}} = emqx_extension_hook_handler:on_client_authenticate(clientinfo(), #{auth_result => not_authorised, anonymous => true}),
|
||||||
|
{stop, allow} = emqx_extension_hook_handler:on_client_check_acl(clientinfo(), publish, <<"t/a">>, deny),
|
||||||
|
ok = emqx_extension_hook_handler:on_client_subscribe(clientinfo(), #{}, sub_topicfilters()),
|
||||||
|
ok = emqx_extension_hook_handler:on_client_unsubscribe(clientinfo(), #{}, unsub_topicfilters()),
|
||||||
|
|
||||||
|
ok = emqx_extension_hook_handler:on_session_created(clientinfo(), sessinfo()),
|
||||||
|
ok = emqx_extension_hook_handler:on_session_subscribed(clientinfo(), <<"t/a">>, subopts()),
|
||||||
|
ok = emqx_extension_hook_handler:on_session_unsubscribed(clientinfo(), <<"t/a">>, subopts()),
|
||||||
|
ok = emqx_extension_hook_handler:on_session_resumed(clientinfo(), sessinfo()),
|
||||||
|
ok = emqx_extension_hook_handler:on_session_discarded(clientinfo(), sessinfo()),
|
||||||
|
ok = emqx_extension_hook_handler:on_session_takeovered(clientinfo(), sessinfo()),
|
||||||
|
ok = emqx_extension_hook_handler:on_session_terminated(clientinfo(), sockerr, sessinfo()).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Generator
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
conninfo() ->
|
||||||
|
#{clientid => <<"123">>,
|
||||||
|
username => <<"abc">>,
|
||||||
|
peername => {{127,0,0,1}, 2341},
|
||||||
|
sockname => {{0,0,0,0}, 1883},
|
||||||
|
proto_name => <<"MQTT">>,
|
||||||
|
proto_ver => 4,
|
||||||
|
keepalive => 60
|
||||||
|
}.
|
||||||
|
|
||||||
|
clientinfo() ->
|
||||||
|
#{clientid => <<"123">>,
|
||||||
|
username => <<"abc">>,
|
||||||
|
peerhost => {127,0,0,1},
|
||||||
|
sockport => 1883,
|
||||||
|
protocol => 'mqtt',
|
||||||
|
mountpoint => undefined
|
||||||
|
}.
|
||||||
|
|
||||||
|
sub_topicfilters() ->
|
||||||
|
[{<<"t/a">>, #{qos => 1}}].
|
||||||
|
|
||||||
|
unsub_topicfilters() ->
|
||||||
|
[<<"t/a">>].
|
||||||
|
|
||||||
|
sessinfo() ->
|
||||||
|
{session,xxx,yyy}.
|
||||||
|
|
||||||
|
subopts() ->
|
||||||
|
#{qos => 1, rh => 0, rap => 0, nl => 0}.
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.erlport.erlang.term.*;
|
||||||
|
|
||||||
|
class State implements Serializable {
|
||||||
|
|
||||||
|
Integer times;
|
||||||
|
|
||||||
|
public State() {
|
||||||
|
times = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer incr() {
|
||||||
|
times += 1;
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("State(times: %d)", times);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static Object init() {
|
||||||
|
System.err.printf("Initiate driver...\n");
|
||||||
|
|
||||||
|
// [{"topics", ["t/#", "t/a"]}]
|
||||||
|
List<Object> topics = new ArrayList<Object>();
|
||||||
|
topics.add(new Binary("t/#"));
|
||||||
|
topics.add(new Binary("test/#"));
|
||||||
|
|
||||||
|
List<Object> actionOpts = new ArrayList<Object>();
|
||||||
|
actionOpts.add(Tuple.two(new Atom("topics"), topics));
|
||||||
|
|
||||||
|
Object[] actions0 = new Object[] {
|
||||||
|
Tuple.three("client_connect", "Main", "on_client_connect"),
|
||||||
|
Tuple.three("client_connack", "Main", "on_client_connack"),
|
||||||
|
Tuple.three("client_connected", "Main", "on_client_connected"),
|
||||||
|
Tuple.three("client_disconnected", "Main", "on_client_disconnected"),
|
||||||
|
Tuple.three("client_authenticate", "Main", "on_client_authenticate"),
|
||||||
|
Tuple.three("client_check_acl", "Main", "on_client_check_acl"),
|
||||||
|
Tuple.three("client_subscribe", "Main", "on_client_subscribe"),
|
||||||
|
Tuple.three("client_unsubscribe", "Main", "on_client_unsubscribe"),
|
||||||
|
|
||||||
|
Tuple.three("session_created", "Main", "on_session_created"),
|
||||||
|
Tuple.three("session_subscribed", "Main", "on_session_subscribed"),
|
||||||
|
Tuple.three("session_unsubscribed", "Main", "on_session_unsubscribed"),
|
||||||
|
Tuple.three("session_resumed", "Main", "on_session_resumed"),
|
||||||
|
Tuple.three("session_discarded", "Main", "on_session_discarded"),
|
||||||
|
Tuple.three("session_takeovered", "Main", "on_session_takeovered"),
|
||||||
|
Tuple.three("session_terminated", "Main", "on_session_terminated"),
|
||||||
|
|
||||||
|
Tuple.four("message_publish", "Main", "on_message_publish", actionOpts),
|
||||||
|
Tuple.four("message_delivered", "Main", "on_message_delivered", actionOpts),
|
||||||
|
Tuple.four("message_acked", "Main", "on_message_acked", actionOpts),
|
||||||
|
Tuple.four("message_dropped", "Main", "on_message_dropped", actionOpts)
|
||||||
|
};
|
||||||
|
|
||||||
|
List<Object> actions = new ArrayList<Object>(Arrays.asList(actions0));
|
||||||
|
|
||||||
|
State state = new State();
|
||||||
|
//Tuple state = new Tuple(0);
|
||||||
|
|
||||||
|
// {0 | 1, [{HookName, CallModule, CallFunction, Opts}]}
|
||||||
|
return Tuple.two(0, Tuple.two(actions, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deinit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
|
||||||
|
public static void on_client_connect(Object connInfo, Object props, Object state) {
|
||||||
|
System.err.printf("[Java] on_client_connect: connInfo: %s, props: %s, state: %s\n", connInfo, props, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_client_connack(Object connInfo, Object rc, Object props, Object state) {
|
||||||
|
System.err.printf("[Java] on_client_connack: connInfo: %s, rc: %s, props: %s, state: %s\n", connInfo, rc, props, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_client_connected(Object clientInfo, Object state) {
|
||||||
|
System.err.printf("[Java] on_client_connected: clientinfo: %s, state: %s\n", clientInfo, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_client_disconnected(Object clientInfo, Object reason, Object state) {
|
||||||
|
System.err.printf("[Java] on_client_disconnected: clientinfo: %s, reason: %s, state: %s\n", clientInfo, reason, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object on_client_authenticate(Object clientInfo, Object authresult, Object state) {
|
||||||
|
System.err.printf("[Java] on_client_authenticate: clientinfo: %s, authresult: %s, state: %s\n", clientInfo, authresult, state);
|
||||||
|
|
||||||
|
return Tuple.two(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object on_client_check_acl(Object clientInfo, Object pubsub, Object topic, Object result, Object state) {
|
||||||
|
System.err.printf("[Java] on_client_check_acl: clientinfo: %s, pubsub: %s, topic: %s, result: %s, state: %s\n", clientInfo, pubsub, topic, result, state);
|
||||||
|
|
||||||
|
return Tuple.two(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_client_subscribe(Object clientInfo, Object props, Object topic, Object state) {
|
||||||
|
System.err.printf("[Java] on_client_subscribe: clientinfo: %s, props: %s, topic: %s, state: %s\n", clientInfo, props, topic, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_client_unsubscribe(Object clientInfo, Object props, Object topic, Object state) {
|
||||||
|
System.err.printf("[Java] on_client_unsubscribe: clientinfo: %s, props: %s, topic: %s, state: %s\n", clientInfo, props, topic, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sessions
|
||||||
|
|
||||||
|
public static void on_session_created(Object clientInfo, Object state) {
|
||||||
|
System.err.printf("[Java] on_session_created: clientinfo: %s, state: %s\n", clientInfo, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_session_subscribed(Object clientInfo, Object topic, Object opts, Object state) {
|
||||||
|
System.err.printf("[Java] on_session_subscribed: clientinfo: %s, topic: %s, subopts: %s, state: %s\n", clientInfo, topic, opts, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_session_unsubscribed(Object clientInfo, Object topic, Object state) {
|
||||||
|
System.err.printf("[Java] on_session_unsubscribed: clientinfo: %s, topic: %s, state: %s\n", clientInfo, topic, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_session_resumed(Object clientInfo, Object state) {
|
||||||
|
System.err.printf("[Java] on_session_resumed: clientinfo: %s, state: %s\n", clientInfo, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_session_discarded(Object clientInfo, Object state) {
|
||||||
|
System.err.printf("[Java] on_session_discarded: clientinfo: %s, state: %s\n", clientInfo, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_session_takeovered(Object clientInfo, Object state) {
|
||||||
|
System.err.printf("[Java] on_session_takeovered: clientinfo: %s, state: %s\n", clientInfo, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_session_terminated(Object clientInfo, Object reason, Object state) {
|
||||||
|
System.err.printf("[Java] on_session_terminated: clientinfo: %s, reason: %s, state: %s\n", clientInfo, reason, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Messages
|
||||||
|
|
||||||
|
public static Object on_message_publish(Object message, Object state) {
|
||||||
|
System.err.printf("[Java] on_message_publish: message: %s, state: %s\n", message, state);
|
||||||
|
return Tuple.two(0, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_message_dropped(Object message, Object reason, Object state) {
|
||||||
|
System.err.printf("[Java] on_message_dropped: message: %s, reason: %s, state: %s\n", message, reason, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_message_delivered(Object clientInfo, Object message, Object state) {
|
||||||
|
System.err.printf("[Java] on_message_delivered: clientinfo: %s, message: %s, state: %s\n", clientInfo, message, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void on_message_acked(Object clientInfo, Object message, Object state) {
|
||||||
|
System.err.printf("[Java] on_message_acked: clientinfo: %s, message: %s, state: %s\n", clientInfo, message, state);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
|
OK = 0
|
||||||
|
ERROR = 1
|
||||||
|
|
||||||
|
## Return :: (HookSpec, State)
|
||||||
|
##
|
||||||
|
## HookSpec :: [(HookName, CallbackModule, CallbackFunction, Opts)]
|
||||||
|
## State :: Any
|
||||||
|
##
|
||||||
|
## HookName :: "client_connect" | "client_connack" | "client_connected" | ...
|
||||||
|
## CallbackModule :: ...
|
||||||
|
## CallbackFunctiin :: ...
|
||||||
|
## Opts :: [(Key, Value)]
|
||||||
|
def init():
|
||||||
|
## Maybe a connection object?
|
||||||
|
state = ()
|
||||||
|
hookspec = [("client_connect", "main", "on_client_connect", []),
|
||||||
|
("client_connack", "main", "on_client_connack", []),
|
||||||
|
("client_connected", "main", "on_client_connected", []),
|
||||||
|
("client_disconnected", "main", "on_client_disconnected", []),
|
||||||
|
("client_authenticate", "main", "on_client_authenticate", []),
|
||||||
|
("client_check_acl", "main", "on_client_check_acl", []),
|
||||||
|
("client_subscribe", "main", "on_client_subscribe", []),
|
||||||
|
("client_unsubscribe", "main", "on_client_unsubscribe", []),
|
||||||
|
("session_created", "main", "on_session_created", []),
|
||||||
|
("session_subscribed", "main", "on_session_subscribed", []),
|
||||||
|
("session_unsubscribed","main", "on_session_unsubscribed", []),
|
||||||
|
("session_resumed", "main", "on_session_resumed", []),
|
||||||
|
("session_discarded", "main", "on_session_discarded", []),
|
||||||
|
("session_takeovered", "main", "on_session_takeovered", []),
|
||||||
|
("session_terminated", "main", "on_session_terminated", []),
|
||||||
|
("message_publish", "main", "on_message_publish", [("topics", ["t/#"])]),
|
||||||
|
("message_delivered", "main", "on_message_delivered", [("topics", ["t/#"])]),
|
||||||
|
("message_acked", "main", "on_message_acked", [("topics", ["t/#"])]),
|
||||||
|
("message_dropped", "main", "on_message_dropped", [("topics", ["t/#"])])
|
||||||
|
]
|
||||||
|
return (OK, (hookspec, state))
|
||||||
|
|
||||||
|
def deinit():
|
||||||
|
return
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Callback functions
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Clients
|
||||||
|
|
||||||
|
def on_client_connect(conninfo, props, state):
|
||||||
|
print("on_client_connect: conninfo: {0}, props: {1}, state: {2}".format(conninfo, props, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_client_connack(conninfo, rc, props, state):
|
||||||
|
print("on_client_connack: conninfo: {0}, rc{1}, props: {2}, state: {3}".format(conninfo, rc, props, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_client_connected(clientinfo, state):
|
||||||
|
print("on_client_connected: clientinfo: {0}, state: {1}".format(clientinfo, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_client_disconnected(clientinfo, reason, state):
|
||||||
|
print("on_client_disconnected: clientinfo: {0}, reason: {1}, state: {2}".format(clientinfo, reason, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_client_authenticate(clientinfo, authresult, state):
|
||||||
|
print("on_client_authenticate: clientinfo: {0}, authresult: {1}, state: {2}".format(clientinfo, authresult, state))
|
||||||
|
## True / False
|
||||||
|
return (OK, True)
|
||||||
|
|
||||||
|
def on_client_check_acl(clientinfo, pubsub, topic, result, state):
|
||||||
|
print("on_client_check_acl: clientinfo: {0}, pubsub: {1}, topic: {2}, result: {3}, state: {4}".format(clientinfo, pubsub, topic, result, state))
|
||||||
|
## True / False
|
||||||
|
return (OK, True)
|
||||||
|
|
||||||
|
def on_client_subscribe(clientinfo, props, topics, state):
|
||||||
|
print("on_client_subscribe: clientinfo: {0}, props: {1}, topics: {2}, state: {3}".format(clientinfo, props, topics, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_client_unsubscribe(clientinfo, props, topics, state):
|
||||||
|
print("on_client_unsubscribe: clientinfo: {0}, props: {1}, topics: {2}, state: {3}".format(clientinfo, props, topics, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Sessions
|
||||||
|
|
||||||
|
def on_session_created(clientinfo, state):
|
||||||
|
print("on_session_created: clientinfo: {0}, state: {1}".format(clientinfo, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_session_subscribed(clientinfo, topic, opts, state):
|
||||||
|
print("on_session_subscribed: clientinfo: {0}, topic: {1}, opts: {2}, state: {3}".format(clientinfo, topic, opts, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_session_unsubscribed(clientinfo, topic, state):
|
||||||
|
print("on_session_unsubscribed: clientinfo: {0}, topic: {1}, state: {2}".format(clientinfo, topic, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_session_resumed(clientinfo, state):
|
||||||
|
print("on_session_resumed: clientinfo: {0}, state: {1}".format(clientinfo, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_session_discarded(clientinfo, state):
|
||||||
|
print("on_session_discared: clientinfo: {0}, state: {1}".format(clientinfo, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_session_takeovered(clientinfo, state):
|
||||||
|
print("on_session_takeovered: clientinfo: {0}, state: {1}".format(clientinfo, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_session_terminated(clientinfo, reason, state):
|
||||||
|
print("on_session_terminated: clientinfo: {0}, reason: {1}, state: {2}".format(clientinfo, reason, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Messages
|
||||||
|
|
||||||
|
def on_message_publish(message, state):
|
||||||
|
print("on_message_publish: message: {0}, state: {1}".format(message, state))
|
||||||
|
return message
|
||||||
|
|
||||||
|
def on_message_dropped(message, reason, state):
|
||||||
|
print("on_message_dropped: message: {0}, reason: {1}, state: {2}".format(message, reason, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_message_delivered(clientinfo, message, state):
|
||||||
|
print("on_message_delivered: clientinfo: {0}, message: {1}, state: {2}".format(clientinfo, message, state))
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_message_acked(clientinfo, message, state):
|
||||||
|
print("on_message_acked: clientinfo: {0}, message: {1}, state: {2}".format(clientinfo, message, state))
|
||||||
|
return
|
|
@ -0,0 +1,45 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
!deps/.placeholder
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
!ebin/.placeholder
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
test/ebin/*.beam
|
||||||
|
.exrc
|
||||||
|
plugins/*/ebin
|
||||||
|
log/
|
||||||
|
*.swp
|
||||||
|
*.so
|
||||||
|
.erlang.mk/
|
||||||
|
cover/
|
||||||
|
emqx.d
|
||||||
|
eunit.coverdata
|
||||||
|
test/ct.cover.spec
|
||||||
|
logs
|
||||||
|
ct.coverdata
|
||||||
|
.idea/
|
||||||
|
emqx.iml
|
||||||
|
_rel/
|
||||||
|
data/
|
||||||
|
_build
|
||||||
|
.rebar3
|
||||||
|
rebar3.crashdump
|
||||||
|
.DS_Store
|
||||||
|
emqx.iml
|
||||||
|
bbmustache/
|
||||||
|
etc/gen.emqx.conf
|
||||||
|
compile_commands.json
|
||||||
|
cuttlefish
|
||||||
|
rebar.lock
|
||||||
|
xrefr
|
||||||
|
erlang.mk
|
||||||
|
*.coverdata
|
||||||
|
etc/emqx_exproto.conf.rendered
|
||||||
|
Mnesia.*/
|
||||||
|
__pycache__
|
||||||
|
example/*.class
|
|
@ -0,0 +1,191 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Copyright 2020, JianBo He <heeejianbo@gmail.com>.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
## SDK 规范
|
||||||
|
|
||||||
|
### 动机
|
||||||
|
|
||||||
|
SDK 的目的在于方便用户使用 IDE 集成开发、和模拟调试。
|
||||||
|
|
||||||
|
### 位置
|
||||||
|
|
||||||
|
```
|
||||||
|
+------------------+
|
||||||
|
| User's Codes |
|
||||||
|
+------------------+
|
||||||
|
| SDK | <==== The SDK Located
|
||||||
|
+------------------+
|
||||||
|
| Raw APIs |
|
||||||
|
+------------------+
|
||||||
|
| Driver |
|
||||||
|
+==================+
|
||||||
|
||
|
||||||
|
+==================+
|
||||||
|
| EMQ X Plugin |
|
||||||
|
+------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
因此,SDK 的作用在于封装底层的比较晦涩的数据格式和方法,屏蔽驱动的细节。直接提供优化后的 API 供用户使用。
|
||||||
|
|
||||||
|
|
||||||
|
### 实现要求
|
||||||
|
|
||||||
|
**声明:** stdin, stdout 已用于和 EMQ X 通信,请不要使用。stderr 用于日志输出。
|
||||||
|
|
||||||
|
#### 基础项
|
||||||
|
|
||||||
|
1. 必须实现 `emqx-exproto` 要求的回调函数和 API 接口,并能够暴露给用户使用
|
||||||
|
2. 可以将 `conn()` 类型,封装成为一个连接类。并:
|
||||||
|
- 将各层的回调函数写为不同的 `Interface`,连接类实现该 `Interface`,并强制子类实现其方法。
|
||||||
|
- 将各层的 API 接口写为连接类的方法
|
||||||
|
用户继承该连接类,并实现各个回调。
|
||||||
|
|
||||||
|
3. 必须将各个专有的,晦涩的数据类型封装为清晰的类型结构,例如:
|
||||||
|
- 连接类型 `conn()`
|
||||||
|
- 连接层信息:conninfo()
|
||||||
|
- 客户端信息:clientinfo()
|
||||||
|
- 消息:message()
|
||||||
|
3. 必须要有对应的开发、部署文档说明
|
||||||
|
|
||||||
|
#### 高级项
|
||||||
|
|
||||||
|
1. 应能方便用户能在 IDE 中进行编译,开发
|
||||||
|
2. 应提供集成测试用的模拟代码。
|
||||||
|
- 例如,生成模拟的数据,发送至用户的程序,方便直接断点调试,而不需要先部署才能使用。
|
||||||
|
3. 提供日志输出的方法
|
||||||
|
|
||||||
|
### 部署结构
|
||||||
|
|
||||||
|
#### 代码依赖结构
|
||||||
|
|
||||||
|
从部署的角度看,代码的依赖关系为:
|
||||||
|
|
||||||
|
1. 用户代码:
|
||||||
|
* 一定会依赖 SDK
|
||||||
|
* 允许依赖 某个位置的三方/系统库
|
||||||
|
2. SDK 代码:
|
||||||
|
* 只能依赖 erlport
|
||||||
|
|
||||||
|
#### 部署
|
||||||
|
|
||||||
|
从文件存放的位置来看,一个标准的部署结构为:
|
||||||
|
|
||||||
|
```
|
||||||
|
emqx
|
||||||
|
|
|
||||||
|
|--- data
|
||||||
|
|------- extension
|
||||||
|
|---------- <some-sdk-package-name>
|
||||||
|
|--------------- <some-classes/scripts-in-sdk>
|
||||||
|
|---------- <user's classes/scripts>
|
||||||
|
|
|
||||||
|
|---------- <another-sdk-package-name>
|
||||||
|
|--------------- <some-classes/scripts-in-sdk>
|
||||||
|
|---------- <user's classes/scripts>
|
||||||
|
```
|
||||||
|
|
||||||
|
它表达了:在 `data/extension` 目录下安装了两个 SDK,并且用户都基于 SDK 编写了其回调的代码模块。
|
|
@ -0,0 +1,250 @@
|
||||||
|
##====================================================================
|
||||||
|
## EMQ X ExProto
|
||||||
|
##====================================================================
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Listeners
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## MQTT/TCP - External TCP Listener for MQTT Protocol
|
||||||
|
|
||||||
|
## The IP address and port that the listener will bind.
|
||||||
|
##
|
||||||
|
## Value: <tcp|ssl|udp|dtls>://<ip>:<port>
|
||||||
|
##
|
||||||
|
## Examples: tcp://0.0.0.0:7993 | ssl://127.0.0.1:7994
|
||||||
|
exproto.listener.protoname = tcp://0.0.0.0:7993
|
||||||
|
|
||||||
|
## Driver type
|
||||||
|
##
|
||||||
|
## Value: python3 | java
|
||||||
|
exproto.listener.protoname.driver = python3
|
||||||
|
|
||||||
|
## The Search path for driver codes
|
||||||
|
##
|
||||||
|
exproto.listener.protoname.driver_search_path = {{ platform_data_dir }}/extension
|
||||||
|
|
||||||
|
## The driver callback module/class name
|
||||||
|
##
|
||||||
|
#exproto.listener.protoname.driver_callback_module = main
|
||||||
|
|
||||||
|
## The acceptor pool for external MQTT/TCP listener.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
exproto.listener.protoname.acceptors = 8
|
||||||
|
|
||||||
|
## Maximum number of concurrent MQTT/TCP connections.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
exproto.listener.protoname.max_connections = 1024000
|
||||||
|
|
||||||
|
## Maximum external connections per second.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
exproto.listener.protoname.max_conn_rate = 1000
|
||||||
|
|
||||||
|
## Specify the {active, N} option for the external MQTT/TCP Socket.
|
||||||
|
##
|
||||||
|
## Value: Number
|
||||||
|
exproto.listener.protoname.active_n = 100
|
||||||
|
|
||||||
|
## Idle timeout
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
exproto.listener.protoname.idle_timeout = 30s
|
||||||
|
|
||||||
|
## The access control rules for the MQTT/TCP listener.
|
||||||
|
##
|
||||||
|
## See: https://github.com/emqtt/esockd#allowdeny
|
||||||
|
##
|
||||||
|
## Value: ACL Rule
|
||||||
|
##
|
||||||
|
## Example: allow 192.168.0.0/24
|
||||||
|
exproto.listener.protoname.access.1 = allow all
|
||||||
|
|
||||||
|
## Enable the Proxy Protocol V1/2 if the EMQ X cluster is deployed
|
||||||
|
## behind HAProxy or Nginx.
|
||||||
|
##
|
||||||
|
## See: https://www.haproxy.com/blog/haproxy/proxy-protocol/
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
## exproto.listener.protoname.proxy_protocol = on
|
||||||
|
|
||||||
|
## Sets the timeout for proxy protocol. EMQ X will close the TCP connection
|
||||||
|
## if no proxy protocol packet recevied within the timeout.
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
#exproto.listener.protoname.proxy_protocol_timeout = 3s
|
||||||
|
|
||||||
|
## The TCP backlog defines the maximum length that the queue of pending
|
||||||
|
## connections can grow to.
|
||||||
|
##
|
||||||
|
## Value: Number >= 0
|
||||||
|
exproto.listener.protoname.backlog = 1024
|
||||||
|
|
||||||
|
## The TCP send timeout for external MQTT connections.
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
exproto.listener.protoname.send_timeout = 15s
|
||||||
|
|
||||||
|
## Close the TCP connection if send timeout.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
exproto.listener.protoname.send_timeout_close = on
|
||||||
|
|
||||||
|
## The TCP receive buffer(os kernel) for MQTT connections.
|
||||||
|
##
|
||||||
|
## See: http://erlang.org/doc/man/inet.html
|
||||||
|
##
|
||||||
|
## Value: Bytes
|
||||||
|
#exproto.listener.protoname.recbuf = 2KB
|
||||||
|
|
||||||
|
## The TCP send buffer(os kernel) for MQTT connections.
|
||||||
|
##
|
||||||
|
## See: http://erlang.org/doc/man/inet.html
|
||||||
|
##
|
||||||
|
## Value: Bytes
|
||||||
|
#exproto.listener.protoname.sndbuf = 2KB
|
||||||
|
|
||||||
|
## The size of the user-level software buffer used by the driver.
|
||||||
|
## Not to be confused with options sndbuf and recbuf, which correspond
|
||||||
|
## to the Kernel socket buffers. It is recommended to have val(buffer)
|
||||||
|
## >= max(val(sndbuf),val(recbuf)) to avoid performance issues because
|
||||||
|
## of unnecessary copying. val(buffer) is automatically set to the above
|
||||||
|
## maximum when values sndbuf or recbuf are set.
|
||||||
|
##
|
||||||
|
## See: http://erlang.org/doc/man/inet.html
|
||||||
|
##
|
||||||
|
## Value: Bytes
|
||||||
|
#exproto.listener.protoname.buffer = 2KB
|
||||||
|
|
||||||
|
## Sets the 'buffer = max(sndbuf, recbuf)' if this option is enabled.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
#exproto.listener.protoname.tune_buffer = off
|
||||||
|
|
||||||
|
## The TCP_NODELAY flag for MQTT connections. Small amounts of data are
|
||||||
|
## sent immediately if the option is enabled.
|
||||||
|
##
|
||||||
|
## Value: true | false
|
||||||
|
exproto.listener.protoname.nodelay = true
|
||||||
|
|
||||||
|
## The SO_REUSEADDR flag for TCP listener.
|
||||||
|
##
|
||||||
|
## Value: true | false
|
||||||
|
exproto.listener.protoname.reuseaddr = true
|
||||||
|
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## TLS/DTLS options
|
||||||
|
|
||||||
|
## TLS versions only to protect from POODLE attack.
|
||||||
|
##
|
||||||
|
## See: http://erlang.org/doc/man/ssl.html
|
||||||
|
##
|
||||||
|
## Value: String, seperated by ','
|
||||||
|
#exproto.listener.protoname.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
|
||||||
|
## Path to the file containing the user's private PEM-encoded key.
|
||||||
|
##
|
||||||
|
## See: http://erlang.org/doc/man/ssl.html
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
#exproto.listener.protoname.keyfile = {{ platform_etc_dir }}/certs/key.pem
|
||||||
|
|
||||||
|
## Path to a file containing the user certificate.
|
||||||
|
##
|
||||||
|
## See: http://erlang.org/doc/man/ssl.html
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
#exproto.listener.protoname.certfile = {{ platform_etc_dir }}/certs/cert.pem
|
||||||
|
|
||||||
|
## Path to the file containing PEM-encoded CA certificates. The CA certificates
|
||||||
|
## are used during server authentication and when building the client certificate chain.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
#exproto.listener.protoname.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem
|
||||||
|
|
||||||
|
## The Ephemeral Diffie-Helman key exchange is a very effective way of
|
||||||
|
## ensuring Forward Secrecy by exchanging a set of keys that never hit
|
||||||
|
## the wire. Since the DH key is effectively signed by the private key,
|
||||||
|
## it needs to be at least as strong as the private key. In addition,
|
||||||
|
## the default DH groups that most of the OpenSSL installations have
|
||||||
|
## are only a handful (since they are distributed with the OpenSSL
|
||||||
|
## package that has been built for the operating system it’s running on)
|
||||||
|
## and hence predictable (not to mention, 1024 bits only).
|
||||||
|
## In order to escape this situation, first we need to generate a fresh,
|
||||||
|
## strong DH group, store it in a file and then use the option above,
|
||||||
|
## to force our SSL application to use the new DH group. Fortunately,
|
||||||
|
## OpenSSL provides us with a tool to do that. Simply run:
|
||||||
|
## openssl dhparam -out dh-params.pem 2048
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
#exproto.listener.protoname.dhfile = {{ platform_etc_dir }}/certs/dh-params.pem
|
||||||
|
|
||||||
|
## A server only does x509-path validation in mode verify_peer,
|
||||||
|
## as it then sends a certificate request to the client (this
|
||||||
|
## message is not sent if the verify option is verify_none).
|
||||||
|
## You can then also want to specify option fail_if_no_peer_cert.
|
||||||
|
## More information at: http://erlang.org/doc/man/ssl.html
|
||||||
|
##
|
||||||
|
## Value: verify_peer | verify_none
|
||||||
|
#exproto.listener.protoname.verify = verify_peer
|
||||||
|
|
||||||
|
## Used together with {verify, verify_peer} by an SSL server. If set to true,
|
||||||
|
## the server fails if the client does not have a certificate to send, that is,
|
||||||
|
## sends an empty certificate.
|
||||||
|
##
|
||||||
|
## Value: true | false
|
||||||
|
#exproto.listener.protoname.fail_if_no_peer_cert = true
|
||||||
|
|
||||||
|
## This is the single most important configuration option of an Erlang SSL
|
||||||
|
## application. Ciphers (and their ordering) define the way the client and
|
||||||
|
## server encrypt information over the wire, from the initial Diffie-Helman
|
||||||
|
## key exchange, the session key encryption ## algorithm and the message
|
||||||
|
## digest algorithm. Selecting a good cipher suite is critical for the
|
||||||
|
## application’s data security, confidentiality and performance.
|
||||||
|
##
|
||||||
|
## The cipher list above offers:
|
||||||
|
##
|
||||||
|
## A good balance between compatibility with older browsers.
|
||||||
|
## It can get stricter for Machine-To-Machine scenarios.
|
||||||
|
## Perfect Forward Secrecy.
|
||||||
|
## No old/insecure encryption and HMAC algorithms
|
||||||
|
##
|
||||||
|
## Most of it was copied from Mozilla’s Server Side TLS article
|
||||||
|
##
|
||||||
|
## Value: Ciphers
|
||||||
|
#exproto.listener.protoname.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA
|
||||||
|
|
||||||
|
## Ciphers for TLS PSK.
|
||||||
|
## Note that 'listener.ssl.external.ciphers' and 'listener.ssl.external.psk_ciphers' cannot
|
||||||
|
## be configured at the same time.
|
||||||
|
## See 'https://tools.ietf.org/html/rfc4279#section-2'.
|
||||||
|
#exproto.listener.protoname.psk_ciphers = PSK-AES128-CBC-SHA,PSK-AES256-CBC-SHA,PSK-3DES-EDE-CBC-SHA,PSK-RC4-SHA
|
||||||
|
|
||||||
|
## SSL parameter renegotiation is a feature that allows a client and a server
|
||||||
|
## to renegotiate the parameters of the SSL connection on the fly.
|
||||||
|
## RFC 5746 defines a more secure way of doing this. By enabling secure renegotiation,
|
||||||
|
## you drop support for the insecure renegotiation, prone to MitM attacks.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
#exproto.listener.protoname.secure_renegotiate = off
|
||||||
|
|
||||||
|
## A performance optimization setting, it allows clients to reuse
|
||||||
|
## pre-existing sessions, instead of initializing new ones.
|
||||||
|
## Read more about it here.
|
||||||
|
##
|
||||||
|
## See: http://erlang.org/doc/man/ssl.html
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
#exproto.listener.protoname.reuse_sessions = on
|
||||||
|
|
||||||
|
## An important security setting, it forces the cipher to be set based
|
||||||
|
## on the server-specified order instead of the client-specified order,
|
||||||
|
## hence enforcing the (usually more properly configured) security
|
||||||
|
## ordering of the server administrator.
|
||||||
|
##
|
||||||
|
## Value: on | off
|
||||||
|
#exproto.listener.protoname.honor_cipher_order = on
|
|
@ -0,0 +1,136 @@
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import com.erlport.erlang.term.*;
|
||||||
|
import com.erlport.*;
|
||||||
|
|
||||||
|
class State implements Serializable {
|
||||||
|
|
||||||
|
Integer times;
|
||||||
|
|
||||||
|
public State() {
|
||||||
|
times = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer incr() {
|
||||||
|
times += 1;
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("State(times: %d)", times);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
static Integer OK = 0;
|
||||||
|
static Integer ERROR = 0;
|
||||||
|
|
||||||
|
//-------------------
|
||||||
|
// Connection level
|
||||||
|
|
||||||
|
public static Object init(Object conn, Object connInfo) {
|
||||||
|
System.err.printf("[java] established a conn=%s, connInfo=%s\n", conn, connInfo);
|
||||||
|
|
||||||
|
// set an instance to be the connection state
|
||||||
|
// it just a example structure to record the callback total times
|
||||||
|
Object state = new State();
|
||||||
|
|
||||||
|
// subscribe the topic `t/dn` with qos0
|
||||||
|
subscribe(conn, new Binary("t/dn"), 0);
|
||||||
|
|
||||||
|
// return the initial conn's state
|
||||||
|
return Tuple.two(OK, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object received(Object conn, Object data, Object state) {
|
||||||
|
System.err.printf("[java] received data conn=%s, data=%s, state=%s\n", conn, data, state);
|
||||||
|
|
||||||
|
// echo the conn's data
|
||||||
|
send(conn, data);
|
||||||
|
|
||||||
|
// return the new conn's state
|
||||||
|
State nstate = (State) state;
|
||||||
|
nstate.incr();
|
||||||
|
return Tuple.two(OK, nstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void terminated(Object conn, Object reason, Object state) {
|
||||||
|
System.err.printf("[java] terminated conn=%s, reason=%s, state=%s\n", conn, reason, state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------
|
||||||
|
// Protocol/Session level
|
||||||
|
|
||||||
|
public static Object deliver(Object conn, Object msgs0, Object state) {
|
||||||
|
System.err.printf("[java] received messages conn=%s, msgs=%s, state=%s\n", conn, msgs0, state);
|
||||||
|
|
||||||
|
List<Object> msgs = (List<Object>) msgs0;
|
||||||
|
for(Object msg: msgs) {
|
||||||
|
publish(conn, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the new conn's state
|
||||||
|
State nstate = (State) state;
|
||||||
|
nstate.incr();
|
||||||
|
return Tuple.two(OK, nstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------
|
||||||
|
// APIs
|
||||||
|
public static void send(Object conn, Object data) {
|
||||||
|
try {
|
||||||
|
Erlang.call("emqx_exproto", "send", new Object[]{conn, data}, 5000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.printf("[java] send data error: %s\n", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Object conn) {
|
||||||
|
try {
|
||||||
|
Erlang.call("emqx_exproto", "close", new Object[]{conn}, 5000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.printf("[java] send data error: %s\n", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(Object conn, Object clientInfo) {
|
||||||
|
try {
|
||||||
|
Erlang.call("emqx_exproto", "register", new Object[]{conn, clientInfo}, 5000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.printf("[java] send data error: %s\n", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void publish(Object conn, Object message) {
|
||||||
|
try {
|
||||||
|
Erlang.call("emqx_exproto", "publish", new Object[]{conn, message}, 5000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.printf("[java] send data error: %s\n", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void subscribe(Object conn, Object topic, Object qos) {
|
||||||
|
try {
|
||||||
|
Erlang.call("emqx_exproto", "subscribe", new Object[]{conn, topic, qos}, 5000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.printf("[java] send data error: %s\n", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unsubscribe(Object conn, Object topic) {
|
||||||
|
try {
|
||||||
|
Erlang.call("emqx_exproto", "unsubscribe", new Object[]{conn, topic}, 5000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.printf("[java] send data error: %s\n", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
|
from erlport import Atom
|
||||||
|
from erlport import erlang
|
||||||
|
|
||||||
|
OK = 0
|
||||||
|
ERROR = 1
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Connection level
|
||||||
|
|
||||||
|
def init(conn, conninfo):
|
||||||
|
print(f'[python] established a conn={conn}, conninfo={conninfo}')
|
||||||
|
|
||||||
|
## set an integer num to the connection state
|
||||||
|
## it just a example structure to record the callback total times
|
||||||
|
state = 0
|
||||||
|
|
||||||
|
## subscribe the topic `t/dn` with qos0
|
||||||
|
subscribe(conn, b"t/dn", 0)
|
||||||
|
|
||||||
|
## return the initial conn's state
|
||||||
|
return (OK, state)
|
||||||
|
|
||||||
|
def received(conn, data, state):
|
||||||
|
print(f'[python] received data conn={conn}, data={data}, state={state}')
|
||||||
|
|
||||||
|
## echo the conn's data
|
||||||
|
send(conn, data)
|
||||||
|
|
||||||
|
## return the new conn's state
|
||||||
|
return (OK, state+1)
|
||||||
|
|
||||||
|
def terminated(conn, reason, state):
|
||||||
|
print(f'[python] terminated conn={conn}, reason={reason}, state={state}')
|
||||||
|
return
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Protocol/Session level
|
||||||
|
|
||||||
|
def deliver(conn, msgs, state):
|
||||||
|
print(f'[python] received messages: conn={conn}, msgs={msgs}, state={state}')
|
||||||
|
|
||||||
|
## echo the protocol/session messages
|
||||||
|
for msg in msgs:
|
||||||
|
msg[3] = (Atom(b'topic'), b't/up')
|
||||||
|
publish(conn, msg)
|
||||||
|
|
||||||
|
## return the new conn's state
|
||||||
|
return (OK, state+1)
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## APIs
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
def send(conn, data):
|
||||||
|
erlang.call(Atom(b'emqx_exproto'), Atom(b'send'), [conn, data])
|
||||||
|
return
|
||||||
|
|
||||||
|
def close(conn):
|
||||||
|
erlang.call(Atom(b'emqx_exproto'), Atom(b'close'), [conn])
|
||||||
|
return
|
||||||
|
|
||||||
|
def register(conn, clientinfo):
|
||||||
|
erlang.call(Atom(b'emqx_exproto'), Atom(b'register'), [conn, clientinfo])
|
||||||
|
return
|
||||||
|
|
||||||
|
def publish(conn, message):
|
||||||
|
erlang.call(Atom(b'emqx_exproto'), Atom(b'publish'), [conn, message])
|
||||||
|
return
|
||||||
|
|
||||||
|
def subscribe(conn, topic, qos):
|
||||||
|
erlang.call(Atom(b'emqx_exproto'), Atom(b'subscribe'), [conn, topic, qos])
|
||||||
|
return
|
||||||
|
|
||||||
|
def unsubscribe(conn, topic):
|
||||||
|
erlang.call(Atom(b'emqx_exproto'), Atom(b'subscribe'), [conn, topic])
|
||||||
|
return
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# SDKs
|
||||||
|
|
||||||
|
A specific language SDK is a suite of codes for user-oriented friendly.
|
||||||
|
|
||||||
|
Even it does not need it for you to develop the Multiple language support plugins, but it provides more friendly APIs and Abstract for you
|
||||||
|
|
||||||
|
|
||||||
|
Now, we provide the following SDKs:
|
||||||
|
|
||||||
|
- Java: https://github.com/emqx/emqx-exproto-java-sdk
|
||||||
|
- Python: https://github.com/emqx/emqx-exproto-python-sdk
|
|
@ -0,0 +1,302 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_exproto_driver_mngr).
|
||||||
|
|
||||||
|
-behaviour(gen_server).
|
||||||
|
|
||||||
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
|
-log_header("[ExProto DMngr]").
|
||||||
|
|
||||||
|
-compile({no_auto_import, [erase/1, get/1]}).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([start_link/0]).
|
||||||
|
|
||||||
|
%% Manager APIs
|
||||||
|
-export([ ensure_driver/2
|
||||||
|
, stop_drivers/0
|
||||||
|
, stop_driver/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
%% Driver APIs
|
||||||
|
-export([ lookup/1
|
||||||
|
, call/2
|
||||||
|
]).
|
||||||
|
|
||||||
|
%% gen_server callbacks
|
||||||
|
-export([ init/1
|
||||||
|
, handle_call/3
|
||||||
|
, handle_cast/2
|
||||||
|
, handle_info/2
|
||||||
|
, terminate/2
|
||||||
|
, code_change/3
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(SERVER, ?MODULE).
|
||||||
|
-define(DEFAULT_CBM, main).
|
||||||
|
|
||||||
|
-type driver() :: #{name := driver_name(),
|
||||||
|
type := atom(),
|
||||||
|
cbm := atom(),
|
||||||
|
pid := pid(),
|
||||||
|
opts := list()
|
||||||
|
}.
|
||||||
|
|
||||||
|
-type driver_name() :: atom().
|
||||||
|
|
||||||
|
-type fargs() :: {atom(), list()}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% APIs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
start_link() ->
|
||||||
|
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% APIs - Managers
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec(ensure_driver(driver_name(), list()) -> {ok, pid()} | {error, any()}).
|
||||||
|
ensure_driver(Name, Opts) ->
|
||||||
|
{value, {_, Type}, Opts1} = lists:keytake(type, 1, Opts),
|
||||||
|
{value, {_, Cbm}, Opts2} = lists:keytake(cbm, 1, Opts1),
|
||||||
|
gen_server:call(?SERVER, {ensure, {Type, Name, Cbm, Opts2}}).
|
||||||
|
|
||||||
|
-spec(stop_drivers() -> ok).
|
||||||
|
stop_drivers() ->
|
||||||
|
gen_server:call(?SERVER, stop_all).
|
||||||
|
|
||||||
|
-spec(stop_driver(driver_name()) -> ok).
|
||||||
|
stop_driver(Name) ->
|
||||||
|
gen_server:call(?SERVER, {stop, Name}).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% APIs - Drivers
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec(lookup(driver_name()) -> {ok, driver()} | {error, any()}).
|
||||||
|
lookup(Name) ->
|
||||||
|
case catch persistent_term:get({?MODULE, Name}) of
|
||||||
|
{'EXIT', {badarg, _}} -> {error, not_found};
|
||||||
|
Driver when is_map(Driver) -> {ok, Driver}
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec(call(driver_name(), fargs()) -> ok | {ok, any()} | {error, any()}).
|
||||||
|
call(Name, FArgs) ->
|
||||||
|
ensure_alived(Name, fun(Driver) -> do_call(Driver, FArgs) end).
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
ensure_alived(Name, Fun) ->
|
||||||
|
case catch get(Name) of
|
||||||
|
{'EXIT', _} ->
|
||||||
|
{error, not_found};
|
||||||
|
Driver ->
|
||||||
|
ensure_alived(10, Driver, Fun)
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
ensure_alived(0, _, _) ->
|
||||||
|
{error, driver_process_exited};
|
||||||
|
ensure_alived(N, Driver = #{name := Name, pid := Pid}, Fun) ->
|
||||||
|
case is_process_alive(Pid) of
|
||||||
|
true -> Fun(Driver);
|
||||||
|
_ ->
|
||||||
|
timer:sleep(100),
|
||||||
|
#{pid := NPid} = get(Name),
|
||||||
|
case is_process_alive(NPid) of
|
||||||
|
true -> Fun(Driver);
|
||||||
|
_ -> ensure_alived(N-1, Driver#{pid => NPid}, Fun)
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
do_call(#{type := Type, pid := Pid, cbm := Cbm}, {F, Args}) ->
|
||||||
|
case catch apply(erlport, call, [Pid, Cbm, F, Args, []]) of
|
||||||
|
ok -> ok;
|
||||||
|
undefined -> ok;
|
||||||
|
{_Ok = 0, Return} -> {ok, Return};
|
||||||
|
{_Err = 1, Reason} -> {error, Reason};
|
||||||
|
{'EXIT', Reason, Stk} ->
|
||||||
|
?LOG(error, "CALL ~p ~p:~p(~p), exception: ~p, stacktrace ~0p",
|
||||||
|
[Type, Cbm, F, Args, Reason, Stk]),
|
||||||
|
{error, Reason};
|
||||||
|
_X ->
|
||||||
|
?LOG(error, "CALL ~p ~p:~p(~p), unknown return: ~0p",
|
||||||
|
[Type, Cbm, F, Args, _X]),
|
||||||
|
{error, unknown_return_format}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% gen_server callbacks
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
init([]) ->
|
||||||
|
process_flag(trap_exit, true),
|
||||||
|
{ok, #{drivers => []}}.
|
||||||
|
|
||||||
|
handle_call({ensure, {Type, Name, Cbm, Opts}}, _From, State = #{drivers := Drivers}) ->
|
||||||
|
case lists:keyfind(Name, 1, Drivers) of
|
||||||
|
false ->
|
||||||
|
case do_start_driver(Type, Opts) of
|
||||||
|
{ok, Pid} ->
|
||||||
|
Driver = #{name => Name,
|
||||||
|
type => Type,
|
||||||
|
cbm => Cbm,
|
||||||
|
pid => Pid,
|
||||||
|
opts => Opts},
|
||||||
|
ok = save(Name, Driver),
|
||||||
|
reply({ok, Driver}, State#{drivers => [{Name, Driver} | Drivers]});
|
||||||
|
{error, Reason} ->
|
||||||
|
reply({error, Reason}, State)
|
||||||
|
end;
|
||||||
|
{_, Driver} ->
|
||||||
|
reply({ok, Driver}, State)
|
||||||
|
end;
|
||||||
|
|
||||||
|
handle_call(stop_all, _From, State = #{drivers := Drivers}) ->
|
||||||
|
lists:foreach(
|
||||||
|
fun({Name, #{pid := Pid}}) ->
|
||||||
|
_ = do_stop_drviver(Pid),
|
||||||
|
_ = erase(Name)
|
||||||
|
end, Drivers),
|
||||||
|
reply(ok, State#{drivers => []});
|
||||||
|
|
||||||
|
handle_call({stop, Name}, _From, State = #{drivers := Drivers}) ->
|
||||||
|
case lists:keyfind(Name, 1, Drivers) of
|
||||||
|
false ->
|
||||||
|
reply({error, not_found}, State);
|
||||||
|
{_, #{pid := Pid}} ->
|
||||||
|
_ = do_stop_drviver(Pid),
|
||||||
|
_ = erase(Name),
|
||||||
|
reply(ok, State#{drivers => Drivers -- [{Name, Pid}]})
|
||||||
|
end;
|
||||||
|
|
||||||
|
handle_call(Req, _From, State) ->
|
||||||
|
?WARN("Unexpected request: ~p", [Req]),
|
||||||
|
{reply, ok, State}.
|
||||||
|
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARN("Unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_info({'EXIT', _From, normal}, State) ->
|
||||||
|
{noreply, State};
|
||||||
|
handle_info({'EXIT', From, Reason}, State = #{drivers := Drivers}) ->
|
||||||
|
case [Drv || {_, Drv = #{pid := P}} <- Drivers, P =:= From] of
|
||||||
|
[] -> {noreply, State};
|
||||||
|
[Driver = #{name := Name, type := Type, opts := Opts}] ->
|
||||||
|
?WARN("Driver ~p crashed: ~p", [Name, Reason]),
|
||||||
|
case do_start_driver(Type, Opts) of
|
||||||
|
{ok, Pid} ->
|
||||||
|
NDriver = Driver#{pid => Pid},
|
||||||
|
ok = save(Name, NDriver),
|
||||||
|
NDrivers = lists:keyreplace(Name, 1, Drivers, {Name, NDriver}),
|
||||||
|
?WARN("Restarted driver ~p, pid: ~p", [Name, Pid]),
|
||||||
|
{noreply, State#{drivers => NDrivers}};
|
||||||
|
{error, Reason} ->
|
||||||
|
?WARN("Restart driver ~p failed: ~p", [Name, Reason]),
|
||||||
|
{noreply, State}
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
handle_info(Info, State) ->
|
||||||
|
?WARN("Unexpected info: ~p", [Info]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
terminate(_Reason, _State) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Internal funcs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
do_start_driver(Type, Opts)
|
||||||
|
when Type =:= python2;
|
||||||
|
Type =:= python3 ->
|
||||||
|
NOpts = resovle_search_path(python, Opts),
|
||||||
|
python:start_link([{python, atom_to_list(Type)} | NOpts]);
|
||||||
|
|
||||||
|
do_start_driver(Type, Opts)
|
||||||
|
when Type =:= java ->
|
||||||
|
NOpts = resovle_search_path(java, Opts),
|
||||||
|
java:start_link([{java, atom_to_list(Type)} | NOpts]);
|
||||||
|
|
||||||
|
do_start_driver(Type, _) ->
|
||||||
|
{error, {invalid_driver_type, Type}}.
|
||||||
|
|
||||||
|
do_stop_drviver(DriverPid) ->
|
||||||
|
erlport:stop(DriverPid).
|
||||||
|
%% @private
|
||||||
|
resovle_search_path(java, Opts) ->
|
||||||
|
case lists:keytake(path, 1, Opts) of
|
||||||
|
false -> Opts;
|
||||||
|
{value, {_, Path}, NOpts} ->
|
||||||
|
Solved = lists:flatten(
|
||||||
|
lists:join(pathsep(),
|
||||||
|
[expand_jar_packages(filename:absname(P))
|
||||||
|
|| P <- re:split(Path, pathsep(), [{return, list}]), P /= ""])),
|
||||||
|
[{java_path, Solved} | NOpts]
|
||||||
|
end;
|
||||||
|
resovle_search_path(python, Opts) ->
|
||||||
|
case lists:keytake(path, 1, Opts) of
|
||||||
|
false -> Opts;
|
||||||
|
{value, {_, Path}, NOpts} ->
|
||||||
|
[{python_path, Path} | NOpts]
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
expand_jar_packages(Path) ->
|
||||||
|
IsJarPkgs = fun(Name) ->
|
||||||
|
Ext = filename:extension(Name),
|
||||||
|
Ext == ".jar" orelse Ext == ".zip"
|
||||||
|
end,
|
||||||
|
case file:list_dir(Path) of
|
||||||
|
{ok, []} -> [Path];
|
||||||
|
{error, _} -> [Path];
|
||||||
|
{ok, Names} ->
|
||||||
|
lists:join(pathsep(),
|
||||||
|
[Path] ++ [filename:join([Path, Name]) || Name <- Names, IsJarPkgs(Name)])
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
pathsep() ->
|
||||||
|
case os:type() of
|
||||||
|
{win32, _} ->
|
||||||
|
";";
|
||||||
|
_ ->
|
||||||
|
":"
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Utils
|
||||||
|
|
||||||
|
reply(Term, State) ->
|
||||||
|
{reply, Term, State}.
|
||||||
|
|
||||||
|
save(Name, Driver) ->
|
||||||
|
persistent_term:put({?MODULE, Name}, Driver).
|
||||||
|
|
||||||
|
erase(Name) ->
|
||||||
|
persistent_term:erase({?MODULE, Name}).
|
||||||
|
|
||||||
|
get(Name) ->
|
||||||
|
persistent_term:get({?MODULE, Name}).
|
|
@ -0,0 +1,179 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_exproto_types).
|
||||||
|
|
||||||
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
|
-include_lib("emqx/include/types.hrl").
|
||||||
|
|
||||||
|
-import(proplists, [get_value/2]).
|
||||||
|
|
||||||
|
-export([ parse/2
|
||||||
|
, serialize/2
|
||||||
|
]).
|
||||||
|
|
||||||
|
-type(clientinfo() :: #{ proto_name := maybe(binary())
|
||||||
|
, proto_ver := maybe(non_neg_integer())
|
||||||
|
, clientid := maybe(binary())
|
||||||
|
, username := maybe(binary())
|
||||||
|
, mountpoint := maybe(binary())
|
||||||
|
, keepalive := maybe(non_neg_integer())
|
||||||
|
}).
|
||||||
|
|
||||||
|
-type(conninfo() :: #{ socktype := tcp | tls | udp | dtls
|
||||||
|
, peername := emqx_types:peername()
|
||||||
|
, sockname := emqx_types:sockname()
|
||||||
|
, peercert := nossl | binary() | list()
|
||||||
|
, conn_mod := atom()
|
||||||
|
}).
|
||||||
|
|
||||||
|
-export_type([conninfo/0, clientinfo/0]).
|
||||||
|
|
||||||
|
-define(UP_DATA_SCHEMA_CLIENTINFO,
|
||||||
|
[ {proto_name, optional, binary}
|
||||||
|
, {proto_ver, optional, [integer, binary]}
|
||||||
|
, {clientid, optional, binary}
|
||||||
|
, {username, optional, binary}
|
||||||
|
, {mountpoint, optional, binary}
|
||||||
|
, {keepalive, optional, integer}
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(UP_DATA_SCHEMA_MESSAGE,
|
||||||
|
[ {id, {optional, fun emqx_guid:gen/0}, binary}
|
||||||
|
, {qos, required, [{enum, [0, 1, 2]}]}
|
||||||
|
, {from, optional, [binary, atom]}
|
||||||
|
, {topic, required, binary}
|
||||||
|
, {payload, required, binary}
|
||||||
|
, {timestamp, {optional, fun() -> erlang:system_time(millisecond) end}, integer}
|
||||||
|
]).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% APIs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec(parse(clientinfo | message, list())
|
||||||
|
-> {error, any()}
|
||||||
|
| clientinfo()
|
||||||
|
| emqx_types:message()).
|
||||||
|
parse(clientinfo, Params) ->
|
||||||
|
to_map(do_parsing(?UP_DATA_SCHEMA_CLIENTINFO, Params));
|
||||||
|
|
||||||
|
parse(message, Params) ->
|
||||||
|
to_message(do_parsing(?UP_DATA_SCHEMA_MESSAGE, Params));
|
||||||
|
|
||||||
|
parse(Type, _) ->
|
||||||
|
{error, {unkown_type, Type}}.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
to_map(Err = {error, _}) ->
|
||||||
|
Err;
|
||||||
|
to_map(Ls) ->
|
||||||
|
maps:from_list(Ls).
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
to_message(Err = {error, _}) ->
|
||||||
|
Err;
|
||||||
|
to_message(Ls) ->
|
||||||
|
#message{
|
||||||
|
id = get_value(id, Ls),
|
||||||
|
qos = get_value(qos, Ls),
|
||||||
|
from = get_value(from, Ls),
|
||||||
|
topic = get_value(topic, Ls),
|
||||||
|
payload = get_value(payload, Ls),
|
||||||
|
timestamp = get_value(timestamp, Ls)}.
|
||||||
|
|
||||||
|
-spec(serialize(Type, Struct)
|
||||||
|
-> {error, any()}
|
||||||
|
| [{atom(), any()}]
|
||||||
|
when Type :: conninfo | message,
|
||||||
|
Struct :: conninfo() | emqx_types:message()).
|
||||||
|
serialize(conninfo, #{socktype := A1,
|
||||||
|
peername := A2,
|
||||||
|
sockname := A3,
|
||||||
|
peercert := Peercert
|
||||||
|
}) ->
|
||||||
|
[{socktype, A1},
|
||||||
|
{peername, A2},
|
||||||
|
{sockname, A3},
|
||||||
|
{peercert, do_serializing(peercert, Peercert)}];
|
||||||
|
|
||||||
|
serialize(message, Msg) ->
|
||||||
|
[{id, emqx_message:id(Msg)},
|
||||||
|
{qos, emqx_message:qos(Msg)},
|
||||||
|
{from, emqx_message:from(Msg)},
|
||||||
|
{topic, emqx_message:topic(Msg)},
|
||||||
|
{payload, emqx_message:payload(Msg)},
|
||||||
|
{timestamp, emqx_message:timestamp(Msg)}];
|
||||||
|
|
||||||
|
serialize(Type, _) ->
|
||||||
|
{error, {unkown_type, Type}}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Internal funcs
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
do_parsing(Schema, Params) ->
|
||||||
|
try do_parsing(Schema, Params, [])
|
||||||
|
catch
|
||||||
|
throw:{badarg, Reason} -> {error, Reason}
|
||||||
|
end.
|
||||||
|
do_parsing([], _Params, Acc) ->
|
||||||
|
lists:reverse(Acc);
|
||||||
|
do_parsing([Indictor = {Key, _Optional, Type} | More], Params, Acc) ->
|
||||||
|
Value = case get_value(Key, Params) of
|
||||||
|
undefined -> do_generating(Indictor);
|
||||||
|
InParam -> do_typing(Key, InParam, Type)
|
||||||
|
end,
|
||||||
|
do_parsing(More, Params, [{Key, Value} | Acc]).
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
do_generating({Key, required, _}) ->
|
||||||
|
throw({badarg, errmsg("~s is required", [Key])});
|
||||||
|
do_generating({_, optional, _}) ->
|
||||||
|
undefined;
|
||||||
|
do_generating({_, {_, Generator}, _}) when is_function(Generator) ->
|
||||||
|
Generator();
|
||||||
|
do_generating({_, {_, Default}, _}) ->
|
||||||
|
Default.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
do_typing(Key, InParam, Types) when is_list(Types) ->
|
||||||
|
case length(lists:filter(fun(T) -> is_x_type(InParam, T) end, Types)) of
|
||||||
|
0 ->
|
||||||
|
throw({badarg, errmsg("~s: value ~p data type is not validate to ~p", [Key, InParam, Types])});
|
||||||
|
_ ->
|
||||||
|
InParam
|
||||||
|
end;
|
||||||
|
do_typing(Key, InParam, Type) ->
|
||||||
|
do_typing(Key, InParam, [Type]).
|
||||||
|
|
||||||
|
% @private
|
||||||
|
is_x_type(P, atom) when is_atom(P) -> true;
|
||||||
|
is_x_type(P, binary) when is_binary(P) -> true;
|
||||||
|
is_x_type(P, integer) when is_integer(P) -> true;
|
||||||
|
is_x_type(P, {enum, Ls}) ->
|
||||||
|
lists:member(P, Ls);
|
||||||
|
is_x_type(_, _) -> false.
|
||||||
|
|
||||||
|
do_serializing(peercert, nossl) ->
|
||||||
|
nossl;
|
||||||
|
do_serializing(peercert, Peercert) ->
|
||||||
|
[{dn, esockd_peercert:subject(Peercert)},
|
||||||
|
{cn, esockd_peercert:common_name(Peercert)}].
|
||||||
|
|
||||||
|
errmsg(Fmt, Args) ->
|
||||||
|
lists:flatten(io_lib:format(Fmt, Args)).
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
deps/
|
||||||
|
ebin/
|
||||||
|
_rel/
|
||||||
|
.erlang.mk/
|
||||||
|
*.d
|
||||||
|
data/
|
||||||
|
*.iml
|
||||||
|
.idea/
|
||||||
|
logs/
|
||||||
|
*.beam
|
||||||
|
.DS_Store
|
||||||
|
erlang.mk
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
rebar3.crashdump
|
||||||
|
bbmustache/
|
||||||
|
*.conf.rendered
|
||||||
|
.rebar3
|
||||||
|
*.swp
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,4 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## EMQ X Lua Hook
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
|
@ -1,3 +1,28 @@
|
||||||
{deps,
|
{deps,
|
||||||
[{luerl, {git, "https://github.com/emqx/luerl", {tag, "v0.3.1"}}}
|
[{luerl, {git, "https://github.com/emqx/luerl", {tag, "v0.3.1"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
|
{erl_opts, [warn_unused_vars,
|
||||||
|
warn_shadow_vars,
|
||||||
|
warn_unused_import,
|
||||||
|
warn_obsolete_guard,
|
||||||
|
debug_info,
|
||||||
|
compressed,
|
||||||
|
{parse_transform}
|
||||||
|
]}.
|
||||||
|
{overrides, [{add, [{erl_opts, [compressed]}]}]}.
|
||||||
|
|
||||||
|
{xref_checks, [undefined_function_calls, undefined_functions,
|
||||||
|
locals_not_used, deprecated_function_calls,
|
||||||
|
warnings_as_errors, deprecated_functions]}.
|
||||||
|
{cover_enabled, true}.
|
||||||
|
{cover_opts, [verbose]}.
|
||||||
|
{cover_export_enabled, true}.
|
||||||
|
|
||||||
|
{profiles,
|
||||||
|
[{test,
|
||||||
|
[{deps, [{emqx_ct_helpers, {git, "http://github.com/emqx/emqx-ct-helpers", {tag, "1.2.2"}}}]}
|
||||||
|
]},
|
||||||
|
{erl_opts, [debug_info]}
|
||||||
|
]}.
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
deps/
|
||||||
|
ebin/
|
||||||
|
_rel/
|
||||||
|
.erlang.mk/
|
||||||
|
*.d
|
||||||
|
*.o
|
||||||
|
*.exe
|
||||||
|
data/
|
||||||
|
*.iml
|
||||||
|
.idea/
|
||||||
|
logs/
|
||||||
|
*.beam
|
||||||
|
emqx_coap.d
|
||||||
|
erlang.mk
|
||||||
|
integration_test/emqx-rel/
|
||||||
|
integration_test/build_wakaama/
|
||||||
|
integration_test/case*.txt
|
||||||
|
integration_test/paho/
|
||||||
|
integration_test/wakaama/
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
rebar3.crashdump
|
||||||
|
*.conf.rendered
|
||||||
|
.rebar3/
|
||||||
|
*.swp
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,136 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## LwM2M Gateway
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Protocols
|
||||||
|
|
||||||
|
# To Limit the range of lifetime, in seconds
|
||||||
|
lwm2m.lifetime_min = 1s
|
||||||
|
lwm2m.lifetime_max = 86400s
|
||||||
|
|
||||||
|
# The time window for Q Mode, indicating that after how long time
|
||||||
|
# the downlink commands sent to the client will be cached.
|
||||||
|
#lwm2m.qmode_time_window = 22
|
||||||
|
|
||||||
|
# Auto send observer command to device
|
||||||
|
# on | off
|
||||||
|
#lwm2m.auto_observe = off
|
||||||
|
|
||||||
|
# The topic subscribed by the lwm2m client after it is connected
|
||||||
|
# Placeholders supported:
|
||||||
|
# '%e': Endpoint Name
|
||||||
|
# '%a': IP Address
|
||||||
|
lwm2m.mountpoint = lwm2m/%e/
|
||||||
|
|
||||||
|
# The topic subscribed by the lwm2m client after it is connected
|
||||||
|
# Placeholders supported:
|
||||||
|
# '%e': Endpoint Name
|
||||||
|
# '%a': IP Address
|
||||||
|
lwm2m.topics.command = dn/#
|
||||||
|
|
||||||
|
# The topic to which the lwm2m client's response is published
|
||||||
|
lwm2m.topics.response = up/resp
|
||||||
|
|
||||||
|
# The topic to which the lwm2m client's notify message is published
|
||||||
|
lwm2m.topics.notify = up/notify
|
||||||
|
|
||||||
|
# The topic to which the lwm2m client's register message is published
|
||||||
|
lwm2m.topics.register = up/resp
|
||||||
|
|
||||||
|
# The topic to which the lwm2m client's update message is published
|
||||||
|
lwm2m.topics.update = up/resp
|
||||||
|
|
||||||
|
# Dir where the object definition files can be found
|
||||||
|
lwm2m.xml_dir = {{ platform_etc_dir }}/lwm2m_xml
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## UDP Listener options
|
||||||
|
|
||||||
|
## The IP and port of the LwM2M Gateway
|
||||||
|
##
|
||||||
|
## Default: 0.0.0.0:5683
|
||||||
|
## Examples:
|
||||||
|
## lwm2m.bind.udp.x = 0.0.0.0:5683 | :::5683 | 127.0.0.1:5683 | ::1:5683
|
||||||
|
lwm2m.bind.udp.1 = 0.0.0.0:5683
|
||||||
|
#lwm2m.bind.udp.2 = 0.0.0.0:6683
|
||||||
|
|
||||||
|
## Socket options, used for performance tuning
|
||||||
|
##
|
||||||
|
## Examples:
|
||||||
|
## lwm2m.opts.$name = $value
|
||||||
|
## See: https://erlang.org/doc/man/gen_udp.html#type-option
|
||||||
|
lwm2m.opts.buffer = 1024KB
|
||||||
|
lwm2m.opts.recbuf = 1024KB
|
||||||
|
lwm2m.opts.sndbuf = 1024KB
|
||||||
|
lwm2m.opts.read_packets = 20
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## DTLS Listener Options
|
||||||
|
|
||||||
|
## The DTLS port that LwM2M is listening on.
|
||||||
|
##
|
||||||
|
## Default: 0.0.0.0:5684
|
||||||
|
##
|
||||||
|
## Examples:
|
||||||
|
## lwm2m.bind.dtls.x = 0.0.0.0:5684 | :::5684 | 127.0.0.1:5684 | ::1:5684
|
||||||
|
##
|
||||||
|
lwm2m.bind.dtls.1 = 0.0.0.0:5684
|
||||||
|
#lwm2m.bind.dtls.2 = 0.0.0.0:6684
|
||||||
|
|
||||||
|
## A server only does x509-path validation in mode verify_peer,
|
||||||
|
## as it then sends a certificate request to the client (this
|
||||||
|
## message is not sent if the verify option is verify_none).
|
||||||
|
## You can then also want to specify option fail_if_no_peer_cert.
|
||||||
|
## More information at: http://erlang.org/doc/man/ssl.html
|
||||||
|
##
|
||||||
|
## Value: verify_peer | verify_none
|
||||||
|
#lwm2m.dtls.verify = verify_peer
|
||||||
|
|
||||||
|
## Private key file for DTLS
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
lwm2m.dtls.keyfile = {{ platform_etc_dir }}/certs/key.pem
|
||||||
|
|
||||||
|
## Server certificate for DTLS.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
lwm2m.dtls.certfile = {{ platform_etc_dir }}/certs/cert.pem
|
||||||
|
|
||||||
|
## PEM-encoded CA certificates for DTLS
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
#lwm2m.dtls.cacertfile = {{ platform_etc_dir }}/certs/cacert.pem
|
||||||
|
|
||||||
|
## Used together with {verify, verify_peer} by an SSL server. If set to true,
|
||||||
|
## the server fails if the client does not have a certificate to send, that is,
|
||||||
|
## sends an empty certificate.
|
||||||
|
##
|
||||||
|
## Value: true | false
|
||||||
|
#lwm2m.dtls.fail_if_no_peer_cert = false
|
||||||
|
|
||||||
|
## This is the single most important configuration option of an Erlang SSL
|
||||||
|
## application. Ciphers (and their ordering) define the way the client and
|
||||||
|
## server encrypt information over the wire, from the initial Diffie-Helman
|
||||||
|
## key exchange, the session key encryption ## algorithm and the message
|
||||||
|
## digest algorithm. Selecting a good cipher suite is critical for the
|
||||||
|
## application’s data security, confidentiality and performance.
|
||||||
|
##
|
||||||
|
## The cipher list above offers:
|
||||||
|
##
|
||||||
|
## A good balance between compatibility with older browsers.
|
||||||
|
## It can get stricter for Machine-To-Machine scenarios.
|
||||||
|
## Perfect Forward Secrecy.
|
||||||
|
## No old/insecure encryption and HMAC algorithms
|
||||||
|
##
|
||||||
|
## Most of it was copied from Mozilla’s Server Side TLS article
|
||||||
|
##
|
||||||
|
## Value: Ciphers
|
||||||
|
lwm2m.dtls.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA
|
||||||
|
|
||||||
|
## Ciphers for TLS PSK.
|
||||||
|
##
|
||||||
|
## Note that 'lwm2m.dtls.ciphers' and 'lwm2m.dtls.psk_ciphers' cannot
|
||||||
|
## be configured at the same time.
|
||||||
|
## See 'https://tools.ietf.org/html/rfc4279#section-2'.
|
||||||
|
#lwm2m.dtls.psk_ciphers = PSK-AES128-CBC-SHA,PSK-AES256-CBC-SHA,PSK-3DES-EDE-CBC-SHA,PSK-RC4-SHA
|
|
@ -0,0 +1,128 @@
|
||||||
|
|
||||||
|
.PHONY: clean, clean_result, start_broker stop_broker case1 case2 case3
|
||||||
|
|
||||||
|
EMQX_DIR = emqx-enterprise-rel
|
||||||
|
EMQ = $(EMQX_DIR)/relx.config
|
||||||
|
WAKAAMA = build_wakaama/lightclient
|
||||||
|
PAHO_PYTHON = paho/mqtt/client.py
|
||||||
|
|
||||||
|
all: clean_result $(EMQ) $(WAKAAMA) $(PAHO_PYTHON) start_broker clean_result case1 case2 case3 stop_broker
|
||||||
|
@echo " "
|
||||||
|
@echo " test complete"
|
||||||
|
@echo " "
|
||||||
|
|
||||||
|
clean_result:
|
||||||
|
-rm -f case*.txt
|
||||||
|
|
||||||
|
start_broker:
|
||||||
|
-rm -f $(EMQX_DIR)/_rel/emqx/log/*
|
||||||
|
-$(EMQX_DIR)/_rel/emqx/bin/emqx stop
|
||||||
|
sleep 3
|
||||||
|
$(EMQX_DIR)/_rel/emqx/bin/emqx start
|
||||||
|
sleep 1
|
||||||
|
$(EMQX_DIR)/_rel/emqx/bin/emqx_ctl plugins load emqx_lwm2m
|
||||||
|
|
||||||
|
|
||||||
|
stop_broker:
|
||||||
|
-$(EMQX_DIR)/_rel/emqx/bin/emqx stop
|
||||||
|
|
||||||
|
|
||||||
|
case1:
|
||||||
|
-build_wakaama/lightclient -4 -n jXtestlwm2m &
|
||||||
|
python case1.py
|
||||||
|
-ps aux|grep lightclient|awk '{print $$2}'|xargs kill -2
|
||||||
|
|
||||||
|
case2:
|
||||||
|
-build_wakaama/lightclient -4 -n jXtestlwm2m &
|
||||||
|
python case2.py
|
||||||
|
-ps aux|grep lightclient|awk '{print $$2}'|xargs kill -2
|
||||||
|
|
||||||
|
case3:
|
||||||
|
-build_wakaama/lightclient -4 -n jXtestlwm2m &
|
||||||
|
python case3.py
|
||||||
|
-ps aux|grep lightclient|awk '{print $$2}'|xargs kill -2
|
||||||
|
|
||||||
|
|
||||||
|
$(EMQ):
|
||||||
|
git clone https://github.com/emqx/emqx-enterprise-rel
|
||||||
|
git clone https://github.com/emqx/emqx-lwm2m.git
|
||||||
|
@echo "update emqx-lwm2m with this development code"
|
||||||
|
mv emqx-lwm2m emqx_lwm2m
|
||||||
|
-rm -rf emqx_lwm2m/etc
|
||||||
|
-rm -rf emqx_lwm2m/include
|
||||||
|
-rm -rf emqx_lwm2m/priv
|
||||||
|
-rm -rf emqx_lwm2m/src
|
||||||
|
-rm -rf emqx_lwm2m/Makefile
|
||||||
|
-rm -rf emqx_lwm2m/erlang.mk
|
||||||
|
cp -rf ../etc emqx_lwm2m/
|
||||||
|
cp -rf ../include emqx_lwm2m/
|
||||||
|
cp -rf ../priv emqx_lwm2m/
|
||||||
|
cp -rf ../src emqx_lwm2m/
|
||||||
|
cp -rf ../Makefile emqx_lwm2m/Makefile
|
||||||
|
cp -rf ../erlang.mk emqx_lwm2m/erlang.mk
|
||||||
|
-mkdir $(EMQX_DIR)/deps
|
||||||
|
mv emqx_lwm2m $(EMQX_DIR)/deps/
|
||||||
|
@echo "start building ..."
|
||||||
|
python insert_lwm2m_plugin.py
|
||||||
|
make -C emqx-rel -f Makefile
|
||||||
|
-cp -rf ../lwm2m_xml $(EMQX_DIR)/_rel/emqx/etc/
|
||||||
|
|
||||||
|
|
||||||
|
w:
|
||||||
|
cd build_wakaama && cmake -DCMAKE_BUILD_TYPE=Debug ../wakaama/examples/lightclient && make
|
||||||
|
|
||||||
|
$(WAKAAMA):
|
||||||
|
git clone https://github.com/eclipse/wakaama
|
||||||
|
-mkdir build_wakaama
|
||||||
|
# replace lightclient's source code, change port from 5683 to 5683, since 5683 is the default port of emqx-lwm2m
|
||||||
|
cp -f object_security.c wakaama/examples/lightclient/object_security.c
|
||||||
|
cd build_wakaama && cmake -DCMAKE_BUILD_TYPE=Debug ../wakaama/examples/lightclient && make
|
||||||
|
|
||||||
|
|
||||||
|
mqtt: $(PAHO_PYTHON)
|
||||||
|
# short for paho python client
|
||||||
|
|
||||||
|
$(PAHO_PYTHON):
|
||||||
|
git clone https://github.com/eclipse/paho.mqtt.python.git
|
||||||
|
mv paho.mqtt.python/src/paho ./
|
||||||
|
rm -rf paho.mqtt.python
|
||||||
|
|
||||||
|
|
||||||
|
r: rebuild_emq
|
||||||
|
# r short for rebuild_emq
|
||||||
|
@echo " rebuild complete "
|
||||||
|
|
||||||
|
|
||||||
|
rebuild_emq:
|
||||||
|
-$(EMQX_DIR)/_rel/emqx/bin/emqx stop
|
||||||
|
-mkdir $(EMQX_DIR)/deps
|
||||||
|
-rm -rf $(EMQX_DIR)/deps/emqx_lwm2m/etc
|
||||||
|
-rm -rf $(EMQX_DIR)/deps/emqx_lwm2m/include
|
||||||
|
-rm -rf $(EMQX_DIR)/deps/emqx_lwm2m/priv
|
||||||
|
-rm -rf $(EMQX_DIR)/deps/emqx_lwm2m/src
|
||||||
|
-rm -rf $(EMQX_DIR)/deps/emqx_lwm2m/Makefile
|
||||||
|
-rm -rf $(EMQX_DIR)/deps/emqx_lwm2m/erlang.mk
|
||||||
|
cp -rf ../etc $(EMQX_DIR)/deps/emqx_lwm2m/
|
||||||
|
cp -rf ../include $(EMQX_DIR)/deps/emqx_lwm2m/
|
||||||
|
cp -rf ../priv $(EMQX_DIR)/deps/emqx_lwm2m/
|
||||||
|
cp -rf ../src $(EMQX_DIR)/deps/emqx_lwm2m/
|
||||||
|
cp -rf ../Makefile $(EMQX_DIR)/deps/emqx_lwm2m/Makefile
|
||||||
|
cp -rf ../erlang.mk $(EMQX_DIR)/deps/emqx_lwm2m/erlang.mk
|
||||||
|
make -C $(EMQX_DIR) -f Makefile
|
||||||
|
|
||||||
|
|
||||||
|
clean: clean_result
|
||||||
|
-rm -f client/*.exe
|
||||||
|
-rm -f client/*.o
|
||||||
|
-rm -rf emqx-rel
|
||||||
|
-rm -rf build_wakaama
|
||||||
|
-rm -rf wakaama
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lazy: clean_result start_broker case1 case2 case3 stop_broker
|
||||||
|
# custom your command here
|
||||||
|
@echo "you are so lazy"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,27 @@
|
||||||
{deps,
|
{deps,
|
||||||
[{lwm2m_coap, {git, "https://github.com/emqx/lwm2m-coap", {tag, "v1.1.1"}}}
|
[{lwm2m_coap, {git, "https://github.com/emqx/lwm2m-coap", {tag, "v1.1.1"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{profiles,
|
||||||
|
[{test,
|
||||||
|
[{deps, [{er_coap_client, {git, "https://github.com/emqx/er_coap_client", {tag, "v1.0"}}},
|
||||||
|
{emqx_ct_helpers, {git, "https://github.com/emqx/emqx-ct-helpers", {tag, "1.2.2"}}},
|
||||||
|
{emqtt, {git, "https://github.com/emqx/emqtt", {tag, "1.2.0"}}}
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
|
{erl_opts, [warn_unused_vars,
|
||||||
|
warn_shadow_vars,
|
||||||
|
warn_unused_import,
|
||||||
|
warn_obsolete_guard,
|
||||||
|
debug_info,
|
||||||
|
{parse_transform}]}.
|
||||||
|
|
||||||
|
{xref_checks, [undefined_function_calls, undefined_functions,
|
||||||
|
locals_not_used, deprecated_function_calls,
|
||||||
|
warnings_as_errors, deprecated_functions]}.
|
||||||
|
{cover_enabled, true}.
|
||||||
|
{cover_opts, [verbose]}.
|
||||||
|
{cover_export_enabled, true}.
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin/*.beam
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_management.d
|
||||||
|
ebin/*
|
||||||
|
data/
|
||||||
|
log/
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
rebar3.crashdump
|
||||||
|
.erlang.mk
|
||||||
|
erlang.mk
|
||||||
|
cover/
|
||||||
|
ct.coverdata
|
||||||
|
eunit.coverdata
|
||||||
|
logs/
|
||||||
|
test/ct.cover.spec
|
||||||
|
*.conf.rendered
|
||||||
|
.rebar3/
|
||||||
|
*.swp
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,52 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## EMQ X Management Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## Max Row Limit
|
||||||
|
management.max_row_limit = 10000
|
||||||
|
|
||||||
|
## Application default secret
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
## management.application.default_secret = public
|
||||||
|
|
||||||
|
## Default Application ID
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
management.default_application.id = admin
|
||||||
|
|
||||||
|
## Default Application Secret
|
||||||
|
##
|
||||||
|
## Value: String
|
||||||
|
management.default_application.secret = public
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## HTTP Listener
|
||||||
|
|
||||||
|
management.listener.http = 8081
|
||||||
|
management.listener.http.acceptors = 2
|
||||||
|
management.listener.http.max_clients = 512
|
||||||
|
management.listener.http.backlog = 512
|
||||||
|
management.listener.http.send_timeout = 15s
|
||||||
|
management.listener.http.send_timeout_close = on
|
||||||
|
management.listener.http.inet6 = false
|
||||||
|
management.listener.http.ipv6_v6only = false
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## HTTPS Listener
|
||||||
|
|
||||||
|
## management.listener.https = 8081
|
||||||
|
## management.listener.https.acceptors = 2
|
||||||
|
## management.listener.https.max_clients = 512
|
||||||
|
## management.listener.https.backlog = 512
|
||||||
|
## management.listener.https.send_timeout = 15s
|
||||||
|
## management.listener.https.send_timeout_close = on
|
||||||
|
## management.listener.https.certfile = etc/certs/cert.pem
|
||||||
|
## management.listener.https.keyfile = etc/certs/key.pem
|
||||||
|
## management.listener.https.cacertfile = etc/certs/cacert.pem
|
||||||
|
## management.listener.https.verify = verify_peer
|
||||||
|
## management.listener.https.tls_versions = tlsv1.2,tlsv1.1,tlsv1
|
||||||
|
## management.listener.https.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA
|
||||||
|
## management.listener.https.fail_if_no_peer_cert = true
|
||||||
|
## management.listener.https.inet6 = false
|
||||||
|
## management.listener.https.ipv6_v6only = false
|
|
@ -1 +1,27 @@
|
||||||
{deps, []}.
|
{deps, []}.
|
||||||
|
|
||||||
|
{profiles,
|
||||||
|
[{test,
|
||||||
|
[{deps,
|
||||||
|
[{emqx_ct_helpers, {git, "https://github.com/emqx/emqx-ct-helpers", {branch, "develop"}}},
|
||||||
|
{emqtt, {git, "https://github.com/emqx/emqtt", {tag, "1.1.1"}}},
|
||||||
|
meck
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
|
{erl_opts, [warn_unused_vars,
|
||||||
|
warn_shadow_vars,
|
||||||
|
warn_unused_import,
|
||||||
|
warn_obsolete_guard,
|
||||||
|
warnings_as_errors,
|
||||||
|
debug_info,
|
||||||
|
{parse_transform}]}.
|
||||||
|
|
||||||
|
{xref_checks, [undefined_function_calls, undefined_functions,
|
||||||
|
locals_not_used, deprecated_function_calls,
|
||||||
|
warnings_as_errors, deprecated_functions]}.
|
||||||
|
{cover_enabled, true}.
|
||||||
|
{cover_opts, [verbose]}.
|
||||||
|
{cover_export_enabled, true}.
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## EMQ X Management Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## Max Row Limit
|
||||||
|
management.max_row_limit = 10000
|
||||||
|
|
||||||
|
## Application default secret
|
||||||
|
#
|
||||||
|
# management.application.default_secret = public
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## HTTP Listener
|
||||||
|
|
||||||
|
management.listener.http = 8080
|
||||||
|
management.listener.http.acceptors = 2
|
||||||
|
management.listener.http.max_clients = 512
|
||||||
|
management.listener.http.backlog = 512
|
||||||
|
management.listener.http.send_timeout = 15s
|
||||||
|
management.listener.http.send_timeout_close = on
|
||||||
|
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## HTTPS Listener
|
||||||
|
|
||||||
|
## management.listener.https = 8081
|
||||||
|
## management.listener.https.acceptors = 2
|
||||||
|
## management.listener.https.max_clients = 512
|
||||||
|
## management.listener.https.backlog = 512
|
||||||
|
## management.listener.https.send_timeout = 15s
|
||||||
|
## management.listener.https.send_timeout_close = on
|
||||||
|
## management.listener.https.certfile = etc/certs/cert.pem
|
||||||
|
## management.listener.https.keyfile = etc/certs/key.pem
|
||||||
|
## management.listener.https.cacertfile = etc/certs/cacert.pem
|
||||||
|
## management.listener.https.verify = verify_peer
|
||||||
|
## management.listener.https.fail_if_no_peer_cert = true
|
|
@ -0,0 +1,24 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## Reloader Plugin
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## Interval of hot code reloading.
|
||||||
|
##
|
||||||
|
## Value: Duration
|
||||||
|
## - h: hour
|
||||||
|
## - m: minute
|
||||||
|
## - s: second
|
||||||
|
##
|
||||||
|
## Examples:
|
||||||
|
## - 2h: 2 hours
|
||||||
|
## - 30m: 30 minutes
|
||||||
|
## - 20s: 20 seconds
|
||||||
|
##
|
||||||
|
## Defaut: 60s
|
||||||
|
reloader.interval = 60s
|
||||||
|
|
||||||
|
## Logfile of reloader.
|
||||||
|
##
|
||||||
|
## Value: File
|
||||||
|
reloader.logfile = reloader.log
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin/
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_passwd.d
|
||||||
|
logs/
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
erlang.mk
|
||||||
|
rebar3.crashdump
|
||||||
|
.erlang.mk/
|
||||||
|
.rebar3/
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -5,3 +5,18 @@
|
||||||
{plugins, [
|
{plugins, [
|
||||||
{pc, {git, "https://github.com/emqx/port_compiler.git", {tag, "v1.11.1"}}}
|
{pc, {git, "https://github.com/emqx/port_compiler.git", {tag, "v1.11.1"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
|
{erl_opts, [warn_unused_vars,
|
||||||
|
warn_shadow_vars,
|
||||||
|
warn_unused_import,
|
||||||
|
warn_obsolete_guard,
|
||||||
|
debug_info,
|
||||||
|
{parse_transform}]}.
|
||||||
|
|
||||||
|
{xref_checks, [undefined_function_calls, undefined_functions,
|
||||||
|
locals_not_used, deprecated_function_calls,
|
||||||
|
warnings_as_errors, deprecated_functions]}.
|
||||||
|
{cover_enabled, true}.
|
||||||
|
{cover_opts, [verbose]}.
|
||||||
|
{cover_export_enabled, true}.
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
data/
|
||||||
|
emqx_plugin_template.d
|
||||||
|
.DS_Store
|
||||||
|
erlang.mk
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
test/ct.cover.spec
|
||||||
|
.rebar3
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
[
|
||||||
|
{emqx_plugin_template, []}
|
||||||
|
].
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
.DS_Store
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
emqx_prometheus.d
|
||||||
|
ct.coverdata
|
||||||
|
logs/
|
||||||
|
data/
|
||||||
|
test/ct.cover.spec
|
||||||
|
cover/
|
||||||
|
erlang.mk
|
||||||
|
eunit.coverdata
|
||||||
|
_build/
|
||||||
|
rebar.lock
|
||||||
|
rebar3.crashdump
|
||||||
|
.rebar3
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,13 @@
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
## emqx_prometheus for EMQ X
|
||||||
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
|
## The Prometheus Push Gateway URL address
|
||||||
|
##
|
||||||
|
## Note: You can comment out this line to disable it
|
||||||
|
prometheus.push.gateway.server = http://127.0.0.1:9091
|
||||||
|
|
||||||
|
## The metrics data push interval (millisecond)
|
||||||
|
##
|
||||||
|
## Default: 15000
|
||||||
|
prometheus.interval = 15000
|
|
@ -1,3 +1,26 @@
|
||||||
{deps,
|
{deps,
|
||||||
[{prometheus, {git, "https://github.com/emqx/prometheus.erl", {tag, "v3.1.1"}}}
|
[{prometheus, {git, "https://github.com/emqx/prometheus.erl", {tag, "v3.1.1"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
|
{erl_opts, [warn_unused_vars,
|
||||||
|
warn_shadow_vars,
|
||||||
|
warn_unused_import,
|
||||||
|
warn_obsolete_guard,
|
||||||
|
debug_info,
|
||||||
|
{parse_transform}]}.
|
||||||
|
|
||||||
|
{xref_checks, [undefined_function_calls, undefined_functions,
|
||||||
|
locals_not_used, deprecated_function_calls,
|
||||||
|
warnings_as_errors, deprecated_functions]}.
|
||||||
|
{cover_enabled, true}.
|
||||||
|
{cover_opts, [verbose]}.
|
||||||
|
{cover_export_enabled, true}.
|
||||||
|
|
||||||
|
{profiles,
|
||||||
|
[{test,
|
||||||
|
[{deps,
|
||||||
|
[{emqx_ct_helper, {git, "https://github.com/emqx/emqx-ct-helpers", {tag, "1.2.2"}}}
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
]}.
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
.eunit
|
||||||
|
deps
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
erl_crash.dump
|
||||||
|
ebin
|
||||||
|
rel/example_project
|
||||||
|
.concrete/DEV_MODE
|
||||||
|
.rebar
|
||||||
|
.erlang.mk/
|
||||||
|
data/
|
||||||
|
emqx_actorcloud_schema_parser.d
|
||||||
|
.DS_Store
|
||||||
|
_build
|
||||||
|
rebar.lock
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,2 @@
|
||||||
|
psk.file.path = {{ platform_etc_dir }}/psk.txt
|
||||||
|
psk.file.delimiter = :
|
|
@ -0,0 +1,2 @@
|
||||||
|
client1:1234
|
||||||
|
client2:abcd
|
|
@ -1 +1,16 @@
|
||||||
{deps, []}.
|
{deps, []}.
|
||||||
|
|
||||||
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
|
{erl_opts, [warn_unused_vars,
|
||||||
|
warn_shadow_vars,
|
||||||
|
warn_unused_import,
|
||||||
|
warn_obsolete_guard,
|
||||||
|
debug_info,
|
||||||
|
{parse_transform}]}.
|
||||||
|
|
||||||
|
{xref_checks, [undefined_function_calls, undefined_functions,
|
||||||
|
locals_not_used, deprecated_function_calls,
|
||||||
|
warnings_as_errors, deprecated_functions]}.
|
||||||
|
{cover_enabled, true}.
|
||||||
|
{cover_opts, [verbose]}.
|
||||||
|
{cover_export_enabled, true}.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue