<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 09:03:28 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>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[JAVA-4992] Refactor MongoCredentialWithCache, Authenticator, InternalStreamConnectionFactory</title>
                <link>https://jira.mongodb.org/browse/JAVA-4992</link>
                <project id="10006" key="JAVA">Java Driver</project>
                    <description>&lt;h3&gt;&lt;a name=&quot;Summary&quot;&gt;&lt;/a&gt;Summary&lt;/h3&gt;
&lt;p&gt;&lt;tt&gt;MongoCredentialWithCache&lt;/tt&gt; is in a detrimental state to put it mildly, but it seems like we should be able to improve things.&lt;/p&gt;

&lt;h3&gt;&lt;a name=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h3&gt;
&lt;p&gt;There appear to be the three following possible approaches on how &lt;tt&gt;Authenticator&lt;/tt&gt; may be designed (if one sees more, please add):&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;There is a single thread-safe &lt;tt&gt;Authenticator&lt;/tt&gt; instance per &lt;tt&gt;MongoClient&lt;/tt&gt; that owns state shared by all connections as well as connection-confined state. The state confined to each &lt;tt&gt;InternalConnection&lt;/tt&gt; may be represented via an entry in &lt;tt&gt;ConcurrentHashMap&lt;/tt&gt; where the key is &lt;tt&gt;(ConnectionDescription.getServiceId(), ConnectionDescription.getConnectionId())&lt;/tt&gt;.&lt;/li&gt;
	&lt;li&gt;There is a single thread-safe &lt;tt&gt;Authenticator&lt;/tt&gt; instance per &lt;tt&gt;MongoClient&lt;/tt&gt; that owns state shared by all connections and accesses connection-confined state in its &lt;tt&gt;authenticate&lt;/tt&gt; / &lt;tt&gt;reauthenticate&lt;/tt&gt; methods via &lt;tt&gt;InternalConnection&lt;/tt&gt;, which is passed as an argument.&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;error&quot;&gt;&amp;#91;this one is used in the driver&amp;#93;&lt;/span&gt; There is a single thread-safe object that owns state shared by all connections, and there are multiple &lt;tt&gt;Authenticator&lt;/tt&gt; instances, one per &lt;tt&gt;InternalConnection&lt;/tt&gt;, that all have access to the shared state and own connection-confined state.&lt;/li&gt;
&lt;/ol&gt;


&lt;h4&gt;&lt;a name=&quot;Problemswiththecurrentdesign&quot;&gt;&lt;/a&gt;Problems with the current design&lt;/h4&gt;

&lt;h5&gt;&lt;a name=&quot;Allowsforonlyoneimplementationofthethreadsafeobjectthatownsstatesharedbyallconnections&quot;&gt;&lt;/a&gt;Allows for only one implementation of the thread-safe object that owns state shared by all connections&lt;/h5&gt;

&lt;p&gt;Approach #3 is used in the driver, with &lt;tt&gt;MongoCredentialWithCache&lt;/tt&gt; being the object that owns state shared by all connections. Different &lt;tt&gt;Authenticator&lt;/tt&gt; implementations need different state shared by all connections, yet the only currently possible implementation of that state is &lt;tt&gt;MongoCredentialWithCache&lt;/tt&gt;. The implementation of &lt;tt&gt;OidcAuthenticator&lt;/tt&gt; had to make the &lt;tt&gt;MongoCredentialWithCache&lt;/tt&gt; code even weirder than it was: it had to add state and methods that are specific to &lt;tt&gt;OidcAuthenticator&lt;/tt&gt;, but as a result are visible to all other implementations of &lt;tt&gt;Authenticator&lt;/tt&gt;. Here is the corresponding &lt;a href=&quot;https://github.com/mongodb/mongo-java-driver/pull/1107#discussion_r1206209598&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;PR discussion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can make &lt;tt&gt;Authenticator&lt;/tt&gt; generic over the type of the state shared by all connections, split &lt;tt&gt;MongoCredentialWithCache&lt;/tt&gt; into multiple classes that better fit the needs of different &lt;tt&gt;Authenticator&lt;/tt&gt; implementations, and change &lt;tt&gt;InternalStreamConnectionFactory&lt;/tt&gt; such that it gives its &lt;tt&gt;Authenticator&lt;/tt&gt; implementation the shared state of the type needed by that implementation. This approach came up in both cases when I was independently discussing the issue with &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jeff.yemin%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;jeff.yemin@mongodb.com&quot;&gt;jeff.yemin@mongodb.com&lt;/a&gt; and &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=maxim.katcharov%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;maxim.katcharov@mongodb.com&quot;&gt;maxim.katcharov@mongodb.com&lt;/a&gt;.&lt;/p&gt;

&lt;h5&gt;&lt;a name=&quot;Breaksisolationbysharingthelockownedby%7B%7BMongoCredentialWithCache%7D%7Dwithall%7B%7BAuthenticator%7D%7Dinstances&quot;&gt;&lt;/a&gt;Breaks isolation by sharing the lock owned by &lt;tt&gt;MongoCredentialWithCache&lt;/tt&gt; with all &lt;tt&gt;Authenticator&lt;/tt&gt; instances&lt;/h5&gt;

&lt;p&gt;A situation when one object owns a lock, but has to share it with other objects, which use it explicitly, appears to violate the encapsulation principle and suggests that the object boundaries may have not been designed optimally. It seems to me that of the three approaches described above, only approach #3 results in this specific issue. I raised this concern when reviewing the &lt;tt&gt;OidcAuthenticator&lt;/tt&gt; implementation. Here is the corresponding &lt;a href=&quot;https://github.com/mongodb/mongo-java-driver/pull/1107#discussion_r1206202106&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;PR discussion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I admit the possibility of other approaches either encountering unforeseen complications (this is relevant to approach #1), or also having to break OOP principles (this is relevant to approach #2) if tried to be implemented. I am not currently suggesting to change to approach from #3 to either #2 or #1. I have described this problem here and my thoughts on it just in case.&lt;/p&gt;</description>
                <environment></environment>
        <key id="2353369">JAVA-4992</key>
            <summary>Refactor MongoCredentialWithCache, Authenticator, InternalStreamConnectionFactory</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="4" iconUrl="https://jira.mongodb.org/images/icons/priorities/minor.svg">Minor - P4</priority>
                        <status id="10038" iconUrl="https://jira.mongodb.org/images/icons/subtask.gif" description="">Backlog</status>
                    <statusCategory id="2" key="new" colorName="default"/>
                                    <resolution id="-1">Unresolved</resolution>
                                        <assignee username="-1">Unassigned</assignee>
                                    <reporter username="valentin.kovalenko@mongodb.com">Valentin Kavalenka</reporter>
                        <labels>
                    </labels>
                <created>Tue, 30 May 2023 07:01:15 +0000</created>
                <updated>Tue, 30 May 2023 15:30:04 +0000</updated>
                                                                            <component>Authentication</component>
                                        <votes>0</votes>
                                    <watches>1</watches>
                                                                                                                        <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|i1tkzs:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>