update markdown documentation
[src/app-framework-binder.git] / docs / afb-migration-v1-to-v2.md
1 Migration from binding V1 to binding V2
2 =======================================
3
4 The ***binding*** interface evolved from version 1 to version 2
5 for the following reasons:
6
7 - integration of the security requirements within the bindings
8 - simplification of the API (after developer feedbacks)
9 - removal of obscure features, cleanup
10
11 The ***binder*** can run ***bindings*** v1 and/or v2 in any combination.  
12 Thus moving from v1 to v2 is not enforced, there is no real need.
13
14 More, it is possible to write a dual ***binding***:
15
16 - a ***binding*** that implements the version 1 and the version 2.
17
18 However, IT IS HIGHLY RECOMMENDED TO SWITCH TO ONLY VERSION 2:
19
20 - any new development SHOULD start using ***binding*** V2
21 - existing ***bindings*** SHOULD migrate to the version 2
22
23 This guide covers the migration of bindings from version 1 to version 2.
24
25 It also explains some of the rationale taken when migrating from version 1 to version 2.
26
27 In the future, if ***binding*** api evolves to fresh versions (3, 4, ...)
28 it might be necessarily to write bindings implementing more than
29 just one version.  
30 For example:
31
32 - a ***binding*** being v2 AND v3 will resolve the issue of running on older and newer version of AGL. 
33
34 This should always be possible even if more complicated.
35
36 Important things to known when migrating
37 ----------------------------------------
38
39 One of the most important change when migrating from v1 to v2 is
40 that many functions use an hidden *common* variable.  
41 This affects the functions of the following classes:
42
43 - functions of class **daemon**:
44   - functions starting with **afb_daemon_...**
45   - functions for logging: **ERROR**, **WARNING**, **NOTICE**, **INFO**, **DEBUG**
46 - functions of class **service**:
47   - functions starting with **afb_service_...**
48 - callback functions:
49   - the register function (that is removed)
50   - the service init function
51   - the onevent function
52
53 For these functions, the first parameter is now implicit.
54
55 Let takes an example.  
56 For ***binding*** v1 you had to write:
57
58 ```C
59         afb_daemon_broadcast_event(afbitf->daemon, reason, description);
60 ```
61
62 For ***binding*** v2, you simply write:
63
64 ```C
65         afb_daemon_broadcast_event(reason, description);
66 ```
67
68 This simplification is possible because the header files included for the bindings
69 now provide a common variable for storing the **daemon** and **service** data.
70
71 As a programmer, you shouldn't care much about that hidden variable.  
72 It simplifies the job, that's all and that is the reason of the change.
73
74 An other important difference is between the version 1 and the version 2 is
75 on how the ***binding***'s **API** is documented.  
76 The version 2 emphasis the **OpenAPI v3** description of the **API**.  
77 For this reason, to avoid duplication of descriptions, only one description is expected:
78
79 - The **OpenAPI** one.
80
81 Task list for the migration
82 ---------------------------
83
84 This task list is:
85
86 1. Enforce use of binding v2 by setting **AFB_BINDING_VERSION**
87 1. Rewrite the main structure and the list of exported verbs
88 1. Adapt the init and callback functions
89 1. Removes the first parameter of functions of classes **daemon** and **service**
90 1. Consider where to emit logs for requests
91 1. Take care of store/unstore changes
92 1. Consider use of synchronous (sub)call requests
93 1. Optionally, removes explicit struct
94
95 The remaining chapters explain these task with more details.
96
97 Enforce use of binding v2 by setting AFB_BINDING_VERSION
98 --------------------------------------------------------
99
100 By defining **AFB_BINDING_VERSION** to **2** you switch to version 2.  
101 This is done as below.
102
103 ```C
104 #define AFB_BINDING_VERSION 2
105 #include <afb/afb-binding.h>
106 ```
107
108 After that you will get many errors when compiling.
109
110 Rewrite the main structures and the list of exported verbs
111 ---------------------------------------------------------
112
113 The structures describing the ***binding** changed from version 1 to version 2.
114
115 The structure for describing verbs changed to include security
116 requirements.
117
118 In version 1 it was:
119
120 ```C
121 struct afb_verb_desc_v1
122 {
123        const char *name;                       /* name of the verb */
124        enum afb_session_flags_v1 session;      /* authorization and session requirements of the verb */
125        void (*callback)(struct afb_req req);   /* callback function implementing the verb */
126        const char *info;                       /* textual description of the verb */
127 };
128 ```
129
130 In version 2 it becomes:
131
132 ```C
133 struct afb_verb_v2
134 {
135         const char *verb;                       /* name of the verb */
136         void (*callback)(struct afb_req req);   /* callback function implementing the verb */
137         const struct afb_auth *auth;            /* required authorization */
138         uint32_t session;                       /* authorization and session requirements of the verb */
139 };
140
141 ```
142
143 The migration of instances of that structure requires the following actions:
144
145 - rename field **name** to **verb**
146 - remove field **info**
147 - adapt field **session** if needed
148 - set field **auth** to NULL
149
150 Example:
151
152 ```C
153  { .name= "new",   .session= AFB_SESSION_NONE, .callback= new,   .info= "Starts a new game" }
154 ```
155
156 Becomes
157
158 ```C
159  { .verb = "new",   .session = AFB_SESSION_NONE, .callback = new, .auth = NULL }
160 ```
161
162 The field **auth** can be set to a value describing the requested
163 authorization.
164
165 The main describing structure also changed.
166
167 In version 1 it was:
168
169 ```C
170 struct afb_binding_desc_v1
171 {
172        const char *info;                       /* textual information about the binding */
173        const char *prefix;                     /* required prefix name for the binding */
174        const struct afb_verb_desc_v1 *verbs;   /* array of descriptions of verbs terminated by a NULL name */
175 };
176 ```
177
178 In version 2 it becomes:
179
180 ```C
181 struct afb_binding_v2
182 {
183         const char *api;                        /* api name for the binding */
184         const char *specification;              /* textual specification of the binding */
185         const struct afb_verb_v2 *verbs;        /* array of descriptions of verbs terminated by a NULL name */
186         int (*preinit)();                       /* callback at load of the binding */
187         int (*init)();                          /* callback for starting the service */
188         void (*onevent)(const char *event, struct json_object *object); /* callback for handling events */
189         unsigned noconcurrency: 1;              /* avoids concurrent requests to verbs */
190 };
191 ```
192
193 The migration of instances of that structure requires the following actions:
194
195 - declare, explore, name the structure as ```const struct afb_binding_v2 afbBindingV2```
196 - rename the field **prefix** to **api**
197 - remove the field **info**
198 - setup the fields **preinit**, **init**, **onevent** according to the next section
199 - set the field **noconcurrency** to the right value:
200   - to 1 if you want to avoid concurrent calls to verbs.
201   - to 0 if you allow concurrent calls to verbs.
202
203 Example:
204
205 ```C
206 static const struct afb_binding plugin_desc = {
207         .type = AFB_BINDING_VERSION_1,
208         .v1 = {
209                 .info = "Minimal Hello World Sample",
210                 .prefix = "hello",
211                 .verbs = verbs
212         }
213 ```
214
215 Becomes:
216
217 ```C
218 const struct afb_binding_v2 afbBindingV2 = {
219         .api = "hello",
220         .specification = NULL,
221         .verbs = verbs,
222         .preinit = preinit,
223         .init = init
224 };
225 ```
226
227 The **binder** now relies only on the exported names
228 to deduce the type of the binding.  
229 This make the main structure more simple.
230
231 Adapt the init and callback functions
232 -------------------------------------
233
234 The ***bindings*** version 1 defined 3 exported functions:
235
236 - **afbBindingV1Register**
237 - **afbBindingV1ServiceInit**
238 - **afbBindingV1ServiceEvent**
239
240 These function should not be exported any more and there definition changed.
241
242 The function **afbBindingV1Register** is no more used to describe the binding.  
243 When a binding has to take actions when it is loaded, it must set the field
244 **preinit** of the structure **afbBindingV2**.  
245 This field, this preinit, might be used to check features at load.  
246 When it returns a negative number, the ***binder*** stops before initializing any ***binding***.
247
248 The function **afbBindingV1ServiceInit** is replaced by the field **init**
249 of the structure **afbBindingV2**.  
250 The init function should return 0 in case of success or a negative error code
251 in case of problem.  
252 It is called during initialization of services.
253
254 The function **afbBindingV1ServiceEvent**is replaced by the field **onevent**
255 of the structure **afbBindingV2**.
256
257 The two functions **afbBindingV1Register** and **afbBindingV1ServiceInit**,
258 were taking as parameter the ***binder*** interface and the service interface respectively.  
259 These interfaces are now managed hiddenly for the **binding** by the **binder**.  
260 So the variable that ***bindings*** version used to store the ***binder*** interface
261 and the service interface are no more needed and can be removed.
262
263 Example:
264
265 ```C
266 const struct afb_binding_interface *interface;
267 struct afb_service service;
268
269 static const struct afb_binding plugin_desc = {
270         .type = AFB_BINDING_VERSION_1,
271         .v1 = {
272                 .info = "Minimal Hello World Sample",
273                 .prefix = "hello",
274                 .verbs = verbs
275         }
276 }
277
278 const struct afb_binding *afbBindingV1Register (const struct afb_binding_interface *itf)
279 {
280         interface = itf;
281         NOTICE(interface, "binding register");
282         return &plugin_desc;
283 }
284
285 int afbBindingV1ServiceInit(struct afb_service svc)
286 {
287         service = svc;
288         NOTICE(interface, "binding init");
289         return 0;
290 }
291
292 void afbBindingV1ServiceEvent(const char *event, struct json_object *object)
293 {
294         NOTICE(interface, "onevent %s", event);
295 }
296 ```
297
298 Becomes:
299
300 ```C
301 static int preinit()
302 {
303         AFB_NOTICE("binding preinit (was register)");
304         return 0;
305 }
306
307 static int init()
308 {
309         AFB_NOTICE("binding init");
310         return 0;
311 }
312
313 static void onevent(const char *event, struct json_object *object)
314 {
315         AFB_NOTICE("onevent %s", event);
316 }
317
318 const struct afb_binding_v2 afbBindingV2 = {
319         .api = "hello",
320         .specification = NULL,
321         .verbs = verbs,
322         .preinit = preinit,
323         .init = init,
324         .onevent = onevent
325 };
326 ```
327
328 The two functions **afbBindingV1Register** and **afbBindingV1ServiceInit**,
329 were taking as parameter the ***binder*** interface and the service interface respectively.  
330 These interfaces are now managed hiddenly for the **binding** by the **binder**.  
331 So the variable that ***bindings*** version used to store the ***binder*** interface
332 and the service interface are no more needed and can be removed.
333
334 On the above example the following lines were removed:
335
336 ```C
337 const struct afb_binding_interface *interface;
338 struct afb_service service;
339
340         interface = itf;
341
342         service = svc;
343 ```
344
345 Removes the first parameter of functions of classes **daemon** and **service**
346 ------------------------------------------------------------------------------
347
348 As explained before, many functions loose there first
349 arguments, this are the functions of the following classes:
350
351 - functions of class **daemon**:
352   - functions starting with **afb_daemon_...**
353   - functions for logging: **ERROR**, **WARNING**, **NOTICE**, **INFO**, **DEBUG**
354 - functions of class **service**:
355   - functions starting with **afb_service_...**
356 - callback functions:
357   - the register function (that is removed)
358   - the service init function
359   - the onevent function
360
361 For these functions, the first parameter is now implicit.
362
363 Example:
364
365 ```C
366         afb_daemon_broadcast_event(afbitf->daemon, reason, description);
367 ```
368
369 Becomes:
370
371 ```C
372         afb_daemon_broadcast_event(reason, description);
373 ```
374
375 Also, to avoid possible conflicts, we introduced prefixed logging functions:  
376 the macros 
377
378 - **ERROR**
379 - **WARNING**
380 - **NOTICE**
381 - **INFO**
382 - **DEBUG** 
383
384 have now a prefixed version: 
385
386 - **AFB\_ERROR**
387 - **AFB\_WARNING**
388 - **AFB\_NOTICE**
389 - **AFB\_INFO**
390 - **AFB\_DEBUG**
391
392 It is now recommended to use the prefixed version.
393
394 Example:
395
396 ```C
397         NOTICE(interface, "hello plugin comes to live");
398 ```
399
400 Become:
401
402 ```C
403         NOTICE("hello plugin comes to live");
404 ```
405
406 or, better:
407
408 ```C
409         AFB_NOTICE("hello plugin comes to live");
410 ```
411
412 To remove definition of the un-prefixed versions of logging macros:
413
414 - **ERROR**
415 - **WARNING**
416 - **NOTICE**
417 - **INFO**
418 - **DEBUG** 
419
420 and just define 
421
422 - **AFB_BINDING_PRAGMA_NO_VERBOSE_UNPREFIX**
423
424 before to include **afb/afb-binding.h**.
425
426 ```C
427 #define AFB_BINDING_PRAGMA_NO_VERBOSE_UNPREFIX
428 #define AFB_BINDING_VERSION 2
429 #include <afb/afb-binding.h>
430 ```
431
432 Consider where to emit logs for requests
433 ----------------------------------------
434
435 The ***bindings*** v2 now allows to emit log messages associated to ***requests***.  
436 This feature is valuable when debugging because it allows to return
437 side information associated to a ***request***.
438
439 The defined macros for logging to requests are: 
440
441 - **AFB_REQ_ERROR**
442 - **AFB_REQ_WARNING**
443 - **AFB_REQ_NOTICE**
444 - **AFB_REQ_INFO**
445 - **AFB_REQ_DEBUG**
446
447 We encourage the use of these new logging facilities everywhere it makes sense.
448
449 Example:
450
451 ```C
452         INFO(afbitf, "method 'new' called for boardid %d", board->id);
453 ```
454
455 Might become:
456
457 ```C
458         AFB_REQ_INFO(req, "method 'new' called for boardid %d", board->id);
459 ```
460
461 Take care of store/unstore change
462 ---------------------------------
463
464 For efficiency, the version 2 redefined how storing/un-storing of
465 requests works.  
466 Storing request is needed for asynchronous handling of requests.
467
468 For ***bindings*** version, the signature of the functions were:
469
470 ```C
471 struct afb_req *afb_req_store(struct afb_req req);
472 struct afb_req afb_req_unstore(struct afb_req *req);
473 ```
474
475 For version 2 it becomes
476
477 ```C
478 struct afb_stored_req *afb_req_store(struct afb_req req);
479 struct afb_req afb_req_unstore(struct afb_stored_req *sreq);
480 ```
481
482 Where the structure ```struct afb_stored_req``` is opaque.
483
484 It should require few code change.
485
486 Also check the following chapter that explain that asynchronous (sub)calls
487 can be replaced by synchronous one, avoiding the need to store/unstore
488 requests.
489
490 Consider use of synchronous (sub)call requests
491 ----------------------------------------------
492
493 ***Bindings*** can emit requests for themselves (calls) or for
494 their clients (subcalls).  
495 With ***bindings*** version 2 comes also synchronous requests for both cases.
496
497 So when migrating to bindings version 2, a developer can consider
498 to replace the asynchronous requests (with asynchronous call back)
499 by synchronous ones.
500
501 See functions ***afb_service_call_sync*** and ***afb_req_subcall_sync***.
502
503 Optionally, removes explicit struct
504 -----------------------------------
505
506 The new definitions now includes **typedefs** for common
507 structures, as shown on below sample:
508
509 ```C
510 typedef struct afb_daemon               afb_daemon;
511 typedef struct afb_event                afb_event;
512 typedef struct afb_arg                  afb_arg;
513 typedef struct afb_req                  afb_req;
514 typedef struct afb_service              afb_service;
515 ```
516
517 So you can remove the keyword **struct** if it bores you.
518
519 Example:
520
521 ```C
522 static void verb(struct afb_req req)
523 {
524         ...
525 }
526 ```
527
528 Might become:
529
530 ```C
531 static void verb(afb_req req)
532 {
533         ...
534 }
535 ```
536
537 Example of migration
538 --------------------
539
540 The first ***binding*** that migrated from v1 to v2 was the sample **HelloWorld**.  
541 Here is shown the differences between the version 1 and the version 2.
542
543 ```diff
544 diff --git a/bindings/samples/HelloWorld.c b/bindings/samples/HelloWorld.c
545 index c6fa779..505aee3 100644
546 --- a/bindings/samples/HelloWorld.c
547 +++ b/bindings/samples/HelloWorld.c
548 @@ -21,9 +21,9 @@
549
550  #include <json-c/json.h>
551
552 +#define AFB_BINDING_VERSION 2
553  #include <afb/afb-binding.h>
554
555 -const struct afb_binding_interface *interface;
556  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
557
558  struct event
559 @@ -79,7 +80,7 @@ static int event_add(const char *tag, const char *name)
560          strcpy(e->tag, tag);
561
562          /* make the event */
563 -    e->event = afb_daemon_make_event(interface->daemon, name);
564 +    e->event = afb_daemon_make_event(name);
565          if (!e->event.closure) { free(e); return -1; }
566
567          /* link */
568 @@ -140,7 +141,7 @@ static void pingBug (struct afb_req request)
569  static void pingEvent(struct afb_req request)
570  {
571          json_object *query = afb_req_json(request);
572 -    afb_daemon_broadcast_event(interface->daemon, "event", json_object_get(query));
573 +    afb_daemon_broadcast_event("event", json_object_get(query));
574          ping(request, json_object_get(query), "event");
575  }
576
577 @@ -288,38 +289,43 @@ static void exitnow (struct afb_req request)
578          exit(0);
579  }
580
581 +static int preinit()
582 +{
583 +    AFB_NOTICE("hello binding comes to live");
584 +    return 0;
585 +}
586 +
587 +static int init()
588 +{
589 +    AFB_NOTICE("hello binding starting");
590 +    return 0;
591 +}
592 +
593  // NOTE: this sample does not use session to keep test a basic as possible
594  //       in real application most APIs should be protected with AFB_SESSION_CHECK
595 -static const struct afb_verb_desc_v1 verbs[]= {
596 -  {"ping"     , AFB_SESSION_NONE, pingSample  , "Ping Application Framework"},
597 -  {"pingfail" , AFB_SESSION_NONE, pingFail    , "Fails"},
598 -  {"pingnull" , AFB_SESSION_NONE, pingNull    , "Return NULL"},
599 -  {"pingbug"  , AFB_SESSION_NONE, pingBug     , "Do a Memory Violation"},
600 -  {"pingJson" , AFB_SESSION_NONE, pingJson    , "Return a JSON object"},
601 -  {"pingevent", AFB_SESSION_NONE, pingEvent   , "Send an event"},
602 -  {"subcall",   AFB_SESSION_NONE, subcall     , "Call api/verb(args)"},
603 -  {"subcallsync",   AFB_SESSION_NONE, subcallsync     , "Call api/verb(args)"},
604 -  {"eventadd",  AFB_SESSION_NONE, eventadd    , "adds the event of 'name' for the 'tag'"},
605 -  {"eventdel",  AFB_SESSION_NONE, eventdel    , "deletes the event of 'tag'"},
606 -  {"eventsub",  AFB_SESSION_NONE, eventsub    , "subscribes to the event of 'tag'"},
607 -  {"eventunsub",AFB_SESSION_NONE, eventunsub  , "unsubscribes to the event of 'tag'"},
608 -  {"eventpush", AFB_SESSION_NONE, eventpush   , "pushs the event of 'tag' with the 'data'"},
609 -  {"exit",      AFB_SESSION_NONE, exitnow     , "exits from afb-daemon"},
610 -  {NULL}
611 +static const struct afb_verb_v2 verbs[]= {
612 +  { "ping"     ,    pingSample , NULL, AFB_SESSION_NONE },
613 +  { "pingfail" ,    pingFail   , NULL, AFB_SESSION_NONE },
614 +  { "pingnull" ,    pingNull   , NULL, AFB_SESSION_NONE },
615 +  { "pingbug"  ,    pingBug    , NULL, AFB_SESSION_NONE },
616 +  { "pingJson" ,    pingJson   , NULL, AFB_SESSION_NONE },
617 +  { "pingevent",    pingEvent  , NULL, AFB_SESSION_NONE },
618 +  { "subcall",      subcall    , NULL, AFB_SESSION_NONE },
619 +  { "subcallsync",  subcallsync, NULL, AFB_SESSION_NONE },
620 +  { "eventadd",     eventadd   , NULL, AFB_SESSION_NONE },
621 +  { "eventdel",     eventdel   , NULL, AFB_SESSION_NONE },
622 +  { "eventsub",     eventsub   , NULL, AFB_SESSION_NONE },
623 +  { "eventunsub",   eventunsub , NULL, AFB_SESSION_NONE },
624 +  { "eventpush",    eventpush  , NULL, AFB_SESSION_NONE },
625 +  { "exit",         exitnow    , NULL, AFB_SESSION_NONE },
626 +  { NULL}
627  };
628
629 -static const struct afb_binding plugin_desc = {
630 -    .type = AFB_BINDING_VERSION_1,
631 -    .v1 = {
632 -        .info = "Minimal Hello World Sample",
633 -        .prefix = "hello",
634 -        .verbs = verbs
635 -    }
636 +const struct afb_binding_v2 afbBindingV2 = {
637 +    .api = "hello",
638 +    .specification = NULL,
639 +    .verbs = verbs,
640 +    .preinit = preinit,
641 +    .init = init
642  };
643
644 -const struct afb_binding *afbBindingV1Register (const struct afb_binding_interface *itf)
645 -{
646 -    interface = itf;
647 -    NOTICE(interface, "hello plugin comes to live");
648 -    return &plugin_desc;
649 -}
650 ```