diff --git a/.kokoro/build.sh b/.kokoro/build.sh
index 6ede96a21..0c26eec01 100755
--- a/.kokoro/build.sh
+++ b/.kokoro/build.sh
@@ -61,7 +61,7 @@ javadoc)
integration)
mvn -B ${INTEGRATION_TEST_ARGS} \
-ntp \
- -Dtest=ITBigQueryTest \
+ -Dtest=ITBigQueryTest,ITRemoteUDFTest \
-DtrimStackTrace=false \
-Dclirr.skip=true \
-Denforcer.skip=true \
@@ -72,7 +72,7 @@ integration)
nightly-it)
mvn -B ${INTEGRATION_TEST_ARGS} \
-ntp \
- -Dtest=ITNightlyBigQueryTest \
+ -Dtest=ITNightlyBigQueryTest,ITRemoteUDFTest \
-DtrimStackTrace=false \
-Dclirr.skip=true \
-Denforcer.skip=true \
@@ -82,20 +82,20 @@ nightly-it)
;;
graalvm)
# Run Integration Tests with Native Image. Skip running nightly tests in presubmits.
- mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Dtest=ITBigQueryTest -Pnative -Penable-integration-tests test
+ mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Dtest=ITBigQueryTest,ITRemoteUDFTest -Pnative -Penable-integration-tests test
RETURN_CODE=$?
;;
graalvm17)
# Run Integration Tests with Native Image. Skip running nightly tests in presubmits.
- mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Dtest=ITBigQueryTest -Pnative -Penable-integration-tests test
+ mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Dtest=ITBigQueryTest,ITRemoteUDFTest -Pnative -Penable-integration-tests test
RETURN_CODE=$?
;;
nightly-graalvm)
- mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Dtest=ITNightlyBigQueryTest -Pnative -Penable-integration-tests test
+ mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Dtest=ITNightlyBigQueryTest,ITRemoteUDFTest -Pnative -Penable-integration-tests test
RETURN_CODE=$?
;;
nightly-graalvm17)
- mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Dtest=ITNightlyBigQueryTest -Pnative -Penable-integration-tests test
+ mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Dtest=ITNightlyBigQueryTest,ITRemoteUDFTest -Pnative -Penable-integration-tests test
RETURN_CODE=$?
;;
samples)
diff --git a/google-cloud-bigquery/clirr-ignored-differences.xml b/google-cloud-bigquery/clirr-ignored-differences.xml
index 7a882777a..6b76f78eb 100644
--- a/google-cloud-bigquery/clirr-ignored-differences.xml
+++ b/google-cloud-bigquery/clirr-ignored-differences.xml
@@ -19,4 +19,9 @@
com/google/cloud/bigquery/ExternalTableDefinition*
*ReferenceFileSchemaUri(*)
+
+ 7013
+ com/google/cloud/bigquery/RoutineInfo*
+ *RemoteFunctionOptions(*)
+
\ No newline at end of file
diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml
index 8c1c8fa42..b3301e0df 100644
--- a/google-cloud-bigquery/pom.xml
+++ b/google-cloud-bigquery/pom.xml
@@ -131,9 +131,14 @@
google-cloud-datacatalog
test
+
+ com.google.cloud
+ google-cloud-bigqueryconnection
+ test
+
com.google.api.grpc
- proto-google-cloud-datacatalog-v1
+ proto-google-cloud-bigqueryconnection-v1
test
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RemoteFunctionOptions.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RemoteFunctionOptions.java
new file mode 100644
index 000000000..88496dcb4
--- /dev/null
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RemoteFunctionOptions.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.cloud.bigquery;
+
+import com.google.auto.value.AutoValue;
+import java.io.Serializable;
+import java.util.Map;
+import javax.annotation.Nullable;
+
+/** Represents Remote Function Options. Options for a remote user-defined function. */
+@AutoValue
+public abstract class RemoteFunctionOptions implements Serializable {
+
+ private static final long serialVersionUID = -7334249450657429792L;
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+
+ /**
+ * Sets Endpoint argument Endpoint of the user-provided remote service, e.g.
+ * ```https://us-east1-my_gcf_project.cloudfunctions.net/remote_add```
+ */
+ public abstract Builder setEndpoint(String endpoint);
+
+ /**
+ * Fully qualified name of the user-provided connection object which holds the authentication
+ * information to send requests to the remote service. Format:
+ * ```\"projects/{projectId}/locations/{locationId}/connections/{connectionId}\"```
+ */
+ public abstract Builder setConnection(String connection);
+
+ /**
+ * User-defined context as a set of key/value pairs, which will be sent as function invocation
+ * context together with batched arguments in the requests to the remote service. The total
+ * number of bytes of keys and values must be less than 8KB.
+ */
+ public abstract Builder setUserDefinedContext(Map userDefinedContext);
+
+ /**
+ * Max number of rows in each batch sent to the remote service. If absent or if 0, BigQuery
+ * dynamically decides the number of rows in a batch.
+ */
+ public abstract Builder setMaxBatchingRows(Long maxBatchingRows);
+
+ /** Creates a {@code RemoteFunctionOptions} object. */
+ public abstract RemoteFunctionOptions build();
+ }
+
+ /**
+ * Returns the endpoint of the user-provided service.
+ *
+ * @return String
+ */
+ @Nullable
+ public abstract String getEndpoint();
+
+ /**
+ * Returns the fully qualified name of the user-provided connection object.
+ *
+ * @return String
+ */
+ @Nullable
+ public abstract String getConnection();
+
+ /**
+ * Returns the user-defined context as a set of key/value pairs.
+ *
+ * @return Map
+ */
+ @Nullable
+ public abstract Map getUserDefinedContext();
+
+ /**
+ * Returns max number of rows in each batch sent to the remote service.
+ *
+ * @return Long
+ */
+ @Nullable
+ public abstract Long getMaxBatchingRows();
+
+ /**
+ * Returns a builder pre-populated using the current values of this {@code RemoteFunctionOptions}.
+ */
+ public abstract RemoteFunctionOptions.Builder toBuilder();
+
+ /** Returns a builder for a {@Code RemoteFunctionOptions} object. */
+ public static RemoteFunctionOptions.Builder newBuilder() {
+ return new AutoValue_RemoteFunctionOptions.Builder();
+ }
+
+ public com.google.api.services.bigquery.model.RemoteFunctionOptions toPb() {
+ com.google.api.services.bigquery.model.RemoteFunctionOptions remoteFunctionOptions =
+ new com.google.api.services.bigquery.model.RemoteFunctionOptions();
+ if (getEndpoint() != null) {
+ remoteFunctionOptions.setEndpoint(getEndpoint());
+ }
+ if (getConnection() != null) {
+ remoteFunctionOptions.setConnection(getConnection());
+ }
+ if (getUserDefinedContext() != null) {
+ remoteFunctionOptions.setUserDefinedContext(getUserDefinedContext());
+ }
+ if (getMaxBatchingRows() != null) {
+ remoteFunctionOptions.setMaxBatchingRows(getMaxBatchingRows());
+ }
+ return remoteFunctionOptions;
+ }
+
+ static RemoteFunctionOptions fromPb(
+ com.google.api.services.bigquery.model.RemoteFunctionOptions remoteFunctionOptionsPb) {
+ RemoteFunctionOptions.Builder builder = newBuilder();
+ if (remoteFunctionOptionsPb.getEndpoint() != null) {
+ builder.setEndpoint(remoteFunctionOptionsPb.getEndpoint());
+ }
+ if (remoteFunctionOptionsPb.getConnection() != null) {
+ builder.setConnection(remoteFunctionOptionsPb.getConnection());
+ }
+ if (remoteFunctionOptionsPb.getUserDefinedContext() != null) {
+ builder.setUserDefinedContext(remoteFunctionOptionsPb.getUserDefinedContext());
+ }
+ if (remoteFunctionOptionsPb.getMaxBatchingRows() != null) {
+ builder.setMaxBatchingRows(remoteFunctionOptionsPb.getMaxBatchingRows());
+ }
+ return builder.build();
+ }
+}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Routine.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Routine.java
index a5232c3f9..d2d6ec683 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Routine.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Routine.java
@@ -129,6 +129,12 @@ public Builder setBody(String body) {
return this;
}
+ @Override
+ public Builder setRemoteFunctionOptions(RemoteFunctionOptions remoteFunctionOptions) {
+ infoBuilder.setRemoteFunctionOptions(remoteFunctionOptions);
+ return this;
+ }
+
@Override
public Routine build() {
return new Routine(bigquery, infoBuilder);
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
index daa745577..3001d2fb9 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
@@ -70,6 +70,7 @@ public Routine apply(RoutineInfo routineInfo) {
private final StandardSQLTableType returnTableType;
private final List importedLibrariesList;
private final String body;
+ private final RemoteFunctionOptions remoteFunctionOptions;
public abstract static class Builder {
@@ -148,6 +149,14 @@ public abstract static class Builder {
*/
public abstract Builder setBody(String body);
+ /**
+ * Optional. Remote function specific options.
+ *
+ * @param remoteFunctionOptions
+ * @return
+ */
+ public abstract Builder setRemoteFunctionOptions(RemoteFunctionOptions remoteFunctionOptions);
+
/** Creates a {@code RoutineInfo} object. */
public abstract RoutineInfo build();
}
@@ -166,6 +175,7 @@ static class BuilderImpl extends Builder {
private StandardSQLTableType returnTableType;
private List importedLibrariesList;
private String body;
+ private RemoteFunctionOptions remoteFunctionOptions;
BuilderImpl() {}
@@ -183,6 +193,7 @@ static class BuilderImpl extends Builder {
this.returnTableType = routineInfo.returnTableType;
this.importedLibrariesList = routineInfo.importedLibrariesList;
this.body = routineInfo.body;
+ this.remoteFunctionOptions = routineInfo.remoteFunctionOptions;
}
BuilderImpl(Routine routinePb) {
@@ -210,6 +221,10 @@ static class BuilderImpl extends Builder {
this.importedLibrariesList = routinePb.getImportedLibraries();
}
this.body = routinePb.getDefinitionBody();
+ if (routinePb.getRemoteFunctionOptions() != null) {
+ this.remoteFunctionOptions =
+ RemoteFunctionOptions.fromPb(routinePb.getRemoteFunctionOptions());
+ }
}
@Override
@@ -290,6 +305,12 @@ public Builder setBody(String body) {
return this;
}
+ @Override
+ public Builder setRemoteFunctionOptions(RemoteFunctionOptions remoteFunctionOptions) {
+ this.remoteFunctionOptions = remoteFunctionOptions;
+ return this;
+ }
+
@Override
public RoutineInfo build() {
return new RoutineInfo(this);
@@ -310,6 +331,7 @@ public RoutineInfo build() {
this.returnTableType = builder.returnTableType;
this.importedLibrariesList = builder.importedLibrariesList;
this.body = builder.body;
+ this.remoteFunctionOptions = builder.remoteFunctionOptions;
}
/** Returns the RoutineId identified for the routine resource. * */
@@ -384,6 +406,11 @@ public String getBody() {
return body;
}
+ /** Returns the Remote function specific options. */
+ public RemoteFunctionOptions getRemoteFunctionOptions() {
+ return remoteFunctionOptions;
+ };
+
/** Returns a builder pre-populated using the current values of this routine. */
public Builder toBuilder() {
return new BuilderImpl(this);
@@ -405,6 +432,7 @@ public String toString() {
.add("returnTableType", returnTableType)
.add("importedLibrariesList", importedLibrariesList)
.add("body", body)
+ .add("remoteFunctionOptions", remoteFunctionOptions)
.toString();
}
@@ -423,7 +451,8 @@ public int hashCode() {
returnType,
returnTableType,
importedLibrariesList,
- body);
+ body,
+ remoteFunctionOptions);
}
@Override
@@ -474,6 +503,9 @@ Routine toPb() {
if (getReturnTableType() != null) {
routinePb.setReturnTableType(getReturnTableType().toPb());
}
+ if (getRemoteFunctionOptions() != null) {
+ routinePb.setRemoteFunctionOptions(getRemoteFunctionOptions().toPb());
+ }
return routinePb;
}
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RemoteFunctionOptionsTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RemoteFunctionOptionsTest.java
new file mode 100644
index 000000000..8ee0e4564
--- /dev/null
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RemoteFunctionOptionsTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.cloud.bigquery;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+
+public class RemoteFunctionOptionsTest {
+ private static final String endpoint = "https://aaabbbccc-uc.a.run.app";
+ private static final String connection =
+ "projects/{projectId}/locations/{locationId}/connections/{connectionId}";
+ private static final Map userDefinedContext =
+ new HashMap() {
+ {
+ put("key1", "value1");
+ put("key2", "value2");
+ }
+ };
+ private static final Long maxBatchingRows = 20L;
+
+ private static final RemoteFunctionOptions REMOTE_FUNCTION_OPTIONS =
+ RemoteFunctionOptions.newBuilder()
+ .setEndpoint(endpoint)
+ .setConnection(connection)
+ .setUserDefinedContext(userDefinedContext)
+ .setMaxBatchingRows(maxBatchingRows)
+ .build();
+
+ @Test
+ public void testToBuilder() {
+ compareRemoteFunctionOptions(
+ REMOTE_FUNCTION_OPTIONS, REMOTE_FUNCTION_OPTIONS.toBuilder().build());
+ }
+
+ @Test
+ public void testBuilder() {
+ assertEquals(endpoint, REMOTE_FUNCTION_OPTIONS.getEndpoint());
+ assertEquals(connection, REMOTE_FUNCTION_OPTIONS.getConnection());
+ assertEquals(userDefinedContext, REMOTE_FUNCTION_OPTIONS.getUserDefinedContext());
+ assertEquals(maxBatchingRows, REMOTE_FUNCTION_OPTIONS.getMaxBatchingRows());
+ }
+
+ @Test
+ public void testToAndFromPb() {
+ compareRemoteFunctionOptions(
+ REMOTE_FUNCTION_OPTIONS, RemoteFunctionOptions.fromPb(REMOTE_FUNCTION_OPTIONS.toPb()));
+ }
+
+ public void compareRemoteFunctionOptions(
+ RemoteFunctionOptions expected, RemoteFunctionOptions actual) {
+ assertEquals(expected, actual);
+ assertEquals(expected.getEndpoint(), actual.getEndpoint());
+ assertEquals(expected.getConnection(), actual.getConnection());
+ assertEquals(expected.getMaxBatchingRows(), actual.getMaxBatchingRows());
+ assertEquals(expected.getUserDefinedContext(), actual.getUserDefinedContext());
+ }
+}
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineTest.java
index 89bed602e..c9080e851 100644
--- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineTest.java
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineTest.java
@@ -26,7 +26,9 @@
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -74,6 +76,20 @@ public class RoutineTest {
ImmutableList.of("gs://foo", "gs://bar", "gs://baz");
private static final String BODY = "body";
+ private static final Map userDefinedContext =
+ new HashMap() {
+ {
+ put("key1", "value1");
+ put("key2", "value2");
+ }
+ };
+ private static final RemoteFunctionOptions REMOTE_FUNCTION_OPTIONS =
+ RemoteFunctionOptions.newBuilder()
+ .setEndpoint("endpoint")
+ .setConnection("connection")
+ .setUserDefinedContext(userDefinedContext)
+ .setMaxBatchingRows(10L)
+ .build();
private static final RoutineInfo ROUTINE_INFO =
RoutineInfo.newBuilder(ROUTINE_ID)
@@ -87,6 +103,7 @@ public class RoutineTest {
.setReturnType(RETURN_TYPE)
.setImportedLibraries(IMPORTED_LIBRARIES)
.setBody(BODY)
+ .setRemoteFunctionOptions(REMOTE_FUNCTION_OPTIONS)
.build();
private static final RoutineInfo ROUTINE_INFO_TVF =
@@ -128,6 +145,7 @@ public void testBuilder() {
.setReturnType(RETURN_TYPE)
.setImportedLibraries(IMPORTED_LIBRARIES)
.setBody(BODY)
+ .setRemoteFunctionOptions(REMOTE_FUNCTION_OPTIONS)
.build();
assertEquals(ETAG, builtRoutine.getEtag());
assertEquals(DETERMINISM_LEVEL, builtRoutine.getDeterminismLevel());
@@ -228,5 +246,6 @@ public void compareRoutineInfo(RoutineInfo expected, RoutineInfo value) {
assertEquals(expected.getImportedLibraries(), value.getImportedLibraries());
assertEquals(expected.getBody(), value.getBody());
assertEquals(expected.hashCode(), value.hashCode());
+ assertEquals(expected.getRemoteFunctionOptions(), value.getRemoteFunctionOptions());
}
}
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITRemoteUDFTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITRemoteUDFTest.java
new file mode 100644
index 000000000..7e74a8f4c
--- /dev/null
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITRemoteUDFTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.cloud.bigquery.it;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import com.google.cloud.ServiceOptions;
+import com.google.cloud.bigquery.BigQuery;
+import com.google.cloud.bigquery.DatasetInfo;
+import com.google.cloud.bigquery.RemoteFunctionOptions;
+import com.google.cloud.bigquery.Routine;
+import com.google.cloud.bigquery.RoutineArgument;
+import com.google.cloud.bigquery.RoutineId;
+import com.google.cloud.bigquery.RoutineInfo;
+import com.google.cloud.bigquery.StandardSQLDataType;
+import com.google.cloud.bigquery.connection.v1.CloudResourceProperties;
+import com.google.cloud.bigquery.connection.v1.Connection;
+import com.google.cloud.bigquery.connection.v1.CreateConnectionRequest;
+import com.google.cloud.bigquery.connection.v1.DeleteConnectionRequest;
+import com.google.cloud.bigquery.connection.v1.LocationName;
+import com.google.cloud.bigquery.testing.RemoteBigQueryHelper;
+import com.google.cloud.bigqueryconnection.v1.ConnectionServiceClient;
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ITRemoteUDFTest {
+
+ private static final String ID = UUID.randomUUID().toString().substring(0, 8);
+ private static final String PROJECT_ID = ServiceOptions.getDefaultProjectId();
+ private static final String CONNECTION_ID = "test-connectin-id-" + ID;
+ private static final String LOCATION = "US";
+ private static final String PARENT = LocationName.of(PROJECT_ID, LOCATION).toString();
+ private static final String REMOTE_ENDPOINT = "https://aaabbbccc-uc.a.run.app";
+ private static final String ROUTINE_DATASET = RemoteBigQueryHelper.generateDatasetName();
+ private static ConnectionServiceClient client;
+ private static Connection connection;
+ private static BigQuery bigquery;
+
+ @Before
+ public void setUp() throws IOException {
+ RemoteBigQueryHelper bigqueryHelper = RemoteBigQueryHelper.create();
+ bigquery = bigqueryHelper.getOptions().getService();
+ client = ConnectionServiceClient.create();
+
+ DatasetInfo info =
+ DatasetInfo.newBuilder(ROUTINE_DATASET).setDescription("java routine lifecycle").build();
+ bigquery.create(info);
+ CloudResourceProperties cloudResourceProperties = CloudResourceProperties.newBuilder().build();
+ CreateConnectionRequest request =
+ CreateConnectionRequest.newBuilder()
+ .setParent(PARENT)
+ .setConnection(
+ Connection.newBuilder().setCloudResource(cloudResourceProperties).build())
+ .setConnectionId(CONNECTION_ID)
+ .build();
+ connection = client.createConnection(request);
+ }
+
+ @AfterClass
+ public static void afterClass() {
+ if (bigquery != null) {
+ RemoteBigQueryHelper.forceDelete(bigquery, ROUTINE_DATASET);
+ }
+ // delete a connection
+ DeleteConnectionRequest request =
+ DeleteConnectionRequest.newBuilder().setName(connection.getName()).build();
+ client.deleteConnection(request);
+ client.close();
+ }
+
+ @Test
+ public void testRoutineRemoteUDF() {
+ String routineName = RemoteBigQueryHelper.generateRoutineName();
+ RoutineId routineId = RoutineId.of(ROUTINE_DATASET, routineName);
+ Map userDefinedContext =
+ new HashMap() {
+ {
+ put("key1", "value1");
+ put("key2", "value2");
+ }
+ };
+
+ RemoteFunctionOptions remoteFunctionOptions =
+ RemoteFunctionOptions.newBuilder()
+ .setEndpoint(REMOTE_ENDPOINT)
+ .setConnection(connection.getName())
+ .setMaxBatchingRows(Long.valueOf(30))
+ .setUserDefinedContext(userDefinedContext)
+ .build();
+ RoutineInfo routineInfo =
+ RoutineInfo.newBuilder(routineId)
+ .setRoutineType("SCALAR_FUNCTION")
+ .setArguments(
+ ImmutableList.of(
+ RoutineArgument.newBuilder()
+ .setName("x")
+ .setDataType(StandardSQLDataType.newBuilder("INT64").build())
+ .build()))
+ .setRemoteFunctionOptions(remoteFunctionOptions)
+ .setReturnType(StandardSQLDataType.newBuilder("INT64").build())
+ .build();
+
+ Routine routine = bigquery.create(routineInfo);
+ assertNotNull(routine);
+ assertEquals(routine.getRoutineType(), "SCALAR_FUNCTION");
+ assertEquals(REMOTE_ENDPOINT, routine.getRemoteFunctionOptions().getEndpoint());
+ assertEquals(connection.getName(), routine.getRemoteFunctionOptions().getConnection());
+ }
+}
diff --git a/pom.xml b/pom.xml
index 87fa2e627..572a9faaa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -179,6 +179,18 @@
2.12.0
test
+
+ com.google.cloud
+ google-cloud-bigqueryconnection
+ 2.4.0
+ test
+
+
+ com.google.api.grpc
+ proto-google-cloud-bigqueryconnection-v1
+ 2.4.0
+ test
+