Merge "Migrate OpenFlow plugin dev docs to rst"
[docs.git] / docs / developer-guide / openflow-plugin-project-developer-guide.rst
1 OpenFlow Plugin Project Developer Guide
2 =======================================
3
4 This section covers topics which are developer specific and which have
5 not been covered in the user guide. Please see the OpenFlow
6 plugin user guide first.
7
8 It can be found on `the OpenDaylight software download
9 page <https://www.opendaylight.org/downloads>`__.
10
11 Event Sequences
12 ---------------
13
14 Session Establishment
15 ~~~~~~~~~~~~~~~~~~~~~
16
17 The `OpenFlow Protocol
18 Library <#_openflow_protocol_library_developer_guide>`__ provides
19 interface **SwitchConnectionHandler** which contains method
20 *onSwitchConnected* (step 1). This event is raised in the OpenFlow
21 Protocol Library when an OpenFlow device connects to OpenDaylight and
22 caught in the **ConnectionManagerImpl** class in the OpenFlow plugin.
23
24 There the plugin creates a new instance of the **ConnectionContextImpl**
25 class (step 1.1) and also instances of **HandshakeManagerImpl** (which
26 uses **HandshakeListenerImpl**) and **ConnectionReadyListenerImpl**.
27 **ConnectionReadyListenerImpl** contains method *onConnectionReady()*
28 which is called when connection is prepared. This method starts the
29 handshake with the OpenFlow device (switch) from the OpenFlow plugin
30 side. Then handshake can be also started from device side. In this case
31 method *shake()* from **HandshakeManagerImpl** is called (steps 1.1.1
32 and 2).
33
34 The handshake consists of an exchange of HELLO messages in addition to
35 an exchange of device features (steps 2.1. and 3). The handshake is
36 completed by **HandshakeManagerImpl**. After receiving device features,
37 the **HandshakeListenerImpl** is notifed via the
38 *onHanshakeSuccessfull()* method. After this, the device features, node
39 id and connection state are stored in a **ConnectionContext** and the
40 method *deviceConnected()* of **DeviceManagerImpl** is called.
41
42 When *deviceConnected()* is called, it does the following:
43
44 1. creates a new transaction chain (step 4.1)
45
46 2. creates a new instance of **DeviceContext** (step 4.2.2)
47
48 3. initializes the device context: the static context of device is
49    populated by calling *createDeviceFeaturesForOF<version>()* to
50    populate table, group, meter features and port descriptions (step
51    4.2.1 and 4.2.1.1)
52
53 4. creates an instance of **RequestContext** for each type of feature
54
55 When the OpenFlow device responds to these requests (step 4.2.1.1) with
56 multipart replies (step 5) they are processed and stored to MD-SAL
57 operational datastore. The *createDeviceFeaturesForOF<version>()* method
58 returns a **Future** which is processed in the callback (step 5.1) (part
59 of *initializeDeviceContext()* in the *deviceConnected()* method) by
60 calling the method *onDeviceCtxLevelUp()* from **StatisticsManager**
61 (step 5.1.1).
62
63 The call to *createDeviceFeaturesForOF<version>()*: . creates a new
64 instance of **StatisticsContextImpl** (step 5.1.1.1).
65
66 1. calls *gatherDynamicStatistics()* on that instance which returns a
67    **Future** which will produce a value when done
68
69    a. this method calls methods to get dynamic data (flows, tables,
70       groups) from the device (step 5.1.1.2, 5.1.1.2.1, 5.1.1.2.1.1)
71
72    b. if everything works, this data is also stored in the MD-SAL
73       operational datastore
74
75 If the **Future** is successful, it is processed (step 6.1.1) in a
76 callback in **StatisticsManagerImpl** which:
77
78 1. schedules the next time to poll the device for statistics
79
80 2. sets the device state to synchronized (step 6.1.1.2)
81
82 3. calls *onDeviceContextLevelUp()* in **RpcManagerImpl**
83
84 The *onDeviceContextLevelUp()* call:
85
86 1. creates a new instance of **RequestContextImpl**
87
88 2. registers implementation for supported services
89
90 3. calls *onDeviceContextLevelUp()* in **DeviceManagerImpl** (step
91    6.1.1.2.1.2) which causes the information about the new device be be
92    written to the MD-SAL operational datastore (step 6.1.1.2.2)
93
94 .. figure:: ./images/openflowplugin/odl-ofp-session-establishment.jpg
95    :alt: Session establishment
96
97    Session establishment
98
99 Handshake
100 ~~~~~~~~~
101
102 The first thing that happens when an OpenFlow device connects to
103 OpenDaylight is that the OpenFlow plugin gathers basic information about
104 the device and establishes agreement on key facts like the version of
105 OpenFlow which will be used. This process is called the handshake.
106
107 The handshake starts with HELLO message which can be sent either by the
108 OpenFlow device or the OpenFlow plugin. After this, there are several
109 scenarios which can happen:
110
111 1. if the first HELLO message contains a *version bitmap*, it is
112    possible to determine if there is a common version of OpenFlow or
113    not:
114
115    a. if there is a single common version use it and the **VERSION IS
116       SETTLED**
117
118    b. if there are more than one common versions, use the highest
119       (newest) protocol and the **VERSION IS SETTLED**
120
121    c. if there are no common versions, the device is **DISCONNECTED**
122
123 2. if the first HELLO message does not contain a *version bitmap*, then
124    STEB-BY-STEP negotiation is used
125
126 3. if second (or more) HELLO message is received, then STEP-BY-STEP
127    negotiation is used
128
129 STEP-BY-STEP negotiation:
130 ^^^^^^^^^^^^^^^^^^^^^^^^^
131
132 -  if last version proposed by the OpenFlow plugin is the same as the
133    version received from the OpenFlow device, then the **VERSION IS
134    SETTLED**
135
136 -  if the version received in the current HELLO message from the device
137    is the same as from previous then negotiation has failed and the
138    device is **DISCONNECTED**
139
140 -  if the last version from the device is greater than the last version
141    proposed from the plugin, wait for the next HELLO message in the hope
142    that it will advertise support for a lower version
143
144 -  if the last version from the device is is less than the last version
145    proposed from the plugin:
146
147    -  propose the highest version the plugin supports that is less than
148       or equal to the version received from the device and wait for the
149       next HELLO message
150
151    -  if if the plugin doesn’t support a lower version, the device is
152       **DISCONNECTED**
153
154 After selecting of version we can say that the **VERSION IS SETTLED**
155 and the OpenFlow plugin can ask device for its features. At this point
156 handshake ends.
157
158 .. figure:: ./images/openflowplugin/odl-ofp-handshake.png
159    :alt: Handshake process
160
161    Handshake process
162
163 Adding a Flow
164 ~~~~~~~~~~~~~
165
166 There are two ways to add a flow in in the OpenFlow plugin: adding it to
167 the MD-SAL config datastore or calling an RPC. Both of these can either
168 be done using the native MD-SAL interfaces or using RESTCONF. This
169 discussion focuses on calling the RPC.
170
171 If user send flow via REST interface (step 1) it will cause that
172 *invokeRpc()* is called on **RpcBroker**. The **RpcBroker** then looks
173 for an appropriate implementation of the interface. In the case of the
174 OpenFlow plugin, this is the *addFlow()* method of
175 **SalFlowServiceImpl** (step 1.1). The same thing happens if the RPC is
176 called directly from the native MD-SAL interfaces.
177
178 The *addFlow()* method then
179
180 1. calls the *commitEntry()* method (step 2) from the OpenFlow Protocol
181    Library which is responsible for sending the flow to the device
182
183 2. creates a new **RequestContext** by calling *createRequestContext()*
184    (step 3)
185
186 3. creates a callback to handle any events that happen because of
187    sending the flow to the device
188
189 The callback method is triggered when a barrier reply message (step 2.1)
190 is received from the device indicating that the flow was either
191 installed or an appropriate error message was sent. If the flow was
192 successfully sent to the device, the RPC result is set to success (step
193 5). // **SalFlowService** contains inside method *addFlow()* other
194 callback which caught notification from callback for barrier message.
195
196 At this point, no information pertaining to the flow has been added to
197 the MD-SAL operational datastore. That is accomplished by the periodic
198 gathering of statistics from OpenFlow devices.
199
200 The **StatisticsContext** for each given OpenFlow device periodically
201 polls it using *gatherStatistics()* of **StatisticsGatheringUtil** which
202 issues an OpenFlow OFPT\_MULTIPART\_REQUEST - OFPMP\_FLOW. The response
203 to this request (step 7) is processed in **StatisticsGatheringUtil**
204 class where flow data is written to the MD-SAL operational datastore via
205 the *writeToTransaction()* method of **DeviceContext**.
206
207 .. figure:: ./images/openflowplugin/odl-ofp-add-flow.png
208    :alt: Add flow
209
210    Add flow
211
212 Description of OpenFlow Plugin Modules
213 --------------------------------------
214
215 The OpenFlow plugin project contains a variety of OpenDaylight modules,
216 which are loaded using the configuration subsystem. This section
217 describes the YANG files used to model each module.
218
219 **General model (interfaces)** - openflow-plugin-cfg.yang.
220
221 -  the provided module is defined (``identity openflow-provider``)
222
223 -  and target implementation is assigned (``...OpenflowPluginProvider``)
224
225 .. code:: yang
226
227     module openflow-provider {
228        yang-version 1;
229        namespace "urn:opendaylight:params:xml:ns:yang:openflow:common:config[urn:opendaylight:params:xml:ns:yang:openflow:common:config]";
230        prefix "ofplugin-cfg";
231
232        import config {prefix config; revision-date 2013-04-05; }
233        description
234            "openflow-plugin-custom-config";
235        revision "2014-03-26" {
236            description
237                "Initial revision";
238        }
239        identity openflow-provider{
240            base config:service-type;
241            config:java-class "org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginProvider";
242        }
243     }
244
245 **Implementation model** - openflow-plugin-cfg-impl.yang
246
247 -  the implementation of module is defined
248    (``identity openflow-provider-impl``)
249
250    -  class name of generated implementation is defined
251       (ConfigurableOpenFlowProvider)
252
253 -  via augmentation the configuration of module is defined:
254
255    -  this module requires instance of binding-aware-broker
256       (``container binding-aware-broker``)
257
258    -  and list of openflow-switch-connection-provider (those are
259       provided by openflowjava, one plugin instance will orchestrate
260       multiple openflowjava modules)
261
262 .. code:: yang
263
264     module openflow-provider-impl {
265        yang-version 1;
266        namespace "urn:opendaylight:params:xml:ns:yang:openflow:common:config:impl[urn:opendaylight:params:xml:ns:yang:openflow:common:config:impl]";
267        prefix "ofplugin-cfg-impl";
268
269        import config {prefix config; revision-date 2013-04-05;}
270        import openflow-provider {prefix openflow-provider;}
271        import openflow-switch-connection-provider {prefix openflow-switch-connection-provider;revision-date 2014-03-28;}
272        import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
273
274
275        description
276            "openflow-plugin-custom-config-impl";
277
278        revision "2014-03-26" {
279            description
280                "Initial revision";
281        }
282
283        identity openflow-provider-impl {
284            base config:module-type;
285            config:provided-service openflow-provider:openflow-provider;
286            config:java-name-prefix ConfigurableOpenFlowProvider;
287        }
288
289        augment "/config:modules/config:module/config:configuration" {
290            case openflow-provider-impl {
291                when "/config:modules/config:module/config:type = 'openflow-provider-impl'";
292
293                container binding-aware-broker {
294                    uses config:service-ref {
295                        refine type {
296                            mandatory true;
297                            config:required-identity md-sal-binding:binding-broker-osgi-registry;
298                        }
299                    }
300                }
301                list openflow-switch-connection-provider {
302                    uses config:service-ref {
303                        refine type {
304                            mandatory true;
305                            config:required-identity openflow-switch-connection-provider:openflow-switch-connection-provider;
306                        }
307                    }
308                }
309            }
310        }
311     }
312
313 Generating config and sal classes out of yangs
314 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
315
316 In order to involve suitable code generators, this is needed in pom:
317
318 .. code:: xml
319
320     <build> ...
321       <plugins>
322         <plugin>
323           <groupId>org.opendaylight.yangtools</groupId>
324           <artifactId>yang-maven-plugin</artifactId>
325           <executions>
326             <execution>
327               <goals>
328                 <goal>generate-sources</goal>
329               </goals>
330               <configuration>
331                 <codeGenerators>
332                   <generator>
333                     <codeGeneratorClass>
334                       org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
335                     </codeGeneratorClass>
336                     <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
337                     <additionalConfiguration>
338                       <namespaceToPackage1>
339                         urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
340                       </namespaceToPackage1>
341                     </additionalConfiguration>
342                   </generator>
343                   <generator>
344                     <codeGeneratorClass>
345                       org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
346                     </codeGeneratorClass>
347                     <outputBaseDir>${project.build.directory}/generated-sources/sal</outputBaseDir>
348                   </generator>
349                   <generator>
350                     <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
351                     <outputBaseDir>${project.build.directory}/site/models</outputBaseDir>
352                   </generator>
353                 </codeGenerators>
354                 <inspectDependencies>true</inspectDependencies>
355               </configuration>
356             </execution>
357           </executions>
358           <dependencies>
359             <dependency>
360               <groupId>org.opendaylight.controller</groupId>
361               <artifactId>yang-jmx-generator-plugin</artifactId>
362               <version>0.2.5-SNAPSHOT</version>
363             </dependency>
364             <dependency>
365               <groupId>org.opendaylight.yangtools</groupId>
366               <artifactId>maven-sal-api-gen-plugin</artifactId>
367               <version>${yangtools.version}</version>
368               <type>jar</type>
369             </dependency>
370           </dependencies>
371         </plugin>
372         ...
373
374 -  JMX generator (target/generated-sources/config)
375
376 -  sal CodeGeneratorImpl (target/generated-sources/sal)
377
378 -  documentation generator (target/site/models):
379    `openflow-provider.html <https://jenkins.opendaylight.org/openflowplugin/job/openflowplugin-merge/ws/openflowplugin/target/site/models/openflow-provider.html>`__,
380    `openflow-provider-impl.html <https://jenkins.opendaylight.org/openflowplugin/job/openflowplugin-merge/ws/openflowplugin/target/site/models/openflow-provider-impl.html>`__
381
382 Altering generated files
383 ~~~~~~~~~~~~~~~~~~~~~~~~
384
385 Those files were generated under src/main/java in package as referred in
386 yangs (if exist, generator will not overwrite them):
387
388 -  ConfigurableOpenFlowProviderModuleFactory
389
390        here the **instantiateModule** methods are extended in order to
391        capture and inject osgi BundleContext into module, so it can be
392        injected into final implementation - **OpenflowPluginProvider** +
393        ``module.setBundleContext(bundleContext);``
394
395 -  ConfigurableOpenFlowProviderModule
396
397        here the **createInstance** method is extended in order to inject
398        osgi BundleContext into module implementation +
399        ``pluginProvider.setContext(bundleContext);``
400
401 Configuration xml file
402 ~~~~~~~~~~~~~~~~~~~~~~
403
404 Configuration file contains
405
406 -  required capabilities
407
408    -  modules definitions from openflowjava
409
410    -  modules definitions from openflowplugin
411
412 -  modules definition
413
414    -  openflow:switch:connection:provider:impl (listening on port 6633,
415       name=openflow-switch-connection-provider-legacy-impl)
416
417    -  openflow:switch:connection:provider:impl (listening on port 6653,
418       name=openflow-switch-connection-provider-default-impl)
419
420    -  openflow:common:config:impl (having 2 services (wrapping those 2
421       previous modules) and binding-broker-osgi-registry injected)
422
423 -  provided services
424
425    -  openflow-switch-connection-provider-default
426
427    -  openflow-switch-connection-provider-legacy
428
429    -  openflow-provider
430
431 .. code:: xml
432
433     <snapshot>
434      <required-capabilities>
435        <capability>urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider:impl?module=openflow-switch-connection-provider-impl&revision=2014-03-28</capability>
436        <capability>urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider?module=openflow-switch-connection-provider&revision=2014-03-28</capability>
437        <capability>urn:opendaylight:params:xml:ns:yang:openflow:common:config:impl?module=openflow-provider-impl&revision=2014-03-26</capability>
438        <capability>urn:opendaylight:params:xml:ns:yang:openflow:common:config?module=openflow-provider&revision=2014-03-26</capability>
439      </required-capabilities>
440
441      <configuration>
442
443
444          <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
445            <module>
446              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider:impl">prefix:openflow-switch-connection-provider-impl</type>
447              <name>openflow-switch-connection-provider-default-impl</name>
448              <port>6633</port>
449              <switch-idle-timeout>15000</switch-idle-timeout>
450            </module>
451            <module>
452              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider:impl">prefix:openflow-switch-connection-provider-impl</type>
453              <name>openflow-switch-connection-provider-legacy-impl</name>
454              <port>6653</port>
455              <switch-idle-timeout>15000</switch-idle-timeout>
456            </module>
457
458
459            <module>
460              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:openflow:common:config:impl">prefix:openflow-provider-impl</type>
461              <name>openflow-provider-impl</name>
462
463              <openflow-switch-connection-provider>
464                <type xmlns:ofSwitch="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider">ofSwitch:openflow-switch-connection-provider</type>
465                <name>openflow-switch-connection-provider-default</name>
466              </openflow-switch-connection-provider>
467              <openflow-switch-connection-provider>
468                <type xmlns:ofSwitch="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider">ofSwitch:openflow-switch-connection-provider</type>
469                <name>openflow-switch-connection-provider-legacy</name>
470              </openflow-switch-connection-provider>
471
472
473              <binding-aware-broker>
474                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
475                <name>binding-osgi-broker</name>
476              </binding-aware-broker>
477            </module>
478          </modules>
479
480          <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
481            <service>
482              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider">prefix:openflow-switch-connection-provider</type>
483              <instance>
484                <name>openflow-switch-connection-provider-default</name>
485                <provider>/modules/module[type='openflow-switch-connection-provider-impl'][name='openflow-switch-connection-provider-default-impl']</provider>
486              </instance>
487              <instance>
488                <name>openflow-switch-connection-provider-legacy</name>
489                <provider>/modules/module[type='openflow-switch-connection-provider-impl'][name='openflow-switch-connection-provider-legacy-impl']</provider>
490              </instance>
491            </service>
492
493            <service>
494              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:openflow:common:config">prefix:openflow-provider</type>
495              <instance>
496                <name>openflow-provider</name>
497                <provider>/modules/module[type='openflow-provider-impl'][name='openflow-provider-impl']</provider>
498              </instance>
499            </service>
500          </services>
501
502
503      </configuration>
504     </snapshot>
505
506 API changes
507 ~~~~~~~~~~~
508
509 In order to provide multiple instances of modules from openflowjava
510 there is an API change. Previously OFPlugin got access to
511 SwitchConnectionProvider exposed by OFJava and injected collection of
512 configurations so that for each configuration new instance of tcp
513 listening server was created. Now those configurations are provided by
514 configSubsystem and configured modules (wrapping the original
515 SwitchConnectionProvider) are injected into OFPlugin (wrapping
516 SwitchConnectionHandler).
517
518 Providing config file (IT, local distribution/base, integration/distributions/base)
519 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
520
521 openflowplugin-it
522 ^^^^^^^^^^^^^^^^^
523
524 Here the whole configuration is contained in one file (controller.xml).
525 Required entries needed in order to startup and wire OEPlugin + OFJava
526 are simply added there.
527
528 OFPlugin/distribution/base
529 ^^^^^^^^^^^^^^^^^^^^^^^^^^
530
531 Here new config file has been added
532 (src/main/resources/configuration/initial/42-openflow-protocol-impl.xml)
533 and is being copied to config/initial subfolder of build.
534
535 integration/distributions/build
536 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
537
538 In order to push the actual config into config/initial subfolder of
539 distributions/base in integration project there was a new artifact in
540 OFPlugin created - **openflowplugin-controller-config**, containing only
541 the config xml file under src/main/resources. Another change was
542 committed into integration project. During build this config xml is
543 being extracted and copied to the final folder in order to be accessible
544 during controller run.
545
546 Internal message statistics API
547 -------------------------------
548
549 To aid in testing and diagnosis, the OpenFlow plugin provides
550 information about the number and rate of different internal events.
551
552 The implementation does two things: collects event counts and exposes
553 counts. Event counts are grouped by message type, e.g.,
554 **PacketInMessage**, and checkpoint, e.g.,
555 *TO\_SWITCH\_ENQUEUED\_SUCCESS*. Once gathered, the results are logged
556 as well as being exposed using OSGi command line (deprecated) and JMX.
557
558 Collect
559 ~~~~~~~
560
561 Each message is counted as it passes through various processing
562 checkpoints. The following checkpoints are defined as a Java enum and
563 tracked:
564
565 .. code:: java
566
567       /**
568         * statistic groups overall in OFPlugin
569         */
570       enum STATISTIC_GROUP {
571            /** message from switch, enqueued for processing */
572            FROM_SWITCH_ENQUEUED,
573            /** message from switch translated successfully - source */
574            FROM_SWITCH_TRANSLATE_IN_SUCCESS,
575            /** message from switch translated successfully - target */
576            FROM_SWITCH_TRANSLATE_OUT_SUCCESS,
577            /** message from switch where translation failed - source */
578            FROM_SWITCH_TRANSLATE_SRC_FAILURE,
579            /** message from switch finally published into MD-SAL */
580            FROM_SWITCH_PUBLISHED_SUCCESS,
581            /** message from switch - publishing into MD-SAL failed */
582            FROM_SWITCH_PUBLISHED_FAILURE,
583
584            /** message from MD-SAL to switch via RPC enqueued */
585            TO_SWITCH_ENQUEUED_SUCCESS,
586            /** message from MD-SAL to switch via RPC NOT enqueued */
587            TO_SWITCH_ENQUEUED_FAILED,
588            /** message from MD-SAL to switch - sent to OFJava successfully */
589            TO_SWITCH_SUBMITTED_SUCCESS,
590            /** message from MD-SAL to switch - sent to OFJava but failed*/
591            TO_SWITCH_SUBMITTED_FAILURE
592       }
593
594 When a message passes through any of those checkpoints then counter
595 assigned to corresponding checkpoint and message is incremented by 1.
596
597 Expose statistics
598 ~~~~~~~~~~~~~~~~~
599
600 As described above, there are three ways to access the statistics:
601
602 -  OSGi command line (this is considered deprecated)
603
604        ``osgi> dumpMsgCount``
605
606 -  OpenDaylight logging console (statistics are logged here every 10
607    seconds)
608
609        required logback settings :
610        ``<logger name="org.opendaylight.openflowplugin.openflow.md.queue.MessageSpyCounterImpl" level="DEBUG"\/>``
611
612 -  JMX (via JConsole)
613
614        start OpenFlow plugin with the ``-jmx`` parameter
615
616        start JConsole by running ``jconsole``
617
618        the JConsole MBeans tab should contain
619        org.opendaylight.controller
620
621        RuntimeBean has a msg-spy-service-impl
622
623        Operations provides makeMsgStatistics report functionality
624
625 Example results
626 ^^^^^^^^^^^^^^^
627
628 .. figure:: ./images/openflowplugin/odl-ofp-ofplugin-debug-stats.png
629    :alt: OFplugin Debug stats.png
630
631    OFplugin Debug stats.png
632
633 ::
634
635     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_ENQUEUED: MSG[PortStatusMessage] -> +0 | 1
636     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_ENQUEUED: MSG[MultipartReplyMessage] -> +24 | 81
637     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_ENQUEUED: MSG[PacketInMessage] -> +8 | 111
638     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_IN_SUCCESS: MSG[PortStatusMessage] -> +0 | 1
639     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_IN_SUCCESS: MSG[MultipartReplyMessage] -> +24 | 81
640     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_IN_SUCCESS: MSG[PacketInMessage] -> +8 | 111
641     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[QueueStatisticsUpdate] -> +3 | 7
642     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[NodeUpdated] -> +0 | 3
643     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[NodeConnectorStatisticsUpdate] -> +3 | 7
644     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[GroupDescStatsUpdated] -> +3 | 7
645     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[FlowsStatisticsUpdate] -> +3 | 19
646     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[PacketReceived] -> +8 | 111
647     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[MeterFeaturesUpdated] -> +0 | 3
648     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[GroupStatisticsUpdated] -> +3 | 7
649     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[GroupFeaturesUpdated] -> +0 | 3
650     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[MeterConfigStatsUpdated] -> +3 | 7
651     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[MeterStatisticsUpdated] -> +3 | 7
652     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[NodeConnectorUpdated] -> +0 | 12
653     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_OUT_SUCCESS: MSG[FlowTableStatisticsUpdate] -> +3 | 8
654     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_TRANSLATE_SRC_FAILURE: no activity detected
655     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[QueueStatisticsUpdate] -> +3 | 7
656     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[NodeUpdated] -> +0 | 3
657     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[NodeConnectorStatisticsUpdate] -> +3 | 7
658     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[GroupDescStatsUpdated] -> +3 | 7
659     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[FlowsStatisticsUpdate] -> +3 | 19
660     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[PacketReceived] -> +8 | 111
661     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[MeterFeaturesUpdated] -> +0 | 3
662     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[GroupStatisticsUpdated] -> +3 | 7
663     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[GroupFeaturesUpdated] -> +0 | 3
664     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[MeterConfigStatsUpdated] -> +3 | 7
665     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[MeterStatisticsUpdated] -> +3 | 7
666     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[NodeConnectorUpdated] -> +0 | 12
667     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_SUCCESS: MSG[FlowTableStatisticsUpdate] -> +3 | 8
668     DEBUG o.o.o.s.MessageSpyCounterImpl - FROM_SWITCH_PUBLISHED_FAILURE: no activity detected
669     DEBUG o.o.o.s.MessageSpyCounterImpl - TO_SWITCH_ENQUEUED_SUCCESS: MSG[AddFlowInput] -> +0 | 12
670     DEBUG o.o.o.s.MessageSpyCounterImpl - TO_SWITCH_ENQUEUED_FAILED: no activity detected
671     DEBUG o.o.o.s.MessageSpyCounterImpl - TO_SWITCH_SUBMITTED_SUCCESS: MSG[AddFlowInput] -> +0 | 12
672     DEBUG o.o.o.s.MessageSpyCounterImpl - TO_SWITCH_SUBMITTED_FAILURE: no activity detected
673
674 Application: Forwarding Rules Synchronizer
675 ------------------------------------------
676
677 Basics
678 ~~~~~~
679
680 Description
681 ^^^^^^^^^^^
682
683 Forwarding Rules Synchronizer (FRS) is a newer version of Forwarding
684 Rules Manager (FRM). It was created to solve most shortcomings of FRM.
685 FRS solving errors with retry mechanism. Sending barrier if needed.
686 Using one service for flows, groups and meters. And it has less changes
687 requests send to device since calculating difference and using
688 compression queue.
689
690 It is located in the Java package:
691
692 .. code:: java
693
694     package org.opendaylight.openflowplugin.applications.frsync;
695
696 Listeners
697 ^^^^^^^^^
698
699 -  1x config - FlowCapableNode
700
701 -  1x operational - Node
702
703 System of work
704 ^^^^^^^^^^^^^^
705
706 -  one listener in config datastore waiting for changes
707
708    -  update cache
709
710    -  skip event if operational not present for node
711
712    -  send syncup entry to reactor for synchronization
713
714       -  node added: after part of modification and whole operational
715          snapshot
716
717       -  node updated: after and before part of modification
718
719       -  node deleted: null and before part of modification
720
721 -  one listener in operational datastore waiting for changes
722
723    -  update cache
724
725    -  on device connected
726
727       -  register for cluster services
728
729    -  on device disconnected remove from cache
730
731       -  remove from cache
732
733       -  unregister for cluster services
734
735    -  if registered for reconciliation
736
737       -  do reconciliation through syncup (only when config present)
738
739 -  reactor *(provides syncup w/decorators assembled in this order)*
740
741    -  Cluster decorator - skip action if not master for device
742
743    -  FutureZip decorator (FutureZip extends Future decorator)
744
745       -  Future - run delegate syncup in future - submit task to
746          executor service
747
748       -  FutureZip - provides state compression - compress optimized
749          config delta if waiting for execution with new one
750
751    -  Guard decorator - per device level locking
752
753    -  Retry decorator - register for reconciliation if syncup failed
754
755    -  Reactor impl - calculate diff from after/before parts of syncup
756       entry and execute
757
758 Strategy
759 ^^^^^^^^
760
761 In the *old* FRM uses an incremental strategy with all changes made one
762 by one, where FRS uses a flat batch system with changes made in bulk. It
763 uses one service SalFlatBatchService instead of three (flow, group,
764 meter).
765
766 Boron release
767 ^^^^^^^^^^^^^
768
769 FRS is used in Boron as separate feature and it is not loaded by any
770 other feature. It has to be run separately.
771
772 ::
773
774     odl-openflowplugin-app-forwardingrules-sync
775
776 FRS additions
777 ~~~~~~~~~~~~~
778
779 Retry mechanism
780 ^^^^^^^^^^^^^^^
781
782 -  is started when change request to device return as failed (register
783    for reconcile)
784
785 -  wait for next consistent operational and do reconciliation with
786    actual config (not only diff)
787
788 ZipQueue
789 ^^^^^^^^
790
791 -  only the diff (before/after) between last config changes is sent to
792    device
793
794 -  when there are more config changes for device in a row waiting to be
795    processed they are compressed into one entry (after is still replaced
796    with the latest)
797
798 Cluster-aware
799 ^^^^^^^^^^^^^
800
801 -  FRS is cluster aware using ClusteringSingletonServiceProvider from
802    the MD-SAL
803
804 -  on mastership change reconciliation is done (register for reconcile)
805
806 SalFlatBatchService
807 ^^^^^^^^^^^^^^^^^^^
808
809 FRS uses service with implemented barrier waiting logic between
810 dependent objects
811
812 SalFlatBatchService for FRS
813 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
814
815 SalFlatBatchService was created along forwardingrules-sync application
816 as the service that should application used by default. This service
817 uses only one input with bag of flow/group/meter objects and their
818 common add/update/remove action. So you practically send only one input
819 (of specific bags) to this service.
820
821 Workflow
822 ^^^^^^^^
823
824 -  prepare plan of actions
825
826    -  mark actions where the barrier is needed before continue
827
828 -  run appropriate service calls
829
830    -  start all actions that can be run simultaneously
831
832    -  if there is barrier-needed mark, wait for all fired jobs and only
833       then continue with the next action
834
835 error handling:
836
837 -  there is flag to stop process on the first error (default set to
838    false)
839
840 Cluster singleton approach in plugin
841 ------------------------------------
842
843 Basics
844 ~~~~~~
845
846 Description
847 ^^^^^^^^^^^
848
849 The existing OpenDaylight service deployment model assumes symmetric
850 clusters, where all services are activated on all nodes in the cluster.
851 However, many services require that there is a single active service
852 instance per cluster. We call such services *singleton services*. The
853 Entity Ownership Service (EOS) represents the base Leadership choice for
854 one Entity instance. Every Cluster Singleton service **type** must have
855 its own Entity and every Cluster Singleton service **instance** must
856 have its own Entity Candidate. Every registered Entity Candidate should
857 be notified about its actual role. All this "work" is done by MD-SAL so
858 the Openflowplugin need "only" to register as service in
859 **SingletonClusteringServiceProvider** given by MD-SAL.
860
861 Change against using EOS service listener
862 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
863
864 In this new clustering singleton approach plugin uses API from the
865 MD-SAL project: SingletonClusteringService which comes with three
866 methods.
867
868 ::
869
870     instantiateServiceInstance()
871     closeServiceInstance()
872     getIdentifier()
873
874 This service has to be registered to a
875 SingletonClusteringServiceProvider from MD-SAL which take care if
876 mastership is changed in cluster environment.
877
878 First method in SingletonClusteringService is being called when the
879 cluster node becomes a MASTER. Second is being called when status
880 changes to SLAVE or device is disconnected from cluster. Last method
881 plugins returns NodeId as ServiceGroupIdentifier Startup after device is
882 connected
883
884 On the start up the plugin we need to initialize first four managers for
885 each working area providing information and services
886
887 -  Device manager
888
889 -  RPC manager
890
891 -  Role manager
892
893 -  Statistics manager
894
895 After connection the device the listener Device manager get the event
896 and start up to creating the context for this connection. Startup after
897 device connection
898
899 Services are managed by SinlgetonClusteringServiceProvider from MD-SAL
900 project. So in startup we simply create a instance of LifecycleService
901 and register all contexts into it.
902
903 Role change
904 ~~~~~~~~~~~
905
906 Plugin is no longer registered as Entity Ownership Service (EOS)
907 listener therefore does not need to and cannot respond on EOS ownership
908 changes.
909
910 Service start
911 ^^^^^^^^^^^^^
912
913 Services start asynchronously but the start is managed by
914 LifecycleService. If something goes wrong LifecycleService stop starting
915 services in context and this speeds up the reconnect process. But the
916 services haven’t changed and plugin need to start all this:
917
918 -  Activating transaction chain manager
919
920 -  Initial gathering of device statistics
921
922 -  Initial submit to DS
923
924 -  Sending role MASTER to device
925
926 -  RPC services registration
927
928 -  Statistics gathering start
929
930 Service stop
931 ^^^^^^^^^^^^
932
933 If closeServiceInstance occurred plugin just simply try to store all
934 unsubmitted transactions and close the transaction chain manager, stop
935 RPC services, stop Statistics gathering and after that all unregister
936 txEntity from EOS.
937
938 Yang models and API
939 -------------------
940
941 +--------------------------------------------------------+-------------------+
942 | Model                                                  | DOC               |
943 +========================================================+===================+
944 | ***Openflow basic types***                             |
945 +--------------------------------------------------------+-------------------+
946 | `opendaylight-table-types.yang <https://git.opendaylig | `YangDOC <https:/ |
947 | ht.org/gerrit/gitweb?p=openflowplugin.git;f=model/mode | /jenkins.opendayl |
948 | l-flow-base/src/main/yang/opendaylight-table-types.yan | ight.org/releng/v |
949 | g;a=blob;hb=refs/heads/stable/boron>`__                | iew/openflowplugi |
950 |                                                        | n/job/openflowplu |
951 |                                                        | gin-merge-boron/l |
952 |                                                        | astSuccessfulBuil |
953 |                                                        | d/artifact/model/ |
954 |                                                        | model-flow-base/t |
955 |                                                        | arget/site/models |
956 |                                                        | /opendaylight-tab |
957 |                                                        | le-types.html>`__ |
958 +--------------------------------------------------------+-------------------+
959 | `opendaylight-action-types.yang <https://git.opendayli | `YangDOC <https:/ |
960 | ght.org/gerrit/gitweb?p=openflowplugin.git;f=model/mod | /jenkins.opendayl |
961 | el-flow-base/src/main/yang/opendaylight-action-types.y | ight.org/releng/v |
962 | ang;a=blob;hb=refs/heads/stable/boron>`__              | iew/openflowplugi |
963 |                                                        | n/job/openflowplu |
964 |                                                        | gin-merge-boron/l |
965 |                                                        | astSuccessfulBuil |
966 |                                                        | d/artifact/model/ |
967 |                                                        | model-flow-base/t |
968 |                                                        | arget/site/models |
969 |                                                        | /opendaylight-act |
970 |                                                        | ion-types.html>`_ |
971 |                                                        | _                 |
972 +--------------------------------------------------------+-------------------+
973 | `opendaylight-flow-types.yan <https://git.opendaylight | `YangDOC <https:/ |
974 | .org/gerrit/gitweb?p=openflowplugin.git;f=model/model- | /jenkins.opendayl |
975 | flow-base/src/main/yang/opendaylight-flow-types.yang;a | ight.org/releng/v |
976 | =blob;hb=refs/heads/stable/boron>`__                   | iew/openflowplugi |
977 |                                                        | n/job/openflowplu |
978 |                                                        | gin-merge-boron/l |
979 |                                                        | astSuccessfulBuil |
980 |                                                        | d/artifact/model/ |
981 |                                                        | model-flow-base/t |
982 |                                                        | arget/site/models |
983 |                                                        | /opendaylight-flo |
984 |                                                        | w-types.html>`__  |
985 +--------------------------------------------------------+-------------------+
986 | `opendaylight-meter-types.yang <https://git.opendaylig | `YangDOC <https:/ |
987 | ht.org/gerrit/gitweb?p=openflowplugin.git;f=model/mode | /jenkins.opendayl |
988 | l-flow-base/src/main/yang/opendaylight-meter-types.yan | ight.org/releng/v |
989 | g;a=blob;hb=refs/heads/stable/boron>`__                | iew/openflowplugi |
990 |                                                        | n/job/openflowplu |
991 |                                                        | gin-merge-boron/l |
992 |                                                        | astSuccessfulBuil |
993 |                                                        | d/artifact/model/ |
994 |                                                        | model-flow-base/t |
995 |                                                        | arget/site/models |
996 |                                                        | /opendaylight-met |
997 |                                                        | er-types.html>`__ |
998 +--------------------------------------------------------+-------------------+
999 | `opendaylight-group-types.yang <https://git.opendaylig | `YangDOC <https:/ |
1000 | ht.org/gerrit/gitweb?p=openflowplugin.git;f=model/mode | /jenkins.opendayl |
1001 | l-flow-base/src/main/yang/opendaylight-group-types.yan | ight.org/releng/v |
1002 | g;a=blob;hb=refs/heads/stable/boron>`__                | iew/openflowplugi |
1003 |                                                        | n/job/openflowplu |
1004 |                                                        | gin-merge-boron/l |
1005 |                                                        | astSuccessfulBuil |
1006 |                                                        | d/artifact/model/ |
1007 |                                                        | model-flow-base/t |
1008 |                                                        | arget/site/models |
1009 |                                                        | /opendaylight-gro |
1010 |                                                        | up-types.html>`__ |
1011 +--------------------------------------------------------+-------------------+
1012 | `opendaylight-match-types.yang <https://git.opendaylig | `YangDOC <https:/ |
1013 | ht.org/gerrit/gitweb?p=openflowplugin.git;f=model/mode | /jenkins.opendayl |
1014 | l-flow-base/src/main/yang/opendaylight-match-types.yan | ight.org/releng/v |
1015 | g;a=blob;hb=refs/heads/stable/boron>`__                | iew/openflowplugi |
1016 |                                                        | n/job/openflowplu |
1017 |                                                        | gin-merge-boron/l |
1018 |                                                        | astSuccessfulBuil |
1019 |                                                        | d/artifact/model/ |
1020 |                                                        | model-flow-base/t |
1021 |                                                        | arget/site/models |
1022 |                                                        | /opendaylight-mat |
1023 |                                                        | ch-types.html>`__ |
1024 +--------------------------------------------------------+-------------------+
1025 | `opendaylight-port-types.yang <https://git.opendayligh | `YangDOC <https:/ |
1026 | t.org/gerrit/gitweb?p=openflowplugin.git;f=model/model | /jenkins.opendayl |
1027 | -flow-base/src/main/yang/opendaylight-port-types.yang; | ight.org/releng/v |
1028 | a=blob;hb=refs/heads/stable/boron>`__                  | iew/openflowplugi |
1029 |                                                        | n/job/openflowplu |
1030 |                                                        | gin-merge-boron/l |
1031 |                                                        | astSuccessfulBuil |
1032 |                                                        | d/artifact/model/ |
1033 |                                                        | model-flow-base/t |
1034 |                                                        | arget/site/models |
1035 |                                                        | /opendaylight-por |
1036 |                                                        | t-types.html>`__  |
1037 +--------------------------------------------------------+-------------------+
1038 | `opendaylight-queue-types.yang <https://git.opendaylig | `YangDOC <https:/ |
1039 | ht.org/gerrit/gitweb?p=openflowplugin.git;f=model/mode | /jenkins.opendayl |
1040 | l-flow-base/src/main/yang/opendaylight-queue-types.yan | ight.org/releng/v |
1041 | g;a=blob;hb=refs/heads/stable/boron>`__                | iew/openflowplugi |
1042 |                                                        | n/job/openflowplu |
1043 |                                                        | gin-merge-boron/l |
1044 |                                                        | astSuccessfulBuil |
1045 |                                                        | d/artifact/model/ |
1046 |                                                        | model-flow-base/t |
1047 |                                                        | arget/site/models |
1048 |                                                        | /opendaylight-que |
1049 |                                                        | ue-types.html>`__ |
1050 +--------------------------------------------------------+-------------------+
1051 | ***Openflow services***                                |
1052 +--------------------------------------------------------+-------------------+
1053 | `sal-table.yang <https://git.opendaylight.org/gerrit/g | `YangDOC <https:/ |
1054 | itweb?p=openflowplugin.git;f=model/model-flow-service/ | /jenkins.opendayl |
1055 | src/main/yang/sal-table.yang;a=blob;hb=refs/heads/stab | ight.org/releng/v |
1056 | le/boron>`__                                           | iew/openflowplugi |
1057 |                                                        | n/job/openflowplu |
1058 |                                                        | gin-merge-boron/l |
1059 |                                                        | astSuccessfulBuil |
1060 |                                                        | d/artifact/model/ |
1061 |                                                        | model-flow-servic |
1062 |                                                        | e/target/site/mod |
1063 |                                                        | els/sal-table.htm |
1064 |                                                        | l>`__             |
1065 +--------------------------------------------------------+-------------------+
1066 | `sal-group.yang <https://git.opendaylight.org/gerrit/g | `YangDOC <https:/ |
1067 | itweb?p=openflowplugin.git;f=model/model-flow-service/ | /jenkins.opendayl |
1068 | src/main/yang/sal-group.yang;a=blob;hb=refs/heads/stab | ight.org/releng/v |
1069 | le/boron>`__                                           | iew/openflowplugi |
1070 |                                                        | n/job/openflowplu |
1071 |                                                        | gin-merge-boron/l |
1072 |                                                        | astSuccessfulBuil |
1073 |                                                        | d/artifact/model/ |
1074 |                                                        | model-flow-servic |
1075 |                                                        | e/target/site/mod |
1076 |                                                        | els/sal-group.htm |
1077 |                                                        | l>`__             |
1078 +--------------------------------------------------------+-------------------+
1079 | `sal-queue.yang <https://git.opendaylight.org/gerrit/g | `YangDOC <https:/ |
1080 | itweb?p=openflowplugin.git;f=model/model-flow-service/ | /jenkins.opendayl |
1081 | src/main/yang/sal-queue.yang;a=blob;hb=refs/heads/stab | ight.org/releng/v |
1082 | le/boron>`__                                           | iew/openflowplugi |
1083 |                                                        | n/job/openflowplu |
1084 |                                                        | gin-merge-boron/l |
1085 |                                                        | astSuccessfulBuil |
1086 |                                                        | d/artifact/model/ |
1087 |                                                        | model-flow-servic |
1088 |                                                        | e/target/site/mod |
1089 |                                                        | els/sal-queue.htm |
1090 |                                                        | l>`__             |
1091 +--------------------------------------------------------+-------------------+
1092 | `flow-errors.yang <https://git.opendaylight.org/gerrit | `YangDOC <https:/ |
1093 | /gitweb?p=openflowplugin.git;f=model/model-flow-servic | /jenkins.opendayl |
1094 | e/src/main/yang/flow-errors.yang;a=blob;hb=refs/heads/ | ight.org/releng/v |
1095 | stable/boron>`__                                       | iew/openflowplugi |
1096 |                                                        | n/job/openflowplu |
1097 |                                                        | gin-merge-boron/l |
1098 |                                                        | astSuccessfulBuil |
1099 |                                                        | d/artifact/model/ |
1100 |                                                        | model-flow-servic |
1101 |                                                        | e/target/site/mod |
1102 |                                                        | els/flow-errors.h |
1103 |                                                        | tml>`__           |
1104 +--------------------------------------------------------+-------------------+
1105 | `flow-capable-transaction.yang <https://git.opendaylig | `YangDOC <https:/ |
1106 | ht.org/gerrit/gitweb?p=openflowplugin.git;f=model/mode | /jenkins.opendayl |
1107 | l-flow-service/src/main/yang/flow-capable-transaction. | ight.org/releng/v |
1108 | yang;a=blob;hb=refs/heads/stable/boron>`__             | iew/openflowplugi |
1109 |                                                        | n/job/openflowplu |
1110 |                                                        | gin-merge-boron/l |
1111 |                                                        | astSuccessfulBuil |
1112 |                                                        | d/artifact/model/ |
1113 |                                                        | model-flow-servic |
1114 |                                                        | e/target/site/mod |
1115 |                                                        | els/flow-capable- |
1116 |                                                        | transaction.html> |
1117 |                                                        | `__               |
1118 +--------------------------------------------------------+-------------------+
1119 | `sal-flow.yang <https://git.opendaylight.org/gerrit/gi | `YangDOC <https:/ |
1120 | tweb?p=openflowplugin.git;f=model/model-flow-service/s | /jenkins.opendayl |
1121 | rc/main/yang/sal-flow.yang;a=blob;hb=refs/heads/stable | ight.org/releng/v |
1122 | /boron>`__                                             | iew/openflowplugi |
1123 |                                                        | n/job/openflowplu |
1124 |                                                        | gin-merge-boron/l |
1125 |                                                        | astSuccessfulBuil |
1126 |                                                        | d/artifact/model/ |
1127 |                                                        | model-flow-servic |
1128 |                                                        | e/target/site/mod |
1129 |                                                        | els/sal-flow.html |
1130 |                                                        | >`__              |
1131 +--------------------------------------------------------+-------------------+
1132 | `sal-meter.yang <https://git.opendaylight.org/gerrit/g | `YangDOC <https:/ |
1133 | itweb?p=openflowplugin.git;f=model/model-flow-service/ | /jenkins.opendayl |
1134 | src/main/yang/sal-meter.yang;a=blob;hb=refs/heads/stab | ight.org/releng/v |
1135 | le/boron>`__                                           | iew/openflowplugi |
1136 |                                                        | n/job/openflowplu |
1137 |                                                        | gin-merge-boron/l |
1138 |                                                        | astSuccessfulBuil |
1139 |                                                        | d/artifact/model/ |
1140 |                                                        | model-flow-servic |
1141 |                                                        | e/target/site/mod |
1142 |                                                        | els/sal-meter.htm |
1143 |                                                        | l>`__             |
1144 +--------------------------------------------------------+-------------------+
1145 | `flow-topology-discovery.yang <https://git.opendayligh | `YangDOC <https:/ |
1146 | t.org/gerrit/gitweb?p=openflowplugin.git;f=model/model | /jenkins.opendayl |
1147 | -flow-service/src/main/yang/flow-topology-discovery.ya | ight.org/releng/v |
1148 | ng;a=blob;hb=refs/heads/stable/boron>`__               | iew/openflowplugi |
1149 |                                                        | n/job/openflowplu |
1150 |                                                        | gin-merge-boron/l |
1151 |                                                        | astSuccessfulBuil |
1152 |                                                        | d/artifact/model/ |
1153 |                                                        | model-flow-servic |
1154 |                                                        | e/target/site/mod |
1155 |                                                        | els/flow-topology |
1156 |                                                        | -discovery.html>` |
1157 |                                                        | __                |
1158 +--------------------------------------------------------+-------------------+
1159 | `node-errors.yang <https://git.opendaylight.org/gerrit | `YangDOC <https:/ |
1160 | /gitweb?p=openflowplugin.git;f=model/model-flow-servic | /jenkins.opendayl |
1161 | e/src/main/yang/node-errors.yang;a=blob;hb=refs/heads/ | ight.org/releng/v |
1162 | stable/boron>`__                                       | iew/openflowplugi |
1163 |                                                        | n/job/openflowplu |
1164 |                                                        | gin-merge-boron/l |
1165 |                                                        | astSuccessfulBuil |
1166 |                                                        | d/artifact/model/ |
1167 |                                                        | model-flow-servic |
1168 |                                                        | e/target/site/mod |
1169 |                                                        | els/node-errors.h |
1170 |                                                        | tml>`__           |
1171 +--------------------------------------------------------+-------------------+
1172 | `node-config.yang <https://git.opendaylight.org/gerrit | `YangDOC <https:/ |
1173 | /gitweb?p=openflowplugin.git;f=model/model-flow-servic | /jenkins.opendayl |
1174 | e/src/main/yang/node-config.yang;a=blob;hb=refs/heads/ | ight.org/releng/v |
1175 | stable/boron>`__                                       | iew/openflowplugi |
1176 |                                                        | n/job/openflowplu |
1177 |                                                        | gin-merge-boron/l |
1178 |                                                        | astSuccessfulBuil |
1179 |                                                        | d/artifact/model/ |
1180 |                                                        | model-flow-servic |
1181 |                                                        | e/target/site/mod |
1182 |                                                        | els/node-config.h |
1183 |                                                        | tml>`__           |
1184 +--------------------------------------------------------+-------------------+
1185 | `sal-echo.yang <https://git.opendaylight.org/gerrit/gi | `YangDOC <https:/ |
1186 | tweb?p=openflowplugin.git;f=model/model-flow-service/s | /jenkins.opendayl |
1187 | rc/main/yang/sal-echo.yang;a=blob;hb=refs/heads/stable | ight.org/releng/v |
1188 | /boron>`__                                             | iew/openflowplugi |
1189 |                                                        | n/job/openflowplu |
1190 |                                                        | gin-merge-boron/l |
1191 |                                                        | astSuccessfulBuil |
1192 |                                                        | d/artifact/model/ |
1193 |                                                        | model-flow-servic |
1194 |                                                        | e/target/site/mod |
1195 |                                                        | els/sal-echo.html |
1196 |                                                        | >`__              |
1197 +--------------------------------------------------------+-------------------+
1198 | `sal-port.yang <https://git.opendaylight.org/gerrit/gi | `YangDOC <https:/ |
1199 | tweb?p=openflowplugin.git;f=model/model-flow-service/s | /jenkins.opendayl |
1200 | rc/main/yang/sal-port.yang;a=blob;hb=refs/heads/stable | ight.org/releng/v |
1201 | /boron>`__                                             | iew/openflowplugi |
1202 |                                                        | n/job/openflowplu |
1203 |                                                        | gin-merge-boron/l |
1204 |                                                        | astSuccessfulBuil |
1205 |                                                        | d/artifact/model/ |
1206 |                                                        | model-flow-servic |
1207 |                                                        | e/target/site/mod |
1208 |                                                        | els/sal-port.html |
1209 |                                                        | >`__              |
1210 +--------------------------------------------------------+-------------------+
1211 | `packet-processing.yang <https://git.opendaylight.org/ | `YangDOC <https:/ |
1212 | gerrit/gitweb?p=openflowplugin.git;f=model/model-flow- | /jenkins.opendayl |
1213 | service/src/main/yang/packet-processing.yang;a=blob;hb | ight.org/releng/v |
1214 | =refs/heads/stable/boron>`__                           | iew/openflowplugi |
1215 |                                                        | n/job/openflowplu |
1216 |                                                        | gin-merge-boron/l |
1217 |                                                        | astSuccessfulBuil |
1218 |                                                        | d/artifact/model/ |
1219 |                                                        | model-flow-servic |
1220 |                                                        | e/target/site/mod |
1221 |                                                        | els/packet-proces |
1222 |                                                        | sing.html>`__     |
1223 +--------------------------------------------------------+-------------------+
1224 | `flow-node-inventory.yang <https://git.opendaylight.or | `YangDOC <https:/ |
1225 | g/gerrit/gitweb?p=openflowplugin.git;f=model/model-flo | /jenkins.opendayl |
1226 | w-service/src/main/yang/flow-node-inventory.yang;a=blo | ight.org/releng/v |
1227 | b;hb=refs/heads/stable/boron>`__                       | iew/openflowplugi |
1228 |                                                        | n/job/openflowplu |
1229 |                                                        | gin-merge-boron/l |
1230 |                                                        | astSuccessfulBuil |
1231 |                                                        | d/artifact/model/ |
1232 |                                                        | model-flow-servic |
1233 |                                                        | e/target/site/mod |
1234 |                                                        | els/flow-node-inv |
1235 |                                                        | entory.html>`__   |
1236 +--------------------------------------------------------+-------------------+
1237 | ***Openflow statistics***                              |
1238 +--------------------------------------------------------+-------------------+
1239 | `opendaylight-queue-statistics.yang <https://git.opend | `YangDOC <https:/ |
1240 | aylight.org/gerrit/gitweb?p=openflowplugin.git;f=model | /jenkins.opendayl |
1241 | /model-flow-statistics/src/main/yang/opendaylight-queu | ight.org/releng/v |
1242 | e-statistics.yang;a=blob;hb=refs/heads/stable/boron>`_ | iew/openflowplugi |
1243 | _                                                      | n/job/openflowplu |
1244 |                                                        | gin-merge-boron/l |
1245 |                                                        | astSuccessfulBuil |
1246 |                                                        | d/artifact/model/ |
1247 |                                                        | model-flow-statis |
1248 |                                                        | tics/target/site/ |
1249 |                                                        | models/opendaylig |
1250 |                                                        | ht-queue-statisti |
1251 |                                                        | cs.html>`__       |
1252 +--------------------------------------------------------+-------------------+
1253 | `opendaylight-flow-table-statistics.yang <https://git. | `YangDOC <https:/ |
1254 | opendaylight.org/gerrit/gitweb?p=openflowplugin.git;f= | /jenkins.opendayl |
1255 | model/model-flow-statistics/src/main/yang/opendaylight | ight.org/releng/v |
1256 | -flow-table-statistics.yang;a=blob;hb=refs/heads/stabl | iew/openflowplugi |
1257 | e/boron>`__                                            | n/job/openflowplu |
1258 |                                                        | gin-merge-boron/l |
1259 |                                                        | astSuccessfulBuil |
1260 |                                                        | d/artifact/model/ |
1261 |                                                        | model-flow-statis |
1262 |                                                        | tics/target/site/ |
1263 |                                                        | models/opendaylig |
1264 |                                                        | ht-flow-table-sta |
1265 |                                                        | tistics.html>`__  |
1266 +--------------------------------------------------------+-------------------+
1267 | `opendaylight-port-statistics.yang <https://git.openda | `YangDOC <https:/ |
1268 | ylight.org/gerrit/gitweb?p=openflowplugin.git;f=model/ | /jenkins.opendayl |
1269 | model-flow-statistics/src/main/yang/opendaylight-port- | ight.org/releng/v |
1270 | statistics.yang;a=blob;hb=refs/heads/stable/boron>`__  | iew/openflowplugi |
1271 |                                                        | n/job/openflowplu |
1272 |                                                        | gin-merge-boron/l |
1273 |                                                        | astSuccessfulBuil |
1274 |                                                        | d/artifact/model/ |
1275 |                                                        | model-flow-statis |
1276 |                                                        | tics/target/site/ |
1277 |                                                        | models/opendaylig |
1278 |                                                        | ht-port-statistic |
1279 |                                                        | s.html>`__        |
1280 +--------------------------------------------------------+-------------------+
1281 | `opendaylight-statistics-types.yang <https://git.opend | `YangDOC <https:/ |
1282 | aylight.org/gerrit/gitweb?p=openflowplugin.git;f=model | /jenkins.opendayl |
1283 | /model-flow-statistics/src/main/yang/opendaylight-stat | ight.org/releng/v |
1284 | istics-types.yang;a=blob;hb=refs/heads/stable/boron>`_ | iew/openflowplugi |
1285 | _                                                      | n/job/openflowplu |
1286 |                                                        | gin-merge-boron/l |
1287 |                                                        | astSuccessfulBuil |
1288 |                                                        | d/artifact/model/ |
1289 |                                                        | model-flow-statis |
1290 |                                                        | tics/target/site/ |
1291 |                                                        | models/opendaylig |
1292 |                                                        | ht-statistics-typ |
1293 |                                                        | es.html>`__       |
1294 +--------------------------------------------------------+-------------------+
1295 | `opendaylight-group-statistics.yang <https://git.opend | `YangDOC <https:/ |
1296 | aylight.org/gerrit/gitweb?p=openflowplugin.git;f=model | /jenkins.opendayl |
1297 | /model-flow-statistics/src/main/yang/opendaylight-grou | ight.org/releng/v |
1298 | p-statistics.yang;a=blob;hb=refs/heads/stable/boron>`_ | iew/openflowplugi |
1299 | _                                                      | n/job/openflowplu |
1300 |                                                        | gin-merge-boron/l |
1301 |                                                        | astSuccessfulBuil |
1302 |                                                        | d/artifact/model/ |
1303 |                                                        | model-flow-statis |
1304 |                                                        | tics/target/site/ |
1305 |                                                        | models/opendaylig |
1306 |                                                        | ht-group-statisti |
1307 |                                                        | cs.html>`__       |
1308 +--------------------------------------------------------+-------------------+
1309 | `opendaylight-flow-statistics.yang <https://git.openda | `YangDOC <https:/ |
1310 | ylight.org/gerrit/gitweb?p=openflowplugin.git;f=model/ | /jenkins.opendayl |
1311 | model-flow-statistics/src/main/yang/opendaylight-flow- | ight.org/releng/v |
1312 | statistics.yang;a=blob;hb=refs/heads/stable/boron>`__  | iew/openflowplugi |
1313 |                                                        | n/job/openflowplu |
1314 |                                                        | gin-merge-boron/l |
1315 |                                                        | astSuccessfulBuil |
1316 |                                                        | d/artifact/model/ |
1317 |                                                        | model-flow-statis |
1318 |                                                        | tics/target/site/ |
1319 |                                                        | models/opendaylig |
1320 |                                                        | ht-flow-statistic |
1321 |                                                        | s.html>`__        |
1322 +--------------------------------------------------------+-------------------+
1323 | `opendaylight-meter-statistics.yang <https://git.opend | `YangDOC <https:/ |
1324 | aylight.org/gerrit/gitweb?p=openflowplugin.git;f=model | /jenkins.opendayl |
1325 | /model-flow-statistics/src/main/yang/opendaylight-mete | ight.org/releng/v |
1326 | r-statistics.yang;a=blob;hb=refs/heads/stable/boron>`_ | iew/openflowplugi |
1327 | _                                                      | n/job/openflowplu |
1328 |                                                        | gin-merge-boron/l |
1329 |                                                        | astSuccessfulBuil |
1330 |                                                        | d/artifact/model/ |
1331 |                                                        | model-flow-statis |
1332 |                                                        | tics/target/site/ |
1333 |                                                        | models/opendaylig |
1334 |                                                        | ht-meter-statisti |
1335 |                                                        | cs.html>`__       |
1336 +--------------------------------------------------------+-------------------+
1337
1338 Karaf feature tree
1339 ------------------
1340
1341 .. figure:: ./images/openflowplugin/odl-ofp-feature-tree.png
1342    :alt: Openflow plugin karaf feature tree
1343
1344    Openflow plugin karaf feature tree
1345
1346 Short
1347 `HOWTO <https://wiki.opendaylight.org/view/OpenDaylight_OpenFlow_Plugin:FeatureTreeHowto>`__
1348 create such a tree.
1349
1350 Wiring up notifications
1351 -----------------------
1352
1353 Introduction
1354 ~~~~~~~~~~~~
1355
1356 We need to translate OpenFlow messages coming up from the `OpenFlow
1357 Protocol Library <#_openflow_protocol_library_developer_guide>`__ into
1358 MD-SAL Notification objects and then publish them to the MD-SAL.
1359
1360 Mechanics
1361 ~~~~~~~~~
1362
1363 1. Create a Translator class
1364
1365 2. Register the Translator
1366
1367 3. Register the notificationPopListener to handle your Notification
1368    Objects
1369
1370 Create a Translator class
1371 ^^^^^^^^^^^^^^^^^^^^^^^^^
1372
1373 You can see an example in
1374 `PacketInTranslator.java <https://git.opendaylight.org/gerrit/gitweb?p=openflowplugin.git;a=blob;f=openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/translator/PacketInTranslator.java;hb=refs/heads/stable/boron>`__.
1375
1376 First, simply create the class
1377
1378 ::
1379
1380     public class PacketInTranslator implements IMDMessageTranslator<OfHeader, List<DataObject>> {
1381
1382 Then implement the translate function:
1383
1384 ::
1385
1386     public class PacketInTranslator implements IMDMessageTranslator<OfHeader, List<DataObject>> {
1387
1388         protected static final Logger LOG = LoggerFactory
1389                 .getLogger(PacketInTranslator.class);
1390         @Override
1391         public PacketReceived translate(SwitchConnectionDistinguisher cookie,
1392                 SessionContext sc, OfHeader msg) {
1393                 ...
1394         }
1395
1396 Make sure to check that you are dealing with the expected type and cast
1397 it:
1398
1399 ::
1400
1401     if(msg instanceof PacketInMessage) {
1402         PacketInMessage message = (PacketInMessage)msg;
1403         List<DataObject> list = new CopyOnWriteArrayList<DataObject>();
1404
1405 Do your transation work and return
1406
1407 ::
1408
1409     PacketReceived pktInEvent = pktInBuilder.build();
1410     list.add(pktInEvent);
1411     return list;
1412
1413 Register your Translator Class
1414 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1415
1416 Next you need to go to
1417 `MDController.java <https://git.opendaylight.org/gerrit/gitweb?p=openflowplugin.git;a=blob;f=openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/MDController.java;hb=refs/heads/stable/boron>`__
1418 and in init() add register your Translator:
1419
1420 ::
1421
1422     public void init() {
1423             LOG.debug("Initializing!");
1424             messageTranslators = new ConcurrentHashMap<>();
1425             popListeners = new ConcurrentHashMap<>();
1426             //TODO: move registration to factory
1427             addMessageTranslator(ErrorMessage.class, OF10, new ErrorTranslator());
1428             addMessageTranslator(ErrorMessage.class, OF13, new ErrorTranslator());
1429             addMessageTranslator(PacketInMessage.class,OF10, new PacketInTranslator());
1430             addMessageTranslator(PacketInMessage.class,OF13, new PacketInTranslator());
1431
1432 Notice that there is a separate registration for each of OpenFlow 1.0
1433 and OpenFlow 1.3. Basically, you indicate the type of OpenFlow Protocol
1434 Library message you wish to translate for, the OpenFlow version, and an
1435 instance of your Translator.
1436
1437 Register your MD-SAL Message for Notification to the MD-SAL
1438 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1439
1440 Now, also in MDController.init() register to have the
1441 notificationPopListener handle your MD-SAL Message:
1442
1443 ::
1444
1445     addMessagePopListener(PacketReceived.class, new NotificationPopListener<DataObject>());
1446
1447 You are done
1448 ^^^^^^^^^^^^
1449
1450 That’s all there is to it. Now when a message comes up from the OpenFlow
1451 Protocol Library, it will be translated and published to the MD-SAL.
1452
1453 Message Order Preservation
1454 --------------------------
1455
1456 While the Helium release of OpenFlow Plugin relied on queues to ensure
1457 messages were delivered in order, subsequent releases instead ensure
1458 that all the messages from a given device are delivered using the same
1459 thread and thus message order is guaranteed without queues. The OpenFlow
1460 plugin allocates a number of threads equal to twice the number of
1461 processor cores on machine it is run, e.g., 8 threads if the machine has
1462 4 cores.
1463
1464 .. note::
1465
1466     While each device is assigned to one thread, multiple devices can be
1467     assigned to the same thread.
1468