1919
2020package org .apache .comet .cloud .s3 ;
2121
22+ import java .util .Collections ;
23+ import java .util .HashMap ;
24+ import java .util .Map ;
25+
2226import org .junit .Before ;
2327import org .junit .Test ;
2428
3236public class CometS3CredentialDispatcherTest {
3337
3438 private static final String TEST_PROVIDER = TestCometS3CredentialProvider .class .getName ();
39+ private static final String DK = "test-dispatch-key" ;
3540 private static final int READ = CometS3AccessMode .READ .ordinal ();
3641 private static final int WRITE = CometS3AccessMode .WRITE .ordinal ();
3742
@@ -40,11 +45,16 @@ public void resetTestProvider() {
4045 TestCometS3CredentialProvider .reset ();
4146 }
4247
48+ private void init () {
49+ CometS3CredentialDispatcher .ensureInitialized (TEST_PROVIDER , DK , Collections .emptyMap ());
50+ }
51+
4352 @ Test
4453 public void getCredentialsRoundTripsThroughProvider () throws Exception {
54+ init ();
4555 CometS3Credentials creds =
4656 CometS3CredentialDispatcher .getCredentialsForPath (
47- TEST_PROVIDER , "my-bucket" , "path/to/object" , READ );
57+ TEST_PROVIDER , DK , "my-bucket" , "path/to/object" , READ );
4858
4959 assertNotNull (creds );
5060 assertEquals ("AKIATEST" , creds .getAccessKeyId ());
@@ -60,25 +70,30 @@ public void getCredentialsRoundTripsThroughProvider() throws Exception {
6070
6171 @ Test
6272 public void writeModeIsForwarded () throws Exception {
63- CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "b" , "k" , WRITE );
73+ init ();
74+ CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , DK , "b" , "k" , WRITE );
6475 assertEquals (CometS3AccessMode .WRITE , TestCometS3CredentialProvider .lastMode );
6576 }
6677
6778 @ Test
6879 public void unknownModeRejected () {
80+ init ();
6981 assertThrows (
7082 IllegalArgumentException .class ,
71- () -> CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "b" , "k" , 99 ));
83+ () -> CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , DK , "b" , "k" , 99 ));
7284 }
7385
7486 @ Test
7587 public void emptyClassNameRejected () {
7688 assertThrows (
7789 IllegalArgumentException .class ,
78- () -> CometS3CredentialDispatcher .getCredentialsForPath ("" , "b" , "k" , READ ));
90+ () -> CometS3CredentialDispatcher .ensureInitialized ("" , DK , Collections .emptyMap ()));
91+ assertThrows (
92+ IllegalArgumentException .class ,
93+ () -> CometS3CredentialDispatcher .ensureInitialized (null , DK , Collections .emptyMap ()));
7994 assertThrows (
8095 IllegalArgumentException .class ,
81- () -> CometS3CredentialDispatcher .getCredentialsForPath (null , "b" , "k" , READ ));
96+ () -> CometS3CredentialDispatcher .getCredentialsForPath ("" , DK , "b" , "k" , READ ));
8297 }
8398
8499 @ Test
@@ -87,8 +102,8 @@ public void missingClassReportsActionableError() {
87102 assertThrows (
88103 IllegalStateException .class ,
89104 () ->
90- CometS3CredentialDispatcher .getCredentialsForPath (
91- "com.does.not.Exist" , "b" , "k" , READ ));
105+ CometS3CredentialDispatcher .ensureInitialized (
106+ "com.does.not.Exist" , DK , Collections . emptyMap () ));
92107 assertTrue (thrown .getMessage ().contains ("not found" ));
93108 }
94109
@@ -98,8 +113,8 @@ public void classNotImplementingInterfaceRejected() {
98113 assertThrows (
99114 IllegalStateException .class ,
100115 () ->
101- CometS3CredentialDispatcher .getCredentialsForPath (
102- NotACredentialProvider .class .getName (), "b" , "k" , READ ));
116+ CometS3CredentialDispatcher .ensureInitialized (
117+ NotACredentialProvider .class .getName (), DK , Collections . emptyMap () ));
103118 assertTrue (thrown .getMessage ().contains ("does not implement" ));
104119 }
105120
@@ -109,38 +124,85 @@ public void classWithoutNoArgCtorRejected() {
109124 assertThrows (
110125 IllegalStateException .class ,
111126 () ->
112- CometS3CredentialDispatcher .getCredentialsForPath (
113- NoNoArgCtorProvider .class .getName (), "b" , "k" , READ ));
127+ CometS3CredentialDispatcher .ensureInitialized (
128+ NoNoArgCtorProvider .class .getName (), DK , Collections . emptyMap () ));
114129 assertTrue (thrown .getMessage ().contains ("no-arg constructor" ));
115130 }
116131
132+ @ Test
133+ public void getWithoutEnsureInitializedThrows () {
134+ Exception thrown =
135+ assertThrows (
136+ IllegalStateException .class ,
137+ () ->
138+ CometS3CredentialDispatcher .getCredentialsForPath (
139+ TEST_PROVIDER , "never-initialized" , "b" , "k" , READ ));
140+ assertTrue (thrown .getMessage ().contains ("not initialized" ));
141+ }
142+
143+ @ Test
144+ public void initializeCalledExactlyOncePerKey () {
145+ Map <String , String > props = new HashMap <>();
146+ props .put ("tenant-id" , "T1" );
147+
148+ CometS3CredentialDispatcher .ensureInitialized (TEST_PROVIDER , "cat-a" , props );
149+ CometS3CredentialDispatcher .ensureInitialized (TEST_PROVIDER , "cat-a" , props );
150+ CometS3CredentialDispatcher .ensureInitialized (TEST_PROVIDER , "cat-a" , props );
151+
152+ assertEquals (1 , TestCometS3CredentialProvider .initCount .get ());
153+ }
154+
155+ @ Test
156+ public void distinctDispatchKeysIsolateInstances () throws Exception {
157+ Map <String , String > propsA = new HashMap <>();
158+ propsA .put ("tenant-id" , "T-A" );
159+ Map <String , String > propsB = new HashMap <>();
160+ propsB .put ("tenant-id" , "T-B" );
161+
162+ CometS3CredentialDispatcher .ensureInitialized (TEST_PROVIDER , "iso-cat-a" , propsA );
163+ CometS3CredentialDispatcher .ensureInitialized (TEST_PROVIDER , "iso-cat-b" , propsB );
164+
165+ assertEquals (2 , TestCometS3CredentialProvider .initCount .get ());
166+
167+ CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "iso-cat-a" , "b" , "k" , READ );
168+ assertEquals ("T-A" , TestCometS3CredentialProvider .lastTenantSeen );
169+
170+ CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "iso-cat-b" , "b" , "k" , READ );
171+ assertEquals ("T-B" , TestCometS3CredentialProvider .lastTenantSeen );
172+ }
173+
117174 @ Test
118175 public void providerExceptionsPropagate () {
176+ init ();
119177 IllegalStateException boom = new IllegalStateException ("simulated STS failure" );
120178 TestCometS3CredentialProvider .throwOnNext = boom ;
121179
122180 Exception thrown =
123181 assertThrows (
124182 Exception .class ,
125- () -> CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "b" , "k" , READ ));
183+ () ->
184+ CometS3CredentialDispatcher .getCredentialsForPath (
185+ TEST_PROVIDER , DK , "b" , "k" , READ ));
126186 assertSame (boom , thrown );
127187 }
128188
129189 @ Test
130190 public void nullSessionTokenAllowed () throws Exception {
191+ init ();
131192 TestCometS3CredentialProvider .nextResult = new CometS3Credentials ("AKIA" , "sec" , null , 0L );
132193
133194 CometS3Credentials creds =
134- CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "b" , "k" , READ );
195+ CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , DK , "b" , "k" , READ );
135196
136197 assertNull (creds .getSessionToken ());
137198 }
138199
139200 @ Test
140201 public void providerReceivesEachCallSeparately () throws Exception {
141- CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "b1" , "k1" , READ );
142- CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "b2" , "k2" , READ );
143- CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , "b3" , "k3" , READ );
202+ init ();
203+ CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , DK , "b1" , "k1" , READ );
204+ CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , DK , "b2" , "k2" , READ );
205+ CometS3CredentialDispatcher .getCredentialsForPath (TEST_PROVIDER , DK , "b3" , "k3" , READ );
144206
145207 assertEquals (3 , TestCometS3CredentialProvider .callCount .get ());
146208 assertEquals ("b3" , TestCometS3CredentialProvider .lastBucket );
0 commit comments