Merge "Migrate Atrium dev docs to rst"
[docs.git] / docs / developer-guide / topology-processing-framework-developer-guide.rst
1 Topology Processing Framework Developer Guide
2 =============================================
3
4 Overview
5 --------
6
7 The Topology Processing Framework allows developers to aggregate and
8 filter topologies according to defined correlations. It also provides
9 functionality, which you can use to make your own topology model by
10 automating the translation from one model to another. For example to
11 translate from the opendaylight-inventory model to only using the
12 network-topology model.
13
14 Architecture
15 ------------
16
17 Chapter Overview
18 ~~~~~~~~~~~~~~~~
19
20 In this chapter we describe the architecture of the Topology Processing
21 Framework. In the first part, we provide information about available
22 features and basic class relationships. In the second part, we describe
23 our model specific approach, which is used to provide support for
24 different models.
25
26 Basic Architecture
27 ~~~~~~~~~~~~~~~~~~
28
29 The Topology Processing Framework consists of several Karaf features:
30
31 -  odl-topoprocessing-framework
32
33 -  odl-topoprocessing-inventory
34
35 -  odl-topoprocessing-network-topology
36
37 -  odl-topoprocessing-i2rs
38
39 -  odl-topoprocessing-inventory-rendering
40
41 The feature odl-topoprocessing-framework contains the
42 topoprocessing-api, topoprocessing-spi and topoprocessing-impl bundles.
43 This feature is the core of the Topology Processing Framework and is
44 required by all others features.
45
46 -  topoprocessing-api - contains correlation definitions and definitions
47    required for rendering
48
49 -  topoprocessing-spi - entry point for topoprocessing service (start
50    and close)
51
52 -  topoprocessing-impl - contains base implementations of handlers,
53    listeners, aggregators and filtrators
54
55 TopoProcessingProvider is the entry point for Topology Processing
56 Framework. It requires a DataBroker instance. The DataBroker is needed
57 for listener registration. There is also the TopologyRequestListener
58 which listens on aggregated topology requests (placed into the
59 configuration datastore) and UnderlayTopologyListeners which listen on
60 underlay topology data changes (made in operational datastore). The
61 TopologyRequestHandler saves toporequest data and provides a method for
62 translating a path to the specified leaf. When a change in the topology
63 occurs, the registered UnderlayTopologyListener processes this
64 information for further aggregation and/or filtration. Finally, after an
65 overlay topology is created, it is passed to the TopologyWriter, which
66 writes this topology into operational datastore.
67
68 .. figure:: ./images/topoprocessing/TopologyRequestHandler_classesRelationship.png
69    :alt: Class relationship
70
71    Class relationship
72
73 [1] TopologyRequestHandler instantiates TopologyWriter and
74 TopologyManager. Then, according to the request, initializes either
75 TopologyAggregator, TopologyFiltrator or LinkCalculator.
76
77 [2] It creates as many instances of UnderlayTopologyListener as there
78 are underlay topologies.
79
80 [3] PhysicalNodes are created for relevant incoming nodes (those having
81 node ID).
82
83 [4a] It performs aggregation and creates logical nodes.
84
85 [4b] It performs filtration and creates logical nodes.
86
87 [4c] It performs link computation and creates links between logical
88 nodes.
89
90 [5] Logical nodes are put into wrapper.
91
92 [6] The wrapper is translated into the appropriate format and written
93 into datastore.
94
95 Model Specific Approach
96 ~~~~~~~~~~~~~~~~~~~~~~~
97
98 The Topology Processing Framework consists of several modules and Karaf
99 features, which provide support for different input models. Currently we
100 support the network-topology, opendaylight-inventory and i2rs models.
101 For each of these input models, the Topology Processing Framework has
102 one module and one Karaf feature.
103
104 How it works
105 ^^^^^^^^^^^^
106
107 **User point of view:**
108
109 When you start the odl-topoprocessing-framework feature, the Topology
110 Processing Framework starts without knowledge how to work with any input
111 models. In order to allow the Topology Processing Framework to process
112 some kind of input model, you must install one (or more) model specific
113 features. Installing these features will also start
114 odl-topoprocessing-framework feature if it is not already running. These
115 features inject appropriate logic into the odl-topoprocessing-framework
116 feature. From that point, the Topology Processing Framework is able to
117 process different kinds of input models, specifically those that you
118 install features for.
119
120 **Developer point of view:**
121
122 The topoprocessing-impl module contains (among other things) classes and
123 interfaces, which are common for every model specific topoprocessing
124 module. These classes and interfaces are implemented and extended by
125 classes in particular model specific modules. Model specific modules
126 also depend on the TopoProcessingProvider class in the
127 topoprocessing-spi module. This dependency is injected during
128 installation of model specific features in Karaf. When a model specific
129 feature is started, it calls the registerAdapters(adapters) method of
130 the injected TopoProcessingProvider object. After this step, the
131 Topology Processing Framework is able to use registered model adapters
132 to work with input models.
133
134 To achieve the described functionality we created a ModelAdapter
135 interface. It represents installed feature and provides methods for
136 creating crucial structures specific to each model.
137
138 .. figure:: ./images/topoprocessing/ModelAdapter.png
139    :alt: ModelAdapter interface
140
141    ModelAdapter interface
142
143 Model Specific Features
144 ^^^^^^^^^^^^^^^^^^^^^^^
145
146 -  odl-topoprocessing-network-topology - this feature contains logic to
147    work with network-topology model
148
149 -  odl-topoprocessing-inventory - this feature contains logic to work
150    with opendaylight-inventory model
151
152 -  odl-topoprocessing-i2rs - this feature contains logic to work with
153    i2rs model
154
155 Inventory Model Support
156 ~~~~~~~~~~~~~~~~~~~~~~~
157
158 The opendaylight-inventory model contains only nodes, termination
159 points, information regarding these structures. This model co-operates
160 with network-topology model, where other topology related information is
161 stored. This means that we have to handle two input models at once. To
162 support the inventory model, InventoryListener and
163 NotificationInterConnector classes were introduced. Please see the flow
164 diagrams below.
165
166 .. figure:: ./images/topoprocessing/Network_topology_model_flow_diagram.png
167    :alt: Network topology model
168
169    Network topology model
170
171 .. figure:: ./images/topoprocessing/Inventory_model_listener_diagram.png
172    :alt: Inventory model
173
174    Inventory model
175
176 Here we can see the InventoryListener and NotificationInterConnector
177 classes. InventoryListener listens on data changes in the inventory
178 model and passes these changes wrapped as an UnderlayItem for further
179 processing to NotificationInterConnector. It doesn’t contain node
180 information - it contains a leafNode (node based on which aggregation
181 occurs) instead. The node information is stored in the topology model,
182 where UnderlayTopologyListener is registered as usual. This listener
183 delivers the missing information.
184
185 Then the NotificationInterConnector combines the two notifications into
186 a complete UnderlayItem (no null values) and delivers this UnderlayItem
187 for further processing (to next TopologyOperator).
188
189 Aggregation and Filtration
190 --------------------------
191
192 Chapter Overview
193 ~~~~~~~~~~~~~~~~
194
195 The Topology Processing Framework allows the creation of aggregated
196 topologies and filtered views over existing topologies. Currently,
197 aggregation and filtration is supported for topologies that follow
198 `network-topology <https://github.com/opendaylight/yangtools/blob/master/model/ietf/ietf-topology/src/main/yang/network-topology%402013-10-21.yang>`__,
199 opendaylight-inventory or i2rs model. When a request to create an
200 aggregated or filtered topology is received, the framework creates one
201 listener per underlay topology. Whenever any specified underlay topology
202 is changed, the appropriate listener is triggered with the change and
203 the change is processed. Two types of correlations (functionalities) are
204 currently supported:
205
206 -  Aggregation
207
208    -  Unification
209
210    -  Equality
211
212 -  Filtration
213
214 Terminology
215 ~~~~~~~~~~~
216
217 We use the term underlay item (physical node) for items (nodes, links,
218 termination-points) from underlay and overlay item (logical node) for
219 items from overlay topologies regardless of whether those are actually
220 physical network elements.
221
222 Aggregation
223 ~~~~~~~~~~~
224
225 Aggregation is an operation which creates an aggregated item from two or
226 more items in the underlay topology if the aggregation condition is
227 fulfilled. Requests for aggregated topologies must specify a list of
228 underlay topologies over which the overlay (aggregated) topology will be
229 created and a target field in the underlay item that the framework will
230 check for equality.
231
232 Create Overlay Node
233 ^^^^^^^^^^^^^^^^^^^
234
235 First, each new underlay item is inserted into the proper topology
236 store. Once the item is stored, the framework compares it (using the
237 target field value) with all stored underlay items from underlay
238 topologies. If there is a target-field match, a new overlay item is
239 created containing pointers to all *equal* underlay items. The newly
240 created overlay item is also given new references to its supporting
241 underlay items.
242
243 **Equality case:**
244
245 If an item doesn’t fulfill the equality condition with any other items,
246 processing finishes after adding the item into topology store. It will
247 stay there for future use, ready to create an aggregated item with a new
248 underlay item, with which it would satisfy the equality condition.
249
250 **Unification case:**
251
252 An overlay item is created for all underlay items, even those which
253 don’t fulfill the equality condition with any other items. This means
254 that an overlay item is created for every underlay item, but for items
255 which satisfy the equality condition, an aggregated item is created.
256
257 Update Node
258 ^^^^^^^^^^^
259
260 Processing of updated underlay items depends on whether the target field
261 has been modified. If yes, then:
262
263 -  if the underlay item belonged to some overlay item, it is removed
264    from that item. Next, if the aggregation condition on the target
265    field is satisfied, the item is inserted into another overlay item.
266    If the condition isn’t met then:
267
268    -  in equality case - the item will not be present in overlay
269       topology.
270
271    -  in unification case - the item will create an overlay item with a
272       single underlay item and this will be written into overlay
273       topology.
274
275 -  if the item didn’t belong to some overlay item, it is checked again
276    for aggregation with other underlay items.
277
278 Remove Node
279 ^^^^^^^^^^^
280
281 The underlay item is removed from the corresponding topology store, from
282 it’s overlay item (if it belongs to one) and this way it is also removed
283 from overlay topology.
284
285 **Equality case:**
286
287 If there is only one underlay item left in the overlay item, the overlay
288 item is removed.
289
290 **Unification case:**
291
292 The overlay item is removed once it refers to no underlay item.
293
294 Filtration
295 ~~~~~~~~~~
296
297 Filtration is an operation which results in creation of overlay topology
298 containing only items fulfilling conditions set in the topoprocessing
299 request.
300
301 Create Underlay Item
302 ^^^^^^^^^^^^^^^^^^^^
303
304 If a newly created underlay item passes all filtrators and their
305 conditions, then it is stored in topology store and a creation
306 notification is delivered into topology manager. No operation otherwise.
307
308 Update Underlay Item
309 ^^^^^^^^^^^^^^^^^^^^
310
311 First, the updated item is checked for presence in topology store:
312
313 -  if it is present in topology store:
314
315    -  if it meets the filtering conditions, then processUpdatedData
316       notification is triggered
317
318    -  else processRemovedData notification is triggered
319
320 -  if item isn’t present in topology store
321
322    -  if item meets filtering conditions, then processCreatedData
323       notification is triggered
324
325    -  else it is ignored
326
327 Remove Underlay Item
328 ^^^^^^^^^^^^^^^^^^^^
329
330 If an underlay node is supporting some overlay node, the overlay node is
331 simply removed.
332
333 Default Filtrator Types
334 ^^^^^^^^^^^^^^^^^^^^^^^
335
336 There are seven types of default filtrators defined in the framework:
337
338 -  IPv4-address filtrator - checks if specified field meets IPv4 address
339    + mask criteria
340
341 -  IPv6-address filtrator - checks if specified field meets IPv6 address
342    + mask criteria
343
344 -  Specific number filtrator - checks for specific number
345
346 -  Specific string filtrator - checks for specific string
347
348 -  Range number filtrator - checks if specified field is higher than
349    provided minimum (inclusive) and lower than provided maximum
350    (inclusive)
351
352 -  Range string filtrator - checks if specified field is alphabetically
353    greater than provided minimum (inclusive) and alphabetically lower
354    than provided maximum (inclusive)
355
356 -  Script filtrator - allows a user or application to implement their
357    own filtrator
358
359 Register Custom Filtrator
360 ^^^^^^^^^^^^^^^^^^^^^^^^^
361
362 There might be some use case that cannot be achieved with the default
363 filtrators. In these cases, the framework offers the possibility for a
364 user or application to register a custom filtrator.
365
366 Pre-Filtration / Filtration & Aggregation
367 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
368
369 This feature was introduced in order to lower memory and performance
370 demands. It is a combination of the filtration and aggregation
371 operations. First, uninteresting items are filtered out and then
372 aggregation is performed only on items that passed filtration. This way
373 the framework saves on compute time. The PreAggregationFiltrator and
374 TopologyAggregator share the same TopoStoreProvider (and thus topology
375 store) which results in lower memory demands (as underlay items are
376 stored only in one topology store - they aren’t stored twice).
377
378 Link Computation
379 ----------------
380
381 Chapter Overview
382 ~~~~~~~~~~~~~~~~
383
384 While processing the topology request, we create overlay nodes with
385 lists of supporting underlay nodes. Because these overlay nodes have
386 completely new identifiers, we lose link information. To regain this
387 link information, we provide Link Computation functionality. Its main
388 purpose is to create new overlay links based on the links from the
389 underlay topologies and underlay items from overlay items. The required
390 information for Link Computation is provided via the Link Computation
391 model in
392 (`topology-link-computation.yang <https://git.opendaylight.org/gerrit/gitweb?p=topoprocessing.git;a=blob;f=topoprocessing-api/src/main/yang/topology-link-computation.yang;hb=refs/heads/stable/beryllium>`__).
393
394 Link Computation Functionality
395 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
396
397 Let us consider two topologies with following components:
398
399 Topology 1:
400
401 -  Node: ``node:1:1``
402
403 -  Node: ``node:1:2``
404
405 -  Node: ``node:1:3``
406
407 -  Link: ``link:1:1`` (from ``node:1:1`` to ``node:1:2``)
408
409 -  Link: ``link:1:2`` (from ``node:1:3`` to ``node:1:2``)
410
411 Topology 2:
412
413 -  Node: ``node:2:1``
414
415 -  Node: ``node:2:2``
416
417 -  Node: ``node:2:3``
418
419 -  Link: ``link:2:1`` (from ``node:2:1`` to ``node:2:3``)
420
421 Now let’s say that we applied some operations over these topologies that
422 results into aggregating together
423
424 -  ``node:1:1`` and ``node:2:3`` (``node:1``)
425
426 -  ``node:1:2`` and ``node:2:2`` (``node:2``)
427
428 -  ``node:1:3`` and ``node:2:1`` (``node:3``)
429
430 At this point we can no longer use available links in new topology
431 because of the node ID change, so we must create new overlay links with
432 source and destination node set to new nodes IDs. It means that
433 ``link:1:1`` from topology 1 will create new link ``link:1``. Since
434 original source (``node:1:1``) is already aggregated under ``node:1``,
435 it will become source node for ``link:1``. Using same method the
436 destination will be ``node:2``. And the final output will be three
437 links:
438
439 -  ``link:1``, from ``node:1`` to ``node:2``
440
441 -  ``link:2``, from ``node:3`` to ``node:2``
442
443 -  ``link:3``, from ``node:3`` to ``node:1``
444
445 .. figure:: ./images/topoprocessing/LinkComputation.png
446    :alt: Overlay topology with computed links
447
448    Overlay topology with computed links
449
450 In-Depth Look
451 ~~~~~~~~~~~~~
452
453 The main logic behind Link Computation is executed in the LinkCalculator
454 operator. The required information is passed to LinkCalculator through
455 the LinkComputation section of the topology request. This section is
456 defined in the topology-link-computation.yang file. The main logic also
457 covers cases when some underlay nodes may not pass through other
458 topology operators.
459
460 Link Computation Model
461 ^^^^^^^^^^^^^^^^^^^^^^
462
463 There are three essential pieces of information for link computations.
464 All of them are provided within the LinkComputation section. These
465 pieces are:
466
467 -  output model
468
469 .. code:: yang
470
471     leaf output-model {
472         type identityref {
473             base topo-corr:model;
474         }
475         description "Desired output model for computed links.";
476     }
477
478 -  overlay topology with new nodes
479
480 .. code:: yang
481
482     container node-info {
483         leaf node-topology {
484             type string;
485             mandatory true;
486             description "Topology that contains aggregated nodes.
487                          This topology will be used for storing computed links.";
488         }
489         uses topo-corr:input-model-grouping;
490     }
491
492 -  underlay topologies with original links
493
494 .. code:: yang
495
496     list link-info {
497         key "link-topology input-model";
498         leaf link-topology {
499             type string;
500             mandatory true;
501             description "Topology that contains underlay (base) links.";
502         }
503         leaf aggregated-links {
504             type boolean;
505             description "Defines if link computation should be based on supporting-links.";
506         }
507         uses topo-corr:input-model-grouping;
508     }
509
510 This whole section is augmented into ``network-topology:topology``. By
511 placing this section out of correlations section, it allows us to send
512 link computation request separately from topology operations request.
513
514 Main Logic
515 ^^^^^^^^^^
516
517 Taking into consideration that some of the underlay nodes may not
518 transform into overlay nodes (e.g. they are filtered out), we created
519 two possible states for links:
520
521 -  matched - a link is considered as matched when both original source
522    and destination node were transformed to overlay nodes
523
524 -  waiting - a link is considered as waiting if original source,
525    destination or both nodes are missing from the overlay topology
526
527 All links in waiting the state are stored in waitingLinks list, already
528 matched links are stored in matchedLinks list and overlay nodes are
529 stored in the storedOverlayNodes list. All processing is based only on
530 information in these lists. Processing created, updated and removed
531 underlay items is slightly different and described in next sections
532 separately.
533
534 **Processing Created Items**
535
536 Created items can be either nodes or links, depending on the type of
537 listener from which they came. In the case of a link, it is immediately
538 added to waitingLinks and calculation for possible overlay link
539 creations (calculatePossibleLink) is started. The flow diagram for this
540 process is shown in the following picture:
541
542 .. figure:: ./images/topoprocessing/LinkComputationFlowDiagram.png
543    :alt: Flow diagram of processing created items
544
545    Flow diagram of processing created items
546
547 Searching for the source and destination nodes in the
548 calculatePossibleLink method runs over each node in storedOverlayNodes
549 and the IDs of each supporting node is compared against IDs from the
550 underlay link’s source and destination nodes. If there are any nodes
551 missing, the link remains in the waiting state. If both the source and
552 destination nodes are found, the corresponding overlay nodes is recorded
553 as the new source and destination. The link is then removed from
554 waitingLinks and a new CalculatedLink is added to the matched links. At
555 the end, the new link (if it exists) is written into the datastore.
556
557 If the created item is an overlayNode, this is added to
558 storedOverlayNodes and we call calculatePossibleLink for every link in
559 waitingLinks.
560
561 **Processing Updated Items**
562
563 The difference from processing created items is that we have three
564 possible types of updated items: overlay nodes, waiting underlay links,
565 and matched underlay links.
566
567 -  In the case of a change in a matched link, this must be recalculated
568    and based on the result it will either be matched with new source and
569    destination or will be returned to waiting links. If the link is
570    moved back to a waiting state, it must also be removed from the
571    datastore.
572
573 -  In the case of change in a waiting link, it is passed to the
574    calculation process and based on the result will either remain in
575    waiting state or be promoted to the matched state.
576
577 -  In the case of a change in an overlay node, storedOverlayNodes must
578    be updated properly and all links must be recalculated in case of
579    changes.
580
581 **Processing Removed items**
582
583 Same as for processing updated item. There can be three types of removed
584 items:
585
586 -  In case of waiting link removal, the link is just removed from
587    waitingLinks
588
589 -  In case of matched link removal, the link is removed from
590    matchingLinks and datastore
591
592 -  In case of overlay node removal, the node must be removed form
593    storedOverlayNodes and all matching links must be recalculated
594
595 Wrapper, RPC Republishing, Writing Mechanism
596 --------------------------------------------
597
598 Chapter Overview
599 ~~~~~~~~~~~~~~~~
600
601 During the process of aggregation and filtration, overlay items (so
602 called logical nodes) were created from underlay items (physical nodes).
603 In the topology manager, overlay items are put into a wrapper. A wrapper
604 is identified with unique ID and contains list of logical nodes.
605 Wrappers are used to deal with transitivity of underlay items - which
606 permits grouping of overlay items (into wrappers).
607
608 .. figure:: ./images/topoprocessing/wrapper.png
609    :alt: Wrapper
610
611    Wrapper
612
613 PN1, PN2, PN3 = physical nodes
614
615 LN1, LN2 = logical nodes
616
617 RPC Republishing
618 ~~~~~~~~~~~~~~~~
619
620 All RPCs registered to handle underlay items are re-registered under
621 their corresponding wrapper ID. RPCs of underlay items (belonging to an
622 overlay item) are gathered, and registered under ID of their wrapper.
623
624 RPC Call
625 ^^^^^^^^
626
627 When RPC is called on overlay item, this call is delegated to it’s
628 underlay items, this means that the RPC is called on all underlay items
629 of this overlay item.
630
631 Writing Mechanism
632 ~~~~~~~~~~~~~~~~~
633
634 When a wrapper (containing overlay item(s) with it’s underlay item(s))
635 is ready to be written into data store, it has to be converted into DOM
636 format. After this translation is done, the result is written into
637 datastore. Physical nodes are stored as supporting-nodes. In order to
638 use resources responsibly, writing operation is divided into two steps.
639 First, a set of threads registers prepared operations (deletes and puts)
640 and one thread makes actual write operation in batch.
641
642 Topology Rendering Guide - Inventory Rendering
643 ----------------------------------------------
644
645 Chapter Overview
646 ~~~~~~~~~~~~~~~~
647
648 In the most recent OpenDaylight release, the opendaylight-inventory
649 model is marked as deprecated. To facilitate migration from it to the
650 network-topology model, there were requests to render (translate) data
651 from inventory model (whether augmented or not) to another model for
652 further processing. The Topology Processing Framework was extended to
653 provide this functionality by implementing several rendering-specific
654 classes. This chapter is a step-by-step guide on how to implement your
655 own topology rendering using our inventory rendering as an example.
656
657 Use case
658 ~~~~~~~~
659
660 For the purpose of this guide we are going to render the following
661 augmented fields from the OpenFlow model:
662
663 -  from inventory node:
664
665    -  manufacturer
666
667    -  hardware
668
669    -  software
670
671    -  serial-number
672
673    -  description
674
675    -  ip-address
676
677 -  from inventory node-connector:
678
679    -  name
680
681    -  hardware-address
682
683    -  current-speed
684
685    -  maximum-speed
686
687 We also want to preserve the node ID and termination-point ID from
688 opendaylight-topology-inventory model, which is network-topology part of
689 the inventory model.
690
691 Implementation
692 ~~~~~~~~~~~~~~
693
694 There are two ways to implement support for your specific topology
695 rendering:
696
697 -  add a module to your project that depends on the Topology Processing
698    Framework
699
700 -  add a module to the Topology Processing Framework itself
701
702 Regardless, a successful implementation must complete all of the
703 following steps.
704
705 Step1 - Target Model Creation
706 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
707
708 Because the network-topology node does not have fields to store all
709 desired data, it is necessary to create new model to render this extra
710 data in to. For this guide we created the inventory-rendering model. The
711 picture below shows how data will be rendered and stored.
712
713 .. figure:: ./images/topoprocessing/Inventory_Rendering_Use_case.png
714    :alt: Rendering to the inventory-rendering model
715
716    Rendering to the inventory-rendering model
717
718     **Important**
719
720     When implementing your version of the topology-rendering model in
721     the Topology Processing Framework, the source file of the model
722     (.yang) must be saved in /topoprocessing-api/src/main/yang folder so
723     corresponding structures can be generated during build and can be
724     accessed from every module through dependencies.
725
726 When the target model is created you have to add an identifier through
727 which you can set your new model as output model. To do that you have to
728 add another identity item to topology-correlation.yang file. For our
729 inventory-rendering model identity looks like this:
730
731 .. code:: yang
732
733     identity inventory-rendering-model {
734         description "inventory-rendering.yang";
735         base model;
736     }
737
738 After that you will be able to set inventory-rendering-model as output
739 model in XML.
740
741 Step2 - Module and Feature Creation
742 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
743
744     **Important**
745
746     This and following steps are based on the `model specific
747     approach <#_model_specific_approach>`__ in the Topology Processing
748     Framework. We highly recommend that you familiarize yourself with
749     this approach in advance.
750
751 To create a base module and add it as a feature to Karaf in the Topology
752 Processing Framework we made the changes in following
753 `commit <https://git.opendaylight.org/gerrit/#/c/26223/>`__. Changes in
754 other projects will likely be similar.
755
756 +--------------------------------------+--------------------------------------+
757 | File                                 | Changes                              |
758 +======================================+======================================+
759 | pom.xml                              | add new module to topoprocessing     |
760 +--------------------------------------+--------------------------------------+
761 | features.xml                         | add feature to topoprocessing        |
762 +--------------------------------------+--------------------------------------+
763 | features/pom.xml                     | add dependencies needed by features  |
764 +--------------------------------------+--------------------------------------+
765 | topoprocessing-artifacts/pom.xml     | add artifact                         |
766 +--------------------------------------+--------------------------------------+
767 | topoprocessing-config/pom.xml        | add configuration file               |
768 +--------------------------------------+--------------------------------------+
769 | 81-topoprocessing-inventory-renderin | configuration file for new module    |
770 | g-config.xml                         |                                      |
771 +--------------------------------------+--------------------------------------+
772 | topoprocessing-inventory-rendering/p | main pom for new module              |
773 | om.xml                               |                                      |
774 +--------------------------------------+--------------------------------------+
775 | TopoProcessingProviderIR.java        | contains startup method which        |
776 |                                      | register new model adapter           |
777 +--------------------------------------+--------------------------------------+
778 | TopoProcessingProviderIRModule.java  | generated class which contains       |
779 |                                      | createInstance method. You should    |
780 |                                      | call your startup method from here.  |
781 +--------------------------------------+--------------------------------------+
782 | TopoProcessingProviderIRModuleFactor | generated class. You will probably   |
783 | y.java                               | not need to edit this file           |
784 +--------------------------------------+--------------------------------------+
785 | log4j.xml                            | configuration file for logger        |
786 |                                      | topoprocessing-inventory-rendering-p |
787 |                                      | rovider-impl.yang                    |
788 +--------------------------------------+--------------------------------------+
789
790 Step3 - Module Adapters Creation
791 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
792
793 There are seven mandatory interfaces or abstract classes that needs to
794 be implemented in each module. They are:
795
796 -  TopoProcessingProvider - provides module registration
797
798 -  ModelAdapter - provides model specific instances
799
800 -  TopologyRequestListener - listens on changes in the configuration
801    datastore
802
803 -  TopologyRequestHandler - processes configuration datastore changes
804
805 -  UnderlayTopologyListener - listens for changes in the specific model
806
807 -  LinkTransaltor and NodeTranslator - used by OverlayItemTranslator to
808    create NormalizedNodes from OverlayItems
809
810 The name convention we used was to add an abbreviation for the specific
811 model to the beginning of implementing class name (e.g. the
812 IRModelAdapter refers to class which implements ModelAdapter in module
813 Inventory Rendering). In the case of the provider class, we put the
814 abbreviation at the end.
815
816     **Important**
817
818     -  In the next sections, we use the terms TopologyRequestListener,
819        TopologyRequestHandler, etc. without a prepended or appended
820        abbreviation because the steps apply regardless of which specific
821        model you are targeting.
822
823     -  If you want to implement rendering from inventory to
824        network-topology, you can just copy-paste our module and
825        additional changes will be required only in the output part.
826
827 **Provider part**
828
829 This part is the starting point of the whole module. It is responsible
830 for creating and registering TopologyRequestListeners. It is necessary
831 to create three classes which will import:
832
833 -  **TopoProcessingProviderModule** - is a generated class from
834    topoprocessing-inventory-rendering-provider-impl.yang (created in
835    previous step, file will appear after first build). Its method
836    ``createInstance()`` is called at the feature start and must be
837    modified to create an instance of TopoProcessingProvider and call its
838    ``startup(TopoProcessingProvider topoProvider)`` function.
839
840 -  **TopoProcessingProvider** - in
841    ``startup(TopoProcessingProvider topoProvider)`` function provides
842    ModelAdapter registration to TopoProcessingProviderImpl.
843
844 -  **ModelAdapter** - provides creation of corresponding module specific
845    classes.
846
847 **Input part**
848
849 This includes the creation of the classes responsible for input data
850 processing. In this case, we had to create five classes implementing:
851
852 -  **TopologyRequestListener** and **TopologyRequestHandler** - when
853    notified about a change in the configuration datastore, verify if the
854    change contains a topology request (has correlations in it) and
855    creates UnderlayTopologyListeners if needed. The implementation of
856    these classes will differ according to the model in which are
857    correlations saved (network-topology or i2rs). In the case of using
858    network-topology, as the input model, you can use our classes
859    IRTopologyRequestListener and IRTopologyRequestHandler.
860
861 -  **UnderlayTopologyListener** - registers underlay listeners according
862    to input model. In our case (listening in the inventory model), we
863    created listeners for the network-topology model and inventory model,
864    and set the NotificationInterConnector as the first operator and set
865    the IRRenderingOperator as the second operator (after
866    NotificationInterConnector). Same as for
867    TopologyRequestListener/Handler, if you are rendering from the
868    inventory model, you can use our class IRUnderlayTopologyListener.
869
870 -  **InventoryListener** - a new implementation of this class is
871    required only for inventory input model. This is because the
872    InventoryListener from topoprocessing-impl requires pathIdentifier
873    which is absent in the case of rendering.
874
875 -  **TopologyOperator** - replaces classic topoprocessing operator.
876    While the classic operator provides specific operations on topology,
877    the rendering operator just wraps each received UnderlayItem to
878    OverlayItem and sends them to write.
879
880     **Important**
881
882     For purposes of topology rendering from inventory to
883     network-topology, there are misused fields in UnderlayItem as
884     follows:
885
886     -  item - contains node from network-topology part of inventory
887
888     -  leafItem - contains node from inventory
889
890     In case of implementing UnderlayTopologyListener or
891     InventoryListener you have to carefully adjust UnderlayItem creation
892     to these terms.
893
894 **Output part**
895
896 The output part of topology rendering is responsible for translating
897 received overlay items to normalized nodes. In the case of inventory
898 rendering, this is where node information from inventory are combined
899 with node information from network-topology. This combined information
900 is stored in our inventory-rendering model normalized node and passed to
901 the writer.
902
903 The output part consists of two translators implementing the
904 NodeTranslator and LinkTranslator interfaces.
905
906 **NodeTranslator implementation** - The NodeTranslator interface has one
907 ``translate(OverlayItemWrapper wrapper)`` method. For our purposes,
908 there is one important thing in wrapper - the list of OverlayItems which
909 have one or more common UnderlayItems. Regardless of this list, in the
910 case of rendering it will always contains only one OverlayItem. This
911 item has list of UnderlayItems, but again in case of rendering there
912 will be only one UnderlayItem item in this list. In NodeTranslator, the
913 OverlayItem and corresponding UnderlayItem represent nodes from the
914 translating model.
915
916 The UnderlayItem has several attributes. How you will use these
917 attributes in your rendering is up to you, as you create this item in
918 your topology operator. For example, as mentioned above, in our
919 inventory rendering example is an inventory node normalized node stored
920 in the UnderlayItem leafNode attribute, and we also store node-id from
921 network-topology model in UnderlayItem itemId attribute. You can now use
922 these attributes to build a normalized node for your new model. How to
923 read and create normalized nodes is out of scope of this document.
924
925 **LinkTranslator implementation** - The LinkTranslator interface also
926 has one ``translate(OverlayItemWrapper wrapper)`` method. In our
927 inventory rendering this method returns ``null``, because the inventory
928 model doesn’t have links. But if you also need links, this is the place
929 where you should translate it into a normalized node for your model. In
930 LinkTranslator, the OverlayItem and corresponding UnderlayItem represent
931 links from the translating model. As in NodeTranslator, there will be
932 only one OverlayItem and one UnderlayItem in the corresponding lists.
933
934 Testing
935 ~~~~~~~
936
937 If you want to test our implementation you must apply `this
938 patch <https://git.opendaylight.org/gerrit/#/c/26612>`__. It adds an
939 OpenFlow Plugin dependency so we can use it in the Karaf distribution as
940 a feature. After adding patch and building the whole framework, you can
941 start Karaf. Next, you have to install necessary features. In our case
942 it is:
943
944 ``feature:install odl-restconf-noauth odl-topoprocessing-inventory-rendering odl-openflowplugin-southbound odl-openflowplugin-nsf-model``
945
946 Now you can send messages to REST from any REST client (e.g. Postman in
947 Chrome). Messages have to have following headers:
948
949 +--------------------------------------+--------------------------------------+
950 | Header                               | Value                                |
951 +======================================+======================================+
952 | Content-Type:                        | application/xml                      |
953 +--------------------------------------+--------------------------------------+
954 | Accept:                              | application/xml                      |
955 +--------------------------------------+--------------------------------------+
956 | username:                            | admin                                |
957 +--------------------------------------+--------------------------------------+
958 | password:                            | admin                                |
959 +--------------------------------------+--------------------------------------+
960
961 Firstly send topology request to
962 http://localhost:8181/restconf/config/network-topology:network-topology/topology/render:1
963 with method PUT. Example of simple rendering request:
964
965 .. code:: xml
966
967     <topology xmlns="urn:TBD:params:xml:ns:yang:network-topology">
968       <topology-id>render:1</topology-id>
969         <correlations xmlns="urn:opendaylight:topology:correlation" >
970           <output-model>inventory-rendering-model</output-model>
971           <correlation>
972              <correlation-id>1</correlation-id>
973               <type>rendering-only</type>
974               <correlation-item>node</correlation-item>
975               <rendering>
976                 <underlay-topology>und-topo:1</underlay-topology>
977             </rendering>
978           </correlation>
979         </correlations>
980     </topology>
981
982 This request says that we want create topology with name render:1 and
983 this topology should be stored in the inventory-rendering-model and it
984 should be created from topology flow:1 by node rendering.
985
986 Next we send the network-topology part of topology flow:1. So to the URL
987 http://localhost:8181/restconf/config/network-topology:network-topology/topology/und-topo:1
988 we PUT:
989
990 .. code:: xml
991
992     <topology xmlns="urn:TBD:params:xml:ns:yang:network-topology"
993               xmlns:it="urn:opendaylight:model:topology:inventory"
994               xmlns:i="urn:opendaylight:inventory">
995         <topology-id>und-topo:1</topology-id>
996         <node>
997             <node-id>openflow:1</node-id>
998             <it:inventory-node-ref>
999         /i:nodes/i:node[i:id="openflow:1"]
1000             </it:inventory-node-ref>
1001             <termination-point>
1002                 <tp-id>tp:1</tp-id>
1003                 <it:inventory-node-connector-ref>
1004                     /i:nodes/i:node[i:id="openflow:1"]/i:node-connector[i:id="openflow:1:1"]
1005                 </it:inventory-node-connector-ref>
1006             </termination-point>
1007         </node>
1008     </topology>
1009
1010 And the last input will be inventory part of topology. To the URL
1011 http://localhost:8181/restconf/config/opendaylight-inventory:nodes we
1012 PUT:
1013
1014 .. code:: xml
1015
1016     <nodes
1017         xmlns="urn:opendaylight:inventory">
1018         <node>
1019             <id>openflow:1</id>
1020             <node-connector>
1021                 <id>openflow:1:1</id>
1022                 <port-number
1023                     xmlns="urn:opendaylight:flow:inventory">1
1024                 </port-number>
1025                 <current-speed
1026                     xmlns="urn:opendaylight:flow:inventory">10000000
1027                 </current-speed>
1028                 <name
1029                     xmlns="urn:opendaylight:flow:inventory">s1-eth1
1030                 </name>
1031                 <supported
1032                     xmlns="urn:opendaylight:flow:inventory">
1033                 </supported>
1034                 <current-feature
1035                     xmlns="urn:opendaylight:flow:inventory">copper ten-gb-fd
1036                 </current-feature>
1037                 <configuration
1038                     xmlns="urn:opendaylight:flow:inventory">
1039                 </configuration>
1040                 <peer-features
1041                     xmlns="urn:opendaylight:flow:inventory">
1042                 </peer-features>
1043                 <maximum-speed
1044                     xmlns="urn:opendaylight:flow:inventory">0
1045                 </maximum-speed>
1046                 <advertised-features
1047                     xmlns="urn:opendaylight:flow:inventory">
1048                 </advertised-features>
1049                 <hardware-address
1050                     xmlns="urn:opendaylight:flow:inventory">0E:DC:8C:63:EC:D1
1051                 </hardware-address>
1052                 <state
1053                     xmlns="urn:opendaylight:flow:inventory">
1054                     <link-down>false</link-down>
1055                     <blocked>false</blocked>
1056                     <live>false</live>
1057                 </state>
1058                 <flow-capable-node-connector-statistics
1059                     xmlns="urn:opendaylight:port:statistics">
1060                     <receive-errors>0</receive-errors>
1061                     <receive-frame-error>0</receive-frame-error>
1062                     <receive-over-run-error>0</receive-over-run-error>
1063                     <receive-crc-error>0</receive-crc-error>
1064                     <bytes>
1065                         <transmitted>595</transmitted>
1066                         <received>378</received>
1067                     </bytes>
1068                     <receive-drops>0</receive-drops>
1069                     <duration>
1070                         <second>28</second>
1071                         <nanosecond>410000000</nanosecond>
1072                     </duration>
1073                     <transmit-errors>0</transmit-errors>
1074                     <collision-count>0</collision-count>
1075                     <packets>
1076                         <transmitted>7</transmitted>
1077                         <received>5</received>
1078                     </packets>
1079                     <transmit-drops>0</transmit-drops>
1080                 </flow-capable-node-connector-statistics>
1081             </node-connector>
1082             <node-connector>
1083                 <id>openflow:1:LOCAL</id>
1084                 <port-number
1085                     xmlns="urn:opendaylight:flow:inventory">4294967294
1086                 </port-number>
1087                 <current-speed
1088                     xmlns="urn:opendaylight:flow:inventory">0
1089                 </current-speed>
1090                 <name
1091                     xmlns="urn:opendaylight:flow:inventory">s1
1092                 </name>
1093                 <supported
1094                     xmlns="urn:opendaylight:flow:inventory">
1095                 </supported>
1096                 <current-feature
1097                     xmlns="urn:opendaylight:flow:inventory">
1098                 </current-feature>
1099                 <configuration
1100                     xmlns="urn:opendaylight:flow:inventory">
1101                 </configuration>
1102                 <peer-features
1103                     xmlns="urn:opendaylight:flow:inventory">
1104                 </peer-features>
1105                 <maximum-speed
1106                     xmlns="urn:opendaylight:flow:inventory">0
1107                 </maximum-speed>
1108                 <advertised-features
1109                     xmlns="urn:opendaylight:flow:inventory">
1110                 </advertised-features>
1111                 <hardware-address
1112                     xmlns="urn:opendaylight:flow:inventory">BA:63:87:0C:76:41
1113                 </hardware-address>
1114                 <state
1115                     xmlns="urn:opendaylight:flow:inventory">
1116                     <link-down>false</link-down>
1117                     <blocked>false</blocked>
1118                     <live>false</live>
1119                 </state>
1120                 <flow-capable-node-connector-statistics
1121                     xmlns="urn:opendaylight:port:statistics">
1122                     <receive-errors>0</receive-errors>
1123                     <receive-frame-error>0</receive-frame-error>
1124                     <receive-over-run-error>0</receive-over-run-error>
1125                     <receive-crc-error>0</receive-crc-error>
1126                     <bytes>
1127                         <transmitted>576</transmitted>
1128                         <received>468</received>
1129                     </bytes>
1130                     <receive-drops>0</receive-drops>
1131                     <duration>
1132                         <second>28</second>
1133                         <nanosecond>426000000</nanosecond>
1134                     </duration>
1135                     <transmit-errors>0</transmit-errors>
1136                     <collision-count>0</collision-count>
1137                     <packets>
1138                         <transmitted>6</transmitted>
1139                         <received>6</received>
1140                     </packets>
1141                     <transmit-drops>0</transmit-drops>
1142                 </flow-capable-node-connector-statistics>
1143             </node-connector>
1144             <serial-number
1145                 xmlns="urn:opendaylight:flow:inventory">None
1146             </serial-number>
1147             <manufacturer
1148                 xmlns="urn:opendaylight:flow:inventory">Nicira, Inc.
1149             </manufacturer>
1150             <hardware
1151                 xmlns="urn:opendaylight:flow:inventory">Open vSwitch
1152             </hardware>
1153             <software
1154                 xmlns="urn:opendaylight:flow:inventory">2.1.3
1155             </software>
1156             <description
1157                 xmlns="urn:opendaylight:flow:inventory">None
1158             </description>
1159             <ip-address
1160                 xmlns="urn:opendaylight:flow:inventory">10.20.30.40
1161           </ip-address>
1162             <meter-features
1163                 xmlns="urn:opendaylight:meter:statistics">
1164                 <max_bands>0</max_bands>
1165                 <max_color>0</max_color>
1166                 <max_meter>0</max_meter>
1167             </meter-features>
1168             <group-features
1169                 xmlns="urn:opendaylight:group:statistics">
1170                 <group-capabilities-supported
1171                     xmlns:x="urn:opendaylight:group:types">x:chaining
1172                 </group-capabilities-supported>
1173                 <group-capabilities-supported
1174                     xmlns:x="urn:opendaylight:group:types">x:select-weight
1175                 </group-capabilities-supported>
1176                 <group-capabilities-supported
1177                     xmlns:x="urn:opendaylight:group:types">x:select-liveness
1178                 </group-capabilities-supported>
1179                 <max-groups>4294967040</max-groups>
1180                 <actions>67082241</actions>
1181                 <actions>0</actions>
1182             </group-features>
1183         </node>
1184     </nodes>
1185
1186 After this, the expected result from a GET request to
1187 http://127.0.0.1:8181/restconf/operational/network-topology:network-topology
1188 is:
1189
1190 .. code:: xml
1191
1192     <network-topology
1193         xmlns="urn:TBD:params:xml:ns:yang:network-topology">
1194         <topology>
1195             <topology-id>render:1</topology-id>
1196             <node>
1197                 <node-id>openflow:1</node-id>
1198                 <node-augmentation
1199                     xmlns="urn:opendaylight:topology:inventory:rendering">
1200                     <ip-address>10.20.30.40</ip-address>
1201                     <serial-number>None</serial-number>
1202                     <manufacturer>Nicira, Inc.</manufacturer>
1203                     <description>None</description>
1204                     <hardware>Open vSwitch</hardware>
1205                     <software>2.1.3</software>
1206                 </node-augmentation>
1207                 <termination-point>
1208                     <tp-id>openflow:1:1</tp-id>
1209                     <tp-augmentation
1210                         xmlns="urn:opendaylight:topology:inventory:rendering">
1211                         <hardware-address>0E:DC:8C:63:EC:D1</hardware-address>
1212                         <current-speed>10000000</current-speed>
1213                         <maximum-speed>0</maximum-speed>
1214                         <name>s1-eth1</name>
1215                     </tp-augmentation>
1216                 </termination-point>
1217                 <termination-point>
1218                     <tp-id>openflow:1:LOCAL</tp-id>
1219                     <tp-augmentation
1220                         xmlns="urn:opendaylight:topology:inventory:rendering">
1221                         <hardware-address>BA:63:87:0C:76:41</hardware-address>
1222                         <current-speed>0</current-speed>
1223                         <maximum-speed>0</maximum-speed>
1224                         <name>s1</name>
1225                     </tp-augmentation>
1226                 </termination-point>
1227             </node>
1228         </topology>
1229     </network-topology>
1230
1231 Key APIs and Interfaces
1232 -----------------------
1233
1234 The basic provider class is TopoProcessingProvider which provides
1235 startup and shutdown methods. Otherwise, the framework communicates via
1236 requests and outputs stored in the MD-SAL datastores.
1237
1238 API Reference Documentation
1239 ---------------------------
1240
1241 You can find API examples on `this wiki
1242 page <https://wiki.opendaylight.org/view/Topology_Processing_Framework:Developer_Guide:End_to_End_Example>`__.
1243