Skip to content

Commit 5ffd3bb

Browse files
committed
Add new launch_darkly module
This module implements support for the "Launch Darkly" feature management cloud. The module provide the conectivity to the cloud and the ability to query for feature flags. The development of this module was sponsored by Five9 https://www.five9.com/
1 parent b8bbf14 commit 5ffd3bb

File tree

8 files changed

+719
-1
lines changed

8 files changed

+719
-1
lines changed

Makefile.conf.template

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#identity= Adds support for SIP Identity (see RFC 4474). | SSL library, typically libssl
2929
#jabber= Integrates XODE XML parser for parsing Jabber messages | Expat library.
3030
#json= Introduces a new type of variable that provides both serialization and de-serialization from JSON format. | JSON library, libjson
31+
#launch_darkly= Implements an interface to the Launch Darkly feature management cloud
3132
#ldap= Implements an LDAP search interface for OpenSIPS | OpenLDAP library & development files, typically libldap and libldap-dev
3233
#lua= Easily implement your own OpenSIPS extensions in Lua | liblua5.1-0-dev, libmemcache-dev and libmysqlclient-dev
3334
#httpd= Provides an HTTP transport layer implementation for OpenSIPS. | libmicrohttpd
@@ -67,7 +68,7 @@
6768
#xmpp= Gateway between OpenSIPS and a jabber server. It enables the exchange of IMs between SIP clients and XMPP(jabber) clients. | parsing/building XML files, typically libexpat1-devel
6869
#uuid= UUID generator | uuid-dev
6970

70-
exclude_modules?= aaa_diameter aaa_radius auth_jwt b2b_logic_xml cachedb_cassandra cachedb_couchbase cachedb_memcached cachedb_mongodb cachedb_redis carrierroute cgrates compression cpl_c db_berkeley db_http db_mysql db_oracle db_perlvdb db_postgres db_sqlite db_unixodbc dialplan emergency event_rabbitmq event_kafka h350 httpd identity jabber json ldap lua mi_xmlrpc_ng mmgeoip osp perl pi_http presence presence_dialoginfo presence_mwi presence_xml presence_dfks proto_sctp proto_tls proto_wss pua pua_bla pua_dialoginfo pua_mi pua_usrloc pua_xmpp python regex rabbitmq rabbitmq_consumer rest_client rls siprec sngtc snmpstats stir_shaken tls_mgm tls_openssl tls_wolfssl uuid xcap xcap_client xml xmpp
71+
exclude_modules?= aaa_diameter aaa_radius auth_jwt b2b_logic_xml cachedb_cassandra cachedb_couchbase cachedb_memcached cachedb_mongodb cachedb_redis carrierroute cgrates compression cpl_c db_berkeley db_http db_mysql db_oracle db_perlvdb db_postgres db_sqlite db_unixodbc dialplan emergency event_rabbitmq event_kafka h350 httpd identity jabber json launch_darkly ldap lua mi_xmlrpc_ng mmgeoip osp perl pi_http presence presence_dialoginfo presence_mwi presence_xml presence_dfks proto_sctp proto_tls proto_wss pua pua_bla pua_dialoginfo pua_mi pua_usrloc pua_xmpp python regex rabbitmq rabbitmq_consumer rest_client rls siprec sngtc snmpstats stir_shaken tls_mgm tls_openssl tls_wolfssl uuid xcap xcap_client xml xmpp
7172

7273
include_modules?=
7374

modules/launch_darkly/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# WARNING: do not run this directly, it should be run by the master Makefile
2+
3+
include ../../Makefile.defs
4+
auto_gen=
5+
NAME=launch_darkly.so
6+
7+
8+
DEFS+=-I$(LOCALBASE)/include
9+
LIBS+=-L$(LOCALBASE)/lib -l ldserverapi -l curl -l pthread -l m -l pcre
10+
11+
include ../../Makefile.modules
12+

modules/launch_darkly/doc/contributors.xml

