<!-- 
RSS generated by JIRA (8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d) at Wed Feb 07 20:15:29 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>OpenDaylight JIRA</title>
    <link>https://jira.opendaylight.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>8.20.10</version>
        <build-number>820010</build-number>
        <build-date>22-06-2022</build-date>
    </build-info>


<item>
            <title>[NETCONF-625] Race condition causes multiple notification subscriptions (diagnosed)</title>
                <link>https://jira.opendaylight.org/browse/NETCONF-625</link>
                <project id="10142" key="NETCONF">netconf</project>
                    <description>&lt;p&gt;I&apos;m filing this on behalf of a developer on my team (Lukas), so I may not disambiguate all of these details...&lt;/p&gt;

&lt;p&gt;We hit a race condition in subscribing to notifications in Carbon. I have not had time to figure out if the problem exists in later versions of ODL. The errant behavior is that a subscriber can end up with multiple subscriptions to the same thing, such that a single notification causes multiple callbacks.&lt;/p&gt;

&lt;p&gt;The problem occurs when subscribing more than once successively in a short enough time window.&#160;&lt;/p&gt;

&lt;p&gt;POST:&lt;br/&gt;
 &lt;a href=&quot;http://%7B%7Bcontroller-ip%7D%7D:8181/restconf/operations/sal-remote:create-notification-stream&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://&lt;tt&gt;controller-ip&lt;/tt&gt;:8181/restconf/operations/sal-remote:create-notification-stream&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;{ &#160; &quot;input&quot;: &#160; &#160;&lt;/p&gt;

