Skip to content
This repository was archived by the owner on Feb 24, 2026. It is now read-only.

Commit c6efa77

Browse files
chore: add sample demonstrating sending a nested proto
1 parent e17ada2 commit c6efa77

4 files changed

Lines changed: 245 additions & 0 deletions

File tree

samples/snippets/pom.xml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
</parent>
1919

2020
<properties>
21+
<project.protobuf-java.version>3.25.4</project.protobuf-java.version>
2122
<maven.compiler.target>1.8</maven.compiler.target>
2223
<maven.compiler.source>1.8</maven.compiler.source>
2324
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -96,5 +97,37 @@
9697
<version>1.4.4</version>
9798
<scope>test</scope>
9899
</dependency>
100+
<dependency>
101+
<groupId>com.google.protobuf</groupId>
102+
<artifactId>protobuf-java-util</artifactId>
103+
<version>${project.protobuf-java.version}</version>
104+
</dependency>
99105
</dependencies>
106+
107+
<build>
108+
<extensions>
109+
<extension>
110+
<groupId>kr.motd.maven</groupId>
111+
<artifactId>os-maven-plugin</artifactId>
112+
<version>1.7.1</version>
113+
</extension>
114+
</extensions>
115+
<plugins>
116+
<plugin>
117+
<groupId>org.xolstice.maven.plugins</groupId>
118+
<artifactId>protobuf-maven-plugin</artifactId>
119+
<version>0.6.1</version>
120+
<configuration>
121+
<protocArtifact>com.google.protobuf:protoc:${project.protobuf-java.version}:exe:${os.detected.classifier}</protocArtifact>
122+
</configuration>
123+
<executions>
124+
<execution>
125+
<goals>
126+
<goal>compile</goal>
127+
</goals>
128+
</execution>
129+
</executions>
130+
</plugin>
131+
</plugins>
132+
</build>
100133
</project>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.bigquerystorage;
18+
19+
// [START bigquerystorage_writenestedproto]
20+
import com.google.api.core.ApiFuture;
21+
import com.google.cloud.bigquery.storage.v1.AppendRowsResponse;
22+
import com.google.cloud.bigquery.storage.v1.ProtoRows;
23+
import com.google.cloud.bigquery.storage.v1.ProtoSchemaConverter;
24+
import com.google.cloud.bigquery.storage.v1.StreamWriter;
25+
import com.google.protobuf.Descriptors.DescriptorValidationException;
26+
import java.io.IOException;
27+
import java.util.concurrent.ExecutionException;
28+
29+
public class WriteNestedProto {
30+
31+
public static void runWriteNestedProto(String projectId, String datasetName, String tableName)
32+
throws DescriptorValidationException, InterruptedException, IOException {
33+
StreamWriter streamWriter =
34+
StreamWriter.newBuilder(
35+
"projects/"
36+
+ projectId
37+
+ "/datasets/"
38+
+ datasetName
39+
+ "/tables/"
40+
+ tableName
41+
+ "/_default")
42+
.setWriterSchema(ProtoSchemaConverter.convert(HasNestedMessage.getDescriptor()))
43+
.build();
44+
ProtoRows protoRows =
45+
ProtoRows.newBuilder()
46+
.addSerializedRows(
47+
HasNestedMessage.newBuilder()
48+
.setFoo("foo")
49+
.setBar(
50+
HasNestedMessage.InnerMessage.newBuilder()
51+
.setMyInt(12345)
52+
.setMyString("bar")
53+
.build())
54+
.build()
55+
.toByteString())
56+
.build();
57+
ApiFuture<AppendRowsResponse> future = streamWriter.append(protoRows);
58+
try {
59+
AppendRowsResponse response = future.get();
60+
System.out.println("Appended records successfully.");
61+
} catch (ExecutionException e) {
62+
System.out.println(e);
63+
}
64+
}
65+
}
66+
// [END bigquerystorage_writenestedproto]
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
// [START declaration]
18+
syntax = "proto3";
19+
package nestedprotos;
20+
// [END declaration]
21+
22+
// [START java_declaration]
23+
option java_multiple_files = true;
24+
option java_package = "com.example.bigquerystorage";
25+
option java_outer_classname = "NestedProtos";
26+
// [END java_declaration]
27+
28+
message HasNestedMessage {
29+
optional string foo = 1;
30+
31+
message InnerMessage {
32+
optional int64 my_int = 1;
33+
optional string my_string = 2;
34+
}
35+
36+
optional InnerMessage bar = 2;
37+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.bigquerystorage;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
import static junit.framework.TestCase.assertNotNull;
21+
22+
import com.google.cloud.bigquery.BigQuery;
23+
import com.google.cloud.bigquery.BigQuery.DatasetDeleteOption;
24+
import com.google.cloud.bigquery.BigQueryOptions;
25+
import com.google.cloud.bigquery.DatasetId;
26+
import com.google.cloud.bigquery.DatasetInfo;
27+
import com.google.cloud.bigquery.FieldList;
28+
import com.google.cloud.bigquery.Schema;
29+
import com.google.cloud.bigquery.StandardSQLTypeName;
30+
import com.google.cloud.bigquery.StandardTableDefinition;
31+
import com.google.cloud.bigquery.TableId;
32+
import com.google.cloud.bigquery.TableInfo;
33+
import java.io.ByteArrayOutputStream;
34+
import java.io.PrintStream;
35+
import java.util.UUID;
36+
import org.junit.After;
37+
import org.junit.Before;
38+
import org.junit.BeforeClass;
39+
import org.junit.Test;
40+
import org.junit.runner.RunWith;
41+
import org.junit.runners.JUnit4;
42+
43+
@RunWith(JUnit4.class)
44+
public class WriteNestedProtoIT {
45+
46+
private static final String GOOGLE_CLOUD_PROJECT = System.getenv("GOOGLE_CLOUD_PROJECT");
47+
48+
private ByteArrayOutputStream bout;
49+
private PrintStream out;
50+
private BigQuery bigquery;
51+
private String datasetName;
52+
private String tableName;
53+
54+
private static void requireEnvVar(String varName) {
55+
assertNotNull(
56+
"Environment variable " + varName + " is required to perform these tests.",
57+
System.getenv(varName));
58+
}
59+
60+
@BeforeClass
61+
public static void checkRequirements() {
62+
requireEnvVar("GOOGLE_CLOUD_PROJECT");
63+
}
64+
65+
@Before
66+
public void setUp() {
67+
bout = new ByteArrayOutputStream();
68+
out = new PrintStream(bout);
69+
System.setOut(out);
70+
71+
bigquery = BigQueryOptions.getDefaultInstance().getService();
72+
73+
// Create a new dataset and table for each test.
74+
datasetName = "WRITE_STREAM_TEST" + UUID.randomUUID().toString().substring(0, 8);
75+
tableName = "DEFAULT_STREAM_TEST" + UUID.randomUUID().toString().substring(0, 8);
76+
Schema schema =
77+
Schema.of(
78+
com.google.cloud.bigquery.Field.newBuilder("foo", StandardSQLTypeName.STRING).build(),
79+
com.google.cloud.bigquery.Field.newBuilder(
80+
"bar",
81+
StandardSQLTypeName.STRUCT,
82+
FieldList.of(
83+
com.google.cloud.bigquery.Field.newBuilder(
84+
"my_int", StandardSQLTypeName.INT64)
85+
.build(),
86+
com.google.cloud.bigquery.Field.newBuilder(
87+
"my_string", StandardSQLTypeName.STRING)
88+
.build()))
89+
.build());
90+
bigquery.create(DatasetInfo.newBuilder(datasetName).build());
91+
TableInfo tableInfo =
92+
TableInfo.newBuilder(TableId.of(datasetName, tableName), StandardTableDefinition.of(schema))
93+
.build();
94+
bigquery.create(tableInfo);
95+
}
96+
97+
@After
98+
public void tearDown() {
99+
bigquery.delete(
100+
DatasetId.of(GOOGLE_CLOUD_PROJECT, datasetName), DatasetDeleteOption.deleteContents());
101+
System.setOut(null);
102+
}
103+
104+
@Test
105+
public void testWriteNestedProto() throws Exception {
106+
WriteNestedProto.runWriteNestedProto(GOOGLE_CLOUD_PROJECT, datasetName, tableName);
107+
assertThat(bout.toString()).contains("Appended records successfully.");
108+
}
109+
}

0 commit comments

Comments
 (0)