From 3c6897cd100203522276189938f9ad73fcf3bd9a Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Mon, 23 Jan 2023 10:19:33 -0500 Subject: [PATCH 01/42] samples: schema evolution --- .../java/pubsub/CommitAvroSchemaExample.java | 69 ++++++++ .../java/pubsub/CommitProtoSchemaExample.java | 69 ++++++++ .../java/pubsub/CreateAvroSchemaExample.java | 4 +- .../java/pubsub/CreateProtoSchemaExample.java | 4 +- ...CreateTopicWithSchemaRevisionsExample.java | 82 +++++++++ .../pubsub/DeleteSchemaRevisionExample.java | 51 ++++++ .../java/pubsub/GetSchemaRevisionExample.java | 52 ++++++ .../pubsub/ListSchemaRevisionsExample.java | 46 +++++ .../java/pubsub/RollbackSchemaExample.java | 53 ++++++ ...bscribeWithAvroSchemaRevisionsExample.java | 158 ++++++++++++++++++ .../java/pubsub/UpdateTopicSchemaExample.java | 83 +++++++++ .../src/main/resources/us-states-plus.avsc | 24 +++ .../src/main/resources/us-states-plus.proto | 10 ++ .../src/test/java/pubsub/SchemaIT.java | 138 +++++++++++++-- 14 files changed, 825 insertions(+), 18 deletions(-) create mode 100644 samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java create mode 100644 samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java create mode 100644 samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java create mode 100644 samples/snippets/src/main/resources/us-states-plus.avsc create mode 100644 samples/snippets/src/main/resources/us-states-plus.proto diff --git a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java new file mode 100644 index 000000000..632dc606d --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_commit_avro_schema] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.ProjectName; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class CommitAvroSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + String avscFile = "path/to/an/avro/schema/file/(.avsc)/formatted/in/json"; + + commitAvroSchemaExample(projectId, schemaId, avscFile); + } + + public static Schema commitAvroSchemaExample(String projectId, String schemaId, String avscFile) + throws IOException { + + ProjectName projectName = ProjectName.of(projectId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + // Read an Avro schema file formatted in JSON as a string. + String avscSource = new String(Files.readAllBytes(Paths.get(avscFile))); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = + schemaServiceClient.commitSchema( + schemaName.toString(), + Schema.newBuilder() + .setName(schemaName.toString()) + .setType(Schema.Type.AVRO) + .setDefinition(avscSource) + .build()); + + System.out.println("Committed a schema using an Avro schema:\n" + schema); + return schema; + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + return null; + } + } +} +// [END pubsub_commit_avro_schema] diff --git a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java new file mode 100644 index 000000000..cd7c90eb9 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_commit_proto_schema] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.ProjectName; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class CommitProtoSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + String protoFile = "path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers"; + + commitProtoSchemaExample(projectId, schemaId, protoFile); + } + + public static Schema commitProtoSchemaExample(String projectId, String schemaId, String protoFile) + throws IOException { + + ProjectName projectName = ProjectName.of(projectId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + // Read a proto file as a string. + String protoSource = new String(Files.readAllBytes(Paths.get(protoFile))); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = + schemaServiceClient.commitSchema( + schemaName.toString(), + Schema.newBuilder() + .setName(schemaName.toString()) + .setType(Schema.Type.PROTOCOL_BUFFER) + .setDefinition(protoSource) + .build()); + + System.out.println("Committed a schema using a protobuf schema:\n" + schema); + return schema; + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + return null; + } + } +} +// [END pubsub_commit_proto_schema] diff --git a/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java index 1b93b7fbe..393b128b3 100644 --- a/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java @@ -38,7 +38,7 @@ public static void main(String... args) throws Exception { createAvroSchemaExample(projectId, schemaId, avscFile); } - public static void createAvroSchemaExample(String projectId, String schemaId, String avscFile) + public static Schema createAvroSchemaExample(String projectId, String schemaId, String avscFile) throws IOException { ProjectName projectName = ProjectName.of(projectId); @@ -60,8 +60,10 @@ public static void createAvroSchemaExample(String projectId, String schemaId, St schemaId); System.out.println("Created a schema using an Avro schema:\n" + schema); + return schema; } catch (AlreadyExistsException e) { System.out.println(schemaName + "already exists."); + return null; } } } diff --git a/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java index a8efdeb8e..e7b5bf113 100644 --- a/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java @@ -38,7 +38,7 @@ public static void main(String... args) throws Exception { createProtoSchemaExample(projectId, schemaId, protoFile); } - public static void createProtoSchemaExample(String projectId, String schemaId, String protoFile) + public static Schema createProtoSchemaExample(String projectId, String schemaId, String protoFile) throws IOException { ProjectName projectName = ProjectName.of(projectId); @@ -60,8 +60,10 @@ public static void createProtoSchemaExample(String projectId, String schemaId, S schemaId); System.out.println("Created a schema using a protobuf schema:\n" + schema); + return schema; } catch (AlreadyExistsException e) { System.out.println(schemaName + "already exists."); + return null; } } } diff --git a/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java new file mode 100644 index 000000000..58053f5f0 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java @@ -0,0 +1,82 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_create_topic_with_schema_revisions] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.pubsub.v1.Encoding; +import com.google.pubsub.v1.SchemaName; +import com.google.pubsub.v1.SchemaSettings; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.TopicName; +import java.io.IOException; + +public class CreateTopicWithSchemaRevisionsExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String topicId = "your-topic-id"; + // Use an existing schema. + String schemaId = "your-schema-id"; + // Choose either BINARY or JSON message serialization in this topic. + Encoding encoding = Encoding.BINARY; + // Set the minimum and maximum revsion ID + String firstRevisionId = "your-revision-id"; + String lastRevisionId = "your-revision-id"; + + createTopicWithSchemaRevisionsExample( + projectId, topicId, schemaId, firstRevisionId, lastRevisionId, encoding); + } + + public static void createTopicWithSchemaRevisionsExample( + String projectId, + String topicId, + String schemaId, + String firstRevisionid, + String lastRevisionId, + Encoding encoding) + throws IOException { + TopicName topicName = TopicName.of(projectId, topicId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + SchemaSettings schemaSettings = + SchemaSettings.newBuilder() + .setSchema(schemaName.toString()) + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .setEncoding(encoding) + .build(); + + try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { + + Topic topic = + topicAdminClient.createTopic( + Topic.newBuilder() + .setName(topicName.toString()) + .setSchemaSettings(schemaSettings) + .build()); + + System.out.println("Created topic with schema: " + topic.getName()); + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + } + } +} +// [END pubsub_create_topic_with_schema_revisions] diff --git a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java new file mode 100644 index 000000000..db86e44b4 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java @@ -0,0 +1,51 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_delete_schema_revision] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class DeleteSchemaRevisionExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id@your-revision-id"; + + deleteSchemaRevisionExample(projectId, schemaId); + } + + public static void deleteSchemaRevisionExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + schemaServiceClient.deleteSchema(schemaName); + + System.out.println("Deleted a schema revision:" + schemaName); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_delete_schema_revision] diff --git a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java new file mode 100644 index 000000000..3136fecfc --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java @@ -0,0 +1,52 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_get_schema_revision] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class GetSchemaRevisionExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id@your-schema-revision"; + + getSchemaRevisionExample(projectId, schemaId); + } + + public static void getSchemaRevisionExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = schemaServiceClient.getSchema(schemaName); + + System.out.println("Got a schema:\n" + schema); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_get_schema_revision] diff --git a/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java new file mode 100644 index 000000000..4114a5ca8 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java @@ -0,0 +1,46 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_list_schema_revisions] +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class ListSchemaRevisionsExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + + listSchemaRevisionsExample(projectId, schemaId); + } + + public static void listSchemaRevisionsExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + for (Schema schema : schemaServiceClient.listSchemaRevisions(schemaName).iterateAll()) { + System.out.println(schema); + } + System.out.println("Listed schema revisions."); + } + } +} +// [END pubsub_list_schema_revisions] diff --git a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java new file mode 100644 index 000000000..8ae11585d --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java @@ -0,0 +1,53 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_rollback_schema] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class RollbackSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project"; + String schemaId = "your-schema@your-revision"; + String revisionId = "your-revision"; + + rollbackSchemaExample(projectId, schemaId, revisionId); + } + + public static void rollbackSchemaExample(String projectId, String schemaId, String revisionId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = schemaServiceClient.rollbackSchema(schemaName, revisionId); + + System.out.println("Rolled back a schema:" + schema); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_rollback_schema] diff --git a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java new file mode 100644 index 000000000..6e309a299 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java @@ -0,0 +1,158 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_subscribe_avro_records_with_revisions] + +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.protobuf.ByteString; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import com.google.pubsub.v1.Schema; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.apache.avro.io.Decoder; +import org.apache.avro.io.DecoderFactory; +import org.apache.avro.specific.SpecificDatumReader; +import utilities.State; + +public class SubscribeWithAvroSchemaRevisionsExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + // Use an existing subscription. + String subscriptionId = "your-subscription-id"; + + subscribeWithAvroSchemaRevisionsExample(projectId, subscriptionId); + } + + static SchemaServiceClient getSchemaServiceClient() { + try { + return SchemaServiceClient.create(); + } catch (IOException e) { + System.out.println("Could not get schema client: " + e); + return null; + } + } + + public static void subscribeWithAvroSchemaRevisionsExample( + String projectId, String subscriptionId) { + // Used to get the schemas for revsions. + final SchemaServiceClient schemaServiceClient = getSchemaServiceClient(); + if (schemaServiceClient == null) { + return; + } + + // Cache for the readers for different revision IDs. + Map> revisionReaders = + new HashMap>(); + + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId); + + // Instantiate an asynchronous message receiver. + MessageReceiver receiver = + (PubsubMessage message, AckReplyConsumer consumer) -> { + // Get the schema encoding type. + String name = message.getAttributesMap().get("googclient_schemaname"); + String revision = message.getAttributesMap().get("googclient_schemarevisionid"); + + SpecificDatumReader reader = null; + synchronized (revisionReaders) { + reader = revisionReaders.get(revision); + } + if (reader == null) { + // This is the first time we are seeing this revision. We need to + // fetch the schema and cache its decoder. It would be more typical + // to do this asynchronously, but it shown here in a synchronous + // way to ease readability. + try { + Schema schema = schemaServiceClient.getSchema(name + "@" + revision); + org.apache.avro.Schema avroSchema = + new org.apache.avro.Schema.Parser().parse(schema.getDefinition()); + reader = new SpecificDatumReader(State.getClassSchema(), avroSchema); + synchronized (revisionReaders) { + revisionReaders.put(revision, reader); + } + } catch (Exception e) { + System.out.println("Could not get schema: " + e); + // Without the schema, we cannot read the message, so nack it. + consumer.nack(); + return; + } + } + + ByteString data = message.getData(); + // Send the message data to a byte[] input stream. + InputStream inputStream = new ByteArrayInputStream(data.toByteArray()); + + String encoding = message.getAttributesMap().get("googclient_schemaencoding"); + + Decoder decoder = null; + + // Prepare an appropriate decoder for the message data in the input stream + // based on the schema encoding type. + try { + switch (encoding) { + case "BINARY": + decoder = DecoderFactory.get().directBinaryDecoder(inputStream, /*reuse=*/ null); + System.out.println("Receiving a binary-encoded message:"); + break; + case "JSON": + decoder = DecoderFactory.get().jsonDecoder(State.getClassSchema(), inputStream); + System.out.println("Receiving a JSON-encoded message:"); + break; + default: + System.out.println("Unknown message type; nacking."); + consumer.nack(); + break; + } + + // Obtain an object of the generated Avro class using the decoder. + State state = reader.read(null, decoder); + System.out.println(state.getName() + " is abbreviated as " + state.getPostAbbr()); + + // Ack the message. + consumer.ack(); + } catch (IOException e) { + System.err.println(e); + // If we failed to process the message, nack it. + consumer.nack(); + } + }; + + Subscriber subscriber = null; + try { + subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); + subscriber.startAsync().awaitRunning(); + System.out.printf("Listening for messages on %s:\n", subscriptionName.toString()); + subscriber.awaitTerminated(30, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { + subscriber.stopAsync(); + } + } +} +// [END pubsub_subscribe_avro_records_with_revisions] diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java new file mode 100644 index 000000000..d249ea66b --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -0,0 +1,83 @@ +/* + * Copyright 2020 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 pubsub; + +// [START pubsub_update_topic_schema] + +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.protobuf.FieldMask; +import com.google.pubsub.v1.SchemaSettings; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.TopicName; +import com.google.pubsub.v1.UpdateTopicRequest; +import java.io.IOException; + +public class UpdateTopicSchemaExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + // This is an existing topic that has schema settings attached to it. + String topicId = "your-topic-id"; + // Set the minimum and maximum revsion ID + String firstRevisionId = "your-revision-id"; + String lastRevisionId = "your-revision-id"; + + UpdateTopicSchemaExample.updateTopicSchemaExample( + projectId, topicId, firstRevisionId, lastRevisionId); + } + + public static void updateTopicSchemaExample( + String projectId, String topicId, String firstRevisionid, + String lastRevisionId) + throws IOException { + try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { + + TopicName topicName = TopicName.of(projectId, topicId); + + // Construct the dead letter policy you expect to have after the update. + SchemaSettings schemaSettings = + SchemaSettings.newBuilder() + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .build(); + + // Construct the subscription with the dead letter policy you expect to have + // after the update. Here, values in the required fields (name, topic) help + // identify the subscription. + Topic topic = + Topic.newBuilder() + .setName(topicName.toString()) + .setSchemaSettings(schemaSettings) + .build(); + + // Construct a field mask to indicate which field to update in the subscription. + FieldMask updateMask = + FieldMask.newBuilder().addPaths("schema_settings.first_revision_id").addPaths("schema_settings.last_revision_id").build(); + + UpdateTopicRequest request = + UpdateTopicRequest.newBuilder() + .setTopic(topic) + .setUpdateMask(updateMask) + .build(); + + Topic response = topicAdminClient.updateTopic(request); + + System.out.println("Updated topic with schema: " + topic.getName()); + } + } +} +// [END pubsub_update_topic_schema] diff --git a/samples/snippets/src/main/resources/us-states-plus.avsc b/samples/snippets/src/main/resources/us-states-plus.avsc new file mode 100644 index 000000000..e3e2fbfa3 --- /dev/null +++ b/samples/snippets/src/main/resources/us-states-plus.avsc @@ -0,0 +1,24 @@ +{ + "type":"record", + "name":"State", + "namespace":"utilities", + "doc":"A list of states in the United States of America.", + "fields":[ + { + "name":"name", + "type":"string", + "doc":"The common name of the state." + }, + { + "name":"post_abbr", + "type":"string", + "doc":"The postal code abbreviation of the state." + }, + { + "name":"population", + "type":"long", + "default":0, + "doc":"The postal code abbreviation of the state." + } + ] +} diff --git a/samples/snippets/src/main/resources/us-states-plus.proto b/samples/snippets/src/main/resources/us-states-plus.proto new file mode 100644 index 000000000..646c7dcb6 --- /dev/null +++ b/samples/snippets/src/main/resources/us-states-plus.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package utilities; +option java_outer_classname = "StateProto"; + +message State { + string name = 1; + string post_abbr = 2; + int64 population = 3; +} diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index bec908800..5bc3e5848 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -26,6 +26,7 @@ import com.google.cloud.testing.junit4.MultipleAttemptsRule; import com.google.pubsub.v1.Encoding; import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.Schema; import com.google.pubsub.v1.SchemaName; import com.google.pubsub.v1.TopicName; import java.io.ByteArrayOutputStream; @@ -46,6 +47,7 @@ public class SchemaIT { private static String _suffix; private static String avroTopicId; private static String protoTopicId; + private static String protoTopicWithRevisionsId; private static String avroSubscriptionId; private static String protoSubscriptionId; private static String avroSchemaId; @@ -54,12 +56,17 @@ public class SchemaIT { ClassLoader classLoader = getClass().getClassLoader(); File avscFile = new File(classLoader.getResource("us-states.avsc").getFile()); String absoluteAvscFilePath = avscFile.getAbsolutePath(); + File avscRevisionFile = new File(classLoader.getResource("us-states-plus.avsc").getFile()); + String absoluteAvscRevisionFilePath = avscRevisionFile.getAbsolutePath(); File protoFile = new File(classLoader.getResource("us-states.proto").getFile()); String absoluteProtoFilePath = protoFile.getAbsolutePath(); + File protoRevisionFile = new File(classLoader.getResource("us-states-plus.proto").getFile()); + String absoluteProtoRevisionFilePath = protoFile.getAbsolutePath(); private static TopicName avroTopicName; private static TopicName protoTopicName; + private static TopicName protoTopicWithRevisionsName; private static ProjectSubscriptionName avroSubscriptionName; private static ProjectSubscriptionName protoSubscriptionName; private static SchemaName avroSchemaName; @@ -79,12 +86,14 @@ public void setUp() { _suffix = UUID.randomUUID().toString(); avroTopicId = "avro-topic-" + _suffix; protoTopicId = "proto-topic-" + _suffix; + protoTopicWithRevisionsId = "proto-topic-with-revisions-" + _suffix; avroSubscriptionId = "avro-subscription-" + _suffix; protoSubscriptionId = "proto-subscription-" + _suffix; avroSchemaId = "avro-schema-" + _suffix; protoSchemaId = "proto-schema-" + _suffix; avroTopicName = TopicName.of(projectId, avroTopicId); protoTopicName = TopicName.of(projectId, protoTopicId); + protoTopicWithRevisionsName = TopicName.of(projectId, protoTopicWithRevisionsId); avroSubscriptionName = ProjectSubscriptionName.of(projectId, avroSubscriptionId); protoSubscriptionName = ProjectSubscriptionName.of(projectId, protoSubscriptionId); avroSchemaName = SchemaName.of(projectId, avroSchemaId); @@ -98,26 +107,49 @@ public void setUp() { public void tearDown() throws Exception { // Delete the schemas if they have not been cleaned up. try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { - schemaServiceClient.deleteSchema(protoSchemaName); - schemaServiceClient.deleteSchema(avroSchemaName); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + schemaServiceClient.deleteSchema(protoSchemaName); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + schemaServiceClient.deleteSchema(avroSchemaName); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } // Delete the subscriptions. try (SubscriptionAdminClient subscriptionAdmin = SubscriptionAdminClient.create()) { - subscriptionAdmin.deleteSubscription(avroSubscriptionName.toString()); - subscriptionAdmin.deleteSubscription(protoSubscriptionName.toString()); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + subscriptionAdmin.deleteSubscription(avroSubscriptionName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + subscriptionAdmin.deleteSubscription(protoSubscriptionName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } // Delete the topics. try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { - topicAdminClient.deleteTopic(avroTopicName.toString()); - topicAdminClient.deleteTopic(protoTopicName.toString()); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + topicAdminClient.deleteTopic(avroTopicName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + topicAdminClient.deleteTopic(protoTopicName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + topicAdminClient.deleteTopic(protoTopicWithRevisionsName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } System.setOut(null); } @@ -125,28 +157,69 @@ public void tearDown() throws Exception { @Test public void testSchema() throws Exception { // Test creating Avro schema. - CreateAvroSchemaExample.createAvroSchemaExample(projectId, avroSchemaId, absoluteAvscFilePath); + Schema avroSchema = + CreateAvroSchemaExample.createAvroSchemaExample( + projectId, avroSchemaId, absoluteAvscFilePath); assertThat(bout.toString()).contains("Created a schema using an Avro schema:"); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test committing Avro schema. + CommitAvroSchemaExample.commitAvroSchemaExample( + projectId, avroSchemaId, absoluteAvscRevisionFilePath); + assertThat(bout.toString()).contains("Committed a schema using an Avro schema:"); + // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(avroSchemaName.toString()); + + bout.reset(); // Test creating Proto schema. - CreateProtoSchemaExample.createProtoSchemaExample( - projectId, protoSchemaId, absoluteProtoFilePath); + Schema protoSchema = + CreateProtoSchemaExample.createProtoSchemaExample( + projectId, protoSchemaId, absoluteProtoFilePath); assertThat(bout.toString()).contains("Created a schema using a protobuf schema:"); assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); + // Test committing Proto schema. + Schema protoSchemaRevision = + CommitProtoSchemaExample.commitProtoSchemaExample( + projectId, protoSchemaId, absoluteProtoRevisionFilePath); + assertThat(bout.toString()).contains("Committed a schema using a protobuf schema:"); + // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(protoSchemaName.toString()); + + bout.reset(); + // Test rolling back a schema. + RollbackSchemaExample.rollbackSchemaExample( + projectId, + protoSchemaId + "@" + protoSchema.getRevisionId(), + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Rolled back a schema:"); + // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test getting a schema. GetSchemaExample.getSchemaExample(projectId, avroSchemaId); assertThat(bout.toString()).contains("Got a schema:"); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test getting a schema revision. + GetSchemaRevisionExample.getSchemaRevisionExample( + projectId, protoSchemaId + "@" + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Got a schema:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test listing schemas. ListSchemasExample.listSchemasExample(projectId); assertThat(bout.toString()).contains("Listed schemas."); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test listing schema revisions. + ListSchemaRevisionsExample.listSchemaRevisionsExample(projectId, protoSchemaId); + assertThat(bout.toString()).contains("Listed schema revisions."); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test creating a topic with an Avro schema with BINARY encoding. CreateTopicWithSchemaExample.createTopicWithSchemaExample( @@ -159,6 +232,19 @@ public void testSchema() throws Exception { projectId, protoTopicId, protoSchemaId, Encoding.JSON); assertThat(bout.toString()).contains("Created topic with schema: " + protoTopicName.toString()); + bout.reset(); + // Test creating a topic with a proto schema with revisions specified. + CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( + projectId, + protoTopicWithRevisionsId, + protoSchemaId, + protoSchema.getRevisionId(), + protoSchemaRevision.getRevisionId(), + Encoding.BINARY); + assertThat(bout.toString()) + .contains("Created topic with schema: " + protoTopicWithRevisionsName.toString()); + + bout.reset(); // Attach a default pull subscription to each topic. CreatePullSubscriptionExample.createPullSubscriptionExample( projectId, avroSubscriptionId, avroTopicId); @@ -179,7 +265,8 @@ public void testSchema() throws Exception { bout.reset(); // Test receiving BINARY-encoded Avro records. - SubscribeWithAvroSchemaExample.subscribeWithAvroSchemaExample(projectId, avroSubscriptionId); + SubscribeWithAvroSchemaRevisionsExample.subscribeWithAvroSchemaRevisionsExample( + projectId, avroSubscriptionId); assertThat(bout.toString()).contains("Receiving a binary-encoded message:"); assertThat(bout.toString()).contains(" is abbreviated as "); @@ -189,6 +276,25 @@ public void testSchema() throws Exception { assertThat(bout.toString()).contains("Received a JSON-formatted message:"); assertThat(bout.toString()).contains("Ack'ed the message"); + bout.reset(); + // Test updating a topic schema settings + CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( + projectId, + protoTopicWithRevisionsId, + protoSchemaId, + protoSchemaRevision.getRevisionId(), + protoSchemaRevision.getRevisionId(), + Encoding.BINARY); + assertThat(bout.toString()) + .contains("Updated topic with schema: " + protoTopicWithRevisionsName.toString()); + + bout.reset(); + // Test deleting a schema revision. + DeleteSchemaRevisionExample.deleteSchemaRevisionExample( + projectId, protoSchemaId + "@" + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Deleted a schema revision:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test deleting a schema. DeleteSchemaExample.deleteSchemaExample(projectId, avroSchemaId); From 7ea48d98416cb57eae4675c330e4c61606e95f37 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Mon, 23 Jan 2023 10:22:55 -0500 Subject: [PATCH 02/42] samples: schema evolution --- .../snippets/src/main/java/pubsub/CommitAvroSchemaExample.java | 2 +- .../snippets/src/main/java/pubsub/CommitProtoSchemaExample.java | 2 +- .../main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java | 2 +- .../src/main/java/pubsub/DeleteSchemaRevisionExample.java | 2 +- .../snippets/src/main/java/pubsub/GetSchemaRevisionExample.java | 2 +- .../src/main/java/pubsub/ListSchemaRevisionsExample.java | 2 +- .../snippets/src/main/java/pubsub/RollbackSchemaExample.java | 2 +- .../java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java | 2 +- .../snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java index 632dc606d..e6ac8f278 100644 --- a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java index cd7c90eb9..b32de29dc 100644 --- a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java index 58053f5f0..69322d927 100644 --- a/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java index db86e44b4..148fe391a 100644 --- a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java +++ b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java index 3136fecfc..e811ae9ff 100644 --- a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java +++ b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java index 4114a5ca8..69cfa59ab 100644 --- a/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java +++ b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java index 8ae11585d..795ba33b5 100644 --- a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java index 6e309a299..f86f05107 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java index d249ea66b..b6ec9659f 100644 --- a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 4e5c026e3845fda16ea086697a2fa0520db3f655 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Mon, 23 Jan 2023 12:00:54 -0500 Subject: [PATCH 03/42] Format fixes --- .../java/pubsub/UpdateTopicSchemaExample.java | 21 +++++++++---------- .../src/test/java/pubsub/SchemaIT.java | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java index b6ec9659f..d0412650b 100644 --- a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -41,8 +41,7 @@ public static void main(String... args) throws Exception { } public static void updateTopicSchemaExample( - String projectId, String topicId, String firstRevisionid, - String lastRevisionId) + String projectId, String topicId, String firstRevisionid, String lastRevisionId) throws IOException { try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { @@ -50,10 +49,10 @@ public static void updateTopicSchemaExample( // Construct the dead letter policy you expect to have after the update. SchemaSettings schemaSettings = - SchemaSettings.newBuilder() - .setFirstRevisionId(firstRevisionid) - .setLastRevisionId(lastRevisionId) - .build(); + SchemaSettings.newBuilder() + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .build(); // Construct the subscription with the dead letter policy you expect to have // after the update. Here, values in the required fields (name, topic) help @@ -66,13 +65,13 @@ public static void updateTopicSchemaExample( // Construct a field mask to indicate which field to update in the subscription. FieldMask updateMask = - FieldMask.newBuilder().addPaths("schema_settings.first_revision_id").addPaths("schema_settings.last_revision_id").build(); + FieldMask.newBuilder() + .addPaths("schema_settings.first_revision_id") + .addPaths("schema_settings.last_revision_id") + .build(); UpdateTopicRequest request = - UpdateTopicRequest.newBuilder() - .setTopic(topic) - .setUpdateMask(updateMask) - .build(); + UpdateTopicRequest.newBuilder().setTopic(topic).setUpdateMask(updateMask).build(); Topic response = topicAdminClient.updateTopic(request); diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index 5bc3e5848..3203870e3 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -276,7 +276,7 @@ public void testSchema() throws Exception { assertThat(bout.toString()).contains("Received a JSON-formatted message:"); assertThat(bout.toString()).contains("Ack'ed the message"); - bout.reset(); + bout.reset(); // Test updating a topic schema settings CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( projectId, From 8a814081ab6f38fed99f69a948e510b716d15ca0 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Mon, 23 Jan 2023 12:16:35 -0500 Subject: [PATCH 04/42] Fix documentation for field. --- samples/snippets/src/main/resources/us-states-plus.avsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/src/main/resources/us-states-plus.avsc b/samples/snippets/src/main/resources/us-states-plus.avsc index e3e2fbfa3..74225ae7e 100644 --- a/samples/snippets/src/main/resources/us-states-plus.avsc +++ b/samples/snippets/src/main/resources/us-states-plus.avsc @@ -18,7 +18,7 @@ "name":"population", "type":"long", "default":0, - "doc":"The postal code abbreviation of the state." + "doc":"The population of the state." } ] } From 90800ac241025a24af8cf885112295a5a2d03aa7 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Thu, 26 Jan 2023 16:28:59 +0000 Subject: [PATCH 05/42] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20?= =?UTF-8?q?post-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b8e47b4c2..d9ce2ef0e 100644 --- a/README.md +++ b/README.md @@ -58,13 +58,13 @@ implementation 'com.google.cloud:google-cloud-pubsub' If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-pubsub:1.123.0' +implementation 'com.google.cloud:google-cloud-pubsub:1.123.1' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-pubsub" % "1.123.0" +libraryDependencies += "com.google.cloud" % "google-cloud-pubsub" % "1.123.1" ``` ## Authentication @@ -242,6 +242,8 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | --------------------------- | --------------------------------- | ------ | | Native Image Pub Sub Sample | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/native-image-sample/src/main/java/pubsub/NativeImagePubSubSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/native-image-sample/src/main/java/pubsub/NativeImagePubSubSample.java) | | Publish Operations | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/native-image-sample/src/main/java/utilities/PublishOperations.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/native-image-sample/src/main/java/utilities/PublishOperations.java) | +| Commit Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java) | +| Commit Proto Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java) | | Create Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java) | | Create Big Query Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateBigQuerySubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateBigQuerySubscriptionExample.java) | | Create Proto Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java) | @@ -253,13 +255,17 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Create Subscription With Ordering | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateSubscriptionWithOrdering.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateSubscriptionWithOrdering.java) | | Create Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicExample.java) | | Create Topic With Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaExample.java) | +| Create Topic With Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java) | | Delete Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSchemaExample.java) | +| Delete Schema Revision Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java) | | Delete Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSubscriptionExample.java) | | Delete Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteTopicExample.java) | | Detach Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DetachSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DetachSubscriptionExample.java) | | Get Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSchemaExample.java) | +| Get Schema Revision Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java) | | Get Subscription Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSubscriptionPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSubscriptionPolicyExample.java) | | Get Topic Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetTopicPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetTopicPolicyExample.java) | +| List Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java) | | List Schemas Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSchemasExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSchemasExample.java) | | List Subscriptions In Project Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSubscriptionsInProjectExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSubscriptionsInProjectExample.java) | | List Subscriptions In Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSubscriptionsInTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSubscriptionsInTopicExample.java) | @@ -278,12 +284,14 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Receive Messages With Delivery Attempts Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ReceiveMessagesWithDeliveryAttemptsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ReceiveMessagesWithDeliveryAttemptsExample.java) | | Remove Dead Letter Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/RemoveDeadLetterPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/RemoveDeadLetterPolicyExample.java) | | Resume Publish With Ordering Keys | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ResumePublishWithOrderingKeys.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ResumePublishWithOrderingKeys.java) | +| Rollback Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java) | | Set Subscription Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SetSubscriptionPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SetSubscriptionPolicyExample.java) | | Set Topic Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SetTopicPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SetTopicPolicyExample.java) | | Subscribe Async Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java) | | Subscribe Sync Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeSyncExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeSyncExample.java) | | Subscribe Sync With Lease Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeSyncWithLeaseExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeSyncWithLeaseExample.java) | | Subscribe With Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaExample.java) | +| Subscribe With Avro Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java) | | Subscribe With Concurrency Control Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithConcurrencyControlExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithConcurrencyControlExample.java) | | Subscribe With Custom Attributes Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithCustomAttributesExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithCustomAttributesExample.java) | | Subscribe With Error Listener Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithErrorListenerExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithErrorListenerExample.java) | @@ -294,6 +302,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Test Topic Permissions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/TestTopicPermissionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/TestTopicPermissionsExample.java) | | Update Dead Letter Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdateDeadLetterPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdateDeadLetterPolicyExample.java) | | Update Push Configuration Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdatePushConfigurationExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdatePushConfigurationExample.java) | +| Update Topic Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java) | | State | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/utilities/State.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/utilities/State.java) | | State Proto | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/utilities/StateProto.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/utilities/StateProto.java) | From a88377cd0218ba131501a28b32b9d89c5003b1be Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 26 Jan 2023 13:22:06 -0500 Subject: [PATCH 06/42] Add back in working asserts --- samples/snippets/src/test/java/pubsub/SchemaIT.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index 3203870e3..ee93d3a1a 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -168,7 +168,7 @@ public void testSchema() throws Exception { CommitAvroSchemaExample.commitAvroSchemaExample( projectId, avroSchemaId, absoluteAvscRevisionFilePath); assertThat(bout.toString()).contains("Committed a schema using an Avro schema:"); - // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(avroSchemaName.toString()); + assertThat(bout.toString()).contains(avroSchemaName.toString()); bout.reset(); // Test creating Proto schema. @@ -184,7 +184,7 @@ public void testSchema() throws Exception { CommitProtoSchemaExample.commitProtoSchemaExample( projectId, protoSchemaId, absoluteProtoRevisionFilePath); assertThat(bout.toString()).contains("Committed a schema using a protobuf schema:"); - // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(protoSchemaName.toString()); + assertThat(bout.toString()).contains(protoSchemaName.toString()); bout.reset(); // Test rolling back a schema. @@ -193,7 +193,7 @@ public void testSchema() throws Exception { protoSchemaId + "@" + protoSchema.getRevisionId(), protoSchemaRevision.getRevisionId()); assertThat(bout.toString()).contains("Rolled back a schema:"); - // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(protoSchemaName.toString()); + assertThat(bout.toString()).contains(protoSchemaName.toString()); bout.reset(); // Test getting a schema. @@ -278,13 +278,11 @@ public void testSchema() throws Exception { bout.reset(); // Test updating a topic schema settings - CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( + UpdateTopicSchemaExample.updateTopicSchemaExample( projectId, protoTopicWithRevisionsId, - protoSchemaId, - protoSchemaRevision.getRevisionId(), protoSchemaRevision.getRevisionId(), - Encoding.BINARY); + protoSchemaRevision.getRevisionId()); assertThat(bout.toString()) .contains("Updated topic with schema: " + protoTopicWithRevisionsName.toString()); From 9a07bbd51cb0cf23fca75f72ffa4063301731a24 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 26 Jan 2023 13:59:36 -0500 Subject: [PATCH 07/42] Formatting fixes --- samples/snippets/src/test/java/pubsub/SchemaIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index ee93d3a1a..31685db56 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -172,7 +172,7 @@ public void testSchema() throws Exception { bout.reset(); // Test creating Proto schema. - Schema protoSchema = + final Schema protoSchema = CreateProtoSchemaExample.createProtoSchemaExample( projectId, protoSchemaId, absoluteProtoFilePath); assertThat(bout.toString()).contains("Created a schema using a protobuf schema:"); @@ -180,7 +180,7 @@ public void testSchema() throws Exception { bout.reset(); // Test committing Proto schema. - Schema protoSchemaRevision = + final Schema protoSchemaRevision = CommitProtoSchemaExample.commitProtoSchemaExample( projectId, protoSchemaId, absoluteProtoRevisionFilePath); assertThat(bout.toString()).contains("Committed a schema using a protobuf schema:"); From df27d5702319ac63f0ecadfbe97549297d8f64f9 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Mon, 30 Jan 2023 15:05:21 +0000 Subject: [PATCH 08/42] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20?= =?UTF-8?q?post-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d9ce2ef0e..19f8e4acd 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ If you are using Maven without BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.4.0') +implementation platform('com.google.cloud:libraries-bom:26.5.0') implementation 'com.google.cloud:google-cloud-pubsub' ``` From 7d1c561d06f8b69f4c447086177c3c0af29e9e03 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 14 Feb 2023 11:35:31 -0500 Subject: [PATCH 09/42] Version/delete fixes --- samples/snippets/pom.xml | 2 +- .../src/main/java/pubsub/DeleteSchemaRevisionExample.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index efb1504e2..58a2092b8 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -45,7 +45,7 @@ com.google.cloud libraries-bom - 26.1.5 + 26.8.0 pom import diff --git a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java index 148fe391a..30aa65a53 100644 --- a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java +++ b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java @@ -20,6 +20,7 @@ import com.google.api.gax.rpc.NotFoundException; import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.DeleteSchemaRevisionRequest; import com.google.pubsub.v1.SchemaName; import java.io.IOException; @@ -39,7 +40,10 @@ public static void deleteSchemaRevisionExample(String projectId, String schemaId try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { - schemaServiceClient.deleteSchema(schemaName); + DeleteSchemaRevisionRequest request = + DeleteSchemaRevisionRequest.newBuilder().setName(schemaName.toString()).build(); + + schemaServiceClient.deleteSchemaRevision(request); System.out.println("Deleted a schema revision:" + schemaName); From 646afa7e55782309f7ddefed35a887e8ba25f5a7 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Mon, 23 Jan 2023 10:19:33 -0500 Subject: [PATCH 10/42] samples: schema evolution --- .../java/pubsub/CommitAvroSchemaExample.java | 69 ++++++++ .../java/pubsub/CommitProtoSchemaExample.java | 69 ++++++++ .../java/pubsub/CreateAvroSchemaExample.java | 4 +- .../java/pubsub/CreateProtoSchemaExample.java | 4 +- ...CreateTopicWithSchemaRevisionsExample.java | 82 +++++++++ .../pubsub/DeleteSchemaRevisionExample.java | 51 ++++++ .../java/pubsub/GetSchemaRevisionExample.java | 52 ++++++ .../pubsub/ListSchemaRevisionsExample.java | 46 +++++ .../java/pubsub/RollbackSchemaExample.java | 53 ++++++ ...bscribeWithAvroSchemaRevisionsExample.java | 158 ++++++++++++++++++ .../java/pubsub/UpdateTopicSchemaExample.java | 83 +++++++++ .../src/main/resources/us-states-plus.avsc | 24 +++ .../src/main/resources/us-states-plus.proto | 10 ++ .../src/test/java/pubsub/SchemaIT.java | 138 +++++++++++++-- 14 files changed, 825 insertions(+), 18 deletions(-) create mode 100644 samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java create mode 100644 samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java create mode 100644 samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java create mode 100644 samples/snippets/src/main/resources/us-states-plus.avsc create mode 100644 samples/snippets/src/main/resources/us-states-plus.proto diff --git a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java new file mode 100644 index 000000000..632dc606d --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_commit_avro_schema] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.ProjectName; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class CommitAvroSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + String avscFile = "path/to/an/avro/schema/file/(.avsc)/formatted/in/json"; + + commitAvroSchemaExample(projectId, schemaId, avscFile); + } + + public static Schema commitAvroSchemaExample(String projectId, String schemaId, String avscFile) + throws IOException { + + ProjectName projectName = ProjectName.of(projectId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + // Read an Avro schema file formatted in JSON as a string. + String avscSource = new String(Files.readAllBytes(Paths.get(avscFile))); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = + schemaServiceClient.commitSchema( + schemaName.toString(), + Schema.newBuilder() + .setName(schemaName.toString()) + .setType(Schema.Type.AVRO) + .setDefinition(avscSource) + .build()); + + System.out.println("Committed a schema using an Avro schema:\n" + schema); + return schema; + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + return null; + } + } +} +// [END pubsub_commit_avro_schema] diff --git a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java new file mode 100644 index 000000000..cd7c90eb9 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_commit_proto_schema] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.ProjectName; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class CommitProtoSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + String protoFile = "path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers"; + + commitProtoSchemaExample(projectId, schemaId, protoFile); + } + + public static Schema commitProtoSchemaExample(String projectId, String schemaId, String protoFile) + throws IOException { + + ProjectName projectName = ProjectName.of(projectId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + // Read a proto file as a string. + String protoSource = new String(Files.readAllBytes(Paths.get(protoFile))); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = + schemaServiceClient.commitSchema( + schemaName.toString(), + Schema.newBuilder() + .setName(schemaName.toString()) + .setType(Schema.Type.PROTOCOL_BUFFER) + .setDefinition(protoSource) + .build()); + + System.out.println("Committed a schema using a protobuf schema:\n" + schema); + return schema; + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + return null; + } + } +} +// [END pubsub_commit_proto_schema] diff --git a/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java index 1b93b7fbe..393b128b3 100644 --- a/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java @@ -38,7 +38,7 @@ public static void main(String... args) throws Exception { createAvroSchemaExample(projectId, schemaId, avscFile); } - public static void createAvroSchemaExample(String projectId, String schemaId, String avscFile) + public static Schema createAvroSchemaExample(String projectId, String schemaId, String avscFile) throws IOException { ProjectName projectName = ProjectName.of(projectId); @@ -60,8 +60,10 @@ public static void createAvroSchemaExample(String projectId, String schemaId, St schemaId); System.out.println("Created a schema using an Avro schema:\n" + schema); + return schema; } catch (AlreadyExistsException e) { System.out.println(schemaName + "already exists."); + return null; } } } diff --git a/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java index a8efdeb8e..e7b5bf113 100644 --- a/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java @@ -38,7 +38,7 @@ public static void main(String... args) throws Exception { createProtoSchemaExample(projectId, schemaId, protoFile); } - public static void createProtoSchemaExample(String projectId, String schemaId, String protoFile) + public static Schema createProtoSchemaExample(String projectId, String schemaId, String protoFile) throws IOException { ProjectName projectName = ProjectName.of(projectId); @@ -60,8 +60,10 @@ public static void createProtoSchemaExample(String projectId, String schemaId, S schemaId); System.out.println("Created a schema using a protobuf schema:\n" + schema); + return schema; } catch (AlreadyExistsException e) { System.out.println(schemaName + "already exists."); + return null; } } } diff --git a/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java new file mode 100644 index 000000000..58053f5f0 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java @@ -0,0 +1,82 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_create_topic_with_schema_revisions] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.pubsub.v1.Encoding; +import com.google.pubsub.v1.SchemaName; +import com.google.pubsub.v1.SchemaSettings; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.TopicName; +import java.io.IOException; + +public class CreateTopicWithSchemaRevisionsExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String topicId = "your-topic-id"; + // Use an existing schema. + String schemaId = "your-schema-id"; + // Choose either BINARY or JSON message serialization in this topic. + Encoding encoding = Encoding.BINARY; + // Set the minimum and maximum revsion ID + String firstRevisionId = "your-revision-id"; + String lastRevisionId = "your-revision-id"; + + createTopicWithSchemaRevisionsExample( + projectId, topicId, schemaId, firstRevisionId, lastRevisionId, encoding); + } + + public static void createTopicWithSchemaRevisionsExample( + String projectId, + String topicId, + String schemaId, + String firstRevisionid, + String lastRevisionId, + Encoding encoding) + throws IOException { + TopicName topicName = TopicName.of(projectId, topicId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + SchemaSettings schemaSettings = + SchemaSettings.newBuilder() + .setSchema(schemaName.toString()) + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .setEncoding(encoding) + .build(); + + try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { + + Topic topic = + topicAdminClient.createTopic( + Topic.newBuilder() + .setName(topicName.toString()) + .setSchemaSettings(schemaSettings) + .build()); + + System.out.println("Created topic with schema: " + topic.getName()); + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + } + } +} +// [END pubsub_create_topic_with_schema_revisions] diff --git a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java new file mode 100644 index 000000000..db86e44b4 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java @@ -0,0 +1,51 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_delete_schema_revision] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class DeleteSchemaRevisionExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id@your-revision-id"; + + deleteSchemaRevisionExample(projectId, schemaId); + } + + public static void deleteSchemaRevisionExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + schemaServiceClient.deleteSchema(schemaName); + + System.out.println("Deleted a schema revision:" + schemaName); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_delete_schema_revision] diff --git a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java new file mode 100644 index 000000000..3136fecfc --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java @@ -0,0 +1,52 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_get_schema_revision] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class GetSchemaRevisionExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id@your-schema-revision"; + + getSchemaRevisionExample(projectId, schemaId); + } + + public static void getSchemaRevisionExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = schemaServiceClient.getSchema(schemaName); + + System.out.println("Got a schema:\n" + schema); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_get_schema_revision] diff --git a/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java new file mode 100644 index 000000000..4114a5ca8 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java @@ -0,0 +1,46 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_list_schema_revisions] +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class ListSchemaRevisionsExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + + listSchemaRevisionsExample(projectId, schemaId); + } + + public static void listSchemaRevisionsExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + for (Schema schema : schemaServiceClient.listSchemaRevisions(schemaName).iterateAll()) { + System.out.println(schema); + } + System.out.println("Listed schema revisions."); + } + } +} +// [END pubsub_list_schema_revisions] diff --git a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java new file mode 100644 index 000000000..8ae11585d --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java @@ -0,0 +1,53 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_rollback_schema] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class RollbackSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project"; + String schemaId = "your-schema@your-revision"; + String revisionId = "your-revision"; + + rollbackSchemaExample(projectId, schemaId, revisionId); + } + + public static void rollbackSchemaExample(String projectId, String schemaId, String revisionId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = schemaServiceClient.rollbackSchema(schemaName, revisionId); + + System.out.println("Rolled back a schema:" + schema); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_rollback_schema] diff --git a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java new file mode 100644 index 000000000..6e309a299 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java @@ -0,0 +1,158 @@ +/* + * Copyright 2021 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 pubsub; + +// [START pubsub_subscribe_avro_records_with_revisions] + +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.protobuf.ByteString; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import com.google.pubsub.v1.Schema; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.apache.avro.io.Decoder; +import org.apache.avro.io.DecoderFactory; +import org.apache.avro.specific.SpecificDatumReader; +import utilities.State; + +public class SubscribeWithAvroSchemaRevisionsExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + // Use an existing subscription. + String subscriptionId = "your-subscription-id"; + + subscribeWithAvroSchemaRevisionsExample(projectId, subscriptionId); + } + + static SchemaServiceClient getSchemaServiceClient() { + try { + return SchemaServiceClient.create(); + } catch (IOException e) { + System.out.println("Could not get schema client: " + e); + return null; + } + } + + public static void subscribeWithAvroSchemaRevisionsExample( + String projectId, String subscriptionId) { + // Used to get the schemas for revsions. + final SchemaServiceClient schemaServiceClient = getSchemaServiceClient(); + if (schemaServiceClient == null) { + return; + } + + // Cache for the readers for different revision IDs. + Map> revisionReaders = + new HashMap>(); + + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId); + + // Instantiate an asynchronous message receiver. + MessageReceiver receiver = + (PubsubMessage message, AckReplyConsumer consumer) -> { + // Get the schema encoding type. + String name = message.getAttributesMap().get("googclient_schemaname"); + String revision = message.getAttributesMap().get("googclient_schemarevisionid"); + + SpecificDatumReader reader = null; + synchronized (revisionReaders) { + reader = revisionReaders.get(revision); + } + if (reader == null) { + // This is the first time we are seeing this revision. We need to + // fetch the schema and cache its decoder. It would be more typical + // to do this asynchronously, but it shown here in a synchronous + // way to ease readability. + try { + Schema schema = schemaServiceClient.getSchema(name + "@" + revision); + org.apache.avro.Schema avroSchema = + new org.apache.avro.Schema.Parser().parse(schema.getDefinition()); + reader = new SpecificDatumReader(State.getClassSchema(), avroSchema); + synchronized (revisionReaders) { + revisionReaders.put(revision, reader); + } + } catch (Exception e) { + System.out.println("Could not get schema: " + e); + // Without the schema, we cannot read the message, so nack it. + consumer.nack(); + return; + } + } + + ByteString data = message.getData(); + // Send the message data to a byte[] input stream. + InputStream inputStream = new ByteArrayInputStream(data.toByteArray()); + + String encoding = message.getAttributesMap().get("googclient_schemaencoding"); + + Decoder decoder = null; + + // Prepare an appropriate decoder for the message data in the input stream + // based on the schema encoding type. + try { + switch (encoding) { + case "BINARY": + decoder = DecoderFactory.get().directBinaryDecoder(inputStream, /*reuse=*/ null); + System.out.println("Receiving a binary-encoded message:"); + break; + case "JSON": + decoder = DecoderFactory.get().jsonDecoder(State.getClassSchema(), inputStream); + System.out.println("Receiving a JSON-encoded message:"); + break; + default: + System.out.println("Unknown message type; nacking."); + consumer.nack(); + break; + } + + // Obtain an object of the generated Avro class using the decoder. + State state = reader.read(null, decoder); + System.out.println(state.getName() + " is abbreviated as " + state.getPostAbbr()); + + // Ack the message. + consumer.ack(); + } catch (IOException e) { + System.err.println(e); + // If we failed to process the message, nack it. + consumer.nack(); + } + }; + + Subscriber subscriber = null; + try { + subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); + subscriber.startAsync().awaitRunning(); + System.out.printf("Listening for messages on %s:\n", subscriptionName.toString()); + subscriber.awaitTerminated(30, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { + subscriber.stopAsync(); + } + } +} +// [END pubsub_subscribe_avro_records_with_revisions] diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java new file mode 100644 index 000000000..d249ea66b --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -0,0 +1,83 @@ +/* + * Copyright 2020 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 pubsub; + +// [START pubsub_update_topic_schema] + +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.protobuf.FieldMask; +import com.google.pubsub.v1.SchemaSettings; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.TopicName; +import com.google.pubsub.v1.UpdateTopicRequest; +import java.io.IOException; + +public class UpdateTopicSchemaExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + // This is an existing topic that has schema settings attached to it. + String topicId = "your-topic-id"; + // Set the minimum and maximum revsion ID + String firstRevisionId = "your-revision-id"; + String lastRevisionId = "your-revision-id"; + + UpdateTopicSchemaExample.updateTopicSchemaExample( + projectId, topicId, firstRevisionId, lastRevisionId); + } + + public static void updateTopicSchemaExample( + String projectId, String topicId, String firstRevisionid, + String lastRevisionId) + throws IOException { + try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { + + TopicName topicName = TopicName.of(projectId, topicId); + + // Construct the dead letter policy you expect to have after the update. + SchemaSettings schemaSettings = + SchemaSettings.newBuilder() + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .build(); + + // Construct the subscription with the dead letter policy you expect to have + // after the update. Here, values in the required fields (name, topic) help + // identify the subscription. + Topic topic = + Topic.newBuilder() + .setName(topicName.toString()) + .setSchemaSettings(schemaSettings) + .build(); + + // Construct a field mask to indicate which field to update in the subscription. + FieldMask updateMask = + FieldMask.newBuilder().addPaths("schema_settings.first_revision_id").addPaths("schema_settings.last_revision_id").build(); + + UpdateTopicRequest request = + UpdateTopicRequest.newBuilder() + .setTopic(topic) + .setUpdateMask(updateMask) + .build(); + + Topic response = topicAdminClient.updateTopic(request); + + System.out.println("Updated topic with schema: " + topic.getName()); + } + } +} +// [END pubsub_update_topic_schema] diff --git a/samples/snippets/src/main/resources/us-states-plus.avsc b/samples/snippets/src/main/resources/us-states-plus.avsc new file mode 100644 index 000000000..e3e2fbfa3 --- /dev/null +++ b/samples/snippets/src/main/resources/us-states-plus.avsc @@ -0,0 +1,24 @@ +{ + "type":"record", + "name":"State", + "namespace":"utilities", + "doc":"A list of states in the United States of America.", + "fields":[ + { + "name":"name", + "type":"string", + "doc":"The common name of the state." + }, + { + "name":"post_abbr", + "type":"string", + "doc":"The postal code abbreviation of the state." + }, + { + "name":"population", + "type":"long", + "default":0, + "doc":"The postal code abbreviation of the state." + } + ] +} diff --git a/samples/snippets/src/main/resources/us-states-plus.proto b/samples/snippets/src/main/resources/us-states-plus.proto new file mode 100644 index 000000000..646c7dcb6 --- /dev/null +++ b/samples/snippets/src/main/resources/us-states-plus.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package utilities; +option java_outer_classname = "StateProto"; + +message State { + string name = 1; + string post_abbr = 2; + int64 population = 3; +} diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index bec908800..5bc3e5848 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -26,6 +26,7 @@ import com.google.cloud.testing.junit4.MultipleAttemptsRule; import com.google.pubsub.v1.Encoding; import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.Schema; import com.google.pubsub.v1.SchemaName; import com.google.pubsub.v1.TopicName; import java.io.ByteArrayOutputStream; @@ -46,6 +47,7 @@ public class SchemaIT { private static String _suffix; private static String avroTopicId; private static String protoTopicId; + private static String protoTopicWithRevisionsId; private static String avroSubscriptionId; private static String protoSubscriptionId; private static String avroSchemaId; @@ -54,12 +56,17 @@ public class SchemaIT { ClassLoader classLoader = getClass().getClassLoader(); File avscFile = new File(classLoader.getResource("us-states.avsc").getFile()); String absoluteAvscFilePath = avscFile.getAbsolutePath(); + File avscRevisionFile = new File(classLoader.getResource("us-states-plus.avsc").getFile()); + String absoluteAvscRevisionFilePath = avscRevisionFile.getAbsolutePath(); File protoFile = new File(classLoader.getResource("us-states.proto").getFile()); String absoluteProtoFilePath = protoFile.getAbsolutePath(); + File protoRevisionFile = new File(classLoader.getResource("us-states-plus.proto").getFile()); + String absoluteProtoRevisionFilePath = protoFile.getAbsolutePath(); private static TopicName avroTopicName; private static TopicName protoTopicName; + private static TopicName protoTopicWithRevisionsName; private static ProjectSubscriptionName avroSubscriptionName; private static ProjectSubscriptionName protoSubscriptionName; private static SchemaName avroSchemaName; @@ -79,12 +86,14 @@ public void setUp() { _suffix = UUID.randomUUID().toString(); avroTopicId = "avro-topic-" + _suffix; protoTopicId = "proto-topic-" + _suffix; + protoTopicWithRevisionsId = "proto-topic-with-revisions-" + _suffix; avroSubscriptionId = "avro-subscription-" + _suffix; protoSubscriptionId = "proto-subscription-" + _suffix; avroSchemaId = "avro-schema-" + _suffix; protoSchemaId = "proto-schema-" + _suffix; avroTopicName = TopicName.of(projectId, avroTopicId); protoTopicName = TopicName.of(projectId, protoTopicId); + protoTopicWithRevisionsName = TopicName.of(projectId, protoTopicWithRevisionsId); avroSubscriptionName = ProjectSubscriptionName.of(projectId, avroSubscriptionId); protoSubscriptionName = ProjectSubscriptionName.of(projectId, protoSubscriptionId); avroSchemaName = SchemaName.of(projectId, avroSchemaId); @@ -98,26 +107,49 @@ public void setUp() { public void tearDown() throws Exception { // Delete the schemas if they have not been cleaned up. try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { - schemaServiceClient.deleteSchema(protoSchemaName); - schemaServiceClient.deleteSchema(avroSchemaName); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + schemaServiceClient.deleteSchema(protoSchemaName); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + schemaServiceClient.deleteSchema(avroSchemaName); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } // Delete the subscriptions. try (SubscriptionAdminClient subscriptionAdmin = SubscriptionAdminClient.create()) { - subscriptionAdmin.deleteSubscription(avroSubscriptionName.toString()); - subscriptionAdmin.deleteSubscription(protoSubscriptionName.toString()); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + subscriptionAdmin.deleteSubscription(avroSubscriptionName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + subscriptionAdmin.deleteSubscription(protoSubscriptionName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } // Delete the topics. try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { - topicAdminClient.deleteTopic(avroTopicName.toString()); - topicAdminClient.deleteTopic(protoTopicName.toString()); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + topicAdminClient.deleteTopic(avroTopicName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + topicAdminClient.deleteTopic(protoTopicName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + topicAdminClient.deleteTopic(protoTopicWithRevisionsName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } System.setOut(null); } @@ -125,28 +157,69 @@ public void tearDown() throws Exception { @Test public void testSchema() throws Exception { // Test creating Avro schema. - CreateAvroSchemaExample.createAvroSchemaExample(projectId, avroSchemaId, absoluteAvscFilePath); + Schema avroSchema = + CreateAvroSchemaExample.createAvroSchemaExample( + projectId, avroSchemaId, absoluteAvscFilePath); assertThat(bout.toString()).contains("Created a schema using an Avro schema:"); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test committing Avro schema. + CommitAvroSchemaExample.commitAvroSchemaExample( + projectId, avroSchemaId, absoluteAvscRevisionFilePath); + assertThat(bout.toString()).contains("Committed a schema using an Avro schema:"); + // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(avroSchemaName.toString()); + + bout.reset(); // Test creating Proto schema. - CreateProtoSchemaExample.createProtoSchemaExample( - projectId, protoSchemaId, absoluteProtoFilePath); + Schema protoSchema = + CreateProtoSchemaExample.createProtoSchemaExample( + projectId, protoSchemaId, absoluteProtoFilePath); assertThat(bout.toString()).contains("Created a schema using a protobuf schema:"); assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); + // Test committing Proto schema. + Schema protoSchemaRevision = + CommitProtoSchemaExample.commitProtoSchemaExample( + projectId, protoSchemaId, absoluteProtoRevisionFilePath); + assertThat(bout.toString()).contains("Committed a schema using a protobuf schema:"); + // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(protoSchemaName.toString()); + + bout.reset(); + // Test rolling back a schema. + RollbackSchemaExample.rollbackSchemaExample( + projectId, + protoSchemaId + "@" + protoSchema.getRevisionId(), + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Rolled back a schema:"); + // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test getting a schema. GetSchemaExample.getSchemaExample(projectId, avroSchemaId); assertThat(bout.toString()).contains("Got a schema:"); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test getting a schema revision. + GetSchemaRevisionExample.getSchemaRevisionExample( + projectId, protoSchemaId + "@" + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Got a schema:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test listing schemas. ListSchemasExample.listSchemasExample(projectId); assertThat(bout.toString()).contains("Listed schemas."); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test listing schema revisions. + ListSchemaRevisionsExample.listSchemaRevisionsExample(projectId, protoSchemaId); + assertThat(bout.toString()).contains("Listed schema revisions."); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test creating a topic with an Avro schema with BINARY encoding. CreateTopicWithSchemaExample.createTopicWithSchemaExample( @@ -159,6 +232,19 @@ public void testSchema() throws Exception { projectId, protoTopicId, protoSchemaId, Encoding.JSON); assertThat(bout.toString()).contains("Created topic with schema: " + protoTopicName.toString()); + bout.reset(); + // Test creating a topic with a proto schema with revisions specified. + CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( + projectId, + protoTopicWithRevisionsId, + protoSchemaId, + protoSchema.getRevisionId(), + protoSchemaRevision.getRevisionId(), + Encoding.BINARY); + assertThat(bout.toString()) + .contains("Created topic with schema: " + protoTopicWithRevisionsName.toString()); + + bout.reset(); // Attach a default pull subscription to each topic. CreatePullSubscriptionExample.createPullSubscriptionExample( projectId, avroSubscriptionId, avroTopicId); @@ -179,7 +265,8 @@ public void testSchema() throws Exception { bout.reset(); // Test receiving BINARY-encoded Avro records. - SubscribeWithAvroSchemaExample.subscribeWithAvroSchemaExample(projectId, avroSubscriptionId); + SubscribeWithAvroSchemaRevisionsExample.subscribeWithAvroSchemaRevisionsExample( + projectId, avroSubscriptionId); assertThat(bout.toString()).contains("Receiving a binary-encoded message:"); assertThat(bout.toString()).contains(" is abbreviated as "); @@ -189,6 +276,25 @@ public void testSchema() throws Exception { assertThat(bout.toString()).contains("Received a JSON-formatted message:"); assertThat(bout.toString()).contains("Ack'ed the message"); + bout.reset(); + // Test updating a topic schema settings + CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( + projectId, + protoTopicWithRevisionsId, + protoSchemaId, + protoSchemaRevision.getRevisionId(), + protoSchemaRevision.getRevisionId(), + Encoding.BINARY); + assertThat(bout.toString()) + .contains("Updated topic with schema: " + protoTopicWithRevisionsName.toString()); + + bout.reset(); + // Test deleting a schema revision. + DeleteSchemaRevisionExample.deleteSchemaRevisionExample( + projectId, protoSchemaId + "@" + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Deleted a schema revision:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test deleting a schema. DeleteSchemaExample.deleteSchemaExample(projectId, avroSchemaId); From e0cce5a5ab7a573444d1fe1dedeb8425b48456d0 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Mon, 23 Jan 2023 10:22:55 -0500 Subject: [PATCH 11/42] samples: schema evolution --- .../snippets/src/main/java/pubsub/CommitAvroSchemaExample.java | 2 +- .../snippets/src/main/java/pubsub/CommitProtoSchemaExample.java | 2 +- .../main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java | 2 +- .../src/main/java/pubsub/DeleteSchemaRevisionExample.java | 2 +- .../snippets/src/main/java/pubsub/GetSchemaRevisionExample.java | 2 +- .../src/main/java/pubsub/ListSchemaRevisionsExample.java | 2 +- .../snippets/src/main/java/pubsub/RollbackSchemaExample.java | 2 +- .../java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java | 2 +- .../snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java index 632dc606d..e6ac8f278 100644 --- a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java index cd7c90eb9..b32de29dc 100644 --- a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java index 58053f5f0..69322d927 100644 --- a/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java index db86e44b4..148fe391a 100644 --- a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java +++ b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java index 3136fecfc..e811ae9ff 100644 --- a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java +++ b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java index 4114a5ca8..69cfa59ab 100644 --- a/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java +++ b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java index 8ae11585d..795ba33b5 100644 --- a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java index 6e309a299..f86f05107 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java index d249ea66b..b6ec9659f 100644 --- a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 51deeb08c78e40d41218cc229c7c8fc46186dfd3 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Mon, 23 Jan 2023 12:00:54 -0500 Subject: [PATCH 12/42] Format fixes --- .../java/pubsub/UpdateTopicSchemaExample.java | 21 +++++++++---------- .../src/test/java/pubsub/SchemaIT.java | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java index b6ec9659f..d0412650b 100644 --- a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -41,8 +41,7 @@ public static void main(String... args) throws Exception { } public static void updateTopicSchemaExample( - String projectId, String topicId, String firstRevisionid, - String lastRevisionId) + String projectId, String topicId, String firstRevisionid, String lastRevisionId) throws IOException { try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { @@ -50,10 +49,10 @@ public static void updateTopicSchemaExample( // Construct the dead letter policy you expect to have after the update. SchemaSettings schemaSettings = - SchemaSettings.newBuilder() - .setFirstRevisionId(firstRevisionid) - .setLastRevisionId(lastRevisionId) - .build(); + SchemaSettings.newBuilder() + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .build(); // Construct the subscription with the dead letter policy you expect to have // after the update. Here, values in the required fields (name, topic) help @@ -66,13 +65,13 @@ public static void updateTopicSchemaExample( // Construct a field mask to indicate which field to update in the subscription. FieldMask updateMask = - FieldMask.newBuilder().addPaths("schema_settings.first_revision_id").addPaths("schema_settings.last_revision_id").build(); + FieldMask.newBuilder() + .addPaths("schema_settings.first_revision_id") + .addPaths("schema_settings.last_revision_id") + .build(); UpdateTopicRequest request = - UpdateTopicRequest.newBuilder() - .setTopic(topic) - .setUpdateMask(updateMask) - .build(); + UpdateTopicRequest.newBuilder().setTopic(topic).setUpdateMask(updateMask).build(); Topic response = topicAdminClient.updateTopic(request); diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index 5bc3e5848..3203870e3 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -276,7 +276,7 @@ public void testSchema() throws Exception { assertThat(bout.toString()).contains("Received a JSON-formatted message:"); assertThat(bout.toString()).contains("Ack'ed the message"); - bout.reset(); + bout.reset(); // Test updating a topic schema settings CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( projectId, From a53b56450bdfa977c4c0a39e517f0addfae8cff1 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Mon, 23 Jan 2023 12:16:35 -0500 Subject: [PATCH 13/42] Fix documentation for field. --- samples/snippets/src/main/resources/us-states-plus.avsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/src/main/resources/us-states-plus.avsc b/samples/snippets/src/main/resources/us-states-plus.avsc index e3e2fbfa3..74225ae7e 100644 --- a/samples/snippets/src/main/resources/us-states-plus.avsc +++ b/samples/snippets/src/main/resources/us-states-plus.avsc @@ -18,7 +18,7 @@ "name":"population", "type":"long", "default":0, - "doc":"The postal code abbreviation of the state." + "doc":"The population of the state." } ] } From f1224e6afc7590f9bd5f4d6ca72da2ec8c451528 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 26 Jan 2023 13:22:06 -0500 Subject: [PATCH 14/42] Add back in working asserts --- samples/snippets/src/test/java/pubsub/SchemaIT.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index 3203870e3..ee93d3a1a 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -168,7 +168,7 @@ public void testSchema() throws Exception { CommitAvroSchemaExample.commitAvroSchemaExample( projectId, avroSchemaId, absoluteAvscRevisionFilePath); assertThat(bout.toString()).contains("Committed a schema using an Avro schema:"); - // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(avroSchemaName.toString()); + assertThat(bout.toString()).contains(avroSchemaName.toString()); bout.reset(); // Test creating Proto schema. @@ -184,7 +184,7 @@ public void testSchema() throws Exception { CommitProtoSchemaExample.commitProtoSchemaExample( projectId, protoSchemaId, absoluteProtoRevisionFilePath); assertThat(bout.toString()).contains("Committed a schema using a protobuf schema:"); - // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(protoSchemaName.toString()); + assertThat(bout.toString()).contains(protoSchemaName.toString()); bout.reset(); // Test rolling back a schema. @@ -193,7 +193,7 @@ public void testSchema() throws Exception { protoSchemaId + "@" + protoSchema.getRevisionId(), protoSchemaRevision.getRevisionId()); assertThat(bout.toString()).contains("Rolled back a schema:"); - // ADD BACK ONCE FIXED assertThat(bout.toString()).contains(protoSchemaName.toString()); + assertThat(bout.toString()).contains(protoSchemaName.toString()); bout.reset(); // Test getting a schema. @@ -278,13 +278,11 @@ public void testSchema() throws Exception { bout.reset(); // Test updating a topic schema settings - CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( + UpdateTopicSchemaExample.updateTopicSchemaExample( projectId, protoTopicWithRevisionsId, - protoSchemaId, - protoSchemaRevision.getRevisionId(), protoSchemaRevision.getRevisionId(), - Encoding.BINARY); + protoSchemaRevision.getRevisionId()); assertThat(bout.toString()) .contains("Updated topic with schema: " + protoTopicWithRevisionsName.toString()); From de55b0537a337d7d46fae1cee0c4745f41232022 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Thu, 26 Jan 2023 16:28:59 +0000 Subject: [PATCH 15/42] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20?= =?UTF-8?q?post-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 848c0e5ee..6f543e7ff 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,8 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | --------------------------- | --------------------------------- | ------ | | Native Image Pub Sub Sample | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/native-image-sample/src/main/java/pubsub/NativeImagePubSubSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/native-image-sample/src/main/java/pubsub/NativeImagePubSubSample.java) | | Publish Operations | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/native-image-sample/src/main/java/utilities/PublishOperations.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/native-image-sample/src/main/java/utilities/PublishOperations.java) | +| Commit Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java) | +| Commit Proto Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java) | | Create Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java) | | Create Big Query Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateBigQuerySubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateBigQuerySubscriptionExample.java) | | Create Proto Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java) | @@ -253,13 +255,17 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Create Subscription With Ordering | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateSubscriptionWithOrdering.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateSubscriptionWithOrdering.java) | | Create Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicExample.java) | | Create Topic With Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaExample.java) | +| Create Topic With Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java) | | Delete Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSchemaExample.java) | +| Delete Schema Revision Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java) | | Delete Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSubscriptionExample.java) | | Delete Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteTopicExample.java) | | Detach Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DetachSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DetachSubscriptionExample.java) | | Get Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSchemaExample.java) | +| Get Schema Revision Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java) | | Get Subscription Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSubscriptionPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSubscriptionPolicyExample.java) | | Get Topic Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetTopicPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetTopicPolicyExample.java) | +| List Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java) | | List Schemas Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSchemasExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSchemasExample.java) | | List Subscriptions In Project Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSubscriptionsInProjectExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSubscriptionsInProjectExample.java) | | List Subscriptions In Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSubscriptionsInTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSubscriptionsInTopicExample.java) | @@ -278,12 +284,14 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Receive Messages With Delivery Attempts Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ReceiveMessagesWithDeliveryAttemptsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ReceiveMessagesWithDeliveryAttemptsExample.java) | | Remove Dead Letter Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/RemoveDeadLetterPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/RemoveDeadLetterPolicyExample.java) | | Resume Publish With Ordering Keys | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ResumePublishWithOrderingKeys.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ResumePublishWithOrderingKeys.java) | +| Rollback Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java) | | Set Subscription Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SetSubscriptionPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SetSubscriptionPolicyExample.java) | | Set Topic Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SetTopicPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SetTopicPolicyExample.java) | | Subscribe Async Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java) | | Subscribe Sync Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeSyncExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeSyncExample.java) | | Subscribe Sync With Lease Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeSyncWithLeaseExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeSyncWithLeaseExample.java) | | Subscribe With Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaExample.java) | +| Subscribe With Avro Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java) | | Subscribe With Concurrency Control Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithConcurrencyControlExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithConcurrencyControlExample.java) | | Subscribe With Custom Attributes Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithCustomAttributesExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithCustomAttributesExample.java) | | Subscribe With Error Listener Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithErrorListenerExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithErrorListenerExample.java) | @@ -294,6 +302,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Test Topic Permissions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/TestTopicPermissionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/TestTopicPermissionsExample.java) | | Update Dead Letter Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdateDeadLetterPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdateDeadLetterPolicyExample.java) | | Update Push Configuration Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdatePushConfigurationExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdatePushConfigurationExample.java) | +| Update Topic Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java) | | State | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/utilities/State.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/utilities/State.java) | | State Proto | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/utilities/StateProto.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/utilities/StateProto.java) | From 503339f4fc10d8a4590da42ec35f09b01e0cf7ec Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 26 Jan 2023 13:59:36 -0500 Subject: [PATCH 16/42] Formatting fixes --- samples/snippets/src/test/java/pubsub/SchemaIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index ee93d3a1a..31685db56 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -172,7 +172,7 @@ public void testSchema() throws Exception { bout.reset(); // Test creating Proto schema. - Schema protoSchema = + final Schema protoSchema = CreateProtoSchemaExample.createProtoSchemaExample( projectId, protoSchemaId, absoluteProtoFilePath); assertThat(bout.toString()).contains("Created a schema using a protobuf schema:"); @@ -180,7 +180,7 @@ public void testSchema() throws Exception { bout.reset(); // Test committing Proto schema. - Schema protoSchemaRevision = + final Schema protoSchemaRevision = CommitProtoSchemaExample.commitProtoSchemaExample( projectId, protoSchemaId, absoluteProtoRevisionFilePath); assertThat(bout.toString()).contains("Committed a schema using a protobuf schema:"); From cbd910c213fa99b67486e21ad14b7aadaffbb3a9 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 14 Feb 2023 11:35:31 -0500 Subject: [PATCH 17/42] Version/delete fixes --- .../src/main/java/pubsub/DeleteSchemaRevisionExample.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java index 148fe391a..30aa65a53 100644 --- a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java +++ b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java @@ -20,6 +20,7 @@ import com.google.api.gax.rpc.NotFoundException; import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.DeleteSchemaRevisionRequest; import com.google.pubsub.v1.SchemaName; import java.io.IOException; @@ -39,7 +40,10 @@ public static void deleteSchemaRevisionExample(String projectId, String schemaId try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { - schemaServiceClient.deleteSchema(schemaName); + DeleteSchemaRevisionRequest request = + DeleteSchemaRevisionRequest.newBuilder().setName(schemaName.toString()).build(); + + schemaServiceClient.deleteSchemaRevision(request); System.out.println("Deleted a schema revision:" + schemaName); From 1c7e8403d7cbc878470a86356a9901d37e010bbd Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 23 Feb 2023 17:47:24 -0500 Subject: [PATCH 18/42] samples: Schema evolution (#1499) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * samples: schema evolution * samples: schema evolution * Format fixes * Fix documentation for field. * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Add back in working asserts * Formatting fixes * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Version/delete fixes * samples: schema evolution * samples: schema evolution * Format fixes * Fix documentation for field. * Add back in working asserts * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Formatting fixes * Version/delete fixes --------- Co-authored-by: Owl Bot --- README.md | 9 + .../java/pubsub/CommitAvroSchemaExample.java | 69 ++++++++ .../java/pubsub/CommitProtoSchemaExample.java | 69 ++++++++ .../java/pubsub/CreateAvroSchemaExample.java | 4 +- .../java/pubsub/CreateProtoSchemaExample.java | 4 +- ...CreateTopicWithSchemaRevisionsExample.java | 82 +++++++++ .../pubsub/DeleteSchemaRevisionExample.java | 55 ++++++ .../java/pubsub/GetSchemaRevisionExample.java | 52 ++++++ .../pubsub/ListSchemaRevisionsExample.java | 46 +++++ .../java/pubsub/RollbackSchemaExample.java | 53 ++++++ ...bscribeWithAvroSchemaRevisionsExample.java | 158 ++++++++++++++++++ .../java/pubsub/UpdateTopicSchemaExample.java | 82 +++++++++ .../src/main/resources/us-states-plus.avsc | 24 +++ .../src/main/resources/us-states-plus.proto | 10 ++ .../src/test/java/pubsub/SchemaIT.java | 136 +++++++++++++-- 15 files changed, 835 insertions(+), 18 deletions(-) create mode 100644 samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java create mode 100644 samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java create mode 100644 samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java create mode 100644 samples/snippets/src/main/resources/us-states-plus.avsc create mode 100644 samples/snippets/src/main/resources/us-states-plus.proto diff --git a/README.md b/README.md index 848c0e5ee..6f543e7ff 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,8 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | --------------------------- | --------------------------------- | ------ | | Native Image Pub Sub Sample | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/native-image-sample/src/main/java/pubsub/NativeImagePubSubSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/native-image-sample/src/main/java/pubsub/NativeImagePubSubSample.java) | | Publish Operations | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/native-image-sample/src/main/java/utilities/PublishOperations.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/native-image-sample/src/main/java/utilities/PublishOperations.java) | +| Commit Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java) | +| Commit Proto Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java) | | Create Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java) | | Create Big Query Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateBigQuerySubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateBigQuerySubscriptionExample.java) | | Create Proto Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java) | @@ -253,13 +255,17 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Create Subscription With Ordering | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateSubscriptionWithOrdering.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateSubscriptionWithOrdering.java) | | Create Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicExample.java) | | Create Topic With Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaExample.java) | +| Create Topic With Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java) | | Delete Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSchemaExample.java) | +| Delete Schema Revision Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java) | | Delete Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSubscriptionExample.java) | | Delete Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteTopicExample.java) | | Detach Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DetachSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DetachSubscriptionExample.java) | | Get Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSchemaExample.java) | +| Get Schema Revision Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java) | | Get Subscription Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSubscriptionPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSubscriptionPolicyExample.java) | | Get Topic Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetTopicPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetTopicPolicyExample.java) | +| List Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java) | | List Schemas Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSchemasExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSchemasExample.java) | | List Subscriptions In Project Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSubscriptionsInProjectExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSubscriptionsInProjectExample.java) | | List Subscriptions In Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSubscriptionsInTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSubscriptionsInTopicExample.java) | @@ -278,12 +284,14 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Receive Messages With Delivery Attempts Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ReceiveMessagesWithDeliveryAttemptsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ReceiveMessagesWithDeliveryAttemptsExample.java) | | Remove Dead Letter Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/RemoveDeadLetterPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/RemoveDeadLetterPolicyExample.java) | | Resume Publish With Ordering Keys | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ResumePublishWithOrderingKeys.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ResumePublishWithOrderingKeys.java) | +| Rollback Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java) | | Set Subscription Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SetSubscriptionPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SetSubscriptionPolicyExample.java) | | Set Topic Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SetTopicPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SetTopicPolicyExample.java) | | Subscribe Async Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java) | | Subscribe Sync Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeSyncExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeSyncExample.java) | | Subscribe Sync With Lease Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeSyncWithLeaseExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeSyncWithLeaseExample.java) | | Subscribe With Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaExample.java) | +| Subscribe With Avro Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java) | | Subscribe With Concurrency Control Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithConcurrencyControlExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithConcurrencyControlExample.java) | | Subscribe With Custom Attributes Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithCustomAttributesExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithCustomAttributesExample.java) | | Subscribe With Error Listener Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithErrorListenerExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithErrorListenerExample.java) | @@ -294,6 +302,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Test Topic Permissions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/TestTopicPermissionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/TestTopicPermissionsExample.java) | | Update Dead Letter Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdateDeadLetterPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdateDeadLetterPolicyExample.java) | | Update Push Configuration Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdatePushConfigurationExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdatePushConfigurationExample.java) | +| Update Topic Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java) | | State | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/utilities/State.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/utilities/State.java) | | State Proto | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/utilities/StateProto.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/utilities/StateProto.java) | diff --git a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java new file mode 100644 index 000000000..e6ac8f278 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_commit_avro_schema] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.ProjectName; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class CommitAvroSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + String avscFile = "path/to/an/avro/schema/file/(.avsc)/formatted/in/json"; + + commitAvroSchemaExample(projectId, schemaId, avscFile); + } + + public static Schema commitAvroSchemaExample(String projectId, String schemaId, String avscFile) + throws IOException { + + ProjectName projectName = ProjectName.of(projectId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + // Read an Avro schema file formatted in JSON as a string. + String avscSource = new String(Files.readAllBytes(Paths.get(avscFile))); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = + schemaServiceClient.commitSchema( + schemaName.toString(), + Schema.newBuilder() + .setName(schemaName.toString()) + .setType(Schema.Type.AVRO) + .setDefinition(avscSource) + .build()); + + System.out.println("Committed a schema using an Avro schema:\n" + schema); + return schema; + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + return null; + } + } +} +// [END pubsub_commit_avro_schema] diff --git a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java new file mode 100644 index 000000000..b32de29dc --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_commit_proto_schema] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.ProjectName; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class CommitProtoSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + String protoFile = "path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers"; + + commitProtoSchemaExample(projectId, schemaId, protoFile); + } + + public static Schema commitProtoSchemaExample(String projectId, String schemaId, String protoFile) + throws IOException { + + ProjectName projectName = ProjectName.of(projectId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + // Read a proto file as a string. + String protoSource = new String(Files.readAllBytes(Paths.get(protoFile))); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = + schemaServiceClient.commitSchema( + schemaName.toString(), + Schema.newBuilder() + .setName(schemaName.toString()) + .setType(Schema.Type.PROTOCOL_BUFFER) + .setDefinition(protoSource) + .build()); + + System.out.println("Committed a schema using a protobuf schema:\n" + schema); + return schema; + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + return null; + } + } +} +// [END pubsub_commit_proto_schema] diff --git a/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java index 1b93b7fbe..393b128b3 100644 --- a/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java @@ -38,7 +38,7 @@ public static void main(String... args) throws Exception { createAvroSchemaExample(projectId, schemaId, avscFile); } - public static void createAvroSchemaExample(String projectId, String schemaId, String avscFile) + public static Schema createAvroSchemaExample(String projectId, String schemaId, String avscFile) throws IOException { ProjectName projectName = ProjectName.of(projectId); @@ -60,8 +60,10 @@ public static void createAvroSchemaExample(String projectId, String schemaId, St schemaId); System.out.println("Created a schema using an Avro schema:\n" + schema); + return schema; } catch (AlreadyExistsException e) { System.out.println(schemaName + "already exists."); + return null; } } } diff --git a/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java index a8efdeb8e..e7b5bf113 100644 --- a/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java @@ -38,7 +38,7 @@ public static void main(String... args) throws Exception { createProtoSchemaExample(projectId, schemaId, protoFile); } - public static void createProtoSchemaExample(String projectId, String schemaId, String protoFile) + public static Schema createProtoSchemaExample(String projectId, String schemaId, String protoFile) throws IOException { ProjectName projectName = ProjectName.of(projectId); @@ -60,8 +60,10 @@ public static void createProtoSchemaExample(String projectId, String schemaId, S schemaId); System.out.println("Created a schema using a protobuf schema:\n" + schema); + return schema; } catch (AlreadyExistsException e) { System.out.println(schemaName + "already exists."); + return null; } } } diff --git a/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java new file mode 100644 index 000000000..69322d927 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java @@ -0,0 +1,82 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_create_topic_with_schema_revisions] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.pubsub.v1.Encoding; +import com.google.pubsub.v1.SchemaName; +import com.google.pubsub.v1.SchemaSettings; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.TopicName; +import java.io.IOException; + +public class CreateTopicWithSchemaRevisionsExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String topicId = "your-topic-id"; + // Use an existing schema. + String schemaId = "your-schema-id"; + // Choose either BINARY or JSON message serialization in this topic. + Encoding encoding = Encoding.BINARY; + // Set the minimum and maximum revsion ID + String firstRevisionId = "your-revision-id"; + String lastRevisionId = "your-revision-id"; + + createTopicWithSchemaRevisionsExample( + projectId, topicId, schemaId, firstRevisionId, lastRevisionId, encoding); + } + + public static void createTopicWithSchemaRevisionsExample( + String projectId, + String topicId, + String schemaId, + String firstRevisionid, + String lastRevisionId, + Encoding encoding) + throws IOException { + TopicName topicName = TopicName.of(projectId, topicId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + SchemaSettings schemaSettings = + SchemaSettings.newBuilder() + .setSchema(schemaName.toString()) + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .setEncoding(encoding) + .build(); + + try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { + + Topic topic = + topicAdminClient.createTopic( + Topic.newBuilder() + .setName(topicName.toString()) + .setSchemaSettings(schemaSettings) + .build()); + + System.out.println("Created topic with schema: " + topic.getName()); + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + } + } +} +// [END pubsub_create_topic_with_schema_revisions] diff --git a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java new file mode 100644 index 000000000..30aa65a53 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java @@ -0,0 +1,55 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_delete_schema_revision] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.DeleteSchemaRevisionRequest; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class DeleteSchemaRevisionExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id@your-revision-id"; + + deleteSchemaRevisionExample(projectId, schemaId); + } + + public static void deleteSchemaRevisionExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + DeleteSchemaRevisionRequest request = + DeleteSchemaRevisionRequest.newBuilder().setName(schemaName.toString()).build(); + + schemaServiceClient.deleteSchemaRevision(request); + + System.out.println("Deleted a schema revision:" + schemaName); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_delete_schema_revision] diff --git a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java new file mode 100644 index 000000000..e811ae9ff --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java @@ -0,0 +1,52 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_get_schema_revision] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class GetSchemaRevisionExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id@your-schema-revision"; + + getSchemaRevisionExample(projectId, schemaId); + } + + public static void getSchemaRevisionExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = schemaServiceClient.getSchema(schemaName); + + System.out.println("Got a schema:\n" + schema); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_get_schema_revision] diff --git a/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java new file mode 100644 index 000000000..69cfa59ab --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java @@ -0,0 +1,46 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_list_schema_revisions] +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class ListSchemaRevisionsExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + + listSchemaRevisionsExample(projectId, schemaId); + } + + public static void listSchemaRevisionsExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + for (Schema schema : schemaServiceClient.listSchemaRevisions(schemaName).iterateAll()) { + System.out.println(schema); + } + System.out.println("Listed schema revisions."); + } + } +} +// [END pubsub_list_schema_revisions] diff --git a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java new file mode 100644 index 000000000..795ba33b5 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java @@ -0,0 +1,53 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_rollback_schema] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class RollbackSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project"; + String schemaId = "your-schema@your-revision"; + String revisionId = "your-revision"; + + rollbackSchemaExample(projectId, schemaId, revisionId); + } + + public static void rollbackSchemaExample(String projectId, String schemaId, String revisionId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = schemaServiceClient.rollbackSchema(schemaName, revisionId); + + System.out.println("Rolled back a schema:" + schema); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_rollback_schema] diff --git a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java new file mode 100644 index 000000000..f86f05107 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java @@ -0,0 +1,158 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_subscribe_avro_records_with_revisions] + +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.protobuf.ByteString; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import com.google.pubsub.v1.Schema; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.apache.avro.io.Decoder; +import org.apache.avro.io.DecoderFactory; +import org.apache.avro.specific.SpecificDatumReader; +import utilities.State; + +public class SubscribeWithAvroSchemaRevisionsExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + // Use an existing subscription. + String subscriptionId = "your-subscription-id"; + + subscribeWithAvroSchemaRevisionsExample(projectId, subscriptionId); + } + + static SchemaServiceClient getSchemaServiceClient() { + try { + return SchemaServiceClient.create(); + } catch (IOException e) { + System.out.println("Could not get schema client: " + e); + return null; + } + } + + public static void subscribeWithAvroSchemaRevisionsExample( + String projectId, String subscriptionId) { + // Used to get the schemas for revsions. + final SchemaServiceClient schemaServiceClient = getSchemaServiceClient(); + if (schemaServiceClient == null) { + return; + } + + // Cache for the readers for different revision IDs. + Map> revisionReaders = + new HashMap>(); + + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId); + + // Instantiate an asynchronous message receiver. + MessageReceiver receiver = + (PubsubMessage message, AckReplyConsumer consumer) -> { + // Get the schema encoding type. + String name = message.getAttributesMap().get("googclient_schemaname"); + String revision = message.getAttributesMap().get("googclient_schemarevisionid"); + + SpecificDatumReader reader = null; + synchronized (revisionReaders) { + reader = revisionReaders.get(revision); + } + if (reader == null) { + // This is the first time we are seeing this revision. We need to + // fetch the schema and cache its decoder. It would be more typical + // to do this asynchronously, but it shown here in a synchronous + // way to ease readability. + try { + Schema schema = schemaServiceClient.getSchema(name + "@" + revision); + org.apache.avro.Schema avroSchema = + new org.apache.avro.Schema.Parser().parse(schema.getDefinition()); + reader = new SpecificDatumReader(State.getClassSchema(), avroSchema); + synchronized (revisionReaders) { + revisionReaders.put(revision, reader); + } + } catch (Exception e) { + System.out.println("Could not get schema: " + e); + // Without the schema, we cannot read the message, so nack it. + consumer.nack(); + return; + } + } + + ByteString data = message.getData(); + // Send the message data to a byte[] input stream. + InputStream inputStream = new ByteArrayInputStream(data.toByteArray()); + + String encoding = message.getAttributesMap().get("googclient_schemaencoding"); + + Decoder decoder = null; + + // Prepare an appropriate decoder for the message data in the input stream + // based on the schema encoding type. + try { + switch (encoding) { + case "BINARY": + decoder = DecoderFactory.get().directBinaryDecoder(inputStream, /*reuse=*/ null); + System.out.println("Receiving a binary-encoded message:"); + break; + case "JSON": + decoder = DecoderFactory.get().jsonDecoder(State.getClassSchema(), inputStream); + System.out.println("Receiving a JSON-encoded message:"); + break; + default: + System.out.println("Unknown message type; nacking."); + consumer.nack(); + break; + } + + // Obtain an object of the generated Avro class using the decoder. + State state = reader.read(null, decoder); + System.out.println(state.getName() + " is abbreviated as " + state.getPostAbbr()); + + // Ack the message. + consumer.ack(); + } catch (IOException e) { + System.err.println(e); + // If we failed to process the message, nack it. + consumer.nack(); + } + }; + + Subscriber subscriber = null; + try { + subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); + subscriber.startAsync().awaitRunning(); + System.out.printf("Listening for messages on %s:\n", subscriptionName.toString()); + subscriber.awaitTerminated(30, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { + subscriber.stopAsync(); + } + } +} +// [END pubsub_subscribe_avro_records_with_revisions] diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java new file mode 100644 index 000000000..d0412650b --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -0,0 +1,82 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_update_topic_schema] + +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.protobuf.FieldMask; +import com.google.pubsub.v1.SchemaSettings; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.TopicName; +import com.google.pubsub.v1.UpdateTopicRequest; +import java.io.IOException; + +public class UpdateTopicSchemaExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + // This is an existing topic that has schema settings attached to it. + String topicId = "your-topic-id"; + // Set the minimum and maximum revsion ID + String firstRevisionId = "your-revision-id"; + String lastRevisionId = "your-revision-id"; + + UpdateTopicSchemaExample.updateTopicSchemaExample( + projectId, topicId, firstRevisionId, lastRevisionId); + } + + public static void updateTopicSchemaExample( + String projectId, String topicId, String firstRevisionid, String lastRevisionId) + throws IOException { + try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { + + TopicName topicName = TopicName.of(projectId, topicId); + + // Construct the dead letter policy you expect to have after the update. + SchemaSettings schemaSettings = + SchemaSettings.newBuilder() + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .build(); + + // Construct the subscription with the dead letter policy you expect to have + // after the update. Here, values in the required fields (name, topic) help + // identify the subscription. + Topic topic = + Topic.newBuilder() + .setName(topicName.toString()) + .setSchemaSettings(schemaSettings) + .build(); + + // Construct a field mask to indicate which field to update in the subscription. + FieldMask updateMask = + FieldMask.newBuilder() + .addPaths("schema_settings.first_revision_id") + .addPaths("schema_settings.last_revision_id") + .build(); + + UpdateTopicRequest request = + UpdateTopicRequest.newBuilder().setTopic(topic).setUpdateMask(updateMask).build(); + + Topic response = topicAdminClient.updateTopic(request); + + System.out.println("Updated topic with schema: " + topic.getName()); + } + } +} +// [END pubsub_update_topic_schema] diff --git a/samples/snippets/src/main/resources/us-states-plus.avsc b/samples/snippets/src/main/resources/us-states-plus.avsc new file mode 100644 index 000000000..74225ae7e --- /dev/null +++ b/samples/snippets/src/main/resources/us-states-plus.avsc @@ -0,0 +1,24 @@ +{ + "type":"record", + "name":"State", + "namespace":"utilities", + "doc":"A list of states in the United States of America.", + "fields":[ + { + "name":"name", + "type":"string", + "doc":"The common name of the state." + }, + { + "name":"post_abbr", + "type":"string", + "doc":"The postal code abbreviation of the state." + }, + { + "name":"population", + "type":"long", + "default":0, + "doc":"The population of the state." + } + ] +} diff --git a/samples/snippets/src/main/resources/us-states-plus.proto b/samples/snippets/src/main/resources/us-states-plus.proto new file mode 100644 index 000000000..646c7dcb6 --- /dev/null +++ b/samples/snippets/src/main/resources/us-states-plus.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package utilities; +option java_outer_classname = "StateProto"; + +message State { + string name = 1; + string post_abbr = 2; + int64 population = 3; +} diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index bec908800..31685db56 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -26,6 +26,7 @@ import com.google.cloud.testing.junit4.MultipleAttemptsRule; import com.google.pubsub.v1.Encoding; import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.Schema; import com.google.pubsub.v1.SchemaName; import com.google.pubsub.v1.TopicName; import java.io.ByteArrayOutputStream; @@ -46,6 +47,7 @@ public class SchemaIT { private static String _suffix; private static String avroTopicId; private static String protoTopicId; + private static String protoTopicWithRevisionsId; private static String avroSubscriptionId; private static String protoSubscriptionId; private static String avroSchemaId; @@ -54,12 +56,17 @@ public class SchemaIT { ClassLoader classLoader = getClass().getClassLoader(); File avscFile = new File(classLoader.getResource("us-states.avsc").getFile()); String absoluteAvscFilePath = avscFile.getAbsolutePath(); + File avscRevisionFile = new File(classLoader.getResource("us-states-plus.avsc").getFile()); + String absoluteAvscRevisionFilePath = avscRevisionFile.getAbsolutePath(); File protoFile = new File(classLoader.getResource("us-states.proto").getFile()); String absoluteProtoFilePath = protoFile.getAbsolutePath(); + File protoRevisionFile = new File(classLoader.getResource("us-states-plus.proto").getFile()); + String absoluteProtoRevisionFilePath = protoFile.getAbsolutePath(); private static TopicName avroTopicName; private static TopicName protoTopicName; + private static TopicName protoTopicWithRevisionsName; private static ProjectSubscriptionName avroSubscriptionName; private static ProjectSubscriptionName protoSubscriptionName; private static SchemaName avroSchemaName; @@ -79,12 +86,14 @@ public void setUp() { _suffix = UUID.randomUUID().toString(); avroTopicId = "avro-topic-" + _suffix; protoTopicId = "proto-topic-" + _suffix; + protoTopicWithRevisionsId = "proto-topic-with-revisions-" + _suffix; avroSubscriptionId = "avro-subscription-" + _suffix; protoSubscriptionId = "proto-subscription-" + _suffix; avroSchemaId = "avro-schema-" + _suffix; protoSchemaId = "proto-schema-" + _suffix; avroTopicName = TopicName.of(projectId, avroTopicId); protoTopicName = TopicName.of(projectId, protoTopicId); + protoTopicWithRevisionsName = TopicName.of(projectId, protoTopicWithRevisionsId); avroSubscriptionName = ProjectSubscriptionName.of(projectId, avroSubscriptionId); protoSubscriptionName = ProjectSubscriptionName.of(projectId, protoSubscriptionId); avroSchemaName = SchemaName.of(projectId, avroSchemaId); @@ -98,26 +107,49 @@ public void setUp() { public void tearDown() throws Exception { // Delete the schemas if they have not been cleaned up. try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { - schemaServiceClient.deleteSchema(protoSchemaName); - schemaServiceClient.deleteSchema(avroSchemaName); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + schemaServiceClient.deleteSchema(protoSchemaName); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + schemaServiceClient.deleteSchema(avroSchemaName); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } // Delete the subscriptions. try (SubscriptionAdminClient subscriptionAdmin = SubscriptionAdminClient.create()) { - subscriptionAdmin.deleteSubscription(avroSubscriptionName.toString()); - subscriptionAdmin.deleteSubscription(protoSubscriptionName.toString()); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + subscriptionAdmin.deleteSubscription(avroSubscriptionName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + subscriptionAdmin.deleteSubscription(protoSubscriptionName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } // Delete the topics. try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { - topicAdminClient.deleteTopic(avroTopicName.toString()); - topicAdminClient.deleteTopic(protoTopicName.toString()); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + topicAdminClient.deleteTopic(avroTopicName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + topicAdminClient.deleteTopic(protoTopicName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + topicAdminClient.deleteTopic(protoTopicWithRevisionsName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } System.setOut(null); } @@ -125,28 +157,69 @@ public void tearDown() throws Exception { @Test public void testSchema() throws Exception { // Test creating Avro schema. - CreateAvroSchemaExample.createAvroSchemaExample(projectId, avroSchemaId, absoluteAvscFilePath); + Schema avroSchema = + CreateAvroSchemaExample.createAvroSchemaExample( + projectId, avroSchemaId, absoluteAvscFilePath); assertThat(bout.toString()).contains("Created a schema using an Avro schema:"); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test committing Avro schema. + CommitAvroSchemaExample.commitAvroSchemaExample( + projectId, avroSchemaId, absoluteAvscRevisionFilePath); + assertThat(bout.toString()).contains("Committed a schema using an Avro schema:"); + assertThat(bout.toString()).contains(avroSchemaName.toString()); + + bout.reset(); // Test creating Proto schema. - CreateProtoSchemaExample.createProtoSchemaExample( - projectId, protoSchemaId, absoluteProtoFilePath); + final Schema protoSchema = + CreateProtoSchemaExample.createProtoSchemaExample( + projectId, protoSchemaId, absoluteProtoFilePath); assertThat(bout.toString()).contains("Created a schema using a protobuf schema:"); assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); + // Test committing Proto schema. + final Schema protoSchemaRevision = + CommitProtoSchemaExample.commitProtoSchemaExample( + projectId, protoSchemaId, absoluteProtoRevisionFilePath); + assertThat(bout.toString()).contains("Committed a schema using a protobuf schema:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + + bout.reset(); + // Test rolling back a schema. + RollbackSchemaExample.rollbackSchemaExample( + projectId, + protoSchemaId + "@" + protoSchema.getRevisionId(), + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Rolled back a schema:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test getting a schema. GetSchemaExample.getSchemaExample(projectId, avroSchemaId); assertThat(bout.toString()).contains("Got a schema:"); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test getting a schema revision. + GetSchemaRevisionExample.getSchemaRevisionExample( + projectId, protoSchemaId + "@" + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Got a schema:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test listing schemas. ListSchemasExample.listSchemasExample(projectId); assertThat(bout.toString()).contains("Listed schemas."); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test listing schema revisions. + ListSchemaRevisionsExample.listSchemaRevisionsExample(projectId, protoSchemaId); + assertThat(bout.toString()).contains("Listed schema revisions."); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test creating a topic with an Avro schema with BINARY encoding. CreateTopicWithSchemaExample.createTopicWithSchemaExample( @@ -159,6 +232,19 @@ public void testSchema() throws Exception { projectId, protoTopicId, protoSchemaId, Encoding.JSON); assertThat(bout.toString()).contains("Created topic with schema: " + protoTopicName.toString()); + bout.reset(); + // Test creating a topic with a proto schema with revisions specified. + CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( + projectId, + protoTopicWithRevisionsId, + protoSchemaId, + protoSchema.getRevisionId(), + protoSchemaRevision.getRevisionId(), + Encoding.BINARY); + assertThat(bout.toString()) + .contains("Created topic with schema: " + protoTopicWithRevisionsName.toString()); + + bout.reset(); // Attach a default pull subscription to each topic. CreatePullSubscriptionExample.createPullSubscriptionExample( projectId, avroSubscriptionId, avroTopicId); @@ -179,7 +265,8 @@ public void testSchema() throws Exception { bout.reset(); // Test receiving BINARY-encoded Avro records. - SubscribeWithAvroSchemaExample.subscribeWithAvroSchemaExample(projectId, avroSubscriptionId); + SubscribeWithAvroSchemaRevisionsExample.subscribeWithAvroSchemaRevisionsExample( + projectId, avroSubscriptionId); assertThat(bout.toString()).contains("Receiving a binary-encoded message:"); assertThat(bout.toString()).contains(" is abbreviated as "); @@ -189,6 +276,23 @@ public void testSchema() throws Exception { assertThat(bout.toString()).contains("Received a JSON-formatted message:"); assertThat(bout.toString()).contains("Ack'ed the message"); + bout.reset(); + // Test updating a topic schema settings + UpdateTopicSchemaExample.updateTopicSchemaExample( + projectId, + protoTopicWithRevisionsId, + protoSchemaRevision.getRevisionId(), + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()) + .contains("Updated topic with schema: " + protoTopicWithRevisionsName.toString()); + + bout.reset(); + // Test deleting a schema revision. + DeleteSchemaRevisionExample.deleteSchemaRevisionExample( + projectId, protoSchemaId + "@" + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Deleted a schema revision:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test deleting a schema. DeleteSchemaExample.deleteSchemaExample(projectId, avroSchemaId); From 6195b1ce922b5f7123d998ae308c828127f854b9 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 23 Feb 2023 18:20:26 -0500 Subject: [PATCH 19/42] Minor fixes for comments --- .../src/main/java/pubsub/GetSchemaRevisionExample.java | 2 +- .../src/main/java/pubsub/UpdateTopicSchemaExample.java | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java index e811ae9ff..a4d8feee9 100644 --- a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java +++ b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java @@ -29,7 +29,7 @@ public class GetSchemaRevisionExample { public static void main(String... args) throws Exception { // TODO(developer): Replace these variables before running the sample. String projectId = "your-project-id"; - String schemaId = "your-schema-id@your-schema-revision"; + String schemaId = "your-schema-id[@your-schema-revision]"; getSchemaRevisionExample(projectId, schemaId); } diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java index d0412650b..01f7c6580 100644 --- a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -47,16 +47,14 @@ public static void updateTopicSchemaExample( TopicName topicName = TopicName.of(projectId, topicId); - // Construct the dead letter policy you expect to have after the update. + // Construct the schema settings with the changes you want to make. SchemaSettings schemaSettings = SchemaSettings.newBuilder() .setFirstRevisionId(firstRevisionid) .setLastRevisionId(lastRevisionId) .build(); - // Construct the subscription with the dead letter policy you expect to have - // after the update. Here, values in the required fields (name, topic) help - // identify the subscription. + // Construct the subscription with the schema settings you want to change. Topic topic = Topic.newBuilder() .setName(topicName.toString()) From 18e9c3bde7181f7f24afc87e60ebfd05eb80e368 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 23 Feb 2023 17:47:24 -0500 Subject: [PATCH 20/42] samples: Schema evolution (#1499) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * samples: schema evolution * samples: schema evolution * Format fixes * Fix documentation for field. * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Add back in working asserts * Formatting fixes * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Version/delete fixes * samples: schema evolution * samples: schema evolution * Format fixes * Fix documentation for field. * Add back in working asserts * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * Formatting fixes * Version/delete fixes --------- Co-authored-by: Owl Bot --- README.md | 9 + .../java/pubsub/CommitAvroSchemaExample.java | 69 ++++++++ .../java/pubsub/CommitProtoSchemaExample.java | 69 ++++++++ .../java/pubsub/CreateAvroSchemaExample.java | 4 +- .../java/pubsub/CreateProtoSchemaExample.java | 4 +- ...CreateTopicWithSchemaRevisionsExample.java | 82 +++++++++ .../pubsub/DeleteSchemaRevisionExample.java | 55 ++++++ .../java/pubsub/GetSchemaRevisionExample.java | 52 ++++++ .../pubsub/ListSchemaRevisionsExample.java | 46 +++++ .../java/pubsub/RollbackSchemaExample.java | 53 ++++++ ...bscribeWithAvroSchemaRevisionsExample.java | 158 ++++++++++++++++++ .../java/pubsub/UpdateTopicSchemaExample.java | 82 +++++++++ .../src/main/resources/us-states-plus.avsc | 24 +++ .../src/main/resources/us-states-plus.proto | 10 ++ .../src/test/java/pubsub/SchemaIT.java | 136 +++++++++++++-- 15 files changed, 835 insertions(+), 18 deletions(-) create mode 100644 samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java create mode 100644 samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java create mode 100644 samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java create mode 100644 samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java create mode 100644 samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java create mode 100644 samples/snippets/src/main/resources/us-states-plus.avsc create mode 100644 samples/snippets/src/main/resources/us-states-plus.proto diff --git a/README.md b/README.md index 848c0e5ee..6f543e7ff 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,8 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | --------------------------- | --------------------------------- | ------ | | Native Image Pub Sub Sample | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/native-image-sample/src/main/java/pubsub/NativeImagePubSubSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/native-image-sample/src/main/java/pubsub/NativeImagePubSubSample.java) | | Publish Operations | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/native-image-sample/src/main/java/utilities/PublishOperations.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/native-image-sample/src/main/java/utilities/PublishOperations.java) | +| Commit Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java) | +| Commit Proto Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java) | | Create Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java) | | Create Big Query Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateBigQuerySubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateBigQuerySubscriptionExample.java) | | Create Proto Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java) | @@ -253,13 +255,17 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Create Subscription With Ordering | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateSubscriptionWithOrdering.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateSubscriptionWithOrdering.java) | | Create Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicExample.java) | | Create Topic With Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaExample.java) | +| Create Topic With Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java) | | Delete Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSchemaExample.java) | +| Delete Schema Revision Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java) | | Delete Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteSubscriptionExample.java) | | Delete Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DeleteTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DeleteTopicExample.java) | | Detach Subscription Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/DetachSubscriptionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/DetachSubscriptionExample.java) | | Get Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSchemaExample.java) | +| Get Schema Revision Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java) | | Get Subscription Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetSubscriptionPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetSubscriptionPolicyExample.java) | | Get Topic Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/GetTopicPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/GetTopicPolicyExample.java) | +| List Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java) | | List Schemas Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSchemasExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSchemasExample.java) | | List Subscriptions In Project Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSubscriptionsInProjectExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSubscriptionsInProjectExample.java) | | List Subscriptions In Topic Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ListSubscriptionsInTopicExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ListSubscriptionsInTopicExample.java) | @@ -278,12 +284,14 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Receive Messages With Delivery Attempts Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ReceiveMessagesWithDeliveryAttemptsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ReceiveMessagesWithDeliveryAttemptsExample.java) | | Remove Dead Letter Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/RemoveDeadLetterPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/RemoveDeadLetterPolicyExample.java) | | Resume Publish With Ordering Keys | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/ResumePublishWithOrderingKeys.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/ResumePublishWithOrderingKeys.java) | +| Rollback Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java) | | Set Subscription Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SetSubscriptionPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SetSubscriptionPolicyExample.java) | | Set Topic Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SetTopicPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SetTopicPolicyExample.java) | | Subscribe Async Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java) | | Subscribe Sync Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeSyncExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeSyncExample.java) | | Subscribe Sync With Lease Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeSyncWithLeaseExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeSyncWithLeaseExample.java) | | Subscribe With Avro Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaExample.java) | +| Subscribe With Avro Schema Revisions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java) | | Subscribe With Concurrency Control Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithConcurrencyControlExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithConcurrencyControlExample.java) | | Subscribe With Custom Attributes Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithCustomAttributesExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithCustomAttributesExample.java) | | Subscribe With Error Listener Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/SubscribeWithErrorListenerExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/SubscribeWithErrorListenerExample.java) | @@ -294,6 +302,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-pubsub/tree/m | Test Topic Permissions Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/TestTopicPermissionsExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/TestTopicPermissionsExample.java) | | Update Dead Letter Policy Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdateDeadLetterPolicyExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdateDeadLetterPolicyExample.java) | | Update Push Configuration Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdatePushConfigurationExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdatePushConfigurationExample.java) | +| Update Topic Schema Example | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java) | | State | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/utilities/State.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/utilities/State.java) | | State Proto | [source code](https://github.com/googleapis/java-pubsub/blob/main/samples/snippets/src/main/java/utilities/StateProto.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-pubsub&page=editor&open_in_editor=samples/snippets/src/main/java/utilities/StateProto.java) | diff --git a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java new file mode 100644 index 000000000..e6ac8f278 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_commit_avro_schema] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.ProjectName; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class CommitAvroSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + String avscFile = "path/to/an/avro/schema/file/(.avsc)/formatted/in/json"; + + commitAvroSchemaExample(projectId, schemaId, avscFile); + } + + public static Schema commitAvroSchemaExample(String projectId, String schemaId, String avscFile) + throws IOException { + + ProjectName projectName = ProjectName.of(projectId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + // Read an Avro schema file formatted in JSON as a string. + String avscSource = new String(Files.readAllBytes(Paths.get(avscFile))); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = + schemaServiceClient.commitSchema( + schemaName.toString(), + Schema.newBuilder() + .setName(schemaName.toString()) + .setType(Schema.Type.AVRO) + .setDefinition(avscSource) + .build()); + + System.out.println("Committed a schema using an Avro schema:\n" + schema); + return schema; + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + return null; + } + } +} +// [END pubsub_commit_avro_schema] diff --git a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java new file mode 100644 index 000000000..b32de29dc --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java @@ -0,0 +1,69 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_commit_proto_schema] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.ProjectName; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class CommitProtoSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + String protoFile = "path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers"; + + commitProtoSchemaExample(projectId, schemaId, protoFile); + } + + public static Schema commitProtoSchemaExample(String projectId, String schemaId, String protoFile) + throws IOException { + + ProjectName projectName = ProjectName.of(projectId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + // Read a proto file as a string. + String protoSource = new String(Files.readAllBytes(Paths.get(protoFile))); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = + schemaServiceClient.commitSchema( + schemaName.toString(), + Schema.newBuilder() + .setName(schemaName.toString()) + .setType(Schema.Type.PROTOCOL_BUFFER) + .setDefinition(protoSource) + .build()); + + System.out.println("Committed a schema using a protobuf schema:\n" + schema); + return schema; + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + return null; + } + } +} +// [END pubsub_commit_proto_schema] diff --git a/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java index 1b93b7fbe..393b128b3 100644 --- a/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateAvroSchemaExample.java @@ -38,7 +38,7 @@ public static void main(String... args) throws Exception { createAvroSchemaExample(projectId, schemaId, avscFile); } - public static void createAvroSchemaExample(String projectId, String schemaId, String avscFile) + public static Schema createAvroSchemaExample(String projectId, String schemaId, String avscFile) throws IOException { ProjectName projectName = ProjectName.of(projectId); @@ -60,8 +60,10 @@ public static void createAvroSchemaExample(String projectId, String schemaId, St schemaId); System.out.println("Created a schema using an Avro schema:\n" + schema); + return schema; } catch (AlreadyExistsException e) { System.out.println(schemaName + "already exists."); + return null; } } } diff --git a/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java index a8efdeb8e..e7b5bf113 100644 --- a/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CreateProtoSchemaExample.java @@ -38,7 +38,7 @@ public static void main(String... args) throws Exception { createProtoSchemaExample(projectId, schemaId, protoFile); } - public static void createProtoSchemaExample(String projectId, String schemaId, String protoFile) + public static Schema createProtoSchemaExample(String projectId, String schemaId, String protoFile) throws IOException { ProjectName projectName = ProjectName.of(projectId); @@ -60,8 +60,10 @@ public static void createProtoSchemaExample(String projectId, String schemaId, S schemaId); System.out.println("Created a schema using a protobuf schema:\n" + schema); + return schema; } catch (AlreadyExistsException e) { System.out.println(schemaName + "already exists."); + return null; } } } diff --git a/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java new file mode 100644 index 000000000..69322d927 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/CreateTopicWithSchemaRevisionsExample.java @@ -0,0 +1,82 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_create_topic_with_schema_revisions] + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.pubsub.v1.Encoding; +import com.google.pubsub.v1.SchemaName; +import com.google.pubsub.v1.SchemaSettings; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.TopicName; +import java.io.IOException; + +public class CreateTopicWithSchemaRevisionsExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String topicId = "your-topic-id"; + // Use an existing schema. + String schemaId = "your-schema-id"; + // Choose either BINARY or JSON message serialization in this topic. + Encoding encoding = Encoding.BINARY; + // Set the minimum and maximum revsion ID + String firstRevisionId = "your-revision-id"; + String lastRevisionId = "your-revision-id"; + + createTopicWithSchemaRevisionsExample( + projectId, topicId, schemaId, firstRevisionId, lastRevisionId, encoding); + } + + public static void createTopicWithSchemaRevisionsExample( + String projectId, + String topicId, + String schemaId, + String firstRevisionid, + String lastRevisionId, + Encoding encoding) + throws IOException { + TopicName topicName = TopicName.of(projectId, topicId); + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + SchemaSettings schemaSettings = + SchemaSettings.newBuilder() + .setSchema(schemaName.toString()) + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .setEncoding(encoding) + .build(); + + try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { + + Topic topic = + topicAdminClient.createTopic( + Topic.newBuilder() + .setName(topicName.toString()) + .setSchemaSettings(schemaSettings) + .build()); + + System.out.println("Created topic with schema: " + topic.getName()); + } catch (AlreadyExistsException e) { + System.out.println(schemaName + "already exists."); + } + } +} +// [END pubsub_create_topic_with_schema_revisions] diff --git a/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java new file mode 100644 index 000000000..30aa65a53 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/DeleteSchemaRevisionExample.java @@ -0,0 +1,55 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_delete_schema_revision] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.DeleteSchemaRevisionRequest; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class DeleteSchemaRevisionExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id@your-revision-id"; + + deleteSchemaRevisionExample(projectId, schemaId); + } + + public static void deleteSchemaRevisionExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + DeleteSchemaRevisionRequest request = + DeleteSchemaRevisionRequest.newBuilder().setName(schemaName.toString()).build(); + + schemaServiceClient.deleteSchemaRevision(request); + + System.out.println("Deleted a schema revision:" + schemaName); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_delete_schema_revision] diff --git a/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java new file mode 100644 index 000000000..e811ae9ff --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/GetSchemaRevisionExample.java @@ -0,0 +1,52 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_get_schema_revision] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class GetSchemaRevisionExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id@your-schema-revision"; + + getSchemaRevisionExample(projectId, schemaId); + } + + public static void getSchemaRevisionExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = schemaServiceClient.getSchema(schemaName); + + System.out.println("Got a schema:\n" + schema); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_get_schema_revision] diff --git a/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java new file mode 100644 index 000000000..69cfa59ab --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/ListSchemaRevisionsExample.java @@ -0,0 +1,46 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_list_schema_revisions] +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class ListSchemaRevisionsExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String schemaId = "your-schema-id"; + + listSchemaRevisionsExample(projectId, schemaId); + } + + public static void listSchemaRevisionsExample(String projectId, String schemaId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + for (Schema schema : schemaServiceClient.listSchemaRevisions(schemaName).iterateAll()) { + System.out.println(schema); + } + System.out.println("Listed schema revisions."); + } + } +} +// [END pubsub_list_schema_revisions] diff --git a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java new file mode 100644 index 000000000..795ba33b5 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java @@ -0,0 +1,53 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_rollback_schema] + +import com.google.api.gax.rpc.NotFoundException; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.pubsub.v1.Schema; +import com.google.pubsub.v1.SchemaName; +import java.io.IOException; + +public class RollbackSchemaExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project"; + String schemaId = "your-schema@your-revision"; + String revisionId = "your-revision"; + + rollbackSchemaExample(projectId, schemaId, revisionId); + } + + public static void rollbackSchemaExample(String projectId, String schemaId, String revisionId) + throws IOException { + SchemaName schemaName = SchemaName.of(projectId, schemaId); + + try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { + + Schema schema = schemaServiceClient.rollbackSchema(schemaName, revisionId); + + System.out.println("Rolled back a schema:" + schema); + + } catch (NotFoundException e) { + System.out.println(schemaName + "not found."); + } + } +} +// [END pubsub_rollback_schema] diff --git a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java new file mode 100644 index 000000000..f86f05107 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java @@ -0,0 +1,158 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_subscribe_avro_records_with_revisions] + +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.SchemaServiceClient; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.protobuf.ByteString; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import com.google.pubsub.v1.Schema; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.apache.avro.io.Decoder; +import org.apache.avro.io.DecoderFactory; +import org.apache.avro.specific.SpecificDatumReader; +import utilities.State; + +public class SubscribeWithAvroSchemaRevisionsExample { + + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + // Use an existing subscription. + String subscriptionId = "your-subscription-id"; + + subscribeWithAvroSchemaRevisionsExample(projectId, subscriptionId); + } + + static SchemaServiceClient getSchemaServiceClient() { + try { + return SchemaServiceClient.create(); + } catch (IOException e) { + System.out.println("Could not get schema client: " + e); + return null; + } + } + + public static void subscribeWithAvroSchemaRevisionsExample( + String projectId, String subscriptionId) { + // Used to get the schemas for revsions. + final SchemaServiceClient schemaServiceClient = getSchemaServiceClient(); + if (schemaServiceClient == null) { + return; + } + + // Cache for the readers for different revision IDs. + Map> revisionReaders = + new HashMap>(); + + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId); + + // Instantiate an asynchronous message receiver. + MessageReceiver receiver = + (PubsubMessage message, AckReplyConsumer consumer) -> { + // Get the schema encoding type. + String name = message.getAttributesMap().get("googclient_schemaname"); + String revision = message.getAttributesMap().get("googclient_schemarevisionid"); + + SpecificDatumReader reader = null; + synchronized (revisionReaders) { + reader = revisionReaders.get(revision); + } + if (reader == null) { + // This is the first time we are seeing this revision. We need to + // fetch the schema and cache its decoder. It would be more typical + // to do this asynchronously, but it shown here in a synchronous + // way to ease readability. + try { + Schema schema = schemaServiceClient.getSchema(name + "@" + revision); + org.apache.avro.Schema avroSchema = + new org.apache.avro.Schema.Parser().parse(schema.getDefinition()); + reader = new SpecificDatumReader(State.getClassSchema(), avroSchema); + synchronized (revisionReaders) { + revisionReaders.put(revision, reader); + } + } catch (Exception e) { + System.out.println("Could not get schema: " + e); + // Without the schema, we cannot read the message, so nack it. + consumer.nack(); + return; + } + } + + ByteString data = message.getData(); + // Send the message data to a byte[] input stream. + InputStream inputStream = new ByteArrayInputStream(data.toByteArray()); + + String encoding = message.getAttributesMap().get("googclient_schemaencoding"); + + Decoder decoder = null; + + // Prepare an appropriate decoder for the message data in the input stream + // based on the schema encoding type. + try { + switch (encoding) { + case "BINARY": + decoder = DecoderFactory.get().directBinaryDecoder(inputStream, /*reuse=*/ null); + System.out.println("Receiving a binary-encoded message:"); + break; + case "JSON": + decoder = DecoderFactory.get().jsonDecoder(State.getClassSchema(), inputStream); + System.out.println("Receiving a JSON-encoded message:"); + break; + default: + System.out.println("Unknown message type; nacking."); + consumer.nack(); + break; + } + + // Obtain an object of the generated Avro class using the decoder. + State state = reader.read(null, decoder); + System.out.println(state.getName() + " is abbreviated as " + state.getPostAbbr()); + + // Ack the message. + consumer.ack(); + } catch (IOException e) { + System.err.println(e); + // If we failed to process the message, nack it. + consumer.nack(); + } + }; + + Subscriber subscriber = null; + try { + subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); + subscriber.startAsync().awaitRunning(); + System.out.printf("Listening for messages on %s:\n", subscriptionName.toString()); + subscriber.awaitTerminated(30, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { + subscriber.stopAsync(); + } + } +} +// [END pubsub_subscribe_avro_records_with_revisions] diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java new file mode 100644 index 000000000..d0412650b --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -0,0 +1,82 @@ +/* + * Copyright 2023 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 pubsub; + +// [START pubsub_update_topic_schema] + +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.protobuf.FieldMask; +import com.google.pubsub.v1.SchemaSettings; +import com.google.pubsub.v1.Topic; +import com.google.pubsub.v1.TopicName; +import com.google.pubsub.v1.UpdateTopicRequest; +import java.io.IOException; + +public class UpdateTopicSchemaExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + // This is an existing topic that has schema settings attached to it. + String topicId = "your-topic-id"; + // Set the minimum and maximum revsion ID + String firstRevisionId = "your-revision-id"; + String lastRevisionId = "your-revision-id"; + + UpdateTopicSchemaExample.updateTopicSchemaExample( + projectId, topicId, firstRevisionId, lastRevisionId); + } + + public static void updateTopicSchemaExample( + String projectId, String topicId, String firstRevisionid, String lastRevisionId) + throws IOException { + try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { + + TopicName topicName = TopicName.of(projectId, topicId); + + // Construct the dead letter policy you expect to have after the update. + SchemaSettings schemaSettings = + SchemaSettings.newBuilder() + .setFirstRevisionId(firstRevisionid) + .setLastRevisionId(lastRevisionId) + .build(); + + // Construct the subscription with the dead letter policy you expect to have + // after the update. Here, values in the required fields (name, topic) help + // identify the subscription. + Topic topic = + Topic.newBuilder() + .setName(topicName.toString()) + .setSchemaSettings(schemaSettings) + .build(); + + // Construct a field mask to indicate which field to update in the subscription. + FieldMask updateMask = + FieldMask.newBuilder() + .addPaths("schema_settings.first_revision_id") + .addPaths("schema_settings.last_revision_id") + .build(); + + UpdateTopicRequest request = + UpdateTopicRequest.newBuilder().setTopic(topic).setUpdateMask(updateMask).build(); + + Topic response = topicAdminClient.updateTopic(request); + + System.out.println("Updated topic with schema: " + topic.getName()); + } + } +} +// [END pubsub_update_topic_schema] diff --git a/samples/snippets/src/main/resources/us-states-plus.avsc b/samples/snippets/src/main/resources/us-states-plus.avsc new file mode 100644 index 000000000..74225ae7e --- /dev/null +++ b/samples/snippets/src/main/resources/us-states-plus.avsc @@ -0,0 +1,24 @@ +{ + "type":"record", + "name":"State", + "namespace":"utilities", + "doc":"A list of states in the United States of America.", + "fields":[ + { + "name":"name", + "type":"string", + "doc":"The common name of the state." + }, + { + "name":"post_abbr", + "type":"string", + "doc":"The postal code abbreviation of the state." + }, + { + "name":"population", + "type":"long", + "default":0, + "doc":"The population of the state." + } + ] +} diff --git a/samples/snippets/src/main/resources/us-states-plus.proto b/samples/snippets/src/main/resources/us-states-plus.proto new file mode 100644 index 000000000..646c7dcb6 --- /dev/null +++ b/samples/snippets/src/main/resources/us-states-plus.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package utilities; +option java_outer_classname = "StateProto"; + +message State { + string name = 1; + string post_abbr = 2; + int64 population = 3; +} diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index bec908800..31685db56 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -26,6 +26,7 @@ import com.google.cloud.testing.junit4.MultipleAttemptsRule; import com.google.pubsub.v1.Encoding; import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.Schema; import com.google.pubsub.v1.SchemaName; import com.google.pubsub.v1.TopicName; import java.io.ByteArrayOutputStream; @@ -46,6 +47,7 @@ public class SchemaIT { private static String _suffix; private static String avroTopicId; private static String protoTopicId; + private static String protoTopicWithRevisionsId; private static String avroSubscriptionId; private static String protoSubscriptionId; private static String avroSchemaId; @@ -54,12 +56,17 @@ public class SchemaIT { ClassLoader classLoader = getClass().getClassLoader(); File avscFile = new File(classLoader.getResource("us-states.avsc").getFile()); String absoluteAvscFilePath = avscFile.getAbsolutePath(); + File avscRevisionFile = new File(classLoader.getResource("us-states-plus.avsc").getFile()); + String absoluteAvscRevisionFilePath = avscRevisionFile.getAbsolutePath(); File protoFile = new File(classLoader.getResource("us-states.proto").getFile()); String absoluteProtoFilePath = protoFile.getAbsolutePath(); + File protoRevisionFile = new File(classLoader.getResource("us-states-plus.proto").getFile()); + String absoluteProtoRevisionFilePath = protoFile.getAbsolutePath(); private static TopicName avroTopicName; private static TopicName protoTopicName; + private static TopicName protoTopicWithRevisionsName; private static ProjectSubscriptionName avroSubscriptionName; private static ProjectSubscriptionName protoSubscriptionName; private static SchemaName avroSchemaName; @@ -79,12 +86,14 @@ public void setUp() { _suffix = UUID.randomUUID().toString(); avroTopicId = "avro-topic-" + _suffix; protoTopicId = "proto-topic-" + _suffix; + protoTopicWithRevisionsId = "proto-topic-with-revisions-" + _suffix; avroSubscriptionId = "avro-subscription-" + _suffix; protoSubscriptionId = "proto-subscription-" + _suffix; avroSchemaId = "avro-schema-" + _suffix; protoSchemaId = "proto-schema-" + _suffix; avroTopicName = TopicName.of(projectId, avroTopicId); protoTopicName = TopicName.of(projectId, protoTopicId); + protoTopicWithRevisionsName = TopicName.of(projectId, protoTopicWithRevisionsId); avroSubscriptionName = ProjectSubscriptionName.of(projectId, avroSubscriptionId); protoSubscriptionName = ProjectSubscriptionName.of(projectId, protoSubscriptionId); avroSchemaName = SchemaName.of(projectId, avroSchemaId); @@ -98,26 +107,49 @@ public void setUp() { public void tearDown() throws Exception { // Delete the schemas if they have not been cleaned up. try (SchemaServiceClient schemaServiceClient = SchemaServiceClient.create()) { - schemaServiceClient.deleteSchema(protoSchemaName); - schemaServiceClient.deleteSchema(avroSchemaName); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + schemaServiceClient.deleteSchema(protoSchemaName); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + schemaServiceClient.deleteSchema(avroSchemaName); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } // Delete the subscriptions. try (SubscriptionAdminClient subscriptionAdmin = SubscriptionAdminClient.create()) { - subscriptionAdmin.deleteSubscription(avroSubscriptionName.toString()); - subscriptionAdmin.deleteSubscription(protoSubscriptionName.toString()); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + subscriptionAdmin.deleteSubscription(avroSubscriptionName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + subscriptionAdmin.deleteSubscription(protoSubscriptionName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } // Delete the topics. try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) { - topicAdminClient.deleteTopic(avroTopicName.toString()); - topicAdminClient.deleteTopic(protoTopicName.toString()); - } catch (NotFoundException ignored) { - // Ignore this as resources may have already been cleaned up. + try { + topicAdminClient.deleteTopic(avroTopicName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + topicAdminClient.deleteTopic(protoTopicName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } + try { + topicAdminClient.deleteTopic(protoTopicWithRevisionsName.toString()); + } catch (NotFoundException ignored) { + // Ignore this as resources may have already been cleaned up. + } } System.setOut(null); } @@ -125,28 +157,69 @@ public void tearDown() throws Exception { @Test public void testSchema() throws Exception { // Test creating Avro schema. - CreateAvroSchemaExample.createAvroSchemaExample(projectId, avroSchemaId, absoluteAvscFilePath); + Schema avroSchema = + CreateAvroSchemaExample.createAvroSchemaExample( + projectId, avroSchemaId, absoluteAvscFilePath); assertThat(bout.toString()).contains("Created a schema using an Avro schema:"); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test committing Avro schema. + CommitAvroSchemaExample.commitAvroSchemaExample( + projectId, avroSchemaId, absoluteAvscRevisionFilePath); + assertThat(bout.toString()).contains("Committed a schema using an Avro schema:"); + assertThat(bout.toString()).contains(avroSchemaName.toString()); + + bout.reset(); // Test creating Proto schema. - CreateProtoSchemaExample.createProtoSchemaExample( - projectId, protoSchemaId, absoluteProtoFilePath); + final Schema protoSchema = + CreateProtoSchemaExample.createProtoSchemaExample( + projectId, protoSchemaId, absoluteProtoFilePath); assertThat(bout.toString()).contains("Created a schema using a protobuf schema:"); assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); + // Test committing Proto schema. + final Schema protoSchemaRevision = + CommitProtoSchemaExample.commitProtoSchemaExample( + projectId, protoSchemaId, absoluteProtoRevisionFilePath); + assertThat(bout.toString()).contains("Committed a schema using a protobuf schema:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + + bout.reset(); + // Test rolling back a schema. + RollbackSchemaExample.rollbackSchemaExample( + projectId, + protoSchemaId + "@" + protoSchema.getRevisionId(), + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Rolled back a schema:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test getting a schema. GetSchemaExample.getSchemaExample(projectId, avroSchemaId); assertThat(bout.toString()).contains("Got a schema:"); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test getting a schema revision. + GetSchemaRevisionExample.getSchemaRevisionExample( + projectId, protoSchemaId + "@" + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Got a schema:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test listing schemas. ListSchemasExample.listSchemasExample(projectId); assertThat(bout.toString()).contains("Listed schemas."); assertThat(bout.toString()).contains(avroSchemaName.toString()); + bout.reset(); + // Test listing schema revisions. + ListSchemaRevisionsExample.listSchemaRevisionsExample(projectId, protoSchemaId); + assertThat(bout.toString()).contains("Listed schema revisions."); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test creating a topic with an Avro schema with BINARY encoding. CreateTopicWithSchemaExample.createTopicWithSchemaExample( @@ -159,6 +232,19 @@ public void testSchema() throws Exception { projectId, protoTopicId, protoSchemaId, Encoding.JSON); assertThat(bout.toString()).contains("Created topic with schema: " + protoTopicName.toString()); + bout.reset(); + // Test creating a topic with a proto schema with revisions specified. + CreateTopicWithSchemaRevisionsExample.createTopicWithSchemaRevisionsExample( + projectId, + protoTopicWithRevisionsId, + protoSchemaId, + protoSchema.getRevisionId(), + protoSchemaRevision.getRevisionId(), + Encoding.BINARY); + assertThat(bout.toString()) + .contains("Created topic with schema: " + protoTopicWithRevisionsName.toString()); + + bout.reset(); // Attach a default pull subscription to each topic. CreatePullSubscriptionExample.createPullSubscriptionExample( projectId, avroSubscriptionId, avroTopicId); @@ -179,7 +265,8 @@ public void testSchema() throws Exception { bout.reset(); // Test receiving BINARY-encoded Avro records. - SubscribeWithAvroSchemaExample.subscribeWithAvroSchemaExample(projectId, avroSubscriptionId); + SubscribeWithAvroSchemaRevisionsExample.subscribeWithAvroSchemaRevisionsExample( + projectId, avroSubscriptionId); assertThat(bout.toString()).contains("Receiving a binary-encoded message:"); assertThat(bout.toString()).contains(" is abbreviated as "); @@ -189,6 +276,23 @@ public void testSchema() throws Exception { assertThat(bout.toString()).contains("Received a JSON-formatted message:"); assertThat(bout.toString()).contains("Ack'ed the message"); + bout.reset(); + // Test updating a topic schema settings + UpdateTopicSchemaExample.updateTopicSchemaExample( + projectId, + protoTopicWithRevisionsId, + protoSchemaRevision.getRevisionId(), + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()) + .contains("Updated topic with schema: " + protoTopicWithRevisionsName.toString()); + + bout.reset(); + // Test deleting a schema revision. + DeleteSchemaRevisionExample.deleteSchemaRevisionExample( + projectId, protoSchemaId + "@" + protoSchemaRevision.getRevisionId()); + assertThat(bout.toString()).contains("Deleted a schema revision:"); + assertThat(bout.toString()).contains(protoSchemaName.toString()); + bout.reset(); // Test deleting a schema. DeleteSchemaExample.deleteSchemaExample(projectId, avroSchemaId); From b1d2309dbc0108b3f1f92f96c9fb85d7ac0ec665 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Fri, 10 Mar 2023 07:01:56 -0500 Subject: [PATCH 21/42] Fix rollback example --- .../src/main/java/pubsub/RollbackSchemaExample.java | 2 +- samples/snippets/src/test/java/pubsub/SchemaIT.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java index 795ba33b5..0af304ed5 100644 --- a/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/RollbackSchemaExample.java @@ -29,7 +29,7 @@ public class RollbackSchemaExample { public static void main(String... args) throws Exception { // TODO(developer): Replace these variables before running the sample. String projectId = "your-project"; - String schemaId = "your-schema@your-revision"; + String schemaId = "your-schema"; String revisionId = "your-revision"; rollbackSchemaExample(projectId, schemaId, revisionId); diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index 31685db56..485b77114 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -59,9 +59,9 @@ public class SchemaIT { File avscRevisionFile = new File(classLoader.getResource("us-states-plus.avsc").getFile()); String absoluteAvscRevisionFilePath = avscRevisionFile.getAbsolutePath(); - File protoFile = new File(classLoader.getResource("us-states.proto").getFile()); + File protoFile = new File(classLoader.getResource("us-states-plus.proto").getFile()); String absoluteProtoFilePath = protoFile.getAbsolutePath(); - File protoRevisionFile = new File(classLoader.getResource("us-states-plus.proto").getFile()); + File protoRevisionFile = new File(classLoader.getResource("us-states.proto").getFile()); String absoluteProtoRevisionFilePath = protoFile.getAbsolutePath(); private static TopicName avroTopicName; @@ -190,8 +190,8 @@ public void testSchema() throws Exception { // Test rolling back a schema. RollbackSchemaExample.rollbackSchemaExample( projectId, - protoSchemaId + "@" + protoSchema.getRevisionId(), - protoSchemaRevision.getRevisionId()); + protoSchemaId, + protoSchema.getRevisionId()); assertThat(bout.toString()).contains("Rolled back a schema:"); assertThat(bout.toString()).contains(protoSchemaName.toString()); From 3f74191b3eed4f318abe7c77657523641da11b82 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Fri, 10 Mar 2023 07:09:03 -0500 Subject: [PATCH 22/42] Formatting --- samples/snippets/src/test/java/pubsub/SchemaIT.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index 485b77114..c5f1e79b8 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -189,9 +189,7 @@ public void testSchema() throws Exception { bout.reset(); // Test rolling back a schema. RollbackSchemaExample.rollbackSchemaExample( - projectId, - protoSchemaId, - protoSchema.getRevisionId()); + projectId, protoSchemaId, protoSchema.getRevisionId()); assertThat(bout.toString()).contains("Rolled back a schema:"); assertThat(bout.toString()).contains(protoSchemaName.toString()); From 8b1288a951e85a83f48a39b225be9a0955babb02 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Fri, 10 Mar 2023 07:16:17 -0500 Subject: [PATCH 23/42] Formatting and wording fixes --- .../SubscribeWithAvroSchemaRevisionsExample.java | 2 +- .../main/java/pubsub/UpdateTopicSchemaExample.java | 4 ++-- samples/snippets/src/test/java/pubsub/SchemaIT.java | 12 ++++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java index f86f05107..6c2d31efe 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeWithAvroSchemaRevisionsExample.java @@ -87,7 +87,7 @@ public static void subscribeWithAvroSchemaRevisionsExample( if (reader == null) { // This is the first time we are seeing this revision. We need to // fetch the schema and cache its decoder. It would be more typical - // to do this asynchronously, but it shown here in a synchronous + // to do this asynchronously, but is shown here in a synchronous // way to ease readability. try { Schema schema = schemaServiceClient.getSchema(name + "@" + revision); diff --git a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java index 01f7c6580..4383fffd6 100644 --- a/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/UpdateTopicSchemaExample.java @@ -54,14 +54,14 @@ public static void updateTopicSchemaExample( .setLastRevisionId(lastRevisionId) .build(); - // Construct the subscription with the schema settings you want to change. + // Construct the topic with the schema settings you want to change. Topic topic = Topic.newBuilder() .setName(topicName.toString()) .setSchemaSettings(schemaSettings) .build(); - // Construct a field mask to indicate which field to update in the subscription. + // Construct a field mask to indicate which field to update in the topic. FieldMask updateMask = FieldMask.newBuilder() .addPaths("schema_settings.first_revision_id") diff --git a/samples/snippets/src/test/java/pubsub/SchemaIT.java b/samples/snippets/src/test/java/pubsub/SchemaIT.java index c5f1e79b8..2874ae519 100644 --- a/samples/snippets/src/test/java/pubsub/SchemaIT.java +++ b/samples/snippets/src/test/java/pubsub/SchemaIT.java @@ -268,6 +268,18 @@ public void testSchema() throws Exception { assertThat(bout.toString()).contains("Receiving a binary-encoded message:"); assertThat(bout.toString()).contains(" is abbreviated as "); + bout.reset(); + // Test publishing BINARY-encoded Avro records. + PublishAvroRecordsExample.publishAvroRecordsExample(projectId, avroTopicId); + assertThat(bout.toString()).contains("Preparing a BINARY encoder..."); + assertThat(bout.toString()).contains("Published message ID:"); + + bout.reset(); + // Test receiving BINARY-encoded Avro records. + SubscribeWithAvroSchemaExample.subscribeWithAvroSchemaExample(projectId, avroSubscriptionId); + assertThat(bout.toString()).contains("Receiving a binary-encoded message:"); + assertThat(bout.toString()).contains(" is abbreviated as "); + bout.reset(); // Test receiving JSON-encoded proto messages. SubscribeWithProtoSchemaExample.subscribeWithProtoSchemaExample(projectId, protoSubscriptionId); From 5057f17c7a52149a159b80c7d2a1e5e961c5935a Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Fri, 10 Mar 2023 07:34:57 -0500 Subject: [PATCH 24/42] Add new schemas to test directory --- .../src/test/resources/us-states-plus.avsc | 24 +++++++++++++++++++ .../src/test/resources/us-states-plus.proto | 10 ++++++++ 2 files changed, 34 insertions(+) create mode 100644 samples/snippets/src/test/resources/us-states-plus.avsc create mode 100644 samples/snippets/src/test/resources/us-states-plus.proto diff --git a/samples/snippets/src/test/resources/us-states-plus.avsc b/samples/snippets/src/test/resources/us-states-plus.avsc new file mode 100644 index 000000000..74225ae7e --- /dev/null +++ b/samples/snippets/src/test/resources/us-states-plus.avsc @@ -0,0 +1,24 @@ +{ + "type":"record", + "name":"State", + "namespace":"utilities", + "doc":"A list of states in the United States of America.", + "fields":[ + { + "name":"name", + "type":"string", + "doc":"The common name of the state." + }, + { + "name":"post_abbr", + "type":"string", + "doc":"The postal code abbreviation of the state." + }, + { + "name":"population", + "type":"long", + "default":0, + "doc":"The population of the state." + } + ] +} diff --git a/samples/snippets/src/test/resources/us-states-plus.proto b/samples/snippets/src/test/resources/us-states-plus.proto new file mode 100644 index 000000000..646c7dcb6 --- /dev/null +++ b/samples/snippets/src/test/resources/us-states-plus.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package utilities; +option java_outer_classname = "StateProto"; + +message State { + string name = 1; + string post_abbr = 2; + int64 population = 3; +} From ba3812149128e989e4491822e4f6d8316dff9dff Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Fri, 10 Mar 2023 14:48:07 +0000 Subject: [PATCH 25/42] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20?= =?UTF-8?q?post-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6f543e7ff..1827a5cfe 100644 --- a/README.md +++ b/README.md @@ -51,20 +51,20 @@ If you are using Maven without BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.8.0') +implementation platform('com.google.cloud:libraries-bom:26.10.0') implementation 'com.google.cloud:google-cloud-pubsub' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-pubsub:1.123.3' +implementation 'com.google.cloud:google-cloud-pubsub:1.123.5' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-pubsub" % "1.123.3" +libraryDependencies += "com.google.cloud" % "google-cloud-pubsub" % "1.123.5" ``` ## Authentication From 9dff92e6787ae1832fd3687a6c60d9c9d4c13a82 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Fri, 10 Mar 2023 21:26:03 -0500 Subject: [PATCH 26/42] Samples: Fix exception handling --- .../src/main/java/pubsub/CommitAvroSchemaExample.java | 6 +++--- .../src/main/java/pubsub/CommitProtoSchemaExample.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java index e6ac8f278..8f24e75a2 100644 --- a/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CommitAvroSchemaExample.java @@ -18,7 +18,7 @@ // [START pubsub_commit_avro_schema] -import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.api.gax.rpc.NotFoundException; import com.google.cloud.pubsub.v1.SchemaServiceClient; import com.google.pubsub.v1.ProjectName; import com.google.pubsub.v1.Schema; @@ -60,8 +60,8 @@ public static Schema commitAvroSchemaExample(String projectId, String schemaId, System.out.println("Committed a schema using an Avro schema:\n" + schema); return schema; - } catch (AlreadyExistsException e) { - System.out.println(schemaName + "already exists."); + } catch (NotFoundException e) { + System.out.println(schemaName + "does not exist."); return null; } } diff --git a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java index b32de29dc..e609b9a5f 100644 --- a/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java +++ b/samples/snippets/src/main/java/pubsub/CommitProtoSchemaExample.java @@ -18,7 +18,7 @@ // [START pubsub_commit_proto_schema] -import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.api.gax.rpc.NotFoundException; import com.google.cloud.pubsub.v1.SchemaServiceClient; import com.google.pubsub.v1.ProjectName; import com.google.pubsub.v1.Schema; @@ -60,8 +60,8 @@ public static Schema commitProtoSchemaExample(String projectId, String schemaId, System.out.println("Committed a schema using a protobuf schema:\n" + schema); return schema; - } catch (AlreadyExistsException e) { - System.out.println(schemaName + "already exists."); + } catch (NotFoundException e) { + System.out.println(schemaName + "does not exist."); return null; } } From 3185a3e9d48680d75cc70745f7ea0048d726556b Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 14 Mar 2023 08:22:16 -0400 Subject: [PATCH 27/42] fix: Set x-goog-request-params for streaming pull request --- .../pubsub/v1/StreamingSubscriberConnection.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java index e7046c1be..26547529e 100644 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java +++ b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java @@ -36,6 +36,8 @@ import com.google.api.gax.rpc.StreamController; import com.google.cloud.pubsub.v1.MessageDispatcher.AckProcessor; import com.google.cloud.pubsub.v1.stub.SubscriberStub; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.Any; @@ -86,6 +88,8 @@ final class StreamingSubscriberConnection extends AbstractApiService implements private Duration inititalStreamAckDeadline; + private final Map> streamMetadata; + private final SubscriberStub subscriberStub; private final int channelAffinity; private final String subscription; @@ -134,6 +138,9 @@ private StreamingSubscriberConnection(Builder builder) { inititalStreamAckDeadline = builder.maxDurationPerAckExtension; } + streamMetadata = + ImmutableMap.of("x-goog-request-params", ImmutableList.of("subscription=" + subscription)); + subscriberStub = builder.subscriberStub; channelAffinity = builder.channelAffinity; @@ -273,7 +280,9 @@ private void initialize() { .streamingPullCallable() .splitCall( responseObserver, - GrpcCallContext.createDefault().withChannelAffinity(channelAffinity)); + GrpcCallContext.createDefault() + .withChannelAffinity(channelAffinity) + .withExtraHeaders(streamMetadata)); logger.log(Level.FINER, "Initializing stream to subscription {0}", subscription); // We need to set streaming ack deadline, but it's not useful since we'll modack to send receipt From 3b1f4d9c0751a8fa676159842208b4213d764ee6 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 14 Mar 2023 08:24:01 -0400 Subject: [PATCH 28/42] Revert "fix: Set x-goog-request-params for streaming pull request" This reverts commit 3185a3e9d48680d75cc70745f7ea0048d726556b. --- .../pubsub/v1/StreamingSubscriberConnection.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java index 26547529e..e7046c1be 100644 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java +++ b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java @@ -36,8 +36,6 @@ import com.google.api.gax.rpc.StreamController; import com.google.cloud.pubsub.v1.MessageDispatcher.AckProcessor; import com.google.cloud.pubsub.v1.stub.SubscriberStub; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.Any; @@ -88,8 +86,6 @@ final class StreamingSubscriberConnection extends AbstractApiService implements private Duration inititalStreamAckDeadline; - private final Map> streamMetadata; - private final SubscriberStub subscriberStub; private final int channelAffinity; private final String subscription; @@ -138,9 +134,6 @@ private StreamingSubscriberConnection(Builder builder) { inititalStreamAckDeadline = builder.maxDurationPerAckExtension; } - streamMetadata = - ImmutableMap.of("x-goog-request-params", ImmutableList.of("subscription=" + subscription)); - subscriberStub = builder.subscriberStub; channelAffinity = builder.channelAffinity; @@ -280,9 +273,7 @@ private void initialize() { .streamingPullCallable() .splitCall( responseObserver, - GrpcCallContext.createDefault() - .withChannelAffinity(channelAffinity) - .withExtraHeaders(streamMetadata)); + GrpcCallContext.createDefault().withChannelAffinity(channelAffinity)); logger.log(Level.FINER, "Initializing stream to subscription {0}", subscription); // We need to set streaming ack deadline, but it's not useful since we'll modack to send receipt From 9c576e8e6a5e865fb7aa738961cc1f15332d9fe8 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 14 Mar 2023 08:25:04 -0400 Subject: [PATCH 29/42] Revert "Revert "fix: Set x-goog-request-params for streaming pull request"" This reverts commit 3b1f4d9c0751a8fa676159842208b4213d764ee6. --- .../pubsub/v1/StreamingSubscriberConnection.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java index e7046c1be..26547529e 100644 --- a/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java +++ b/google-cloud-pubsub/src/main/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnection.java @@ -36,6 +36,8 @@ import com.google.api.gax.rpc.StreamController; import com.google.cloud.pubsub.v1.MessageDispatcher.AckProcessor; import com.google.cloud.pubsub.v1.stub.SubscriberStub; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.Any; @@ -86,6 +88,8 @@ final class StreamingSubscriberConnection extends AbstractApiService implements private Duration inititalStreamAckDeadline; + private final Map> streamMetadata; + private final SubscriberStub subscriberStub; private final int channelAffinity; private final String subscription; @@ -134,6 +138,9 @@ private StreamingSubscriberConnection(Builder builder) { inititalStreamAckDeadline = builder.maxDurationPerAckExtension; } + streamMetadata = + ImmutableMap.of("x-goog-request-params", ImmutableList.of("subscription=" + subscription)); + subscriberStub = builder.subscriberStub; channelAffinity = builder.channelAffinity; @@ -273,7 +280,9 @@ private void initialize() { .streamingPullCallable() .splitCall( responseObserver, - GrpcCallContext.createDefault().withChannelAffinity(channelAffinity)); + GrpcCallContext.createDefault() + .withChannelAffinity(channelAffinity) + .withExtraHeaders(streamMetadata)); logger.log(Level.FINER, "Initializing stream to subscription {0}", subscription); // We need to set streaming ack deadline, but it's not useful since we'll modack to send receipt From dea5c9cdfc44e7de1bdcf38821b3668de25175bb Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 31 Aug 2023 17:48:02 -0400 Subject: [PATCH 30/42] Thread example --- .../java/pubsub/SubscribeAsyncExample.java | 155 ++++++++++++++++-- 1 file changed, 141 insertions(+), 14 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java index 4d2f40815..20caab538 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java @@ -26,19 +26,133 @@ import com.google.pubsub.v1.PubsubMessage; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.Set; +import java.util.List; +import java.util.ArrayList; +import com.google.api.gax.core.FixedExecutorProvider; +import com.google.api.gax.core.ExecutorProvider; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.lang.Thread; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.cloud.pubsub.v1.SubscriptionAdminSettings; +import org.threeten.bp.Duration; +import com.google.api.gax.rpc.TransportChannel; +import com.google.auth.Credentials; +import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; +import java.util.Map; public class SubscribeAsyncExample { public static void main(String... args) throws Exception { // TODO(developer): Replace these variables before running the sample. - String projectId = "your-project-id"; - String subscriptionId = "your-subscription-id"; + String projectId = "ordering-keys-testing"; + String subscriptionId = "threads-test"; subscribeAsyncExample(projectId, subscriptionId); } + private static class SinglePubSubChannelProvider implements TransportChannelProvider { + TransportChannel channel; + TransportChannelProvider channelProvider; + + SinglePubSubChannelProvider(ExecutorProvider executorProvider) { + int MAX_INBOUND_MESSAGE_SIZE = + 20 * 1024 * 1024; // 20MB API maximum message size. + int MAX_INBOUND_METADATA_SIZE = + 4 * 1024 * 1024; // 4MB API maximum metadata size + channelProvider = + SubscriptionAdminSettings.defaultGrpcTransportProviderBuilder() + .setMaxInboundMessageSize(MAX_INBOUND_MESSAGE_SIZE) + .setMaxInboundMetadataSize(MAX_INBOUND_METADATA_SIZE) + .setKeepAliveTime(Duration.ofMinutes(5)) + .setExecutor(executorProvider.getExecutor()).build(); + } + + @Override + public TransportChannel getTransportChannel() { + if (channel == null) { + try { + channel = channelProvider.getTransportChannel(); + } catch (Exception e) { + } + } + return channel; + } + + @Override + public boolean acceptsPoolSize() { + return channelProvider.acceptsPoolSize(); + } + + @Override + public String getTransportName() { + return channelProvider.getTransportName(); + } + + @Override + public boolean needsCredentials() { + return channelProvider.needsCredentials(); + } + + @Override + public boolean needsEndpoint() { + return channelProvider.needsEndpoint(); + } + + @Override + public boolean needsExecutor() { + return channelProvider.needsExecutor(); + } + + @Override + public boolean needsHeaders() { + return channelProvider.needsHeaders(); + } + + @Override + public boolean shouldAutoClose() { + return channelProvider.shouldAutoClose(); + } + + @Override + public TransportChannelProvider withCredentials(Credentials credentials) { + channelProvider = channelProvider.withCredentials(credentials); + return this; + } + + @Override + public TransportChannelProvider withEndpoint(String endpoint) { + channelProvider = channelProvider.withEndpoint(endpoint); + return this; + } + + @Override + public TransportChannelProvider withExecutor(Executor executor) { + channelProvider = channelProvider.withExecutor(executor); + return this; + } + + @Override + public TransportChannelProvider withExecutor(ScheduledExecutorService executor) { + channelProvider = channelProvider.withExecutor(executor); + return this; + } + + @Override + public TransportChannelProvider withHeaders(Map headers) { + channelProvider = channelProvider.withHeaders(headers); + return this; + } + + @Override + public TransportChannelProvider withPoolSize(int size) { + channelProvider = channelProvider.withPoolSize(size); + return this; + } + } + public static void subscribeAsyncExample(String projectId, String subscriptionId) { - ProjectSubscriptionName subscriptionName = - ProjectSubscriptionName.of(projectId, subscriptionId); + int subCount = 100; // Instantiate an asynchronous message receiver. MessageReceiver receiver = @@ -49,17 +163,30 @@ public static void subscribeAsyncExample(String projectId, String subscriptionId consumer.ack(); }; - Subscriber subscriber = null; - try { - subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); - // Start the subscriber. - subscriber.startAsync().awaitRunning(); - System.out.printf("Listening for messages on %s:\n", subscriptionName.toString()); - // Allow the subscriber to run for 30s unless an unrecoverable error occurs. - subscriber.awaitTerminated(30, TimeUnit.SECONDS); - } catch (TimeoutException timeoutException) { + FixedExecutorProvider executorProvider = + FixedExecutorProvider.create(new ScheduledThreadPoolExecutor(1)); + SinglePubSubChannelProvider channelProvider = new SinglePubSubChannelProvider(executorProvider); + + List subscribers = new ArrayList<>(); + for (int i = 0; i < subCount; ++i) { + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId + i); + Subscriber subscriber = null; + subscriber = Subscriber.newBuilder(subscriptionName, receiver).setChannelProvider(channelProvider).setExecutorProvider(executorProvider).setSystemExecutorProvider(executorProvider).build(); + // Start the subscriber. + subscriber.startAsync().awaitRunning(); + subscribers.add(subscriber); + } + System.out.printf("Thread count: %d\n", Thread.activeCount()); + System.out.println("Listening for messages."); + for (Subscriber subscriber : subscribers) { + try { + // Allow the subscriber to run for 30s unless an unrecoverable error occurs. + subscriber.awaitTerminated(300, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { // Shut down the subscriber after 30s. Stop receiving messages. - subscriber.stopAsync(); + subscriber.stopAsync(); + } } } } From c58f5a0b03aed519e931cd8905864ea93fd2a37a Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 12 Sep 2023 07:09:49 -0400 Subject: [PATCH 31/42] Add examples for limited and unlimited exeuctors --- ...bscribeAsyncLimitedConcurrencyExample.java | 170 ++++++++++++++++++ ...cribeAsyncUnlimitedConcurrencyExample.java | 93 ++++++++++ 2 files changed, 263 insertions(+) create mode 100644 samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java create mode 100644 samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java new file mode 100644 index 000000000..935557d0e --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java @@ -0,0 +1,170 @@ +/* + * Copyright 2016 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 pubsub; + +import com.google.api.gax.core.FixedExecutorProvider; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.rpc.FixedTransportChannelProvider; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicLong; + +public class SubscribeAsyncLimitedConcurrencyExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String subscriptionId = "my-subscription"; + + subscribeAsyncLimitedConcurrencyExample(projectId, subscriptionId); + } + + static final int MAX_INBOUND_MESSAGE_SIZE = 20 * 1024 * 1024; // 20MB API maximum message size. + static final int MAX_INBOUND_METADATA_SIZE = 4 * 1024 * 1024; // 4MB API maximum metadata size + + private static ManagedChannel createSingleChannel( + String serviceAddress, int port, Executor executor, Executor offloadExecutor) + throws IOException { + ManagedChannelBuilder builder; + builder = ManagedChannelBuilder.forAddress(serviceAddress, port); + builder = + builder + .executor(executor) + .offloadExecutor(offloadExecutor) + .maxInboundMetadataSize(MAX_INBOUND_METADATA_SIZE) + .keepAliveTime(30, TimeUnit.SECONDS); + + ManagedChannel managedChannel = builder.build(); + return managedChannel; + } + + public static void subscribeAsyncLimitedConcurrencyExample( + String projectId, String subscriptionId) { + int subCount = 100; + int transportChannelCount = 20; + final AtomicLong receivedCount = new AtomicLong(); + + // Instantiate an asynchronous message receiver. + MessageReceiver receiver = + (PubsubMessage message, AckReplyConsumer consumer) -> { + // Handle incoming message, then ack the received message. + consumer.ack(); + long currentCount = receivedCount.incrementAndGet(); + if (currentCount % 100 == 0) { + System.out.println("Received " + currentCount); + } + }; + + ThreadFactory callbackThreadFactory = + new ThreadFactoryBuilder().setNameFormat("callback-pool-%d").build(); + ScheduledThreadPoolExecutor callbackExecutor = + new ScheduledThreadPoolExecutor(10, callbackThreadFactory); + callbackExecutor.setMaximumPoolSize(10); + FixedExecutorProvider callbackExecutorProvider = FixedExecutorProvider.create(callbackExecutor); + ThreadFactory leaseThreadFactory = + new ThreadFactoryBuilder().setNameFormat("lease-pool-%d").build(); + ScheduledThreadPoolExecutor leaseExecutor = + new ScheduledThreadPoolExecutor(10, leaseThreadFactory); + leaseExecutor.setMaximumPoolSize(10); + FixedExecutorProvider leaseExecutorProvider = FixedExecutorProvider.create(leaseExecutor); + ThreadFactory channelThreadFactory = + new ThreadFactoryBuilder().setNameFormat("channel-pool-%d").build(); + ScheduledThreadPoolExecutor channelExecutor = + new ScheduledThreadPoolExecutor(10, channelThreadFactory); + ThreadFactory channelOffloadThreadFactory = + new ThreadFactoryBuilder().setNameFormat("channel-offload-pool-%d").build(); + ScheduledThreadPoolExecutor channelOffloadExecutor = + new ScheduledThreadPoolExecutor(10, channelOffloadThreadFactory); + + ArrayList transportChannelProviders = + new ArrayList<>(transportChannelCount); + + for (int i = 0; i < transportChannelCount; ++i) { + TransportChannelProvider channelProvider = null; + try { + channelProvider = + FixedTransportChannelProvider.create( + GrpcTransportChannel.create( + createSingleChannel( + "pubsub.googleapis.com", 443, channelExecutor, channelOffloadExecutor))); + transportChannelProviders.add(channelProvider); + } catch (Exception e) { + System.out.println("Could not create channel provider: " + e); + return; + } + } + + List subscribers = new ArrayList<>(); + for (int i = 0; i < subCount; ++i) { + + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId + i); + Subscriber subscriber = null; + subscriber = + Subscriber.newBuilder(subscriptionName, receiver) + .setChannelProvider(transportChannelProviders.get(i % transportChannelCount)) + .setExecutorProvider(callbackExecutorProvider) + .setSystemExecutorProvider(leaseExecutorProvider) + .build(); + // Start the subscriber. + subscriber.startAsync().awaitRunning(); + subscribers.add(subscriber); + } + printThreads(); + System.out.println("Listening for messages for 30s before checking threads again."); + try { + Thread.sleep(30000); + } catch (Exception e) { + + } + printThreads(); + + for (Subscriber subscriber : subscribers) { + try { + // Allow the subscriber to run for 30s unless an unrecoverable error occurs. + subscriber.awaitTerminated(120, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { + // Shut down the subscriber after 30s. Stop receiving messages. + subscriber.stopAsync(); + } + } + } + + private static void printThreads() { + System.out.println("Thread names:"); + Set threadSet = Thread.getAllStackTraces().keySet(); + for (Thread t : threadSet) { + System.out.println("\t" + t.getName()); + } + System.out.printf("Thread count: %d\n", Thread.activeCount()); + } +} diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java new file mode 100644 index 000000000..253ab99b4 --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java @@ -0,0 +1,93 @@ +/* + * Copyright 2016 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 pubsub; + +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicLong; + +public class SubscribeAsyncUnlimitedConcurrencyExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-topic"; + String subscriptionId = "my-subscription" + + subscribeAsyncUnlimitedConcurrencyExample(projectId, subscriptionId); + } + + public static void subscribeAsyncUnlimitedConcurrencyExample( + String projectId, String subscriptionId) { + int subCount = 100; + final AtomicLong receivedCount = new AtomicLong(); + + // Instantiate an asynchronous message receiver. + MessageReceiver receiver = + (PubsubMessage message, AckReplyConsumer consumer) -> { + // Handle incoming message, then ack the received message. + consumer.ack(); + long currentCount = receivedCount.incrementAndGet(); + if (currentCount % 100 == 0) { + System.out.println("Received " + currentCount); + } + }; + + List subscribers = new ArrayList<>(); + for (int i = 0; i < subCount; ++i) { + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId + i); + Subscriber subscriber = null; + subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); + // Start the subscriber. + subscriber.startAsync().awaitRunning(); + subscribers.add(subscriber); + } + printThreads(); + System.out.println("Listening for messages for 30s before checking threads again."); + try { + Thread.sleep(30000); + } catch (Exception e) { + + } + printThreads(); + for (Subscriber subscriber : subscribers) { + try { + // Allow the subscriber to run for 30s unless an unrecoverable error occurs. + subscriber.awaitTerminated(300, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { + // Shut down the subscriber after 30s. Stop receiving messages. + subscriber.stopAsync(); + } + } + } + + private static void printThreads() { + System.out.println("Thread names:"); + Set threadSet = Thread.getAllStackTraces().keySet(); + for (Thread t : threadSet) { + System.out.println("\t" + t.getName()); + } + System.out.printf("Thread count: %d\n", Thread.activeCount()); + } +} From 6d8186fccfaa040c5a134fb087ce4775040c4fea Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 12 Sep 2023 07:10:31 -0400 Subject: [PATCH 32/42] Add back missing semicolon --- .../java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java index 253ab99b4..21027663b 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java @@ -32,7 +32,7 @@ public class SubscribeAsyncUnlimitedConcurrencyExample { public static void main(String... args) throws Exception { // TODO(developer): Replace these variables before running the sample. String projectId = "my-topic"; - String subscriptionId = "my-subscription" + String subscriptionId = "my-subscription"; subscribeAsyncUnlimitedConcurrencyExample(projectId, subscriptionId); } From 307019a23cad3208307a1a3afb5d507d6becb2f4 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 12 Sep 2023 07:15:55 -0400 Subject: [PATCH 33/42] Revert changes to original async example --- .../java/pubsub/SubscribeAsyncExample.java | 157 ++---------------- 1 file changed, 15 insertions(+), 142 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java index 20caab538..abca3368f 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java @@ -26,133 +26,19 @@ import com.google.pubsub.v1.PubsubMessage; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.Set; -import java.util.List; -import java.util.ArrayList; -import com.google.api.gax.core.FixedExecutorProvider; -import com.google.api.gax.core.ExecutorProvider; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.lang.Thread; -import com.google.api.gax.rpc.TransportChannelProvider; -import com.google.cloud.pubsub.v1.SubscriptionAdminSettings; -import org.threeten.bp.Duration; -import com.google.api.gax.rpc.TransportChannel; -import com.google.auth.Credentials; -import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; -import java.util.Map; public class SubscribeAsyncExample { public static void main(String... args) throws Exception { // TODO(developer): Replace these variables before running the sample. - String projectId = "ordering-keys-testing"; - String subscriptionId = "threads-test"; + String projectId = "your-project-id"; + String subscriptionId = "your-subscription-id"; subscribeAsyncExample(projectId, subscriptionId); } - private static class SinglePubSubChannelProvider implements TransportChannelProvider { - TransportChannel channel; - TransportChannelProvider channelProvider; - - SinglePubSubChannelProvider(ExecutorProvider executorProvider) { - int MAX_INBOUND_MESSAGE_SIZE = - 20 * 1024 * 1024; // 20MB API maximum message size. - int MAX_INBOUND_METADATA_SIZE = - 4 * 1024 * 1024; // 4MB API maximum metadata size - channelProvider = - SubscriptionAdminSettings.defaultGrpcTransportProviderBuilder() - .setMaxInboundMessageSize(MAX_INBOUND_MESSAGE_SIZE) - .setMaxInboundMetadataSize(MAX_INBOUND_METADATA_SIZE) - .setKeepAliveTime(Duration.ofMinutes(5)) - .setExecutor(executorProvider.getExecutor()).build(); - } - - @Override - public TransportChannel getTransportChannel() { - if (channel == null) { - try { - channel = channelProvider.getTransportChannel(); - } catch (Exception e) { - } - } - return channel; - } - - @Override - public boolean acceptsPoolSize() { - return channelProvider.acceptsPoolSize(); - } - - @Override - public String getTransportName() { - return channelProvider.getTransportName(); - } - - @Override - public boolean needsCredentials() { - return channelProvider.needsCredentials(); - } - - @Override - public boolean needsEndpoint() { - return channelProvider.needsEndpoint(); - } - - @Override - public boolean needsExecutor() { - return channelProvider.needsExecutor(); - } - - @Override - public boolean needsHeaders() { - return channelProvider.needsHeaders(); - } - - @Override - public boolean shouldAutoClose() { - return channelProvider.shouldAutoClose(); - } - - @Override - public TransportChannelProvider withCredentials(Credentials credentials) { - channelProvider = channelProvider.withCredentials(credentials); - return this; - } - - @Override - public TransportChannelProvider withEndpoint(String endpoint) { - channelProvider = channelProvider.withEndpoint(endpoint); - return this; - } - - @Override - public TransportChannelProvider withExecutor(Executor executor) { - channelProvider = channelProvider.withExecutor(executor); - return this; - } - - @Override - public TransportChannelProvider withExecutor(ScheduledExecutorService executor) { - channelProvider = channelProvider.withExecutor(executor); - return this; - } - - @Override - public TransportChannelProvider withHeaders(Map headers) { - channelProvider = channelProvider.withHeaders(headers); - return this; - } - - @Override - public TransportChannelProvider withPoolSize(int size) { - channelProvider = channelProvider.withPoolSize(size); - return this; - } - } - public static void subscribeAsyncExample(String projectId, String subscriptionId) { - int subCount = 100; + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId); // Instantiate an asynchronous message receiver. MessageReceiver receiver = @@ -163,32 +49,19 @@ public static void subscribeAsyncExample(String projectId, String subscriptionId consumer.ack(); }; - FixedExecutorProvider executorProvider = - FixedExecutorProvider.create(new ScheduledThreadPoolExecutor(1)); - SinglePubSubChannelProvider channelProvider = new SinglePubSubChannelProvider(executorProvider); - - List subscribers = new ArrayList<>(); - for (int i = 0; i < subCount; ++i) { - ProjectSubscriptionName subscriptionName = - ProjectSubscriptionName.of(projectId, subscriptionId + i); - Subscriber subscriber = null; - subscriber = Subscriber.newBuilder(subscriptionName, receiver).setChannelProvider(channelProvider).setExecutorProvider(executorProvider).setSystemExecutorProvider(executorProvider).build(); - // Start the subscriber. - subscriber.startAsync().awaitRunning(); - subscribers.add(subscriber); - } - System.out.printf("Thread count: %d\n", Thread.activeCount()); - System.out.println("Listening for messages."); - for (Subscriber subscriber : subscribers) { - try { - // Allow the subscriber to run for 30s unless an unrecoverable error occurs. - subscriber.awaitTerminated(300, TimeUnit.SECONDS); - } catch (TimeoutException timeoutException) { + Subscriber subscriber = null; + try { + subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); + // Start the subscriber. + subscriber.startAsync().awaitRunning(); + System.out.printf("Listening for messages on %s:\n", subscriptionName.toString()); + // Allow the subscriber to run for 30s unless an unrecoverable error occurs. + subscriber.awaitTerminated(30, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { // Shut down the subscriber after 30s. Stop receiving messages. - subscriber.stopAsync(); - } + subscriber.stopAsync(); } } } // [END pubsub_subscriber_async_pull] -// [END pubsub_quickstart_subscriber] +// [END pubsub_quickstart_subscriber] \ No newline at end of file From aed305a156d71a6ab214c10aa7db5b7fa154caa1 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 12 Sep 2023 07:16:47 -0400 Subject: [PATCH 34/42] Revert changes to original async example --- .../snippets/src/main/java/pubsub/SubscribeAsyncExample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java index abca3368f..4d2f40815 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncExample.java @@ -64,4 +64,4 @@ public static void subscribeAsyncExample(String projectId, String subscriptionId } } // [END pubsub_subscriber_async_pull] -// [END pubsub_quickstart_subscriber] \ No newline at end of file +// [END pubsub_quickstart_subscriber] From 11cddae49c042ecc8a52983fd68adc73a06dc873 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Thu, 31 Aug 2023 17:48:02 -0400 Subject: [PATCH 35/42] Add examples of different threading models --- ...bscribeAsyncLimitedConcurrencyExample.java | 170 ++++++++++++++++++ ...cribeAsyncUnlimitedConcurrencyExample.java | 93 ++++++++++ 2 files changed, 263 insertions(+) create mode 100644 samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java create mode 100644 samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java new file mode 100644 index 000000000..935557d0e --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java @@ -0,0 +1,170 @@ +/* + * Copyright 2016 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 pubsub; + +import com.google.api.gax.core.FixedExecutorProvider; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.rpc.FixedTransportChannelProvider; +import com.google.api.gax.rpc.TransportChannelProvider; +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicLong; + +public class SubscribeAsyncLimitedConcurrencyExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project"; + String subscriptionId = "my-subscription"; + + subscribeAsyncLimitedConcurrencyExample(projectId, subscriptionId); + } + + static final int MAX_INBOUND_MESSAGE_SIZE = 20 * 1024 * 1024; // 20MB API maximum message size. + static final int MAX_INBOUND_METADATA_SIZE = 4 * 1024 * 1024; // 4MB API maximum metadata size + + private static ManagedChannel createSingleChannel( + String serviceAddress, int port, Executor executor, Executor offloadExecutor) + throws IOException { + ManagedChannelBuilder builder; + builder = ManagedChannelBuilder.forAddress(serviceAddress, port); + builder = + builder + .executor(executor) + .offloadExecutor(offloadExecutor) + .maxInboundMetadataSize(MAX_INBOUND_METADATA_SIZE) + .keepAliveTime(30, TimeUnit.SECONDS); + + ManagedChannel managedChannel = builder.build(); + return managedChannel; + } + + public static void subscribeAsyncLimitedConcurrencyExample( + String projectId, String subscriptionId) { + int subCount = 100; + int transportChannelCount = 20; + final AtomicLong receivedCount = new AtomicLong(); + + // Instantiate an asynchronous message receiver. + MessageReceiver receiver = + (PubsubMessage message, AckReplyConsumer consumer) -> { + // Handle incoming message, then ack the received message. + consumer.ack(); + long currentCount = receivedCount.incrementAndGet(); + if (currentCount % 100 == 0) { + System.out.println("Received " + currentCount); + } + }; + + ThreadFactory callbackThreadFactory = + new ThreadFactoryBuilder().setNameFormat("callback-pool-%d").build(); + ScheduledThreadPoolExecutor callbackExecutor = + new ScheduledThreadPoolExecutor(10, callbackThreadFactory); + callbackExecutor.setMaximumPoolSize(10); + FixedExecutorProvider callbackExecutorProvider = FixedExecutorProvider.create(callbackExecutor); + ThreadFactory leaseThreadFactory = + new ThreadFactoryBuilder().setNameFormat("lease-pool-%d").build(); + ScheduledThreadPoolExecutor leaseExecutor = + new ScheduledThreadPoolExecutor(10, leaseThreadFactory); + leaseExecutor.setMaximumPoolSize(10); + FixedExecutorProvider leaseExecutorProvider = FixedExecutorProvider.create(leaseExecutor); + ThreadFactory channelThreadFactory = + new ThreadFactoryBuilder().setNameFormat("channel-pool-%d").build(); + ScheduledThreadPoolExecutor channelExecutor = + new ScheduledThreadPoolExecutor(10, channelThreadFactory); + ThreadFactory channelOffloadThreadFactory = + new ThreadFactoryBuilder().setNameFormat("channel-offload-pool-%d").build(); + ScheduledThreadPoolExecutor channelOffloadExecutor = + new ScheduledThreadPoolExecutor(10, channelOffloadThreadFactory); + + ArrayList transportChannelProviders = + new ArrayList<>(transportChannelCount); + + for (int i = 0; i < transportChannelCount; ++i) { + TransportChannelProvider channelProvider = null; + try { + channelProvider = + FixedTransportChannelProvider.create( + GrpcTransportChannel.create( + createSingleChannel( + "pubsub.googleapis.com", 443, channelExecutor, channelOffloadExecutor))); + transportChannelProviders.add(channelProvider); + } catch (Exception e) { + System.out.println("Could not create channel provider: " + e); + return; + } + } + + List subscribers = new ArrayList<>(); + for (int i = 0; i < subCount; ++i) { + + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId + i); + Subscriber subscriber = null; + subscriber = + Subscriber.newBuilder(subscriptionName, receiver) + .setChannelProvider(transportChannelProviders.get(i % transportChannelCount)) + .setExecutorProvider(callbackExecutorProvider) + .setSystemExecutorProvider(leaseExecutorProvider) + .build(); + // Start the subscriber. + subscriber.startAsync().awaitRunning(); + subscribers.add(subscriber); + } + printThreads(); + System.out.println("Listening for messages for 30s before checking threads again."); + try { + Thread.sleep(30000); + } catch (Exception e) { + + } + printThreads(); + + for (Subscriber subscriber : subscribers) { + try { + // Allow the subscriber to run for 30s unless an unrecoverable error occurs. + subscriber.awaitTerminated(120, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { + // Shut down the subscriber after 30s. Stop receiving messages. + subscriber.stopAsync(); + } + } + } + + private static void printThreads() { + System.out.println("Thread names:"); + Set threadSet = Thread.getAllStackTraces().keySet(); + for (Thread t : threadSet) { + System.out.println("\t" + t.getName()); + } + System.out.printf("Thread count: %d\n", Thread.activeCount()); + } +} diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java new file mode 100644 index 000000000..21027663b --- /dev/null +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java @@ -0,0 +1,93 @@ +/* + * Copyright 2016 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 pubsub; + +import com.google.cloud.pubsub.v1.AckReplyConsumer; +import com.google.cloud.pubsub.v1.MessageReceiver; +import com.google.cloud.pubsub.v1.Subscriber; +import com.google.pubsub.v1.ProjectSubscriptionName; +import com.google.pubsub.v1.PubsubMessage; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicLong; + +public class SubscribeAsyncUnlimitedConcurrencyExample { + public static void main(String... args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-topic"; + String subscriptionId = "my-subscription"; + + subscribeAsyncUnlimitedConcurrencyExample(projectId, subscriptionId); + } + + public static void subscribeAsyncUnlimitedConcurrencyExample( + String projectId, String subscriptionId) { + int subCount = 100; + final AtomicLong receivedCount = new AtomicLong(); + + // Instantiate an asynchronous message receiver. + MessageReceiver receiver = + (PubsubMessage message, AckReplyConsumer consumer) -> { + // Handle incoming message, then ack the received message. + consumer.ack(); + long currentCount = receivedCount.incrementAndGet(); + if (currentCount % 100 == 0) { + System.out.println("Received " + currentCount); + } + }; + + List subscribers = new ArrayList<>(); + for (int i = 0; i < subCount; ++i) { + ProjectSubscriptionName subscriptionName = + ProjectSubscriptionName.of(projectId, subscriptionId + i); + Subscriber subscriber = null; + subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); + // Start the subscriber. + subscriber.startAsync().awaitRunning(); + subscribers.add(subscriber); + } + printThreads(); + System.out.println("Listening for messages for 30s before checking threads again."); + try { + Thread.sleep(30000); + } catch (Exception e) { + + } + printThreads(); + for (Subscriber subscriber : subscribers) { + try { + // Allow the subscriber to run for 30s unless an unrecoverable error occurs. + subscriber.awaitTerminated(300, TimeUnit.SECONDS); + } catch (TimeoutException timeoutException) { + // Shut down the subscriber after 30s. Stop receiving messages. + subscriber.stopAsync(); + } + } + } + + private static void printThreads() { + System.out.println("Thread names:"); + Set threadSet = Thread.getAllStackTraces().keySet(); + for (Thread t : threadSet) { + System.out.println("\t" + t.getName()); + } + System.out.printf("Thread count: %d\n", Thread.activeCount()); + } +} From 079acc47b7a021fffa70ab17e721f0d060284b1e Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 12 Sep 2023 07:31:42 -0400 Subject: [PATCH 36/42] Make variables final to conform to style. --- .../java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java | 5 +++-- .../pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java index 935557d0e..491071f1f 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java @@ -60,6 +60,7 @@ private static ManagedChannel createSingleChannel( builder .executor(executor) .offloadExecutor(offloadExecutor) + .maxInboundMessageSize(MAX_INBOUND_MESSAGE_SIZE) .maxInboundMetadataSize(MAX_INBOUND_METADATA_SIZE) .keepAliveTime(30, TimeUnit.SECONDS); @@ -69,8 +70,8 @@ private static ManagedChannel createSingleChannel( public static void subscribeAsyncLimitedConcurrencyExample( String projectId, String subscriptionId) { - int subCount = 100; - int transportChannelCount = 20; + final int subCount = 100; + final int transportChannelCount = 20; final AtomicLong receivedCount = new AtomicLong(); // Instantiate an asynchronous message receiver. diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java index 21027663b..b1accadd0 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java @@ -39,7 +39,7 @@ public static void main(String... args) throws Exception { public static void subscribeAsyncUnlimitedConcurrencyExample( String projectId, String subscriptionId) { - int subCount = 100; + final int subCount = 100; final AtomicLong receivedCount = new AtomicLong(); // Instantiate an asynchronous message receiver. From af96f231fb85760f91942d3916a8420f7e66131e Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 12 Sep 2023 08:38:22 -0400 Subject: [PATCH 37/42] Fix catches --- .../pubsub/SubscribeAsyncLimitedConcurrencyExample.java | 7 ++++--- .../pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java index 491071f1f..c011bd944 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java @@ -42,8 +42,8 @@ public class SubscribeAsyncLimitedConcurrencyExample { public static void main(String... args) throws Exception { // TODO(developer): Replace these variables before running the sample. - String projectId = "my-project"; - String subscriptionId = "my-subscription"; + String projectId = "ordering-keys-testing"; + String subscriptionId = "threads-test"; subscribeAsyncLimitedConcurrencyExample(projectId, subscriptionId); } @@ -145,7 +145,8 @@ public static void subscribeAsyncLimitedConcurrencyExample( try { Thread.sleep(30000); } catch (Exception e) { - + System.out.println("Could not sleep: " + e); + return; } printThreads(); diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java index b1accadd0..fbbb5225e 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java @@ -68,7 +68,8 @@ public static void subscribeAsyncUnlimitedConcurrencyExample( try { Thread.sleep(30000); } catch (Exception e) { - + System.out.println("Could not sleep: " + e); + return; } printThreads(); for (Subscriber subscriber : subscribers) { From 11fda48daf25aba8f069bb98356dcdca6020468e Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 12 Sep 2023 08:40:46 -0400 Subject: [PATCH 38/42] Fix ids --- .../java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java index c011bd944..1fd6d756a 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java @@ -42,8 +42,8 @@ public class SubscribeAsyncLimitedConcurrencyExample { public static void main(String... args) throws Exception { // TODO(developer): Replace these variables before running the sample. - String projectId = "ordering-keys-testing"; - String subscriptionId = "threads-test"; + String projectId = "my-project"; + String subscriptionId = "my-subscription"; subscribeAsyncLimitedConcurrencyExample(projectId, subscriptionId); } From 2e58cd57f80fbb0ecf7d936bcacab419df1a91f1 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Tue, 12 Sep 2023 08:52:21 -0400 Subject: [PATCH 39/42] Fix naming --- .../java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java index fbbb5225e..7419e0ba9 100644 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java +++ b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java @@ -31,7 +31,7 @@ public class SubscribeAsyncUnlimitedConcurrencyExample { public static void main(String... args) throws Exception { // TODO(developer): Replace these variables before running the sample. - String projectId = "my-topic"; + String projectId = "my-project"; String subscriptionId = "my-subscription"; subscribeAsyncUnlimitedConcurrencyExample(projectId, subscriptionId); From a1394c62814647f2f7c264b6b9ee523304ecab39 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Fri, 20 Oct 2023 13:55:38 -0400 Subject: [PATCH 40/42] Revert "Merge pull request #2 from kamalaboulhosn/ML_experiments" This reverts commit 5a435fad03f8c5bc577906ef0088b9899c2963cd, reversing changes made to c3a572560f74fa8e10b7f354352bdd736e6f58aa. --- ...bscribeAsyncLimitedConcurrencyExample.java | 172 ------------------ ...cribeAsyncUnlimitedConcurrencyExample.java | 94 ---------- 2 files changed, 266 deletions(-) delete mode 100644 samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java delete mode 100644 samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java deleted file mode 100644 index 1fd6d756a..000000000 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncLimitedConcurrencyExample.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2016 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 pubsub; - -import com.google.api.gax.core.FixedExecutorProvider; -import com.google.api.gax.grpc.GrpcTransportChannel; -import com.google.api.gax.rpc.FixedTransportChannelProvider; -import com.google.api.gax.rpc.TransportChannelProvider; -import com.google.cloud.pubsub.v1.AckReplyConsumer; -import com.google.cloud.pubsub.v1.MessageReceiver; -import com.google.cloud.pubsub.v1.Subscriber; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.google.pubsub.v1.ProjectSubscriptionName; -import com.google.pubsub.v1.PubsubMessage; -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicLong; - -public class SubscribeAsyncLimitedConcurrencyExample { - public static void main(String... args) throws Exception { - // TODO(developer): Replace these variables before running the sample. - String projectId = "my-project"; - String subscriptionId = "my-subscription"; - - subscribeAsyncLimitedConcurrencyExample(projectId, subscriptionId); - } - - static final int MAX_INBOUND_MESSAGE_SIZE = 20 * 1024 * 1024; // 20MB API maximum message size. - static final int MAX_INBOUND_METADATA_SIZE = 4 * 1024 * 1024; // 4MB API maximum metadata size - - private static ManagedChannel createSingleChannel( - String serviceAddress, int port, Executor executor, Executor offloadExecutor) - throws IOException { - ManagedChannelBuilder builder; - builder = ManagedChannelBuilder.forAddress(serviceAddress, port); - builder = - builder - .executor(executor) - .offloadExecutor(offloadExecutor) - .maxInboundMessageSize(MAX_INBOUND_MESSAGE_SIZE) - .maxInboundMetadataSize(MAX_INBOUND_METADATA_SIZE) - .keepAliveTime(30, TimeUnit.SECONDS); - - ManagedChannel managedChannel = builder.build(); - return managedChannel; - } - - public static void subscribeAsyncLimitedConcurrencyExample( - String projectId, String subscriptionId) { - final int subCount = 100; - final int transportChannelCount = 20; - final AtomicLong receivedCount = new AtomicLong(); - - // Instantiate an asynchronous message receiver. - MessageReceiver receiver = - (PubsubMessage message, AckReplyConsumer consumer) -> { - // Handle incoming message, then ack the received message. - consumer.ack(); - long currentCount = receivedCount.incrementAndGet(); - if (currentCount % 100 == 0) { - System.out.println("Received " + currentCount); - } - }; - - ThreadFactory callbackThreadFactory = - new ThreadFactoryBuilder().setNameFormat("callback-pool-%d").build(); - ScheduledThreadPoolExecutor callbackExecutor = - new ScheduledThreadPoolExecutor(10, callbackThreadFactory); - callbackExecutor.setMaximumPoolSize(10); - FixedExecutorProvider callbackExecutorProvider = FixedExecutorProvider.create(callbackExecutor); - ThreadFactory leaseThreadFactory = - new ThreadFactoryBuilder().setNameFormat("lease-pool-%d").build(); - ScheduledThreadPoolExecutor leaseExecutor = - new ScheduledThreadPoolExecutor(10, leaseThreadFactory); - leaseExecutor.setMaximumPoolSize(10); - FixedExecutorProvider leaseExecutorProvider = FixedExecutorProvider.create(leaseExecutor); - ThreadFactory channelThreadFactory = - new ThreadFactoryBuilder().setNameFormat("channel-pool-%d").build(); - ScheduledThreadPoolExecutor channelExecutor = - new ScheduledThreadPoolExecutor(10, channelThreadFactory); - ThreadFactory channelOffloadThreadFactory = - new ThreadFactoryBuilder().setNameFormat("channel-offload-pool-%d").build(); - ScheduledThreadPoolExecutor channelOffloadExecutor = - new ScheduledThreadPoolExecutor(10, channelOffloadThreadFactory); - - ArrayList transportChannelProviders = - new ArrayList<>(transportChannelCount); - - for (int i = 0; i < transportChannelCount; ++i) { - TransportChannelProvider channelProvider = null; - try { - channelProvider = - FixedTransportChannelProvider.create( - GrpcTransportChannel.create( - createSingleChannel( - "pubsub.googleapis.com", 443, channelExecutor, channelOffloadExecutor))); - transportChannelProviders.add(channelProvider); - } catch (Exception e) { - System.out.println("Could not create channel provider: " + e); - return; - } - } - - List subscribers = new ArrayList<>(); - for (int i = 0; i < subCount; ++i) { - - ProjectSubscriptionName subscriptionName = - ProjectSubscriptionName.of(projectId, subscriptionId + i); - Subscriber subscriber = null; - subscriber = - Subscriber.newBuilder(subscriptionName, receiver) - .setChannelProvider(transportChannelProviders.get(i % transportChannelCount)) - .setExecutorProvider(callbackExecutorProvider) - .setSystemExecutorProvider(leaseExecutorProvider) - .build(); - // Start the subscriber. - subscriber.startAsync().awaitRunning(); - subscribers.add(subscriber); - } - printThreads(); - System.out.println("Listening for messages for 30s before checking threads again."); - try { - Thread.sleep(30000); - } catch (Exception e) { - System.out.println("Could not sleep: " + e); - return; - } - printThreads(); - - for (Subscriber subscriber : subscribers) { - try { - // Allow the subscriber to run for 30s unless an unrecoverable error occurs. - subscriber.awaitTerminated(120, TimeUnit.SECONDS); - } catch (TimeoutException timeoutException) { - // Shut down the subscriber after 30s. Stop receiving messages. - subscriber.stopAsync(); - } - } - } - - private static void printThreads() { - System.out.println("Thread names:"); - Set threadSet = Thread.getAllStackTraces().keySet(); - for (Thread t : threadSet) { - System.out.println("\t" + t.getName()); - } - System.out.printf("Thread count: %d\n", Thread.activeCount()); - } -} diff --git a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java b/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java deleted file mode 100644 index 7419e0ba9..000000000 --- a/samples/snippets/src/main/java/pubsub/SubscribeAsyncUnlimitedConcurrencyExample.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2016 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 pubsub; - -import com.google.cloud.pubsub.v1.AckReplyConsumer; -import com.google.cloud.pubsub.v1.MessageReceiver; -import com.google.cloud.pubsub.v1.Subscriber; -import com.google.pubsub.v1.ProjectSubscriptionName; -import com.google.pubsub.v1.PubsubMessage; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicLong; - -public class SubscribeAsyncUnlimitedConcurrencyExample { - public static void main(String... args) throws Exception { - // TODO(developer): Replace these variables before running the sample. - String projectId = "my-project"; - String subscriptionId = "my-subscription"; - - subscribeAsyncUnlimitedConcurrencyExample(projectId, subscriptionId); - } - - public static void subscribeAsyncUnlimitedConcurrencyExample( - String projectId, String subscriptionId) { - final int subCount = 100; - final AtomicLong receivedCount = new AtomicLong(); - - // Instantiate an asynchronous message receiver. - MessageReceiver receiver = - (PubsubMessage message, AckReplyConsumer consumer) -> { - // Handle incoming message, then ack the received message. - consumer.ack(); - long currentCount = receivedCount.incrementAndGet(); - if (currentCount % 100 == 0) { - System.out.println("Received " + currentCount); - } - }; - - List subscribers = new ArrayList<>(); - for (int i = 0; i < subCount; ++i) { - ProjectSubscriptionName subscriptionName = - ProjectSubscriptionName.of(projectId, subscriptionId + i); - Subscriber subscriber = null; - subscriber = Subscriber.newBuilder(subscriptionName, receiver).build(); - // Start the subscriber. - subscriber.startAsync().awaitRunning(); - subscribers.add(subscriber); - } - printThreads(); - System.out.println("Listening for messages for 30s before checking threads again."); - try { - Thread.sleep(30000); - } catch (Exception e) { - System.out.println("Could not sleep: " + e); - return; - } - printThreads(); - for (Subscriber subscriber : subscribers) { - try { - // Allow the subscriber to run for 30s unless an unrecoverable error occurs. - subscriber.awaitTerminated(300, TimeUnit.SECONDS); - } catch (TimeoutException timeoutException) { - // Shut down the subscriber after 30s. Stop receiving messages. - subscriber.stopAsync(); - } - } - } - - private static void printThreads() { - System.out.println("Thread names:"); - Set threadSet = Thread.getAllStackTraces().keySet(); - for (Thread t : threadSet) { - System.out.println("\t" + t.getName()); - } - System.out.printf("Thread count: %d\n", Thread.activeCount()); - } -} From d2f52cfc53ab0546385f3d53a8f6af58e6079721 Mon Sep 17 00:00:00 2001 From: Kamal Aboul-Hosn Date: Fri, 20 Oct 2023 13:56:02 -0400 Subject: [PATCH 41/42] Set blunderbuss config to auto-assign issues and PRs --- .github/blunderbuss.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 2176b0543..44ab091e1 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1,5 +1,9 @@ # Configuration for the Blunderbuss GitHub app. For more info see # https://github.com/googleapis/repo-automation-bots/tree/main/packages/blunderbuss +assign_issues: + - maitrimangal +assign_prs: + - maitrimangal assign_prs_by: - labels: - samples From ffccdd34e7257c05f871be5e080600db40f8371d Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Mon, 23 Oct 2023 15:28:29 +0000 Subject: [PATCH 42/42] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20?= =?UTF-8?q?post-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- .github/blunderbuss.yml | 4 ---- README.md | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 44ab091e1..2176b0543 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1,9 +1,5 @@ # Configuration for the Blunderbuss GitHub app. For more info see # https://github.com/googleapis/repo-automation-bots/tree/main/packages/blunderbuss -assign_issues: - - maitrimangal -assign_prs: - - maitrimangal assign_prs_by: - labels: - samples diff --git a/README.md b/README.md index 2fe83530a..2c8d63df4 100644 --- a/README.md +++ b/README.md @@ -52,20 +52,20 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.19.0') +implementation platform('com.google.cloud:libraries-bom:26.25.0') implementation 'com.google.cloud:google-cloud-pubsub' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-pubsub:1.123.18' +implementation 'com.google.cloud:google-cloud-pubsub:1.125.7' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-pubsub" % "1.123.18" +libraryDependencies += "com.google.cloud" % "google-cloud-pubsub" % "1.125.7" ``` @@ -408,7 +408,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-pubsub/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-pubsub.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-pubsub/1.123.18 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-pubsub/1.125.7 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles