1616
1717package com .google .cloud .bigquery .storage .v1 .it ;
1818
19+ import static com .google .common .truth .Truth .assertThat ;
1920import static com .google .common .truth .Truth .assertWithMessage ;
2021import static org .junit .Assert .assertArrayEquals ;
2122import static org .junit .Assert .assertEquals ;
2223import static org .junit .Assert .assertNotNull ;
2324import static org .junit .Assert .assertNull ;
2425import static org .junit .Assert .assertTrue ;
26+ import static org .junit .Assert .fail ;
2527
28+ import com .google .api .gax .core .FixedCredentialsProvider ;
2629import com .google .api .gax .core .InstantiatingExecutorProvider ;
2730import com .google .api .gax .rpc .ServerStream ;
31+ import com .google .api .gax .rpc .UnauthenticatedException ;
32+ import com .google .auth .oauth2 .GoogleCredentials ;
2833import com .google .cloud .RetryOption ;
2934import com .google .cloud .ServiceOptions ;
3035import com .google .cloud .bigquery .BigQuery ;
5459import com .google .cloud .bigquery .testing .RemoteBigQueryHelper ;
5560import com .google .common .base .Preconditions ;
5661import com .google .protobuf .Timestamp ;
62+ import java .io .ByteArrayInputStream ;
5763import java .io .IOException ;
64+ import java .io .InputStream ;
5865import java .math .BigDecimal ;
5966import java .nio .ByteBuffer ;
6067import java .util .ArrayList ;
8289
8390/** Integration tests for BigQuery Storage API. */
8491public class ITBigQueryStorageTest {
85-
8692 private static final Logger LOG = Logger .getLogger (ITBigQueryStorageTest .class .getName ());
8793 private static final String DATASET = RemoteBigQueryHelper .generateDatasetName ();
8894 private static final String DESCRIPTION = "BigQuery Storage Java client test dataset" ;
@@ -91,6 +97,66 @@ public class ITBigQueryStorageTest {
9197 private static String parentProjectId ;
9298 private static BigQuery bigquery ;
9399
100+ private static final String FAKE_JSON_CRED_WITH_GOOGLE_DOMAIN =
101+ "{\n "
102+ + " \" private_key_id\" : \" somekeyid\" ,\n "
103+ + " \" private_key\" : \" -----BEGIN PRIVATE KEY-----\\ nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS"
104+ + "kAgEAAoIBAQC+K2hSuFpAdrJI\\ nnCgcDz2M7t7bjdlsadsasad+fvRSW6TjNQZ3p5LLQY1kSZRqBqylRkzteMOyHg"
105+ + "aR\\ n0Pmxh3ILCND5men43j3h4eDbrhQBuxfEMalkG92sL+PNQSETY2tnvXryOvmBRwa/\\ nQP/9dJfIkIDJ9Fw9N4"
106+ + "Bhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\ nknddadwkwewcVxHFhcZJO+XWf6ofLUXpRwiTZakGMn8EE1uVa2"
107+ + "LgczOjwWHGi99MFjxSer5m9\\ n1tCa3/KEGKiS/YL71JvjwX3mb+cewlkcmweBKZHM2JPTk0ZednFSpVZMtycjkbLa"
108+ + "\\ ndYOS8V85AgMBewECggEBAKksaldajfDZDV6nGqbFjMiizAKJolr/M3OQw16K6o3/\\ n0S31xIe3sSlgW0+UbYlF"
109+ + "4U8KifhManD1apVSC3csafaspP4RZUHFhtBywLO9pR5c\\ nr6S5aLp+gPWFyIp1pfXbWGvc5VY/v9x7ya1VEa6rXvL"
110+ + "sKupSeWAW4tMj3eo/64ge\\ nsdaceaLYw52KeBYiT6+vpsnYrEkAHO1fF/LavbLLOFJmFTMxmsNaG0tuiJHgjshB\\ "
111+ + "n82DpMCbXG9YcCgI/DbzuIjsdj2JC1cascSP//3PmefWysucBQe7Jryb6NQtASmnv\\ nCdDw/0jmZTEjpe4S1lxfHp"
112+ + "lAhHFtdgYTvyYtaLZiVVkCgYEA8eVpof2rceecw/I6\\ n5ng1q3Hl2usdWV/4mZMvR0fOemacLLfocX6IYxT1zA1FF"
113+ + "JlbXSRsJMf/Qq39mOR2\\ nSpW+hr4jCoHeRVYLgsbggtrevGmILAlNoqCMpGZ6vDmJpq6ECV9olliDvpPgWOP+\\ nm"
114+ + "YPDreFBGxWvQrADNbRt2dmGsrsCgYEAyUHqB2wvJHFqdmeBsaacewzV8x9WgmeX\\ ngUIi9REwXlGDW0Mz50dxpxcK"
115+ + "CAYn65+7TCnY5O/jmL0VRxU1J2mSWyWTo1C+17L0\\ n3fUqjxL1pkefwecxwecvC+gFFYdJ4CQ/MHHXU81Lwl1iWdF"
116+ + "Cd2UoGddYaOF+KNeM\\ nHC7cmqra+JsCgYEAlUNywzq8nUg7282E+uICfCB0LfwejuymR93CtsFgb7cRd6ak\\ nECR"
117+ + "8FGfCpH8ruWJINllbQfcHVCX47ndLZwqv3oVFKh6pAS/vVI4dpOepP8++7y1u\\ ncoOvtreXCX6XqfrWDtKIvv0vjl"
118+ + "HBhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\ nkndj5uNl5SiuVxHFhcZJO+XWf6ofLUregtevZakGMn8EE1uVa"
119+ + "2AY7eafmoU/nZPT\\ n00YB0TBATdCbn/nBSuKDESkhSg9s2GEKQZG5hBmL5uCMfo09z3SfxZIhJdlerreP\\ nJ7gSi"
120+ + "dI12N+EZxYd4xIJh/HFDgp7RRO87f+WJkofMQKBgGTnClK1VMaCRbJZPriw\\ nEfeFCoOX75MxKwXs6xgrw4W//AYG"
121+ + "GUjDt83lD6AZP6tws7gJ2IwY/qP7+lyhjEqN\\ nHtfPZRGFkGZsdaksdlaksd323423d+15/UvrlRSFPNj1tWQmNKk"
122+ + "XyRDW4IG1Oa2p\\ nrALStNBx5Y9t0/LQnFI4w3aG\\ n-----END PRIVATE KEY-----\\ n\" ,\n "
123+ + " \" project_id\" : \" someprojectid\" ,\n "
124+ + " \" client_email\" : \" someclientid@developer.gserviceaccount.com\" ,\n "
125+ + " \" client_id\" : \" someclientid.apps.googleusercontent.com\" ,\n "
126+ + " \" type\" : \" service_account\" ,\n "
127+ + " \" universe_domain\" : \" googleapis.com\" \n "
128+ + "}" ;
129+
130+ private static final String FAKE_JSON_CRED_WITH_INVALID_DOMAIN =
131+ "{\n "
132+ + " \" private_key_id\" : \" somekeyid\" ,\n "
133+ + " \" private_key\" : \" -----BEGIN PRIVATE KEY-----\\ nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS"
134+ + "kAgEAAoIBAQC+K2hSuFpAdrJI\\ nnCgcDz2M7t7bjdlsadsasad+fvRSW6TjNQZ3p5LLQY1kSZRqBqylRkzteMOyHg"
135+ + "aR\\ n0Pmxh3ILCND5men43j3h4eDbrhQBuxfEMalkG92sL+PNQSETY2tnvXryOvmBRwa/\\ nQP/9dJfIkIDJ9Fw9N4"
136+ + "Bhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\ nknddadwkwewcVxHFhcZJO+XWf6ofLUXpRwiTZakGMn8EE1uVa2"
137+ + "LgczOjwWHGi99MFjxSer5m9\\ n1tCa3/KEGKiS/YL71JvjwX3mb+cewlkcmweBKZHM2JPTk0ZednFSpVZMtycjkbLa"
138+ + "\\ ndYOS8V85AgMBewECggEBAKksaldajfDZDV6nGqbFjMiizAKJolr/M3OQw16K6o3/\\ n0S31xIe3sSlgW0+UbYlF"
139+ + "4U8KifhManD1apVSC3csafaspP4RZUHFhtBywLO9pR5c\\ nr6S5aLp+gPWFyIp1pfXbWGvc5VY/v9x7ya1VEa6rXvL"
140+ + "sKupSeWAW4tMj3eo/64ge\\ nsdaceaLYw52KeBYiT6+vpsnYrEkAHO1fF/LavbLLOFJmFTMxmsNaG0tuiJHgjshB\\ "
141+ + "n82DpMCbXG9YcCgI/DbzuIjsdj2JC1cascSP//3PmefWysucBQe7Jryb6NQtASmnv\\ nCdDw/0jmZTEjpe4S1lxfHp"
142+ + "lAhHFtdgYTvyYtaLZiVVkCgYEA8eVpof2rceecw/I6\\ n5ng1q3Hl2usdWV/4mZMvR0fOemacLLfocX6IYxT1zA1FF"
143+ + "JlbXSRsJMf/Qq39mOR2\\ nSpW+hr4jCoHeRVYLgsbggtrevGmILAlNoqCMpGZ6vDmJpq6ECV9olliDvpPgWOP+\\ nm"
144+ + "YPDreFBGxWvQrADNbRt2dmGsrsCgYEAyUHqB2wvJHFqdmeBsaacewzV8x9WgmeX\\ ngUIi9REwXlGDW0Mz50dxpxcK"
145+ + "CAYn65+7TCnY5O/jmL0VRxU1J2mSWyWTo1C+17L0\\ n3fUqjxL1pkefwecxwecvC+gFFYdJ4CQ/MHHXU81Lwl1iWdF"
146+ + "Cd2UoGddYaOF+KNeM\\ nHC7cmqra+JsCgYEAlUNywzq8nUg7282E+uICfCB0LfwejuymR93CtsFgb7cRd6ak\\ nECR"
147+ + "8FGfCpH8ruWJINllbQfcHVCX47ndLZwqv3oVFKh6pAS/vVI4dpOepP8++7y1u\\ ncoOvtreXCX6XqfrWDtKIvv0vjl"
148+ + "HBhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\ nkndj5uNl5SiuVxHFhcZJO+XWf6ofLUregtevZakGMn8EE1uVa"
149+ + "2AY7eafmoU/nZPT\\ n00YB0TBATdCbn/nBSuKDESkhSg9s2GEKQZG5hBmL5uCMfo09z3SfxZIhJdlerreP\\ nJ7gSi"
150+ + "dI12N+EZxYd4xIJh/HFDgp7RRO87f+WJkofMQKBgGTnClK1VMaCRbJZPriw\\ nEfeFCoOX75MxKwXs6xgrw4W//AYG"
151+ + "GUjDt83lD6AZP6tws7gJ2IwY/qP7+lyhjEqN\\ nHtfPZRGFkGZsdaksdlaksd323423d+15/UvrlRSFPNj1tWQmNKk"
152+ + "XyRDW4IG1Oa2p\\ nrALStNBx5Y9t0/LQnFI4w3aG\\ n-----END PRIVATE KEY-----\\ n\" ,\n "
153+ + " \" project_id\" : \" someprojectid\" ,\n "
154+ + " \" client_email\" : \" someclientid@developer.gserviceaccount.com\" ,\n "
155+ + " \" client_id\" : \" someclientid.apps.googleusercontent.com\" ,\n "
156+ + " \" type\" : \" service_account\" ,\n "
157+ + " \" universe_domain\" : \" fake.domain\" \n "
158+ + "}" ;
159+
94160 @ BeforeClass
95161 public static void beforeClass () throws IOException {
96162 client = BigQueryReadClient .create ();
@@ -859,6 +925,147 @@ public void testSimpleReadWithBackgroundExecutorProvider() throws IOException {
859925 assertEquals (164_656 , rowCount );
860926 }
861927
928+ @ Test
929+ public void testUniverseDomainWithInvalidUniverseDomain () throws IOException {
930+ BigQueryReadSettings bigQueryReadSettings =
931+ BigQueryReadSettings .newBuilder ()
932+ .setCredentialsProvider (
933+ FixedCredentialsProvider .create (loadCredentials (FAKE_JSON_CRED_WITH_GOOGLE_DOMAIN )))
934+ .setUniverseDomain ("invalid.domain" )
935+ .build ();
936+ BigQueryReadClient localClient = BigQueryReadClient .create (bigQueryReadSettings );
937+
938+ String table =
939+ BigQueryResource .FormatTableResource (
940+ /* projectId = */ "bigquery-public-data" ,
941+ /* datasetId = */ "samples" ,
942+ /* tableId = */ "shakespeare" );
943+
944+ try {
945+ localClient .createReadSession (
946+ /* parent = */ parentProjectId ,
947+ /* readSession = */ ReadSession .newBuilder ()
948+ .setTable (table )
949+ .setDataFormat (DataFormat .AVRO )
950+ .build (),
951+ /* maxStreamCount = */ 1 );
952+ fail ("RPCs to invalid universe domain should fail" );
953+ } catch (UnauthenticatedException e ) {
954+ assertThat (
955+ (e .getMessage ()
956+ .contains ("does not match the universe domain found in the credentials" )))
957+ .isTrue ();
958+ }
959+ localClient .close ();
960+ }
961+
962+ @ Test
963+ public void testInvalidUniverseDomainWithMismatchCredentials () throws IOException {
964+ BigQueryReadSettings bigQueryReadSettings =
965+ BigQueryReadSettings .newBuilder ()
966+ .setCredentialsProvider (
967+ FixedCredentialsProvider .create (
968+ loadCredentials (FAKE_JSON_CRED_WITH_INVALID_DOMAIN )))
969+ .setUniverseDomain ("invalid.domain" )
970+ .build ();
971+ BigQueryReadClient localClient = BigQueryReadClient .create (bigQueryReadSettings );
972+
973+ String table =
974+ BigQueryResource .FormatTableResource (
975+ /* projectId = */ "bigquery-public-data" ,
976+ /* datasetId = */ "samples" ,
977+ /* tableId = */ "shakespeare" );
978+
979+ try {
980+ ReadSession session =
981+ localClient .createReadSession (
982+ /* parent = */ parentProjectId ,
983+ /* readSession = */ ReadSession .newBuilder ()
984+ .setTable (table )
985+ .setDataFormat (DataFormat .AVRO )
986+ .build (),
987+ /* maxStreamCount = */ 1 );
988+ fail ("RPCs to invalid universe domain should fail" );
989+ } catch (UnauthenticatedException e ) {
990+ assertThat (
991+ (e .getMessage ()
992+ .contains ("does not match the universe domain found in the credentials" )))
993+ .isTrue ();
994+ }
995+ localClient .close ();
996+ }
997+
998+ @ Test
999+ public void testUniverseDomainWithMatchingDomain () throws IOException {
1000+ // Test a valid domain using the default credentials and Google default universe domain.
1001+ BigQueryReadSettings bigQueryReadSettings =
1002+ BigQueryReadSettings .newBuilder ().setUniverseDomain ("googleapis.com" ).build ();
1003+ BigQueryReadClient localClient = BigQueryReadClient .create (bigQueryReadSettings );
1004+
1005+ String table =
1006+ BigQueryResource .FormatTableResource (
1007+ /* projectId = */ "bigquery-public-data" ,
1008+ /* datasetId = */ "samples" ,
1009+ /* tableId = */ "shakespeare" );
1010+
1011+ ReadSession session =
1012+ localClient .createReadSession (
1013+ /* parent = */ parentProjectId ,
1014+ /* readSession = */ ReadSession .newBuilder ()
1015+ .setTable (table )
1016+ .setDataFormat (DataFormat .AVRO )
1017+ .build (),
1018+ /* maxStreamCount = */ 1 );
1019+
1020+ ReadRowsRequest readRowsRequest =
1021+ ReadRowsRequest .newBuilder ().setReadStream (session .getStreams (0 ).getName ()).build ();
1022+
1023+ long rowCount = 0 ;
1024+ ServerStream <ReadRowsResponse > stream = client .readRowsCallable ().call (readRowsRequest );
1025+ for (ReadRowsResponse response : stream ) {
1026+ rowCount += response .getRowCount ();
1027+ }
1028+
1029+ assertEquals (164_656 , rowCount );
1030+ localClient .close ();
1031+ }
1032+
1033+ public void testUniverseDomain () throws IOException {
1034+ // This test is not yet part presubmit integration test as it requires the apis-tpclp.goog
1035+ // universe domain credentials.
1036+ // Test a valid read session in the universe domain gdutst.
1037+ BigQueryReadSettings bigQueryReadSettings =
1038+ BigQueryReadSettings .newBuilder ().setUniverseDomain ("apis-tpclp.goog" ).build ();
1039+ BigQueryReadClient localClient = BigQueryReadClient .create (bigQueryReadSettings );
1040+
1041+ String table =
1042+ BigQueryResource .FormatTableResource (
1043+ /* projectId = */ "google-tpc-testing-environment:cloudsdk-test-project" ,
1044+ /* datasetId = */ "tpc_demo_dataset" ,
1045+ /* tableId = */ "new_table" );
1046+
1047+ ReadSession session =
1048+ localClient .createReadSession (
1049+ /* parent = */ parentProjectId ,
1050+ /* readSession = */ ReadSession .newBuilder ()
1051+ .setTable (table )
1052+ .setDataFormat (DataFormat .AVRO )
1053+ .build (),
1054+ /* maxStreamCount = */ 1 );
1055+
1056+ ReadRowsRequest readRowsRequest =
1057+ ReadRowsRequest .newBuilder ().setReadStream (session .getStreams (0 ).getName ()).build ();
1058+
1059+ long rowCount = 0 ;
1060+ ServerStream <ReadRowsResponse > stream = localClient .readRowsCallable ().call (readRowsRequest );
1061+ for (ReadRowsResponse response : stream ) {
1062+ rowCount += response .getRowCount ();
1063+ }
1064+
1065+ assertEquals (1 , rowCount );
1066+ localClient .close ();
1067+ }
1068+
8621069 /**
8631070 * Reads to the specified row offset within the stream. If the stream does not have the desired
8641071 * rows to read, it will read all of them.
@@ -1015,4 +1222,14 @@ private Job RunQueryJobAndExpectSuccess(QueryJobConfiguration configuration)
10151222
10161223 return completedJob ;
10171224 }
1225+
1226+ static GoogleCredentials loadCredentials (String credentialFile ) {
1227+ try {
1228+ InputStream keyStream = new ByteArrayInputStream (credentialFile .getBytes ());
1229+ return GoogleCredentials .fromStream (keyStream );
1230+ } catch (IOException e ) {
1231+ fail ("Couldn't create fake JSON credentials." );
1232+ }
1233+ return null ;
1234+ }
10181235}
0 commit comments