Clean up upgrade process a bit
[docs.git] / docs / release-notes / upgrade-process.rst
1 ===================================
2 2021.09 Phosphorus Platform Upgrade
3 ===================================
4
5 This document describes the steps to help users upgrade from Aluminium
6 to Silicon planned platform. Refer to `Managed Release Integrated (MRI)
7 project <https://git.opendaylight.org/gerrit/q/topic:phosphorus-mri>`_
8 upgrade patches for more information.
9
10 .. contents:: Contents
11
12 Preparation
13 -----------
14
15 JDK 11 Version
16 ^^^^^^^^^^^^^^
17 Phosphorus requires Java 11, both during compile-time and run-time.
18 Make sure to install JDK 11 corresponding to at least ``openjdk-11.0.10``,
19 and that the JAVA_HOME environment variable points to the JDK directory.
20
21 Version Bump
22 ^^^^^^^^^^^^
23 Before performing platform upgrade, do the following to bump the odlparent
24 versions (for example, `bump-odl-version <https://github.com/skitt/odl-tools/blob/master/bump-odl-version>`_):
25
26 1. Update the odlparent version from 8.1.1 to 9.0.2. There should
27    not be any reference to **org.opendaylight.odlparent**, except
28    for 9.0.2. This includes custom feature.xml templates
29    (``src/main/feature/feature.xml``), the version range should
30    be "[9,10)" instead of "[8.1,9)", "[5.0.3,6)" or any other variation.
31
32  .. code-block:: shell
33
34   bump-odl-version odlparent 8.1.1 9.0.2
35
36 2. Update the direct yangtools version references from 6.0.5 to 7.0.3,
37    There should not be any reference to **org.opendaylight.yangtools**,
38    except for 7.0.3. This includes custom feature.xml templates
39    (``src/main/feature/feature.xml``), the version range should
40    be "[7,8)" instead of "[6,7)".
41
42  .. code-block:: shell
43
44   bump-odl-version yangtools 8.1.1 7.0.3
45
46 3. Update the MD-SAL version from 7.0.6 to 8.0.0. There should not be
47    any reference to **org.opendaylight.mdsal**, except for 8.0.0.
48
49  .. code-block:: shell
50
51   bump-odl-version mdsal 7.0.6 8.0.0
52
53 4. Update the Controller version from 3.0.7 to 4.0.0. There should not be
54    any reference to **org.opendaylight.controller**, except for 4.0.0.
55
56  .. code-block:: shell
57
58   bump-odl-version controller 3.0.7 4.0.0
59
60 5. Update the InfraUtils version from 1.9.6 to 2.0.2. There should not be
61    any reference to **org.opendaylight.infrautils**, except for 2.0.2.
62
63  .. code-block:: shell
64
65   bump-odl-version infrautils 1.9.6 2.0.2
66
67 6. Update the AAA version from 1.13.0 to 0.14.0. There should not be
68    any reference to **org.opendaylight.aaa**, except for 0.14.0.
69
70  .. code-block:: shell
71
72   bump-odl-version aaa 0.13.2 1.14.0
73
74 7. Update the NETCONF version from 1.13.1 to 2.0.1. There should not be
75    any reference to **org.opendaylight.netconf**, except for 2.0.1.
76
77  .. code-block:: shell
78
79   bump-odl-version netconf 1.13.1 2.0.1
80
81 Install Dependent Projects
82 ^^^^^^^^^^^^^^^^^^^^^^^^^^
83 Before performing platform upgrade, users must also install
84 any dependent project. To locally install a dependent project,
85 pull and install the respective
86 `phosphorus-mri <https://git.opendaylight.org/gerrit/q/topic:phosphorus-mri>`_
87 changes for any dependent project.
88
89 Perform the following steps to save time when locally installing
90 any dependent project:
91
92 * For quick install:
93
94  .. code-block:: shell
95
96   mvn -Pq clean install
97
98 * If previously installed, go offline and/or use the
99   no-snapshot-update option.
100
101  .. code-block:: shell
102
103   mvn -Pq -o -nsu clean install
104
105 Upgrade the ODL Parent
106 ----------------------
107 The following sub-section describes how to upgrade to
108 the ODL Parent version 9. Refer to the `ODL Parent Release Notes
109 <https://github.com/opendaylight/odlparent/blob/master/docs/NEWS.rst#version-902>`_
110 for more information.
111
112 Features
113 ^^^^^^^^
114 Any version range referencing version 8 or 8.1 of ODL Parent must be changed
115 to “[9,10)” for ODL Parent 9.
116
117  .. code-block:: xml
118
119    <feature name="odl-infrautils-caches">
120        <feature version="[9,10)">odl-guava</feature>
121    </feature>
122
123 ODL Parent Impacts
124 ------------------
125
126 Updated JSR-330 coordinates
127 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
128 ODL Parent has switched to sourcing ``javax.inject`` artifact from the GuicedEE project in version 8.1.
129 With odlparent-9, the old coordinates were removed. Downstreams need to update their dependency blocks to:
130
131  .. code-block:: xml
132
133    <dependency>
134        <groupId>com.guicedee.services</groupId>
135        <artifactId>javax.inject</artifactId>
136        <optional>true</optional>
137    </dependency>
138
139
140 Removed OSGi Release 6 `osgi-core`
141 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
142 The artifact name for OSGi Core specification has changed in Release 7. Where odlparent-8.1 provided both R6 and R7
143 declarations, odlparent-9 removes the legacy declaration. Downstreams need to update their dependency blocks to:
144
145  .. code-block:: xml
146
147    <dependency>
148        <groupId>org.osgi</groupId>
149        <artifactId>osgi.core</artifactId>
150    </dependency>
151
152
153 YANG Tools Impacts
154 ------------------
155
156 SchemaNode.getPath() can throw UnsupportedOperationException
157 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
158 The original idea that each SchemaNode has a unique identifier, available through ``SchemaNode.getPath()``,
159 has proven to be a scalability issue with vendor models. The identifiers themselves account for up to 19%
160 of all objects retained by EffectiveModelContext, holding up to 17% of retained memory. These are also
161 preventing a number of useful performance and memory footprint optimizations.
162
163 In yangtools-6 we set out on eliminating this problem, with TypeDefinition's `getPath()` method being
164 specified as being optional -- but the implementation supported this method.
165
166 In yangtools-7 we are taking next three steps:
167   * we make `SchemaNode.getPath()` an default method, with the default implementation throwing
168     UnsupportedOperationException
169   * we are changing TypeDefinition implementation to actually throw UnsupportedOperationException
170     in all cases
171   * we are making `SchemaNode.getPath()` deprecated for removal
172
173 All other types of SchemaNode except TypeDefinition retain a fully functional `getPath()` as an implementation
174 detail, providing seamless interoperation with current code in most cases.
175
176
177 NormalizedNode hierarchy was updated
178 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
179 The interfaces representing normalized view of YANG-modeled data, rooted at
180 ``org.opendaylight.yangtools.yang.data.api.NormalizedNode``, have been revamped for easier use and better
181 consistency of operations.
182
183 The most prolific change is the reduction of number of generic arguments for ``NormalizedNode``, ``DataContainerChild``
184 and ``NormalizedNodeContainer``. The first two now do not have any generic arguments, while NormalizedNodeContainer
185 has only a single argument.
186
187 This prompts a very simple replacement pattern, where uses like this:
188
189  .. code-block:: java
190
191    NormalizedNode<?, ?> node = ...
192    NormalizedNodeContainer<?, ?, ?> parent = ...
193    DataContainerChild<?, ?> child = ...
194
195 are simplified down to
196
197  .. code-block:: java
198
199    NormalizedNode node = ...
200    NormalizedNodeContainer<?> parent = ...
201    DataContainerChild child = ...
202
203
204 Base NormalizedNode interface has also been changed. The ``NormalizedNode.getNodeType()`` method has been removed,
205 as it does not work well with ``AugmentationIdentifier`` -- leaving only three methods:
206
207   * ``getIdentifier()`` inherited from the ``Identifiable`` contract
208   * ``body()``, which is actually the new name for ``value()``
209   * ``contract()``, which identifies which NormalizedNode specialization, such as ContainerNode or AnydataNode,
210     a particular object represents
211
212 For most users, this change simply means replacing code blocks like
213
214  .. code-block:: java
215
216    NormalizedNode<?, ?> node;
217    QName type = node.getNodeType();
218    Object value = node.getValue();
219
220 with a slightly more verbose
221
222  .. code-block:: java
223
224    NormalizedNode node;
225    QName type = node.getIdentifier().getNodeType();
226    Object value = node.body();
227
228 which makes safety of `getNodeType()` obvious as soon as NormalizedNode subtypes (such as ContainerNode, MapNode) are
229 actually involved.
230
231 Also NormalizedNodeContainer's function has changed. It now correctly acts as a common interface
232 between containers which allow key-based child look-up (``DistinctNodeContainer``) and containers which allow
233 offset-based child look-up (``OrderedNodeContainer``), hosting utility methods like ``size()`` and ``isEmpty()``.
234 Call sites which iterate through all available children should continue using NormalizedNodeContainer. Call sites
235 which require accessing a child by its identifier need to switch to using DistinctNodeContainer:
236
237  .. code-block:: java
238
239    NormalizedNodeContainer<?, ?, ?> container;
240    PathArgument arg;
241    DataContainerChild<?, ?> child = container.getDataChildByName(arg);
242
243 ends up being migrated to
244
245  .. code-block:: java
246
247    DistinctNodeContainer<?> container;
248    PathArgument arg;
249    DataContainerChild child = container.childByArg(arg);
250
251 There actually are now three different methods to access a child, allowing flexible and expressive integration:
252   * ``childByArg()``, which returns a child or ``null``,
253   * ``findChildByArg()``, which returns a ``Optional`` child,
254   * ``getChildByArg()``, which returns a child or throws VerifyException
255
256
257 Another aspect that got attention is child ordering contract. Both ``MapNode`` and ``LeafSetNode`` are now
258 specialized in disjunct interfaces based on how child iteration order affects semantics. ``SystemMapNode`` and
259 ``SystemLeafSetNode`` represent ``list`` and ``leaf-list`` constructs which have ``ordered-by system`` semantics --
260 which is to say order of nodes is not part of semantics similar to what ``java.util.Set`` does. On the other hand
261 we have ``UserMapNode`` and ``UserLeafSetNode`` for constructs which are ``ordered-by user`` -- hence the child
262 iteration order is part of semantics, i.e. what ``java.util.List`` does.
263
264
265 ModelStatement non-existent arguments
266 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
267 The type mapping of YANG statements argument in the no-argument case has changed. These have been previously mapped
268 to ``java.lang.Void`` to express non-presence. This mapping has caused nullability issues of ``ModelStatement.argument()``.
269 These have been resolved through mapping non-existent arguments to ``org.opendaylight.yangtools.yang.common.Empty``,
270 which maintains the same 'nothingness' contract through a singleton non-null object.
271
272
273 XML namespace has a dedicated construct
274 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
275 In previous versions, we have used ``java.net.URI`` to model the argument of YANG ``namespace`` statement. This has
276 proven to be a bit inefficient from both memory and CPU perspective, for example during looks. In this version, YANG
277 namespace is represented by a dedicated ``org.opendaylight.yangtools.yang.common.XMLNamespace`` class. It performs
278 same validation as ``URI.create()`` does, but it does not break the string into its constituents for storage like URI
279 does.
280
281
282 DataSchemaNode's `isConfigration()` is three-state
283 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
284 The idea that a DataSchemaNode has a boolean attribute representing the effective value of ``config`` statement argument
285 has been problematic due to its ignoring definition scope. As an example, ``leaf`` defined in a ``grouping`` has neither
286 ``config true`` nor ``config false`` effective statement.
287
288 In order to fix this modeling problem, as well to stop users from attempting to perform various recovery strategies,
289 a new method, ``DataSchemaNode.effectiveConfig()``, has been introduced. This method returns ``Optional<Boolean>``,
290 accurately modeling the three possibilities. ``DataSchemaNode.isConfiguration()`` has also been deprecated for removal.
291
292
293 SchemaContextUtil has been removed
294 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
295 A number of utilities dealing with SchemaNode traversal have been hosted in SchemaContextUtil. All of these were created
296 with assumptions of ``SchemaPath`` and with the object model not understanding YANG XPath expressions. This has lead to
297 some very obscure code with problematic edge cases.
298
299 All of these utilities have been centralized in a stateful SchemaInferenceStack. This stack encapsulates state related to
300 how a piece of logic has come to know about an EffectiveStatement. There are number of simple operations, such as
301 ``enterDataTree(QName)``, ``enterGrouping(QName)``, ``exit()`` and similar.
302
303 The stack also provides faculties to resolve ``type leafref`` path expressions, adjusting its internal state to provide
304 a path from the conceptual schema root to the leaf a particular leafref (indirectly) points to.
305
306 State of a SchemaInferenceStack can be converted to an immutable ``EffectiveStatementInference`` instance. This construct
307 serves as the modern replacement of ``SchemaPath``. Rather than containing an opaque path, though, it contains a sequence
308 of statements and attached semantics. This allows us to accurately address statements and communicate the state of the
309 SchemaInferenceStack across API boundaries, as a SchemaInferenceStack can readily be reconstituted from a number of different
310 EffectiveStatementInferences.
311
312 A number of entry-points, most notably to XML and JSON codecs, now take an ``EffectiveStatementInference`` instead of
313 a ``SchemaPath`` or a context ``SchemaNode``. For migration purposes, users having these available can use the following
314 snippet to migrate:
315
316  .. code-block:: java
317
318    EffectiveModelContext context = ...;
319    SchemaNode node = ...;
320    EffectiveStatementInference inference = SchemaInferenceStack.ofSchemaPath(context, node.getPath()).toInference();
321
322
323 Unrecognized YANG statement handling
324 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
325 YANG parser does not reflect unrecognized YANG language extensions, defined by
326 an ``extension`` statement, in the effective model as exposed by EffectiveModelContext.
327
328 This has a direct impact on the contents of ``DocumentedNode.getUnknownSchemaNodes()``, as unrecognized extensions
329 will not be presented in the list.
330
331 Unrecognized extensions are those that are defined by an ``extension`` statement, but do not have a corresponding
332 YANG parser handler. These extensions cannot be semantically be bound and the YANG parser handles in accordance with
333 `RFC6020 <https://datatracker.ietf.org/doc/html/rfc6020#section-6.3.1>`__ by treating them as unsupported extensions
334 and ignoring them.
335
336
337 MD-SAL Impacts
338 --------------
339 This MD-SAL release contains a completely rewritten Java Binding generator.
340
341 The implementation now performs a multi-pass generation as opposed to a memorized single-pass generation approach
342 taken by the previous implementation. Multiple passes allow for proper name allocation policies, with conflicts
343 being resolved in a consistent matter-of-course way.
344
345 Forward compatibility with Java 16
346 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
347 Java has reserved a few new keywords, ``var``, ``yield`` and most notably ``record``. These are now taken into
348 account when generating Java bindings, resulting in slightly different package names being generated, as they are
349 now prefixed with a single underscore.
350
351 For example ``org.opendaylight.yang.gen.v1.foo.record.bar`` is now generated as
352 ``org.opendaylight.yang.gen.v1.foo._record.bar``.
353
354
355 Augmentation child package names
356 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
357 As part of class/package name mapping rules, augmentation class name overrides also apply to package names. For
358 this example YANG
359
360  .. code-block:: yang
361
362    import yang-ext {
363      prefix ext;
364    }
365
366    container foo {
367      container bar;
368    }
369
370    augment /foo/bar {
371      ext:augment-identifier baz;
372
373      container xyzzy;
374    }
375
376
377 we would generate ``foo.bar.Xyzzy`` interface. Since the augmentation now makes a proper claim on the ``baz``
378 name, we generate ``baz.Xyzzy`` instead.
379
380 This change also mean that attempts to define multiple augments with the same augment-identifier will result
381 in a build failure.
382
383
384 RPCs now reserve the corresponding class name
385 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
386 Binding mapping of ``action`` and ``rpc`` statements are slightly different, reflecting the evolution of Java
387 as well as our assembly of features. In the long term we want to evolve ``rpc`` mapping to resemble more the
388 way ``action`` is mapped. As a preparatory step, ``rpc`` statements now reserve the class (and package) names
389 corresponding to the RPC argument. This does not affect most use cases, but slightly changes interactions with
390 groupings on naming overlap. For the following fragment
391
392  .. code-block:: yang
393
394    module foo {
395      grouping foo;
396      rpc foo;
397    }
398
399 we used to generate ``FooService``, ``FooInput`` and ``FooOutput`` for the RPC and ``Foo`` for the grouping. In
400 this release we generate ``Foo$G`` for the grouping, leaving ``Foo`` non-existent. A future version will take
401 advantage of this gap and generate an interface for the RPC.
402
403
404 DOMDataTreeChangeListener.onInitialData() is mandatory
405 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
406 DOMDataTreeChangeListener's callback for initially-empty data, ``onInitialData()``, is no longer a default
407 method and therefore is mandatory to implement. It is okay for this method to do nothing, but some users may
408 choose to perform some processing, similar to what they'd do if the listen root were to be deleted.
409
410
411 Widened Integer/Long/BigInteger compatibility setters and constructors removed
412 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
413 In releases prior to Magnesium ``uint8``, ``uint16``, ``uint32`` and ``uint64`` types were mapped to Short, Integer,
414 Long and BigInteger respectively. With Magnesium, this mapping changed to ``yang.common.Uint{8,16,32,64}`` and
415 compatibility ``setFoo(Short)`` methods were retained as adapters to minimize the API churn.
416
417 In this release these compatibility methods are no longer generated, as detailed in
418 `this MD-SAL issue <https://jira.opendaylight.org/browse/MDSAL-490>`__.
419
420
421 List/Map compatibility setters and constructors removed
422 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
423 In releases prior to Aluminium, ``list`` statements were always mapped to ``java.util.List``. With Aluminium, this
424 mapping was updated to take into account the semantic meaning implied by ``ordered-by`` statements. For ``list``
425 statements, which are ``ordered-by system`` and also have a ``key`` statement, the mapping was changed to
426 ``java.util.Map``. Compatibility constructors and setters were retained as adapters to minimize the API churn.
427
428 In this release these compatibility methods are no longer generated, as detailed in
429 `this MD-SAL issue <https://jira.opendaylight.org/browse/MDSAL-540>`__.
430
431
432 Boolean compatibility getters removed
433 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
434 In releases prior to Silicon, ``type boolean`` getters were mapped to ``is`` prefix instead of the regular ``get``
435 prefix. With Silicon, this mapping was made regular, i.e. all getters share the same ``get`` prefix. Compatibility
436 getters were retained as simple adapters, so that both ``boolean isFoo()`` and ``boolean getFoo()`` were available.
437
438 In this release these compatibility methods are no longer generated, as detailed in
439 `this MD-SAL issue <https://jira.opendaylight.org/browse/MDSAL-659>`__.
440
441
442 Producer/Consumer APIs removed
443 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
444 ``DOMDataTreeShard`` as well as ``DataTreeProducer``, ``DataTreeConsumer`` and related class were removed. These
445 APIs failed to get productized and were very problematic in a clustered setting and they were impossible to migrate
446 to gradually. A future version of MD-SAL will define a set of replacement interfaces along with a migration guide,
447 allowing for gradual migration.
448
449
450 Controller Impacts
451 ------------------
452
453 Distributed Datastore backwards compatibility reduced to Sodium SR1
454 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
455 Backwards compatibility glue in prior versions spanned as far back as Boron release. In this release a number of glue
456 items were removed, removing compatibility with datastore versions prior to Sodium SR1.
457
458
459 Prefix-based shards removed
460 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
461 Prefix-based sharding implementation in the Distributed Datastore has been removed as a consequence of MD-SAL APIs
462 it implemented being removed.
463
464
465 Message Bus component removed
466 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
467 The experimental ``messagebus`` component was removed. This component has had only one implementation in NETCONF
468 project. The combination has been a proof of concept and was never productized nor has it been tested in real world
469 for the past 4 years.
470
471
472 `opendaylight-topology` and `opendaylight-inventory` removed
473 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
474 These two sets of models are only used in OpenFlow plugin and its users. Most of the concepts they introduce have
475 been superseded by IETF-standardized ``ietf-network`` and related models. These models are removed from the controller
476 project and reintroduced in OpenFlow Plugin. Users are advised to either consume them from OpenFlow, or migrate to
477 using `RFC8345 <https://datatracker.ietf.org/doc/html/rfc8345>`__ instead.
478
479
480 Removed support for deprecated `datastore.cfg` properties
481 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
482 The following properties in `datastore.cfg` have been deprecated and were no-ops in previous releases:
483   * ``max-shard-data-change-executor-pool-size``
484   * ``max-shard-data-change-executor-queue-size``
485   * ``max-shard-data-change-listener-queue-size``
486   * ``max-shard-data-store-executor-queue-size``
487
488 This release no longer recognizes these properties and treats them as errors.
489