16
16
17
17
package com .google .cloud .bigquery .storage .v1 .it ;
18
18
19
+ import static com .google .common .truth .Truth .assertThat ;
19
20
import static com .google .common .truth .Truth .assertWithMessage ;
20
21
import static org .junit .Assert .assertArrayEquals ;
21
22
import static org .junit .Assert .assertEquals ;
22
23
import static org .junit .Assert .assertNotNull ;
23
24
import static org .junit .Assert .assertNull ;
24
25
import static org .junit .Assert .assertTrue ;
26
+ import static org .junit .Assert .fail ;
25
27
28
+ import com .google .api .gax .core .FixedCredentialsProvider ;
26
29
import com .google .api .gax .core .InstantiatingExecutorProvider ;
27
30
import com .google .api .gax .rpc .ServerStream ;
31
+ import com .google .api .gax .rpc .UnauthenticatedException ;
32
+ import com .google .auth .oauth2 .GoogleCredentials ;
28
33
import com .google .cloud .RetryOption ;
29
34
import com .google .cloud .ServiceOptions ;
30
35
import com .google .cloud .bigquery .BigQuery ;
54
59
import com .google .cloud .bigquery .testing .RemoteBigQueryHelper ;
55
60
import com .google .common .base .Preconditions ;
56
61
import com .google .protobuf .Timestamp ;
62
+ import java .io .ByteArrayInputStream ;
57
63
import java .io .IOException ;
64
+ import java .io .InputStream ;
58
65
import java .math .BigDecimal ;
59
66
import java .nio .ByteBuffer ;
60
67
import java .util .ArrayList ;
82
89
83
90
/** Integration tests for BigQuery Storage API. */
84
91
public class ITBigQueryStorageTest {
85
-
86
92
private static final Logger LOG = Logger .getLogger (ITBigQueryStorageTest .class .getName ());
87
93
private static final String DATASET = RemoteBigQueryHelper .generateDatasetName ();
88
94
private static final String DESCRIPTION = "BigQuery Storage Java client test dataset" ;
@@ -91,6 +97,66 @@ public class ITBigQueryStorageTest {
91
97
private static String parentProjectId ;
92
98
private static BigQuery bigquery ;
93
99
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\" : \" [email protected] \" ,\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\" : \" [email protected] \" ,\n "
155
+ + " \" client_id\" : \" someclientid.apps.googleusercontent.com\" ,\n "
156
+ + " \" type\" : \" service_account\" ,\n "
157
+ + " \" universe_domain\" : \" fake.domain\" \n "
158
+ + "}" ;
159
+
94
160
@ BeforeClass
95
161
public static void beforeClass () throws IOException {
96
162
client = BigQueryReadClient .create ();
@@ -859,6 +925,147 @@ public void testSimpleReadWithBackgroundExecutorProvider() throws IOException {
859
925
assertEquals (164_656 , rowCount );
860
926
}
861
927
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
+
862
1069
/**
863
1070
* Reads to the specified row offset within the stream. If the stream does not have the desired
864
1071
* rows to read, it will read all of them.
@@ -1015,4 +1222,14 @@ private Job RunQueryJobAndExpectSuccess(QueryJobConfiguration configuration)
1015
1222
1016
1223
return completedJob ;
1017
1224
}
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
+ }
1018
1235
}
0 commit comments