1 ===================================
2 2021.09 Phosphorus Platform Upgrade
3 ===================================
5 This document describes the steps to help users upgrade from Silicon
6 to Phosphorus 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.
10 .. contents:: Contents
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.
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>`_):
26 1. Update the odlparent version from 8.1.1 to 9.0.5. There should
27 not be any reference to **org.opendaylight.odlparent**, except
28 for 9.0.5. 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.
34 bump-odl-version odlparent 8.1.1 9.0.5
36 2. Update the direct yangtools version references from 6.0.5 to 7.0.7,
37 There should not be any reference to **org.opendaylight.yangtools**,
38 except for 7.0.7. This includes custom feature.xml templates
39 (``src/main/feature/feature.xml``), the version range should
40 be "[7,8)" instead of "[6,7)".
44 bump-odl-version yangtools 6.0.5 7.0.7
46 3. Update the MD-SAL version from 7.0.6 to 8.0.5. There should not be
47 any reference to **org.opendaylight.mdsal**, except for 8.0.5.
51 bump-odl-version mdsal 7.0.6 8.0.5
53 4. Update the Controller version from 3.0.7 to 4.0.2. There should not be
54 any reference to **org.opendaylight.controller**, except for 4.0.2.
58 bump-odl-version controller 3.0.7 4.0.2
60 5. Update the InfraUtils version from 1.9.6 to 2.0.5. There should not be
61 any reference to **org.opendaylight.infrautils**, except for 2.0.5.
65 bump-odl-version infrautils 1.9.6 2.0.5
67 6. Update the AAA version from 1.13.0 to 0.14.2. There should not be
68 any reference to **org.opendaylight.aaa**, except for 0.14.2.
72 bump-odl-version aaa 0.13.2 0.14.2
74 7. Update the NETCONF version from 1.13.1 to 2.0.5. There should not be
75 any reference to **org.opendaylight.netconf**, except for 2.0.5.
79 bump-odl-version netconf 1.13.1 2.0.5
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.
89 Perform the following steps to save time when locally installing
90 any dependent project:
98 * If previously installed, go offline and/or use the
99 no-snapshot-update option.
101 .. code-block:: shell
103 mvn -Pq -o -nsu clean install
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.
114 Any version range referencing version 8 or 8.1 of ODL Parent must be changed
115 to “[9,10)” for ODL Parent 9.
119 <feature name="odl-infrautils-caches">
120 <feature version="[9,10)">odl-guava</feature>
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:
134 <groupId>com.guicedee.services</groupId>
135 <artifactId>javax.inject</artifactId>
136 <optional>true</optional>
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:
148 <groupId>org.osgi</groupId>
149 <artifactId>osgi.core</artifactId>
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.
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.
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
171 * we are making `SchemaNode.getPath()` deprecated for removal
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.
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.
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.
187 This prompts a very simple replacement pattern, where uses like this:
191 NormalizedNode<?, ?> node = ...
192 NormalizedNodeContainer<?, ?, ?> parent = ...
193 DataContainerChild<?, ?> child = ...
195 are simplified down to
199 NormalizedNode node = ...
200 NormalizedNodeContainer<?> parent = ...
201 DataContainerChild child = ...
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:
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
212 For most users, this change simply means replacing code blocks like
216 NormalizedNode<?, ?> node;
217 QName type = node.getNodeType();
218 Object value = node.getValue();
220 with a slightly more verbose
225 QName type = node.getIdentifier().getNodeType();
226 Object value = node.body();
228 which makes safety of `getNodeType()` obvious as soon as NormalizedNode subtypes (such as ContainerNode, MapNode) are
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:
239 NormalizedNodeContainer<?, ?, ?> container;
241 DataContainerChild<?, ?> child = container.getDataChildByName(arg);
243 ends up being migrated to
247 DistinctNodeContainer<?> container;
249 DataContainerChild child = container.childByArg(arg);
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
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.
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.
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
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.
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.
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.
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.
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.
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.
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
318 EffectiveModelContext context = ...;
319 SchemaNode node = ...;
320 EffectiveStatementInference inference = SchemaInferenceStack.ofSchemaPath(context, node.getPath()).toInference();
323 Strictly-compliant `leafref` path interpretation
324 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
325 Previous versions of YANG Tools have had a number of ways how to resolve where a ``leafref``'s ``path`` statement is
326 pointing to. Each of these operated on a different set of assumptions and had its share of caveats and outright bugs --
327 most of them stemming from their attempt to operate on raw strings as declared in YANG files.
329 All of these utilities have been removed in this release and superseded by a single implementation in aforementioned
330 ``SchemaInferenceStack``. This implementation maintains an
331 `XPath Context <https://datatracker.ietf.org/doc/html/rfc7950#section-6.4.1>`__ and performs unqualified name resolution
332 based upon its rules.
334 Low-level API is ``SchemaInferenceStack.resolvePathExpression()``, which takes a ``PathExpression`` and interprets it
335 in the context of its current state. On successful return the statement which the expression points will be return and
336 the stack will be updated to be at that statement.
338 High-level API is captured in ``LeafrefResolver`` API, allowing users to (recursively) resolve the actual type that a
339 particular ``LeafrefTypeDefinition`` points to. SchemaInferenceStack is its canonical implementation.
341 End-user visible behavior has changed in that incorrect leafref paths are now readily identified. This typically affects
342 cross-module use of ``type leafref`` with absolute paths in either ``typedef`` or in ``grouping`` contexts. Typical source
343 of trouble looks like this:
373 Note how ``foo-ref`` is using an absolute path with unqualified name. The intent seems to be to point at the ``foo:foo``
374 leaf and in fact all uses within ``foo`` module operate as expected. In the context of ``bar`` module, though, things
375 break down. When we are looking at ``bar:bar`` leaf, the path becomes ``/bar:foo`` -- and thus attempts to resolve it
376 will fail. Correct fix in this situation is to correct the definition of the path to use qualified names:
387 Unrecognized YANG statement handling
388 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
389 YANG parser does not reflect unrecognized YANG language extensions, defined by
390 an ``extension`` statement, in the effective model as exposed by EffectiveModelContext.
392 This has a direct impact on the contents of ``DocumentedNode.getUnknownSchemaNodes()``, as unrecognized extensions
393 will not be presented in the list.
395 Unrecognized extensions are those that are defined by an ``extension`` statement, but do not have a corresponding
396 YANG parser handler. These extensions cannot be semantically be bound and the YANG parser handles in accordance with
397 `RFC6020 <https://datatracker.ietf.org/doc/html/rfc6020#section-6.3.1>`__ by treating them as unsupported extensions
403 This MD-SAL release contains a completely rewritten Java Binding generator.
405 The implementation now performs a multi-pass generation as opposed to a memorized single-pass generation approach
406 taken by the previous implementation. Multiple passes allow for proper name allocation policies, with conflicts
407 being resolved in a consistent matter-of-course way.
409 Forward compatibility with Java 16
410 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
411 Java has reserved a few new keywords, ``var``, ``yield`` and most notably ``record``. These are now taken into
412 account when generating Java bindings, resulting in slightly different package names being generated, as they are
413 now prefixed with a single underscore.
415 For example ``org.opendaylight.yang.gen.v1.foo.record.bar`` is now generated as
416 ``org.opendaylight.yang.gen.v1.foo._record.bar``.
419 Augmentation child package names
420 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
421 As part of class/package name mapping rules, augmentation class name overrides also apply to package names. For
435 ext:augment-identifier baz;
441 we would generate ``foo.bar.Xyzzy`` interface. Since the augmentation now makes a proper claim on the ``baz``
442 name, we generate ``baz.Xyzzy`` instead.
444 This change also mean that attempts to define multiple augments with the same augment-identifier will result
448 RPCs now reserve the corresponding class name
449 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
450 Binding mapping of ``action`` and ``rpc`` statements are slightly different, reflecting the evolution of Java
451 as well as our assembly of features. In the long term we want to evolve ``rpc`` mapping to resemble more the
452 way ``action`` is mapped. As a preparatory step, ``rpc`` statements now reserve the class (and package) names
453 corresponding to the RPC argument. This does not affect most use cases, but slightly changes interactions with
454 groupings on naming overlap. For the following fragment
463 we used to generate ``FooService``, ``FooInput`` and ``FooOutput`` for the RPC and ``Foo`` for the grouping. In
464 this release we generate ``Foo$G`` for the grouping, leaving ``Foo`` non-existent. A future version will take
465 advantage of this gap and generate an interface for the RPC.
468 DOMDataTreeChangeListener.onInitialData() is mandatory
469 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
470 DOMDataTreeChangeListener's callback for initially-empty data, ``onInitialData()``, is no longer a default
471 method and therefore is mandatory to implement. It is okay for this method to do nothing, but some users may
472 choose to perform some processing, similar to what they'd do if the listen root were to be deleted.
475 Widened Integer/Long/BigInteger compatibility setters and constructors removed
476 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
477 In releases prior to Magnesium ``uint8``, ``uint16``, ``uint32`` and ``uint64`` types were mapped to Short, Integer,
478 Long and BigInteger respectively. With Magnesium, this mapping changed to ``yang.common.Uint{8,16,32,64}`` and
479 compatibility ``setFoo(Short)`` methods were retained as adapters to minimize the API churn.
481 In this release these compatibility methods are no longer generated, as detailed in
482 `this MD-SAL issue <https://jira.opendaylight.org/browse/MDSAL-490>`__.
485 List/Map compatibility setters and constructors removed
486 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
487 In releases prior to Aluminium, ``list`` statements were always mapped to ``java.util.List``. With Aluminium, this
488 mapping was updated to take into account the semantic meaning implied by ``ordered-by`` statements. For ``list``
489 statements, which are ``ordered-by system`` and also have a ``key`` statement, the mapping was changed to
490 ``java.util.Map``. Compatibility constructors and setters were retained as adapters to minimize the API churn.
492 In this release these compatibility methods are no longer generated, as detailed in
493 `this MD-SAL issue <https://jira.opendaylight.org/browse/MDSAL-540>`__.
496 Boolean compatibility getters removed
497 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
498 In releases prior to Silicon, ``type boolean`` getters were mapped to ``is`` prefix instead of the regular ``get``
499 prefix. With Silicon, this mapping was made regular, i.e. all getters share the same ``get`` prefix. Compatibility
500 getters were retained as simple adapters, so that both ``boolean isFoo()`` and ``boolean getFoo()`` were available.
502 In this release these compatibility methods are no longer generated, as detailed in
503 `this MD-SAL issue <https://jira.opendaylight.org/browse/MDSAL-659>`__.
506 Producer/Consumer APIs removed
507 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
508 ``DOMDataTreeShard`` as well as ``DataTreeProducer``, ``DataTreeConsumer`` and related class were removed. These
509 APIs failed to get productized and were very problematic in a clustered setting and they were impossible to migrate
510 to gradually. A future version of MD-SAL will define a set of replacement interfaces along with a migration guide,
511 allowing for gradual migration.
517 Distributed Datastore backwards compatibility reduced to Sodium SR1
518 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
519 Backwards compatibility glue in prior versions spanned as far back as Boron release. In this release a number of glue
520 items were removed, removing compatibility with datastore versions prior to Sodium SR1.
523 Prefix-based shards removed
524 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
525 Prefix-based sharding implementation in the Distributed Datastore has been removed as a consequence of MD-SAL APIs
526 it implemented being removed.
529 Message Bus component removed
530 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
531 The experimental ``messagebus`` component was removed. This component has had only one implementation in NETCONF
532 project. The combination has been a proof of concept and was never productized nor has it been tested in real world
533 for the past 4 years.
536 `opendaylight-topology` and `opendaylight-inventory` removed
537 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
538 These two sets of models are only used in OpenFlow plugin and its users. Most of the concepts they introduce have
539 been superseded by IETF-standardized ``ietf-network`` and related models. These models are removed from the controller
540 project and reintroduced in OpenFlow Plugin. Users are advised to either consume them from OpenFlow, or migrate to
541 using `RFC8345 <https://datatracker.ietf.org/doc/html/rfc8345>`__ instead.
544 Removed support for deprecated `datastore.cfg` properties
545 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
546 The following properties in `datastore.cfg` have been deprecated and were no-ops in previous releases:
547 * ``max-shard-data-change-executor-pool-size``
548 * ``max-shard-data-change-executor-queue-size``
549 * ``max-shard-data-change-listener-queue-size``
550 * ``max-shard-data-store-executor-queue-size``
552 This release no longer recognizes these properties and treats them as errors.