{&#160; &#160; &quot;notifications&quot;: [ &#160; &#160; &#160; &quot;([http://verizon.com/yang/notification?revision=2018-11-15)event-notification]&quot;, &#160; &#160; &#160; &quot;([http://verizon.com/yang/notification?revision=2018-11-15)node-status-notification]&quot; &#160; &#160; ], &#160; &#160; &quot;notification-output-type&quot;: &quot;JSON&quot; &#160; }

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;GET:&lt;br/&gt;
 &lt;a href=&quot;http://%7B%7Bcontroller-ip%7D%7D:8181/restconf/streams/stream/create-notification-stream/bnc-notification:node-status-notification,bnc-notification:event-notification&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://&lt;tt&gt;controller-ip&lt;/tt&gt;:8181/restconf/streams/stream/create-notification-stream/bnc-notification:node-status-notification,bnc-notification:event-notification&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Carbon version of the code is here&lt;/p&gt;

&lt;p&gt;POST:&lt;br/&gt;
 &lt;a href=&quot;https://github.com/opendaylight/netconf/blob/stable/carbon/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/services/impl/RestconfInvokeOperationsServiceImpl.java&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/opendaylight/netconf/blob/stable/carbon/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/services/impl/RestconfInvokeOperationsServiceImpl.java&lt;/a&gt;&lt;br/&gt;
 GET:&lt;br/&gt;
 &lt;a href=&quot;https://github.com/opendaylight/netconf/blob/stable/carbon/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/services/impl/RestconfStreamsSubscriptionServiceImpl.java&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/opendaylight/netconf/blob/stable/carbon/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/services/impl/RestconfStreamsSubscriptionServiceImpl.java&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The master branch version of the code is here...&lt;/p&gt;

&lt;p&gt;POST:&lt;br/&gt;
 &lt;a href=&quot;https://github.com/opendaylight/netconf/blob/master/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfInvokeOperationsServiceImpl.java&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/opendaylight/netconf/blob/master/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfInvokeOperationsServiceImpl.java&lt;/a&gt;&lt;br/&gt;
 GET:&lt;br/&gt;
 &lt;a href=&quot;https://github.com/opendaylight/netconf/blob/master/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/opendaylight/netconf/blob/master/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking at the code, the culprit is likely in&#160;&lt;/p&gt;

&lt;p&gt;./restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/SubscribeToStreamUtil.java:notifYangStream&lt;br/&gt;
 ./restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/restful/utils/SubscribeToStreamUtil.java:registerToListenNotification&lt;br/&gt;
 org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter.registerNotificationListener&lt;/p&gt;

&lt;p&gt;probably do synchronized inside of this:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
&#160; &#160; &lt;span class=&quot;code-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;static&lt;/span&gt; void registerToListenNotification(&lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; NotificationListenerAdapter listener,
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; NotificationServiceHandler notificationServiceHandler) {
&#160; &#160; &#160; &#160; &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (listener.isListening()) { ---&amp;gt;&amp;gt;&amp;gt;condition through which pass both threads in same time
&#160; &#160; &#160; &#160; &#160; &#160; &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt;;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ---&amp;gt;&amp;gt;&amp;gt;&lt;span class=&quot;code-keyword&quot;&gt;synchronized&lt;/span&gt; to listener is probably ideal because it is same &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; both calls
&#160; &#160; &#160; &#160; }

&#160; &#160; &#160; &#160; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; SchemaPath path = listener.getSchemaPath();
&#160; &#160; &#160; &#160; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; ListenerRegistration&amp;lt;DOMNotificationListener&amp;gt; registration =
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; notificationServiceHandler.get().registerNotificationListener(listener, path);

&#160; &#160; &#160; &#160; listener.setRegistration(registration);

&#160; &#160; }
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The master branch shows similar logic so will suffer the same behavior.&lt;/p&gt;

&lt;p&gt;The problem likely exists in NETCONF, where there is duplicate code...&lt;/p&gt;

&lt;p&gt;./restconf/restconf-nb-bierman02/src/main/java/org/opendaylight/netconf/sal/restconf/impl/BrokerFacade.java&lt;/p&gt;

&lt;p&gt;There is a method with the same name and body registerToListenNotification&lt;/p&gt;</description>
                <environment></environment>
        <key id="31739">NETCONF-625</key>
            <summary>Race condition causes multiple notification subscriptions (diagnosed)</summary>
                <type id="10001" iconUrl="https://jira.opendaylight.org/images/icons/issuetypes/story.svg">Story</type>
                                            <priority id="2" iconUrl="https://jira.opendaylight.org/images/icons/priorities/critical.svg">High</priority>
                        <status id="3" iconUrl="https://jira.opendaylight.org/images/icons/statuses/inprogress.png" description="This issue is being actively worked on at the moment by the assignee.">In Progress</status>
                    <statusCategory id="4" key="indeterminate" colorName="yellow"/>
                                    <resolution id="-1">Unresolved</resolution>
                                        <assignee username="SowmiyaChidambaram">Sowmiya Chidambaram</assignee>
                                    <reporter username="allanclarke">Allan Clarke</reporter>
                        <labels>
                    </labels>
                <created>Mon, 10 Jun 2019 13:46:40 +0000</created>
                <updated>Wed, 12 Feb 2020 10:48:24 +0000</updated>
                                                                            <component>netconf</component>
                    <component>restconf-nb</component>
                        <due></due>
                            <votes>0</votes>
                                    <watches>4</watches>
                                                                                                                <comments>
                            <comment id="67607" author="sowmiyac95" created="Fri, 3 Jan 2020 16:46:26 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.opendaylight.org/secure/ViewProfile.jspa?name=allanclarke&quot; class=&quot;user-hover&quot; rel=&quot;allanclarke&quot;&gt;allanclarke&lt;/a&gt;,&#160;&lt;/p&gt;

&lt;p&gt;I gave a try to reproduce this issue. Below are the steps followed,&#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;POST&lt;/b&gt; &amp;#8211; &lt;a href=&quot;http://localhost:8181/restconf/operations/sal-remote:create-notification-streamPOST&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://localhost:8181/restconf/operations/sal-remote:create-notification-streamPOST&lt;/a&gt; &amp;#8211; &lt;a href=&quot;http://localhost:8181/restconf/operations/sal-remote:create-notification-stream&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://localhost:8181/restconf/operations/sal-remote:create-notification-stream&lt;/a&gt;&lt;br/&gt;
{&#160; &quot;input&quot;: {&#160; &#160; &quot;notifications&quot;: &lt;span class=&quot;error&quot;&gt;&amp;#91;&#160; &#160; &#160; &amp;quot;(http://netconfcentral.org/ns/toaster?revision=2009-11-20)toasterRestocked&amp;quot;, &#160; &amp;quot;(http://netconfcentral.org/ns/toaster?revision=2009-11-20)toasterOutOfBread&amp;quot;&#160; &#160; &amp;#93;&lt;/span&gt;,&#160; &#160; &quot;notification-output-type&quot;: &quot;JSON&quot;&#160; }}&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Response :&lt;/b&gt;&lt;br/&gt;
{&#160; &quot;output&quot;: {&#160; &#160; &quot;notification-stream-identifier&quot;: &quot;create-notification-stream/toaster:toasterRestocked,toaster:toasterOutOfBread&quot;&#160; }}&lt;/p&gt;

&lt;p&gt;&#160;&lt;/p&gt;

&lt;p&gt;Executed the above mentioned request around 5-7 times within a second. Then, executed the following request to get websocket link,&lt;/p&gt;


&lt;p&gt;&lt;b&gt;GET&lt;/b&gt; &amp;#8211; &lt;a href=&quot;http://localhost:8181/restconf/streams/stream/create-notification-stream/toaster:toasterRestocked,toaster:toasterOutOfBread&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://localhost:8181/restconf/streams/stream/create-notification-stream/toaster:toasterRestocked,toaster:toasterOutOfBread&lt;/a&gt;&lt;br/&gt;
&lt;b&gt;Response&lt;/b&gt; :&lt;/p&gt;
{&quot;location&quot;:&quot;ws://localhost:8185/create-notification-stream/toaster:toasterRestocked,toaster:toasterOutOfBread&quot;}


&lt;p&gt;Finally opened the websocket client with above ws url and started listening to notifications.&lt;br/&gt;
Created both (toasterRestocked and&#160;toasterOutOfBread ) types of notifications with toaster app.&lt;/p&gt;


&lt;p&gt;First type of notification,&lt;/p&gt;

&lt;p&gt;&lt;b&gt;POST&lt;/b&gt; &amp;#8211; &lt;a href=&quot;http://localhost:8181/restconf/operations/toaster:restock-toaster&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://localhost:8181/restconf/operations/toaster:restock-toaster&lt;/a&gt;&lt;br/&gt;
{&#160; &quot;input&quot; :&#160; {&#160; &#160; &quot;toaster:amountOfBreadToStock&quot;: &quot;1&quot;&#160; }}&lt;br/&gt;
&lt;b&gt;Response code :&lt;/b&gt; 204&#160;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Received single notification in websocket.&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&#160;{&quot;ietf-restconf:notification&quot;:{&quot;toaster:toasterRestocked&quot;:{&quot;amountOfBread&quot;:1}},&quot;event-time&quot;:&quot;2020-01-03T19:12:19.006858+05:30&quot;}&lt;/p&gt;


&lt;p&gt;Second type of notification,&lt;/p&gt;

&lt;p&gt;&lt;b&gt;POST&lt;/b&gt; &amp;#8211; &lt;a href=&quot;http://localhost:8181/restconf/operations/toaster:make-toast&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;http://localhost:8181/restconf/operations/toaster:make-toast&lt;/a&gt;&lt;br/&gt;
{&#160; &quot;toaster:input&quot;: {&#160; &#160; &quot;toaster:toasterDoneness&quot;: &quot;5&quot;,&#160; &#160; &quot;toaster:toasterToastType&quot;: &quot;wheat-bread&quot;&#160; }}&lt;br/&gt;
&lt;b&gt;Response code&lt;/b&gt; : 204&lt;br/&gt;
&lt;b&gt;Received single notification in websocket.&lt;/b&gt;&#160;&lt;br/&gt;
{&quot;ietf-restconf:notification&quot;:{&quot;toaster:toasterOutOfBread&quot;:{}},&quot;event-time&quot;:&quot;2020-01-03T19:12:30.503999+05:30&quot;}&lt;/p&gt;


&lt;p&gt;Here in both cases, only one notification&#160; has been received per request. As per the ticket, more than one should be received.&#160;&lt;/p&gt;

&lt;p&gt;Tested this in carbon-sr4 as well as with latest netconf master code base. Is the steps followed here are correct or something has been missed out?&#160;&lt;/p&gt;

&lt;p&gt;Also, in which release of carbon you are facing this issue?&#160;&lt;/p&gt;</comment>
                            <comment id="67642" author="sowmiyac95" created="Sun, 12 Jan 2020 09:59:46 +0000"  >&lt;p&gt;Gentle reminder. Please do respond.&lt;/p&gt;</comment>
                            <comment id="67824" author="allanclarke" created="Mon, 10 Feb 2020 15:20:06 +0000"  >&lt;p&gt;I can get Lukas to respond. I forgot that he was the originator. I apologize for any delay/confusion.&lt;/p&gt;</comment>
                            <comment id="67825" author="JIRAUSER12904" created="Mon, 10 Feb 2020 18:11:14 +0000"  >&lt;p&gt;hello,&lt;/p&gt;

&lt;p&gt;im remember for subscribe to odl is needed both calls(POST+GET). When you call only POST several time in short time internally in odl is subscribe not created. Im look on this more than 8 months back.&lt;/p&gt;

&lt;p&gt;Probably best for reproduce will be call POST+GET several time in same time&lt;/p&gt;</comment>
                            <comment id="67836" author="JIRAUSER12901" created="Wed, 12 Feb 2020 10:48:24 +0000"  >&lt;p&gt;Thanks &lt;a href=&quot;https://jira.opendaylight.org/secure/ViewProfile.jspa?name=allanclarke&quot; class=&quot;user-hover&quot; rel=&quot;allanclarke&quot;&gt;allanclarke&lt;/a&gt;&#160;and &lt;a href=&quot;https://jira.opendaylight.org/secure/ViewProfile.jspa?name=LukasB+3&quot; class=&quot;user-hover&quot; rel=&quot;LukasB 3&quot;&gt;LukasB 3&lt;/a&gt;&#160;for your response. Since it&apos;s a rarely occurring one, will again try to reproduce.&#160;&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                            <customfield id="customfield_11400" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10000" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>0|i03o5r:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>