Whitespace-only changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding='UTF-8'?>
2+
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3+
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
4+
5+
6+
<!ENTITY admin SYSTEM "launch_darkly_admin.xml">
7+
<!ENTITY contrib SYSTEM "contributors.xml">
8+
9+
<!-- Include general documentation entities -->
10+
<!ENTITY % docentities SYSTEM "../../../doc/entities.xml">
11+
%docentities;
12+
13+
]>
14+
15+
<book>
16+
<bookinfo>
17+
<title>launch_darkly Module</title>
18+
<productname class="trade">&osipsname;</productname>
19+
</bookinfo>
20+
<toc></toc>
21+
22+
&admin;
23+
&contrib;
24+
25+
&docCopyrights;
26+
<para>&copyright; 2023 Five9 Inc.</para>
27+
</book>
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
<!-- Module User's Guide -->
2+
3+
<chapter>
4+
5+
<title>&adminguide;</title>
6+
7+
<section id="overview" xreflabel="Overview">
8+
<title>Overview</title>
9+
<para>
10+
This module implements support for the
11+
<ulink url="https://launchdarkly.com/">Launch Darkly</ulink> feature
12+
management cloud. The module provide the conectivity to the cloud and
13+
the ability to query for feature flags.
14+
</para>
15+
<para>
16+
OpenSIPS uses the <ulink url="https://launchdarkly.com/features/sdk/">server side C/C++ SDK</ulink> provided by Launch Darkly.
17+
</para>
18+
</section>
19+
20+
<section id="dependencies" xreflabel="Dependencies">
21+
<title>Dependencies</title>
22+
<section>
23+
<title>&osips; Modules</title>
24+
<para>
25+
The following modules must be loaded before this module:
26+
<itemizedlist>
27+
<listitem>
28+
<para>
29+
<emphasis>none</emphasis>.
30+
</para>
31+
</listitem>
32+
</itemizedlist>
33+
</para>
34+
</section>
35+
<section>
36+
<title>External Libraries or Applications</title>
37+
<para>
38+
The following libraries or applications must be installed before
39+
running &osips; with this module loaded:
40+
<itemizedlist>
41+
<listitem>
42+
<para>
43+
<emphasis>ldserverapi</emphasis>
44+
</para>
45+
</listitem>
46+
</itemizedlist>
47+
</para>
48+
<para>
49+
<emphasis>ldserverapi</emphasis> must be compiled and installed
50+
from the official
51+
<ulink url="https://github.com/launchdarkly/c-server-sdk">GITHUB repository </ulink>.
52+
</para>
53+
<para>
54+
The instructions for a quick installations of the library (note that it has to be compiled as shared lib in order to be compatible with the OpenSIPS modules):
55+
</para>
56+
<programlisting format="linespecific">
57+
...
58+
$ git clone https://github.com/launchdarkly/c-server-sdk.git
59+
$ cd c-server-sdk
60+
$ cmake -DBUILD_SHARED_LIBS=On -DBUILD_TESTING=OFF .
61+
$ sudo make install
62+
...
63+
</programlisting>
64+
</section>
65+
</section>
66+
67+
<section id="exported_parameters" xreflabel="Exported Parameters">
68+
<title>Exported Parameters</title>
69+
70+
<section id="param_sdk_key" xreflabel="sdk_key">
71+
<title><varname>sdk_key</varname> (string)</title>
72+
<para>
73+
The LaunchDarkly SDK key used to connect to the service. This
74+
is a mandatory parameter.
75+
</para>
76+
<example>
77+
<title>Set <varname>sdk_key</varname> parameter</title>
78+
<programlisting format="linespecific">
79+
...
80+
modparam("launch_darkly", "sdk_key", "sdk-12345678-abcd-12ab-1234-0123456789abc")
81+
...
82+
</programlisting>
83+
</example>
84+
</section>
85+
86+
<section id="param_ld_log_level" xreflabel="ld_log_level">
87+
<title><varname>ld_log_level</varname> (string)</title>
88+
<para>
89+
The LaunchDarkly specific log level to be used by the LD SDK/libray to
90+
log its internal messages. Note that these log produced by the LD
91+
library (according to this ld_log_level) will be further subject to
92+
filtering according to the overall OpenSIPS log_level.
93+
</para>
94+
<para>
95+
Accepted values are
96+
<emphasis>LD_LOG_FATAL</emphasis>,
97+
<emphasis>LD_LOG_CRITICAL</emphasis>,
98+
<emphasis>LD_LOG_ERROR</emphasis>,
99+
<emphasis>LD_LOG_WARNING</emphasis>,
100+
<emphasis>LD_LOG_INFO</emphasis>,
101+
<emphasis>LD_LOG_DEBUG</emphasis>,
102+
<emphasis>LD_LOG_TRACE</emphasis>.
103+
</para>
104+
<para>
105+
If not set or set to an unsupported value, the
106+
<emphasis>LD_LOG_WARNING</emphasis> level will be used by default.
107+
</para>
108+
<example>
109+
<title>Set <varname>log_level</varname> parameter</title>
110+
<programlisting format="linespecific">
111+
...
112+
modparam("launch_darkly", "ld_log_level", "LD_LOG_CRITICAL")
113+
...
114+
</programlisting>
115+
</example>
116+
</section>
117+
118+
<section id="param_connect_wait" xreflabel="connect_wait">
119+
<title><varname>connect_wait</varname> (integer)</title>
120+
<para>
121+
The time to wait (in miliseconds) when connecting to the LD service.
122+
An initial failure in connecting to the LD service may be addressed
123+
by increasing this wait value.
124+
</para>
125+
<para>
126+
The default value is 500 miliseconds.
127+
</para>
128+
<example>
129+
<title>Set <varname>connect_wait</varname> parameter</title>
130+
<programlisting format="linespecific">
131+
...
132+
modparam("launch_darkly", "connect_wait", 100)
133+
...
134+
</programlisting>
135+
</example>
136+
</section>
137+
138+
<section id="param_re_init_interval" xreflabel="re_init_interval">
139+
<title><varname>re_init_interval</varname> (integer)</title>
140+
<para>
141+
The minimum time interval (in seconds) to try again to init
142+
the LD client in the situation when the module was not able to init
143+
the LC connection at startup. In case of such failure, the module will
144+
automatically re-try to init its LD client on-demand, whnever the
145+
feature flag is checked from script, but not sooner than
146+
`re_init_interval`. Note: if there are no flag checkings to be
147+
performed, the re-init may be attempted longer than `re_init_interval`.
148+
</para>
149+
<para>
150+
The default value is 10 seconds.
151+
</para>
152+
<example>
153+
<title>Set <varname>re_init_interval</varname> parameter</title>
154+
<programlisting format="linespecific">
155+
...
156+
modparam("launch_darkly", "re_init_interval", 30)
157+
...
158+
</programlisting>
159+
</example>
160+
</section>
161+
162+
163+
</section>
164+
165+
<section id="exported_functions" xreflabel="exported_functions">
166+
<title>Exported Functions</title>
167+
<section id="func_ld_feature_enabled" xreflabel="ld_feature_enabled()">
168+
<title>
169+
<function moreinfo="none">ld_feature_enabled( flag, user, [user_extra], [fallback])</function>
170+
</title>
171+
<para>
172+
Function to evaluate a LaunchDarkly boolean feature flag
173+
</para>
174+
<para>
175+
Returns <emphasis>1</emphasis> if the flag was found TRUE
176+
or <emphasis>-1</emphasis> otherwise.
177+
</para>
178+
<para>
179+
In case of error, the fallback (TRUE or FALSE) value will be
180+
returned In such cases, a "fallback" TRUE is returned as 2 and a
181+
fallback FALSE as -2, so you can may a difference between a real
182+
TRUE (returned by the LD service) and a fallback TRUE due to an
183+
error.
184+
</para>
185+
<para>
186+
This function can be used from any route.
187+
</para>
188+
<para>
189+
The function has the following parameters:
190+
</para>
191+
<itemizedlist>
192+
<listitem>
193+
<para>
194+
<emphasis>flag</emphasis> (string) - the key of the flag
195+
to evaluate. May not be NULL or empty.
196+
</para>
197+
</listitem>
198+
<listitem>
199+
<para>
200+
<emphasis>user</emphasis> (string) - the user to evaluate
201+
the flag against. May not be NULL or empty.
202+
</para>
203+
</listitem>
204+
<listitem>
205+
<para>
206+
<emphasis>user_extra</emphasis> (AVP, optional) - an AVP
207+
holding one or multiple key-value attributes to be
208+
attached to the user. The format of the AVP value is
209+
"key=value".
210+
</para>
211+
</listitem>
212+
<listitem>
213+
<para>
214+
<emphasis>fallback</emphasis> (int, optional) - the value
215+
to be returned on error. By default FALSE will be returned.
216+
</para>
217+
</listitem>
218+
219+
</itemizedlist>
220+
<example>
221+
<title><function>ld_feature_enabled()</function> function usage</title>
222+
<programlisting format="linespecific">
223+
...
224+
$avp(extra) = "domainId=123456";
225+
if (ld_feature_enabled("my-flag","opensips", $avp(extra), false))
226+
xlog("-------TRUE\n");
227+
else
228+
xlog("-------FALSE\n");
229+
...
230+
</programlisting>
231+
</example>
232+
</section>
233+
</section>
234+
235+
</chapter>

0 commit comments

Comments
 (0)