This repository was archived by the owner on Mar 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdeveloper.html
More file actions
434 lines (303 loc) · 29.7 KB
/
Copy pathdeveloper.html
File metadata and controls
434 lines (303 loc) · 29.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>1. Agent API — Flopsar Documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/hacks.css" type="text/css" />
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Troubleshooting" href="tshooting.html" />
<link rel="prev" title="1. Workstation Installation" href="user.html" />
<script src="_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="index.html">
<img src="_static/flopsar_logo.png" class="logo" alt="Logo"/>
</a>
<div class="version">
2.4
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<p class="caption"><span class="caption-text">Overview</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="overview.html">1. What is Flopsar</a></li>
<li class="toctree-l1"><a class="reference internal" href="overview.html#versioning">2. Versioning</a></li>
<li class="toctree-l1"><a class="reference internal" href="overview.html#releasing">3. Releasing</a></li>
<li class="toctree-l1"><a class="reference internal" href="overview.html#licensing">4. Licensing</a></li>
<li class="toctree-l1"><a class="reference internal" href="overview.html#architectural-fundamentals">5. Architectural Fundamentals</a></li>
<li class="toctree-l1"><a class="reference internal" href="overview.html#supported-platforms-and-requirements">6. Supported Platforms and Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="overview.html#distribution-package">7. Distribution Package</a></li>
<li class="toctree-l1"><a class="reference internal" href="overview.html#release-notes">8. Release Notes</a></li>
</ul>
<p class="caption"><span class="caption-text">Administrator Guide</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="admin.html">1. Installation</a></li>
<li class="toctree-l1"><a class="reference internal" href="admin.html#logging">2. Logging</a></li>
<li class="toctree-l1"><a class="reference internal" href="admin.html#id2">3. Agent</a></li>
<li class="toctree-l1"><a class="reference internal" href="manager.html">4. Manager</a></li>
<li class="toctree-l1"><a class="reference internal" href="database.html">5. Database</a></li>
</ul>
<p class="caption"><span class="caption-text">User Guide</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="user.html">1. Workstation Installation</a></li>
<li class="toctree-l1"><a class="reference internal" href="user.html#accessing-flopsar-environment">2. Accessing Flopsar Environment</a></li>
<li class="toctree-l1"><a class="reference internal" href="user.html#start-page">3. Start Page</a></li>
<li class="toctree-l1"><a class="reference internal" href="user.html#settings">4. Settings</a></li>
<li class="toctree-l1"><a class="reference internal" href="user.html#configurations">5. Configurations</a></li>
<li class="toctree-l1"><a class="reference internal" href="user.html#galaxies">6. Galaxies</a></li>
<li class="toctree-l1"><a class="reference internal" href="user.html#agents">7. Agents</a></li>
<li class="toctree-l1"><a class="reference internal" href="user.html#queries">8. Queries</a></li>
</ul>
<p class="caption"><span class="caption-text">Developer Guide</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">1. Agent API</a></li>
<li class="toctree-l1"><a class="reference internal" href="#agent-formatters">2. Agent Formatters</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#standard">2.1. Standard</a></li>
<li class="toctree-l2"><a class="reference internal" href="#custom">2.2. Custom</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="#database-api">3. Database API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#java">3.1. Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="#c-c">3.2. C/C++</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="#plugins">4. Plugins</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#plugin-authentication">4.1. Plugin: Authentication</a></li>
</ul>
</li>
</ul>
<p class="caption"><span class="caption-text">Miscellaneous</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="tshooting.html">Troubleshooting</a></li>
<li class="toctree-l1"><a class="reference internal" href="demo.html">Demo</a></li>
<li class="toctree-l1"><a class="reference internal" href="contrib.html">Third-party Components</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Flopsar</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html">Docs</a> »</li>
<li>1. Agent API</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="agent-api">
<span id="id1"></span><h1>1. Agent API<a class="headerlink" href="#agent-api" title="Permalink to this headline">¶</a></h1>
<p>If you want to provide your own, non-JVM, data and store them in the Flopsar environment, you can do it using the agent API. This functionality is embedded in the Flopsar Agent. In order to make use of the API, you must add <code class="file docutils literal notranslate"><span class="pre">flopsar-agent-2.4.jar</span></code> as a dependency to your project. The API contains a single class <span class="code">com.flopsar.agent.api.Agent</span> with the following methods:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">static</span> <span class="n">Agent</span> <span class="nf">createConnection</span><span class="o">(</span><span class="n">String</span> <span class="n">flopsarId</span><span class="o">,</span><span class="n">String</span> <span class="n">fsmHost</span><span class="o">,</span>
<span class="kt">int</span> <span class="n">fsmPort</span><span class="o">,</span><span class="kt">long</span> <span class="n">outboundQueueSize</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">setupLogger</span><span class="o">(</span><span class="n">String</span> <span class="n">loggerDirectory</span><span class="o">,</span><span class="kt">int</span> <span class="n">logSize</span><span class="o">,</span>
<span class="n">AbstractLoggerLevel</span> <span class="n">level</span><span class="o">);</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isConnected</span><span class="o">();</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kt">void</span> <span class="nf">close</span><span class="o">();</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kt">void</span> <span class="nf">submitAsKV</span><span class="o">(</span><span class="n">String</span> <span class="n">key</span><span class="o">,</span><span class="kt">long</span> <span class="n">timestamp</span><span class="o">,</span><span class="kt">long</span> <span class="n">value</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="n">String</span> <span class="nf">buildKey</span><span class="o">(</span><span class="n">String</span><span class="o">...</span> <span class="n">element</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kt">void</span> <span class="nf">submitAsStack</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">,</span><span class="n">String</span> <span class="n">signature</span><span class="o">,</span><span class="kt">long</span> <span class="n">timestamp</span><span class="o">,</span>
<span class="kt">int</span> <span class="n">duration</span><span class="o">,</span><span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">parameters</span><span class="o">);</span>
</pre></div>
</div>
<p>The first method is used to create a new <span class="code">Agent</span> object. When you call this method, a new connection to your manager is established asynchronously. That means the method returns immediately, so you must make sure the connection is established by calling the <span class="code">isConnected</span> method.</p>
<p>There is a simple example below:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="cm">/* First you must setup a logger */</span>
<span class="n">Agent</span><span class="o">.</span><span class="na">setupLogger</span><span class="o">(</span><span class="s">"/some/directory"</span><span class="o">,</span><span class="mi">10</span><span class="o">,</span><span class="n">AbstractLoggerLevel</span><span class="o">.</span><span class="na">INFO</span><span class="o">);</span>
<span class="cm">/* Next, connect to the manager */</span>
<span class="n">Agent</span> <span class="n">a</span> <span class="o">=</span> <span class="n">Agent</span><span class="o">.</span><span class="na">createConnection</span><span class="o">(</span><span class="s">"myAgentId"</span><span class="o">,</span><span class="s">"192.168.0.10"</span><span class="o">,</span><span class="mi">9000</span><span class="o">,</span><span class="mi">100</span><span class="o">);</span>
<span class="cm">/* Wait, until the connection is established */</span>
<span class="k">while</span> <span class="o">(</span><span class="n">a</span><span class="o">.</span><span class="na">isConnected</span><span class="o">()){</span>
<span class="n">Thread</span><span class="o">.</span><span class="na">sleep</span><span class="o">(</span><span class="mi">1000</span><span class="o">);</span>
<span class="o">}</span>
<span class="cm">/* Now, you can produce your data and send it to the manager */</span>
</pre></div>
</div>
</div>
<div class="section" id="agent-formatters">
<h1>2. Agent Formatters<a class="headerlink" href="#agent-formatters" title="Permalink to this headline">¶</a></h1>
<p>The formatters enable to extend agent functionalities. Unlike other vendors, we provide a mechanism which you can use to extend your application diagnosis and trace your data flow. It makes Flopsar an open tool, that can be extended. There are two types of formatters, which can be used: <em>standard</em> and <em>custom</em>.</p>
<div class="section" id="standard">
<h2>2.1. Standard<a class="headerlink" href="#standard" title="Permalink to this headline">¶</a></h2>
<p>The <em>standard</em> formatter is embedded in <span class="flp">agent</span>. This formatter will execute the following method on each argument it gets:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">static</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">valueOf</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Object</span><span class="o">);</span>
</pre></div>
</div>
<p>and return a result in a form of concatenated pairs of parameter identifier and the corresponding <span class="code">valueOf</span> function result. The following parameters are returned (in order of appearance):</p>
<dl class="docutils">
<dt><span class="code">THIS</span></dt>
<dd>If the instrumented method is static, this parameter is <span class="code">null</span>, otherwise a class instance the method is executed on.</dd>
<dt><span class="code">ARGS</span></dt>
<dd>List of all arguments of the instrumented method.</dd>
<dt><span class="code">RET</span></dt>
<dd>Only if the instrumented method does not return <span class="code">void</span> and the instrumentation is performed at the method exit.</dd>
</dl>
</div>
<div class="section" id="custom">
<h2>2.2. Custom<a class="headerlink" href="#custom" title="Permalink to this headline">¶</a></h2>
<p>If you are not satisfied with the standard formatter and you want to extract some additional information (or make some preprocessing) you must implement your own, <em>custom</em> formatter.</p>
<p>Suppose, you have some method</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="n">FooBar</span> <span class="nf">foo</span><span class="o">(</span><span class="n">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">.</span><span class="na">Object1</span><span class="o">,</span> <span class="n">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">.</span><span class="na">Object2</span><span class="o">,</span> <span class="o">...);</span>
</pre></div>
</div>
<p>and you are interested in some additional information extracted from the first and second arguments. Your formatter implementation can look like the one below:</p>
<div class="highlight-java notranslate"><div class="highlight"><pre><span></span><span class="kd">public</span> <span class="kd">static</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">myFormatter</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Object</span><span class="o">[]</span> <span class="n">args</span><span class="o">){</span>
<span class="kd">final</span> <span class="kt">char</span> <span class="n">SEPARATOR</span> <span class="o">=</span> <span class="mh">0x1E</span><span class="o">;</span>
<span class="k">try</span> <span class="o">{</span>
<span class="n">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">.</span><span class="na">Object0</span> <span class="n">_this</span> <span class="o">=</span> <span class="o">(</span><span class="n">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">.</span><span class="na">Object0</span><span class="o">)</span><span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span>
<span class="n">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">.</span><span class="na">Object1</span> <span class="n">obj1</span> <span class="o">=</span> <span class="o">(</span><span class="n">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">.</span><span class="na">Object1</span><span class="o">)</span><span class="n">args</span><span class="o">[</span><span class="mi">1</span><span class="o">];</span>
<span class="n">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">.</span><span class="na">Object2</span> <span class="n">obj2</span> <span class="o">=</span> <span class="o">(</span><span class="n">foo</span><span class="o">.</span><span class="na">bar</span><span class="o">.</span><span class="na">Object2</span><span class="o">)</span><span class="n">args</span><span class="o">[</span><span class="mi">2</span><span class="o">];</span>
<span class="cm">/*</span>
<span class="cm"> implement your logic here</span>
<span class="cm"> to produce string output.</span>
<span class="cm"> */</span>
<span class="n">String</span> <span class="n">output1</span> <span class="o">=</span> <span class="n">some_logic1</span><span class="o">(</span><span class="n">obj1</span><span class="o">);</span>
<span class="n">String</span> <span class="n">output2</span> <span class="o">=</span> <span class="n">some_logic2</span><span class="o">(</span><span class="n">obj2</span><span class="o">);</span>
<span class="k">return</span> <span class="s">"Object1"</span><span class="o">+</span><span class="n">SEPARATOR</span><span class="o">+</span><span class="n">output1</span><span class="o">+</span><span class="n">SEPARATOR</span><span class="o">+</span><span class="s">"Object2"</span><span class="o">+</span><span class="n">SEPARATOR</span><span class="o">+</span><span class="n">output2</span><span class="o">;</span>
<span class="o">}</span> <span class="k">catch</span><span class="o">(</span><span class="n">Throwable</span> <span class="n">ex</span><span class="o">){</span>
<span class="k">return</span> <span class="s">"Error"</span><span class="o">+</span><span class="n">SEPARATOR</span><span class="o">+</span><span class="n">ex</span><span class="o">.</span><span class="na">getMessage</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
</div>
<p>You can give any name to the formatter method, but the signature of the method must be preserved. Otherwise, it will not work. The argument of the formatter is an array of the instrumented method arguments delivered to your formatter. These are your original application objects, not clones. When you set up the configuration correctly, <span class="flp">agent</span> will inject your formatter code into the instrumented methods during the instrumentation. It can be injected in one of the two places, i.e. at the beginning or the end of the method. Note, your formatter code is executed inside your instrumented method, so make sure your formatter code generates minimal overhead.</p>
<div class="admonition important">
<p class="first admonition-title">Important</p>
<p class="last">Please, use <span class="code">U+001E</span> as a separator in your formatters. Otherwise, the result will not be formatted properly in the Workstation.</p>
</div>
<p>Please, use <span class="code">try-catch</span> block to protect your application from any errors you can make in your formatter implementation. Otherwise, any errors inside the formatter can interfere your application processing.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Design and implement formatters with performance in mind. If your formatters code performs poorly, obviously the instrumented methods will perform poorly as well.</p>
</div>
<p>Your result should always consist of pairs of key and value. <span class="code">U+001E</span> separates each entry in the result, that means you should always have an odd number of separators. The resulting string size cannot be greater than 8192 B, otherwise it will be truncated.</p>
<p>There are some tips, you should take into account when writing formatters:</p>
<ul class="simple">
<li>do not modify arguments delivered to your formatter since they are your genuine application objects. Make sure that whatever you do with them will not cause any problem to your application flow.</li>
<li>try not to use reflections, unless there is no other way.</li>
<li>try not to create too many new objects, otherwise you risk increased GC overhead.</li>
<li>deploy your formatter classes into separate jar files. This can save you a lot of trouble when dealing with class loading issues.</li>
</ul>
<div class="admonition important">
<p class="first admonition-title">Important</p>
<p class="last">No formatter implementation is supported by Flopsar Technology.</p>
</div>
</div>
</div>
<div class="section" id="database-api">
<h1>3. Database API<a class="headerlink" href="#database-api" title="Permalink to this headline">¶</a></h1>
<p>Flopsar provides API, which you can use to access your collected data.
<span class="flp">fdbc</span> enables only local access to the database.</p>
<div class="section" id="java">
<h2>3.1. Java<a class="headerlink" href="#java" title="Permalink to this headline">¶</a></h2>
<p>For Java API, please refer to <a class="reference external" href="http://docs.flopsar.com/fdbc/index.html">http://docs.flopsar.com/fdbc/index.html</a></p>
</div>
<div class="section" id="c-c">
<h2>3.2. C/C++<a class="headerlink" href="#c-c" title="Permalink to this headline">¶</a></h2>
<p>For C/C++ API, please refer to an fdbc(3) man page.</p>
</div>
</div>
<div class="section" id="plugins">
<span id="id2"></span><h1>4. Plugins<a class="headerlink" href="#plugins" title="Permalink to this headline">¶</a></h1>
<p>Flopsar provides a few functionalities implemented as plugins. These implementations can be easily replaced with user defined implementations. In this version of Flopsar only <span class="flp">manager</span> supports plugins. There is one plugin currently available: <em>authentication</em> and it can be replaced.</p>
<p>Flopsar provides a C API for writing custom implementations of plugins. In order to write a plugin, you need to include in your project the main header <code class="file docutils literal notranslate"><span class="pre">fs2plugin_api.h</span></code> file, which can be found in <code class="file docutils literal notranslate"><span class="pre">/usr/include/flopsar/</span></code> directory. This file contains prototypes of functions to implement. The function below is the most important one and must be implemented. This function is called only once when the application loads the plugin.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span> <span class="nf">init_plugin</span><span class="p">(</span><span class="k">struct</span> <span class="n">plugin_fs2</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">home_dir</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">plugins_conf_dir</span><span class="p">);</span>
</pre></div>
</div>
<p>When you call the function above you will be provided with three arguments. The <span class="code">p</span> argument is a structure representing your plugin. You should keep it, since it is required when you register your plugin hooks. The <span class="code">home_dir</span> argument is a path to your <span class="flp">manager</span> environment directory. The last argument <span class="code">plugins_conf_dir</span> is a path to your <span class="flp">manager</span> configuration directory. This can be used to add any additonal configuration to your plugin (see ref{plg-ntfy} as an example).</p>
<div class="admonition important">
<p class="first admonition-title">Important</p>
<p class="last">Do not change the name of the function above. It must stay <span class="code">init_plugin</span>, otherwise a plugin will not be loaded.</p>
</div>
<p>Implement your own plugin initialization and register your functions to the application within this function.</p>
<p>There is an optional function to implement:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span> <span class="nf">int</span> <span class="p">(</span><span class="o">*</span><span class="n">fs2_plugin_test</span><span class="p">)(</span><span class="kt">void</span><span class="p">);</span>
</pre></div>
</div>
<p>which can be registered by executing the function below:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="nf">fs2_register_test_hook</span><span class="p">(</span><span class="k">struct</span> <span class="n">plugin_fs2</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span><span class="n">fs2_plugin_test</span> <span class="n">hook</span><span class="p">);</span>
</pre></div>
</div>
<p>This is a test function, which can be used to implement some test that will help you to check if your plugin work as expected in runtime. If the test succeeds the function should return <span class="code">0</span>, otherwise <span class="code">-1</span>. In order to trigger the test you must execute the following command:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ fs2mgr set --plugins-test <manager_home>
</pre></div>
</div>
<p>This command will execute all the registered plugins test hooks.</p>
<div class="section" id="plugin-authentication">
<span id="plugins-auth"></span><h2>4.1. Plugin: Authentication<a class="headerlink" href="#plugin-authentication" title="Permalink to this headline">¶</a></h2>
<p>If you want to use your own authentication system, you must implement a plugin in order to be able to authenticate your users against this system. In order to write a custom authentication plugin, you must include an additional header <code class="file docutils literal notranslate"><span class="pre">fs2plugin_api_auth.h</span></code> file. All you have to do is to implement the function below:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span> <span class="nf">int</span> <span class="p">(</span><span class="o">*</span><span class="n">fs2_user_auth</span><span class="p">)(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">username</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">password</span><span class="p">);</span>
</pre></div>
</div>
<p>and then register it by means of the function</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="nf">fs2_register_user_auth_hook</span><span class="p">(</span><span class="k">struct</span> <span class="n">plugin_fs2</span> <span class="o">*</span><span class="n">p</span><span class="p">,</span> <span class="n">fs2_user_auth</span> <span class="n">hook</span><span class="p">);</span>
</pre></div>
</div>
<p>in the <span class="code">init_plugin</span> function. The <span class="code">fs2_user_auth</span> takes two arguments: <span class="code">username</span> and <span class="code">password</span>. It should return <span class="code">0</span> if the credentials are valid or <span class="code">-1</span> otherwise.</p>
<p>If your implementation is done, compile the code to a library and put it into the <code class="file docutils literal notranslate"><span class="pre">FLOPSAR_HOME/lib</span></code> directory. You must also update the manager configuration file and replace the <span class="opt">plugins</span> option value <span class="opt">libfs2plg_authbasic.so</span> with the full name of your library.</p>
</div>
</div>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="tshooting.html" class="btn btn-neutral float-right" title="Troubleshooting" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="user.html" class="btn btn-neutral" title="1. Workstation Installation" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
© Copyright 2018, Flopsar Technology Sp. z o.o..
</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'./',
VERSION:'2.4',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: false,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>