[CONTROLLER-604] No API exists to get created data from onDataChanged() after sequential PUTs Created: 06/Jul/14 Updated: 25/Jul/23 Resolved: 10/Mar/17 |
|
| Status: | Resolved |
| Project: | controller |
| Component/s: | mdsal |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | ||
| Reporter: | Reinaldo Penno | Assignee: | Tony Tkacik |
| Resolution: | Cannot Reproduce | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Operating System: All |
||
| Issue Links: |
|
||||||||
| Description |
|
Scenario is very simple 1 - First I send a PUT: I can get the data created with: change.getUpdatedConfigurationData() or 2 - I send a second PUT put /config/service-function:service-functions/service-function/nat44-2/ I get a callback but existing API can tell me the created data in a DataObject. They all return NULL. I can see from a GET that both service-functions were created in the datastore. |
| Comments |
| Comment by Reinaldo Penno [ 06/Jul/14 ] |
|
It should read "...but no existing API" And more information. It seems all information is on some cache variables but I have no idea of their purpose. |
| Comment by Tony Tkacik [ 07/Jul/14 ] |
|
Decreased to normal, API is same and scenario you described works for FRM and Openflow related plugins for more then half an year, 1. How you registered for data change events? Snippet of code would be helpful. 2. How you read data change event? Snippet of code would be helpful 3. What was payload for first put and what was payload for second put? |
| Comment by Reinaldo Penno [ 07/Jul/14 ] |
| Comment by Tony Tkacik [ 08/Jul/14 ] |
|
put /config/service-function-chain:service-function-chains/service-function-chain/Chain-2/ { , { "name" : "proxy-or", "type" : "proxy" } ] osgi> 2014-07-07 21:46:56.655 PDT [pool-14-thread-2] INFO o.o.s.p.SfcProviderSfcDataListener -
Oops. Something went wrong. getUpdatedConfigurationData, getOriginalConfigurationData nor getCreatedConfigurationData gave me any data! |
| Comment by Tony Tkacik [ 08/Jul/14 ] |
|
Bugfix is contained in https://git.opendaylight.org/gerrit/#/c/8807/ |
| Comment by Reinaldo Penno [ 15/Jul/14 ] |
|
Problem simple to reproduce. module mymodule { container A { list list-of-B { } If I use PUT to replace the value in container B such as http://localhost:8080/restconf/config/module:A/list-of-B/name/B/ there is no API in onDataChanged() that allows me to get the old value: change.getRemovedConfigurationData() is empty The only resort is to compare original and updated configs but in a huge complex configuration like mine this is not practical. If the original value of container B was removed and a new one was added, I should get something in getRemovedConfigurationData and getCreatedConfigurationData(). thanks, Reinaldo |
| Comment by Reinaldo Penno [ 16/Jul/14 ] |
|
Please hold any further changes until I test with the new Async APIs. Results and recourse might be different. |
| Comment by Tony Tkacik [ 01/Aug/14 ] |
|
Please verify if data change event is delivered after sequential puts, |
| Comment by Jan Hajnar [ 01/Aug/14 ] |
|
I tested the scenario described in Comment 6 with AsyncDataBroker and got the same results as Reinaldo before. After second PUT replacing container B: |
| Comment by Jan Hajnar [ 08/Aug/14 ] |
|
Added tests that show that TranslatedDataChangeEvent object that is received on data change contains only new Container B in getUpdatedData() and old container B in getOriginalData(). However, I think since the B container contains only leaf nodes, this behavior is correct (Leaf nodes cannot be identified in BA context). In the underlying DOMImmutableDataChangeEvent (from which data for TranslatedDataChangeEvent are generated) that contains NormalizedNode level events, all leaf modifications are properly captured (because YangInstanceIdentifier can identify leaves). If I add another container C under container B I get correct modification results on BA level. Tests that show behavior: |
| Comment by Reinaldo Penno [ 08/Aug/14 ] |
|
My original point is that since HTTP PUT is always a create (idempotent), the first or any subsequent PUT should generate: getCreatedData() created data |
| Comment by Reinaldo Penno [ 08/Aug/14 ] |
|
Why close it? I opened it and do not believe the behavior is correct. What the current implementation can or can not do is a different matter. |
| Comment by Robert Varga [ 10/Aug/14 ] |
|
RESTCONF is just one avenue of how to get the data into data store – please do not generalize it to all users, as consumers of data have different needs. At the end of the day, this boils down to how you perceive what constitutes "changed data". If you the same document twice, precisely as you said, the second put has no effect from pure data perspective – nothing has changed. So why should we emit a change at all? Another aspect of this is whether the transaction boundary is guaranteed to be present. I would argue it should not, as it would create tight coupling and at the end of the day, you really care about the delta, not now that delta was entered into the system. This allows for more efficient operation, for example by compressing state changes when your listener cannot keep up. On a final note, it is a fair ask to be able to specify what object granularity you want reported, e.g. even if the documents differ in a single field, you want to see them changed, without caring about that particular field – but that requires a new API. At any rate, this is not a bug per se, but an enhancement request. |
| Comment by Reinaldo Penno [ 10/Aug/14 ] |
|
There is a disconnect here. The data used in the second PUT is not the same as the first one. This is one of the main issues reported. The first PUT is considered a "create" and every subsequent PUT (even with different data) is considered an "update". This is not consistent. As far as transaction boundary goes, I understand the datastore can be modified through many methods, but there are deep repercussions from an user and standards perspective. From a HTTP point of view you expect all PUTs to be "creates", but the user is notified as an "update". This does not seem consistent with HTTP. If our current implementation can not provide proper semantics, then we might need to have different data notification based on the producer. And the user subscriber to those with something like a RestconfListener instead of a generic listener. |
| Comment by Robert Varga [ 11/Aug/14 ] |
|
I understand, but it really looks like tight coupling of components. Is there a specific use case, where you really need this level of visibility and the current stack does not give you sufficient information? |
| Comment by Reinaldo Penno [ 11/Aug/14 ] |
|
use-case: In SFC I need to know what was created, I mean really created as opposed to updated, in order to build a proper HTTP request, construct the payload and send to southbound switches. Creating a switch configuration when was actually an update or vice-versa creates a chain of repercussions all the way down to the switch's data plane. Answering your question: Now, all the info I need is there, but many times not where I normally expect so the code is convoluted and brittle because I need checks on onDataChanged() to catch a create and/or also an update depending on the occasion. This means the interaction with SB switches as I mentioned above problematic. Now, I understand this is not a small change and we need to properly schedule it but for use-cases like mine having the HTTP REST semantics carried properly across the system is very important. |
| Comment by Tony Tkacik [ 19/May/15 ] |
|
DataTreeChangeListener API provides raw-access to data changes and does not hide |