[MDSAL-813] Add DataBroker.registerListener(DataTreeIdentifier,DataListener) Created: 10/Feb/23  Updated: 21/Jun/23  Resolved: 21/Jun/23

Status: Resolved
Project: mdsal
Component/s: Binding API, Binding runtime
Affects Version/s: None
Fix Version/s: 12.0.0

Type: New Feature Priority: High
Reporter: Robert Varga Assignee: Oleksandr Panasiuk
Resolution: Done Votes: 0
Labels: pt
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Current ClusteredDataTreeChangeListener exposes the details about what changed in the entire tree.

There are a number of users which receive these changes like this:

@Override
public void onDataTreeChanged(Collection<DataTreeModification<Config>> changes) {
    updateConfig(Iterables.getLast(changes).getRootNode().getDataAfter());
}

i.e. they are interested only in the last state.

Since we are overlaying on DOMDataBroker, whose version of DTCL provides a List of changes, it should be trivial to support:

@FunctionalInterface
public interface DataListener<T extends DataObject> {
    // Note: needs a better name
    void dataChangedTo(@Nullable T data);
}

and users doing just:

@Override
public void dataChangedTo(Config data) {
    // the contents of updateConfig(data);
}

This will make for much simpler users, as this also covers the case of onInitialData(). Furthermore users do not care about data locality – hence this should imply ClusteredDataTreeChangeListener in all cases, without the distinction available through DataTreeChangeListener – i.e. an implementation could be (just painting a picture!)

@FunctionalInterface
interface DataObjectListenerAdapter<T extends DataObject> extends ClusteredDataTreeChangeListener<T>, DataListener<T> {
    @Override
    public final void onInitialData() {
         dataChangedTo(null);
    }

    @Override
    public final void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
         dataChangedTo(Iterables.getLast(changes).getRootNode().getDataAfter());
    }
}

Implementation-wise, mdsal-binding-dom-adapter can perform the equivalent of getLast()... on top of DOM data (which is a List, not a Collection) and just decode the last fragment – which will be very efficient indeed.

There is a wrinkle with wildcard InstanceIdentifiers, where this approach falls flat. As a first step, DataBroker.registerListener() should reject wildcards with an IllegalArgumentException. A follow-up will provide similar interfaces which report the InstanceIdentifier as well (and thus can deal with wildcards).

A further use case is comparison on before-value and after-value, so another interface like:

@FunctionalInterface
interface DataChangeListener<T extends DataObject> {
    void dataChanged(@Nullable T previousValue, @Nullable T currentValue);
}

which is to say: previousValue = first.getRootNode().getDataBefore(), currentValue = last.getRootNode().getDataAfter() in terms of DTCL.



 Comments   
Comment by Robert Varga [ 10/Feb/23 ]

Since this can be solved with default interface methods for compatibility, we should introduce this in 11.0.x stream.

Generated at Wed Feb 07 20:11:02 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.