registries =
- service
- .projects()
- .locations()
- .registries()
- .list(projectPath)
- .execute()
- .getDeviceRegistries();
- return registries;
- }
-
- /**
- * clearRegistry
- *
- *
- * - Registries can't be deleted if they contain devices,
- *
- Gateways (a type of device) can't be deleted if they have bound devices
- *
- Devices can't be deleted if bound to gateways...
- *
- *
- * To completely remove a registry, you must unbind all devices from gateways, then remove all
- * devices in a registry before removing the registry. As pseudocode:
- * ForAll gateways
- * ForAll devicesBoundToGateway
- * unbindDeviceFromGateway
- * ForAll devices
- * Delete device by ID
- * Delete registry
- *
- */
- protected static void clearRegistry(String cloudRegion, String projectId, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- CloudIot.Projects.Locations.Registries regAlias = service.projects().locations().registries();
- CloudIot.Projects.Locations.Registries.Devices devAlias = regAlias.devices();
-
- // Remove all devices from the regsitry
- List devices = devAlias.list(registryPath).execute().getDevices();
-
- if (devices != null) {
- System.out.println("Found " + devices.size() + " devices");
- for (Device d : devices) {
- String deviceId = d.getId();
- String devicePath = String.format("%s/devices/%s", registryPath, deviceId);
- service.projects().locations().registries().devices().delete(devicePath).execute();
- }
- }
-
- // Delete the registry
- service.projects().locations().registries().delete(registryPath).execute();
- }
-}
diff --git a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleMqttDevice.java b/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleMqttDevice.java
deleted file mode 100644
index d846832e4b0..00000000000
--- a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleMqttDevice.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2019 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.endtoend;
-
-import io.jsonwebtoken.JwtBuilder;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.security.KeyFactory;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.time.Instant;
-import java.util.Date;
-import java.util.Properties;
-import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
-import org.eclipse.paho.client.mqttv3.MqttCallback;
-import org.eclipse.paho.client.mqttv3.MqttClient;
-import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
-import org.eclipse.paho.client.mqttv3.MqttException;
-import org.eclipse.paho.client.mqttv3.MqttMessage;
-import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Sample device that consumes configuration from Google Cloud IoT. This example represents a simple
- * device with a temperature sensor and a fan (simulated with software). When the device's fan is
- * turned on, its temperature decreases by one degree per second, and when the device's fan is
- * turned off, its temperature increases by one degree per second.
- *
- * Every second, the device publishes its temperature reading to Google Cloud IoT Core. The
- * server meanwhile receives these temperature readings, and decides whether to re-configure the
- * device to turn its fan on or off. The server will instruct the device to turn the fan on when the
- * device's temperature exceeds 10 degrees, and to turn it off when the device's temperature is less
- * than 0 degrees. In a real system, one could use the cloud to compute the optimal thresholds for
- * turning on and off the fan, but for illustrative purposes we use a simple threshold model.
- *
- * To connect the device you must have downloaded Google's CA root certificates, and a copy of
- * your private key file. See cloud.google.com/iot for instructions on how to do this. Run this
- * script with the corresponding algorithm flag.
- *
- *
- * $ mvn clean compile assembly:single
- *
- * $ mvn exec:java \
- * -Dexec.mainClass="com.example.cloud.iot.endtoend.CloudiotPubsubExampleMqttDevice" \
- * -Dexec.args="-project_id=your-iot-project \
- * -registry_id=your-registry-id \
- * -device_id=device-id \
- * -private_key_file=path-to-keyfile \
- * -algorithm=RS256|ES256"
- *
- *
- * With a single server, you can run multiple instances of the device with different device ids,
- * and the server will distinguish them. Try creating a few devices and running them all at the same
- * time.
- */
-public class CloudiotPubsubExampleMqttDevice {
-
- /** Create a RSA-based JWT for the given project id, signed with the given private key. */
- private static String createJwtRsa(String projectId, String privateKeyFile) throws Exception {
- Instant now = Instant.now();
- // Create a JWT to authenticate this device. The device will be disconnected after the token
- // expires, and will have to reconnect with a new token. The audience field should always be set
- // to the GCP project id.
- JwtBuilder jwtBuilder =
- Jwts.builder()
- .setIssuedAt(Date.from(now))
- .setExpiration(Date.from(now.plusSeconds(60 * 20)))
- .setAudience(projectId);
-
- byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory kf = KeyFactory.getInstance("RSA");
-
- return jwtBuilder.signWith(SignatureAlgorithm.RS256, kf.generatePrivate(spec)).compact();
- }
-
- /** Create an ES-based JWT for the given project id, signed with the given private key. */
- private static String createJwtEs(String projectId, String privateKeyFile) throws Exception {
- Instant now = Instant.now();
- // Create a JWT to authenticate this device. The device will be disconnected after the token
- // expires, and will have to reconnect with a new token. The audience field should always be set
- // to the GCP project id.
- JwtBuilder jwtBuilder =
- Jwts.builder()
- .setIssuedAt(Date.from(now))
- .setExpiration(Date.from(now.plusSeconds(60 * 20)))
- .setAudience(projectId);
-
- byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory kf = KeyFactory.getInstance("EC");
-
- return jwtBuilder.signWith(SignatureAlgorithm.ES256, kf.generatePrivate(spec)).compact();
- }
-
- /** Represents the state of a single device. */
- static class Device implements MqttCallback {
- private int temperature;
- private boolean isFanOn;
- private boolean isConnected;
-
- public Device(CloudiotPubsubExampleMqttDeviceOptions options) {
- this.temperature = 0;
- this.isFanOn = false;
- this.isConnected = false;
- }
-
- /**
- * Pretend to read the device's sensor data. If the fan is on, assume the temperature decreased
- * one degree, otherwise assume that it increased one degree.
- */
- public void updateSensorData() {
- if (this.isFanOn) {
- this.temperature -= 1;
- } else {
- this.temperature += 1;
- }
- }
-
- /** Wait for the device to become connected. */
- public void waitForConnection(int timeOut) throws InterruptedException {
- // Wait for the device to become connected.
- int totalTime = 0;
- while (!this.isConnected && totalTime < timeOut) {
- Thread.sleep(1000);
- totalTime += 1;
- }
-
- if (!this.isConnected) {
- throw new RuntimeException("Could not connect to MQTT bridge.");
- }
- }
-
- /** Callback when the device receives a PUBACK from the MQTT bridge. */
- @Override
- public void deliveryComplete(IMqttDeliveryToken token) {
- System.out.println("Published message acked.");
- }
-
- /** Callback when the device receives a message on a subscription. */
- @Override
- public void messageArrived(String topic, MqttMessage message) {
- String payload = new String(message.getPayload());
- System.out.println(
- String.format(
- "Received message %s on topic %s with Qos %d", payload, topic, message.getQos()));
-
- // The device will receive its latest config when it subscribes to the
- // config topic. If there is no configuration for the device, the device
- // will receive a config with an empty payload.
- if (payload == null || payload.length() == 0) {
- return;
- }
-
- // The config is passed in the payload of the message. In this example,
- // the server sends a serialized JSON string.
- JSONObject data = null;
- try {
- data = new JSONObject(payload);
- if (data.get("fan_on") instanceof Boolean && (Boolean) data.get("fan_on") != this.isFanOn) {
- // If changing the state of the fan, print a message and
- // update the internal state.
- this.isFanOn = (Boolean) data.get("fan_on");
- if (this.isFanOn) {
- System.out.println("Fan turned on");
- } else {
- System.out.println("Fan turned off");
- }
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- /** Callback for when a device disconnects. */
- @Override
- public void connectionLost(Throwable cause) {
- System.out.println("Disconnected: " + cause.getMessage());
- this.isConnected = false;
- }
- }
-
- /** Entry point for CLI. */
- public static void main(String[] args) throws Exception {
- CloudiotPubsubExampleMqttDeviceOptions options =
- CloudiotPubsubExampleMqttDeviceOptions.fromFlags(args);
- if (options == null) {
- System.exit(1);
- }
- final Device device = new Device(options);
- final String mqttTelemetryTopic = String.format("/devices/%s/events", options.deviceId);
- // This is the topic that the device will receive configuration updates on.
- final String mqttConfigTopic = String.format("/devices/%s/config", options.deviceId);
-
- final String mqttServerAddress =
- String.format("ssl://%s:%s", options.mqttBridgeHostname, options.mqttBridgePort);
- final String mqttClientId =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- options.projectId, options.cloudRegion, options.registryId, options.deviceId);
- MqttConnectOptions connectOptions = new MqttConnectOptions();
- connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
-
- Properties sslProps = new Properties();
- sslProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
- connectOptions.setSSLProperties(sslProps);
-
- connectOptions.setUserName("unused");
- if (options.algorithm.equals("RS256")) {
- System.out.println(options.privateKeyFile);
-
- connectOptions.setPassword(
- createJwtRsa(options.projectId, options.privateKeyFile).toCharArray());
- System.out.println(
- String.format(
- "Creating JWT using RS256 from private key file %s", options.privateKeyFile));
- } else if (options.algorithm.equals("ES256")) {
- connectOptions.setPassword(
- createJwtEs(options.projectId, options.privateKeyFile).toCharArray());
- } else {
- throw new IllegalArgumentException(
- "Invalid algorithm " + options.algorithm + ". Should be one of 'RS256' or 'ES256'.");
- }
-
- device.isConnected = true;
-
- MqttClient client = new MqttClient(mqttServerAddress, mqttClientId, new MemoryPersistence());
-
- try {
- client.setCallback(device);
- client.connect(connectOptions);
- } catch (MqttException e) {
- e.printStackTrace();
- }
-
- // wait for it to connect
- device.waitForConnection(5);
-
- client.subscribe(mqttConfigTopic, 1);
-
- for (int i = 0; i < options.numMessages; i++) {
- device.updateSensorData();
-
- JSONObject payload = new JSONObject();
- payload.put("temperature", device.temperature);
- System.out.println("Publishing payload " + payload.toString());
- MqttMessage message = new MqttMessage(payload.toString().getBytes());
- message.setQos(1);
- client.publish(mqttTelemetryTopic, message);
- Thread.sleep(1000);
- }
- client.disconnect();
-
- System.out.println("Finished looping successfully : " + options.mqttBridgeHostname);
- }
-}
diff --git a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleMqttDeviceOptions.java b/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleMqttDeviceOptions.java
deleted file mode 100644
index 73bf82f709a..00000000000
--- a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleMqttDeviceOptions.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2019 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.endtoend;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** Command line options for the Pubsub Mqtt device example. */
-public class CloudiotPubsubExampleMqttDeviceOptions {
- String projectId;
- String registryId;
- String deviceId;
- String privateKeyFile;
- String algorithm;
- String cloudRegion = "us-central1";
- int numMessages = 100;
- String mqttBridgeHostname = "mqtt.googleapis.com";
- short mqttBridgePort = 8883; // if running from a Compute VM, use 443.
- String messageType = "event";
-
- static final Options options = new Options();
-
- public static CloudiotPubsubExampleMqttDeviceOptions fromFlags(String[] args) {
- // Required arguments
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("registry_id")
- .hasArg()
- .desc("Cloud IoT Core registry id.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("device_id")
- .hasArg()
- .desc("Cloud IoT Core device id.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("private_key_file")
- .hasArg()
- .desc("Path to private key file.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("algorithm")
- .hasArg()
- .desc("Encryption algorithm to use to generate the JWT. Either 'RS256' or 'ES256'.")
- .required()
- .build());
- // Optional arguments
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("project_id")
- .hasArg()
- .desc("GCP cloud project name.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("cloud_region")
- .hasArg()
- .desc("GCP cloud region.")
- .build());
- options.addOption(
- Option.builder()
- .type(Number.class)
- .longOpt("num_messages")
- .hasArg()
- .desc("Number of messages to publish.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("mqtt_bridge_hostname")
- .hasArg()
- .desc("MQTT bridge hostname.")
- .build());
- options.addOption(
- Option.builder()
- .type(Number.class)
- .longOpt("mqtt_bridge_port") // this supports either 8883 or 443,
- .hasArg() // if running on Cloud shell, use 443.
- .desc("MQTT bridge port.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("message_type")
- .hasArg()
- .desc("Indicates whether the message is a telemetry event or a device state message")
- .build());
-
- CommandLineParser parser = new DefaultParser();
- CommandLine commandLine;
-
- try {
- commandLine = parser.parse(options, args);
- CloudiotPubsubExampleMqttDeviceOptions res = new CloudiotPubsubExampleMqttDeviceOptions();
-
- res.registryId = commandLine.getOptionValue("registry_id");
- res.deviceId = commandLine.getOptionValue("device_id");
- res.privateKeyFile = commandLine.getOptionValue("private_key_file");
- res.algorithm = commandLine.getOptionValue("algorithm");
-
- if (commandLine.hasOption("project_id")) {
- res.projectId = commandLine.getOptionValue("project_id");
- } else {
- try {
- res.projectId = System.getenv("GOOGLE_CLOUD_PROJECT");
- } catch (NullPointerException npe) {
- res.projectId = System.getenv("GCLOUD_PROJECT");
- }
- }
- if (commandLine.hasOption("cloud_region")) {
- res.cloudRegion = commandLine.getOptionValue("cloud_region");
- }
- if (commandLine.hasOption("num_messages")) {
- res.numMessages = ((Number) commandLine.getParsedOptionValue("num_messages")).intValue();
- }
- if (commandLine.hasOption("mqtt_bridge_hostname")) {
- res.mqttBridgeHostname = commandLine.getOptionValue("mqtt_bridge_hostname");
- }
- if (commandLine.hasOption("mqtt_bridge_port")) {
- res.mqttBridgePort =
- ((Number) commandLine.getParsedOptionValue("mqtt_bridge_port")).shortValue();
- }
- if (commandLine.hasOption("message_type")) {
- res.messageType = commandLine.getOptionValue("message_type");
- }
-
- return res;
- } catch (ParseException e) {
- System.err.println(e.getMessage());
- return null;
- }
- }
-}
diff --git a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServer.java b/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServer.java
deleted file mode 100644
index 1cc7e50b611..00000000000
--- a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServer.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright 2019 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.endtoend;
-
-import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
-import com.google.api.client.http.HttpRequestInitializer;
-import com.google.api.client.json.JsonFactory;
-import com.google.api.client.json.gson.GsonFactory;
-import com.google.api.services.cloudiot.v1.CloudIot;
-import com.google.api.services.cloudiot.v1.CloudIotScopes;
-import com.google.api.services.cloudiot.v1.model.Device;
-import com.google.api.services.cloudiot.v1.model.DeviceRegistry;
-import com.google.api.services.cloudiot.v1.model.EventNotificationConfig;
-import com.google.api.services.cloudiot.v1.model.GatewayConfig;
-import com.google.api.services.cloudiot.v1.model.ModifyCloudToDeviceConfigRequest;
-import com.google.auth.http.HttpCredentialsAdapter;
-import com.google.auth.oauth2.GoogleCredentials;
-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.MoreExecutors;
-import com.google.pubsub.v1.ProjectSubscriptionName;
-import com.google.pubsub.v1.PubsubMessage;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.List;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Sample server that pushes configuration to Google Cloud IoT devices.
- *
- * This example represents a server that consumes telemetry data from multiple Cloud IoT devices.
- * The devices report telemetry data, which the server consumes from a Cloud Pub/Sub topic. The
- * server then decides whether to turn on or off individual devices fans.
- *
- * If you are running this example from a Compute Engine VM, you will have to enable the Cloud
- * Pub/Sub API for your project, which you can do from the Cloud Console. Create a pubsub topic, for
- * example projects/my-project-id/topics/my-topic-name, and a subscription, for example
- * projects/my-project-id/subscriptions/my-topic-subscription.
- *
- * You can then run the example with
- * $ mvn clean compile assembly:single
- *
- * $ mvn exec:java \
- * -Dexec.mainClass="com.example.cloud.iot.endtoend.CloudiotPubsubExampleServer" \
- * -Dexec.args="-project_id=your-iot-project \
- * -pubsub_subscription=your-pubsub-subscription"
- *
- *
- */
-public class CloudiotPubsubExampleServer {
-
- static final String APP_NAME = "CloudiotPubsubExampleServer";
-
- CloudIot service;
-
- /** Represents the state of the server. */
- public CloudiotPubsubExampleServer() throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- this.service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
- }
-
- /** Create a registry for Cloud IoT. */
- public static void createRegistry(
- String cloudRegion, String projectId, String registryName, String pubsubTopicPath)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String projectPath = "projects/" + projectId + "/locations/" + cloudRegion;
- final String fullPubsubPath = "projects/" + projectId + "/topics/" + pubsubTopicPath;
-
- DeviceRegistry registry = new DeviceRegistry();
- EventNotificationConfig notificationConfig = new EventNotificationConfig();
- notificationConfig.setPubsubTopicName(fullPubsubPath);
- List notificationConfigs = new ArrayList();
- notificationConfigs.add(notificationConfig);
- registry.setEventNotificationConfigs(notificationConfigs);
- registry.setId(registryName);
-
- DeviceRegistry reg =
- service.projects().locations().registries().create(projectPath, registry).execute();
- System.out.println("Created registry: " + reg.getName());
- }
-
- /** Delete this registry from Cloud IoT. */
- public static void deleteRegistry(String cloudRegion, String projectId, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- System.out.println("Deleting: " + registryPath);
- service.projects().locations().registries().delete(registryPath).execute();
- }
-
- /** Delete this device from Cloud IoT. */
- public static void deleteDevice(
- String deviceId, String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- System.out.println("Deleting device " + devicePath);
- service.projects().locations().registries().devices().delete(devicePath).execute();
- }
-
- /** Create a device to bind to a gateway. */
- public static void createDevice(
- String projectId, String cloudRegion, String registryName, String deviceId)
- throws GeneralSecurityException, IOException {
- // [START create_device]
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- List devices =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .list(registryPath)
- .setFieldMask("config,gatewayConfig")
- .execute()
- .getDevices();
-
- if (devices != null) {
- System.out.println("Found " + devices.size() + " devices");
- for (Device d : devices) {
- if ((d.getId() != null && d.getId().equals(deviceId))
- || (d.getName() != null && d.getName().equals(deviceId))) {
- System.out.println("Device exists, skipping.");
- return;
- }
- }
- }
-
- System.out.println("Creating device with id: " + deviceId);
- Device device = new Device();
- device.setId(deviceId);
-
- GatewayConfig gwConfig = new GatewayConfig();
- gwConfig.setGatewayType("NON_GATEWAY");
- gwConfig.setGatewayAuthMethod("ASSOCIATION_ONLY");
-
- device.setGatewayConfig(gwConfig);
- Device createdDevice =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .create(registryPath, device)
- .execute();
-
- System.out.println("Created device: " + createdDevice.toPrettyString());
- // [END create_device]
- }
-
- /** Push the data to the given device as configuration. */
- public void updateDeviceConfig(
- String projectId, String region, String registryId, String deviceId, JSONObject data)
- throws JSONException, UnsupportedEncodingException {
- // Push the data to the given device as configuration.
- JSONObject configData = new JSONObject();
- System.out.println(
- String.format("Device %s has temperature of: %d", deviceId, data.getInt("temperature")));
- if (data.getInt("temperature") < 0) {
- // Turn off the fan
- configData.put("fan_on", false);
- System.out.println("Setting fan state for device " + deviceId + " to off.");
- } else if (data.getInt("temperature") > 10) {
- // Turn on the fan
- configData.put("fan_on", true);
- System.out.println("Setting fan state for device " + deviceId + " to on.");
- } else {
- // temperature is okay, don't need to push new config
- return;
- }
- // Data sent through the wire has to be base64 encoded.
- Base64.Encoder encoder = Base64.getEncoder();
- String encPayload = encoder.encodeToString(configData.toString().getBytes("UTF-8"));
-
- ModifyCloudToDeviceConfigRequest request = new ModifyCloudToDeviceConfigRequest();
- request.setBinaryData(encPayload);
-
- String deviceName =
- String.format(
- "projects/%s/locations/%s/" + "registries/%s/devices/%s",
- projectId, region, registryId, deviceId);
-
- try {
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .modifyCloudToDeviceConfig(deviceName, request)
- .execute();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /** The main loop. Consumes messages from the Pub/Sub subscription. */
- public void run(String projectId, String subscriptionId) {
- ProjectSubscriptionName subscriptionName =
- ProjectSubscriptionName.of(projectId, subscriptionId);
- // Instantiate an asynchronous message receiver
- MessageReceiver receiver =
- new MessageReceiver() {
- @Override
- public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
- // handle incoming message, then ack/nack the received message
- try {
- JSONObject data = new JSONObject(message.getData().toStringUtf8());
- String projectId = message.getAttributesOrThrow("projectId");
- String region = message.getAttributesOrThrow("deviceRegistryLocation");
- String registryId = message.getAttributesOrThrow("deviceRegistryId");
- String deviceId = message.getAttributesOrThrow("deviceId");
-
- CloudiotPubsubExampleServer.this.updateDeviceConfig(
- projectId, region, registryId, deviceId, data);
- consumer.ack();
- } catch (JSONException e) {
- e.printStackTrace();
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- }
- };
-
- Subscriber subscriber = null;
- try {
- subscriber = Subscriber.newBuilder(subscriptionName, receiver).build();
- subscriber.addListener(
- new Subscriber.Listener() {
- @Override
- public void failed(Subscriber.State from, Throwable failure) {
- // Handle failure. This is called when the Subscriber encountered a fatal error and is
- // shutting down.
- System.err.println(failure);
- }
- },
- MoreExecutors.directExecutor());
- subscriber.startAsync().awaitRunning();
- System.out.println(
- String.format("Listening for messages on %s", subscriber.getSubscriptionNameString()));
- while (true) {
- Thread.sleep(60000);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- if (subscriber != null) {
- subscriber.stopAsync().awaitTerminated();
- }
- }
- }
-
- /** Entry point for CLI. */
- public static void main(String[] args) throws Exception {
- CloudiotPubsubExampleServerOptions options = CloudiotPubsubExampleServerOptions.fromFlags(args);
- if (options == null) {
- System.exit(1);
- }
-
- CloudiotPubsubExampleServer server = new CloudiotPubsubExampleServer();
- String projectId = options.projectId;
- String pubsubscription = options.pubsubSubscription;
- server.run(projectId, pubsubscription);
- }
-}
diff --git a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServerOptions.java b/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServerOptions.java
deleted file mode 100644
index 0038fe0d458..00000000000
--- a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServerOptions.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2019 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.endtoend;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-public class CloudiotPubsubExampleServerOptions {
- String projectId;
- String pubsubSubscription;
-
- static final Options options = new Options();
-
- public static CloudiotPubsubExampleServerOptions fromFlags(String[] args) {
- // Required arguments
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("pubsub_subscription")
- .hasArg()
- .desc("Google Cloud Pub/Sub subscription name.")
- .required()
- .build());
-
- // Optional arguments
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("project_id")
- .hasArg()
- .desc("GCP cloud project name.")
- .build());
-
- CommandLineParser parser = new DefaultParser();
- CommandLine commandLine;
-
- try {
- commandLine = parser.parse(options, args);
- CloudiotPubsubExampleServerOptions res = new CloudiotPubsubExampleServerOptions();
-
- if (commandLine.hasOption("project_id")) {
- res.projectId = commandLine.getOptionValue("project_id");
- } else {
- try {
- res.projectId = System.getenv("GOOGLE_CLOUD_PROJECT");
- } catch (NullPointerException npe) {
- res.projectId = System.getenv("GCLOUD_PROJECT");
- }
- }
-
- if (commandLine.hasOption("pubsub_subscription")) {
- res.pubsubSubscription = commandLine.getOptionValue("pubsub_subscription");
- }
-
- return res;
- } catch (ParseException e) {
- System.err.println(e.getMessage());
- return null;
- }
- }
-}
diff --git a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/RetryHttpInitializerWrapper.java b/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/RetryHttpInitializerWrapper.java
deleted file mode 100644
index e63a9b091d3..00000000000
--- a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/RetryHttpInitializerWrapper.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2019 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.endtoend;
-
-import com.google.api.client.auth.oauth2.Credential;
-import com.google.api.client.http.HttpBackOffIOExceptionHandler;
-import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
-import com.google.api.client.http.HttpRequest;
-import com.google.api.client.http.HttpRequestInitializer;
-import com.google.api.client.http.HttpResponse;
-import com.google.api.client.http.HttpUnsuccessfulResponseHandler;
-import com.google.api.client.util.ExponentialBackOff;
-import com.google.api.client.util.Sleeper;
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.util.logging.Logger;
-
-/**
- * RetryHttpInitializerWrapper will automatically retry upon RPC failures, preserving the
- * auto-refresh behavior of the Google Credentials.
- */
-public class RetryHttpInitializerWrapper implements HttpRequestInitializer {
-
- /** A private logger. */
- private static final Logger LOG = Logger.getLogger(RetryHttpInitializerWrapper.class.getName());
-
- /** One minutes in milliseconds. */
- private static final int ONE_MINUTE_MILLIS = 60 * 1000;
-
- /**
- * Intercepts the request for filling in the "Authorization" header field, as well as recovering
- * from certain unsuccessful error codes wherein the Credential must refresh its token for a
- * retry.
- */
- private final Credential wrappedCredential;
-
- /** A sleeper; you can replace it with a mock in your test. */
- private final Sleeper sleeper;
-
- /**
- * A constructor.
- *
- * @param wrappedCredential Credential which will be wrapped and used for providing auth header.
- */
- public RetryHttpInitializerWrapper(final Credential wrappedCredential) {
- this(wrappedCredential, Sleeper.DEFAULT);
- }
-
- /**
- * A protected constructor only for testing.
- *
- * @param wrappedCredential Credential which will be wrapped and used for providing auth header.
- * @param sleeper Sleeper for easy testing.
- */
- RetryHttpInitializerWrapper(final Credential wrappedCredential, final Sleeper sleeper) {
- this.wrappedCredential = Preconditions.checkNotNull(wrappedCredential);
- this.sleeper = sleeper;
- }
-
- /** Initializes the given request. */
- @Override
- public final void initialize(final HttpRequest request) {
- request.setReadTimeout(2 * ONE_MINUTE_MILLIS); // 2 minutes read timeout
- final HttpUnsuccessfulResponseHandler backoffHandler =
- new HttpBackOffUnsuccessfulResponseHandler(new ExponentialBackOff()).setSleeper(sleeper);
- request.setInterceptor(wrappedCredential);
- request.setUnsuccessfulResponseHandler(
- new HttpUnsuccessfulResponseHandler() {
- @Override
- public boolean handleResponse(
- final HttpRequest request, final HttpResponse response, final boolean supportsRetry)
- throws IOException {
- if (wrappedCredential.handleResponse(request, response, supportsRetry)) {
- // If credential decides it can handle it, the return code or message indicated
- // something specific to authentication, and no backoff is desired.
- return true;
- } else if (backoffHandler.handleResponse(request, response, supportsRetry)) {
- // Otherwise, we defer to the judgment of our internal backoff handler.
- LOG.info("Retrying " + request.getUrl().toString());
- return true;
- } else {
- return false;
- }
- }
- });
- request.setIOExceptionHandler(
- new HttpBackOffIOExceptionHandler(new ExponentialBackOff()).setSleeper(sleeper));
- }
-}
diff --git a/iot/api-client/end-to-end-example/src/test/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServerTest.java b/iot/api-client/end-to-end-example/src/test/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServerTest.java
deleted file mode 100644
index 65d96a00da1..00000000000
--- a/iot/api-client/end-to-end-example/src/test/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServerTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2019 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.endtoend;
-
-import com.google.api.client.googleapis.json.GoogleJsonResponseException;
-import com.google.api.services.cloudiot.v1.model.DeviceRegistry;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.List;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for iot End to End sample. */
-@RunWith(JUnit4.class)
-@SuppressWarnings("checkstyle:abbreviationaswordinname")
-public class CloudiotPubsubExampleServerTest {
- private ByteArrayOutputStream bout;
- private PrintStream out;
-
- private static final String CLOUD_REGION = "us-central1";
- private static final String DEVICE_ID_TEMPLATE = "test-device-%s";
- private static final String DEVICE_ID =
- String.format(DEVICE_ID_TEMPLATE, System.currentTimeMillis() * 1000);
- private static final String TOPIC_ID =
- String.format("test-device-events-%d", System.currentTimeMillis() * 1000);
- private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT");
- private static final String REGISTRY_ID =
- String.format("test-registry-%d", System.currentTimeMillis() * 1000);
-
- @Before
- public void setUp() throws Exception {
- bout = new ByteArrayOutputStream();
- out = new PrintStream(bout);
- System.setOut(out);
- }
-
- @After
- public void tearDown() throws Exception {
- System.setOut(null);
- }
-
- @Test
- public void testConfigTurnOn() throws GeneralSecurityException, IOException, JSONException {
- int maxTemp = 11;
- JSONObject data = new JSONObject();
-
- try {
- CloudiotPubsubExampleServer.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- } catch (GoogleJsonResponseException ex) {
- if (!ex.isSuccessStatusCode() || ex.getDetails().getCode() == 429) {
- System.out.println("Cleaning up registry: " + REGISTRY_ID);
- // Clean up the 80% of old registries
- deleteUnusedOldRegistries(PROJECT_ID, CLOUD_REGION);
- // retry since the creation failed.
- CloudiotPubsubExampleServer.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- }
- }
-
- // Set up
- CloudiotPubsubExampleServer.createDevice(PROJECT_ID, CLOUD_REGION, REGISTRY_ID, DEVICE_ID);
-
- data.put("temperature", maxTemp);
- CloudiotPubsubExampleServer server = new CloudiotPubsubExampleServer();
- server.updateDeviceConfig(PROJECT_ID, CLOUD_REGION, REGISTRY_ID, DEVICE_ID, data);
- String got = bout.toString();
- Assert.assertTrue(got.contains("on"));
- Assert.assertTrue(got.contains("11"));
- Assert.assertTrue(got.contains("test-device-"));
-
- // Clean up
- CloudiotPubsubExampleServer.deleteDevice(DEVICE_ID, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- CloudiotPubsubExampleServer.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- private void deleteUnusedOldRegistries(String projectId, String region)
- throws IOException, GeneralSecurityException {
- // Clean 50 oldest registries with testing prefix in the project.
- System.out.println("The maximum number of registries is about to exceed.");
- System.out.println("Deleting the oldest 50 registries with IoT Test prefix");
-
- // Gather all the registries into temp list
- List registries = CleanUpHelper.getRegisteries(PROJECT_ID, CLOUD_REGION);
-
- // Filter all registries with prefix.
- // since the list is already sorted by currentMillis suffix,
- // first 50 will be the oldest.
- List filteredRegistries = new ArrayList<>();
-
- for (int i = 0; i < registries.size(); i++) {
- DeviceRegistry registry = registries.get(i);
- if (registry.getName().contains("test-registry-")
- || registry.getName().contains("java-reg-")) {
- filteredRegistries.add(registry);
- }
- }
-
- // Delete the 50 oldest registries
- for (DeviceRegistry registry : filteredRegistries) {
- CleanUpHelper.clearRegistry(CLOUD_REGION, PROJECT_ID, registry.getId());
- }
- }
-
- @Test
- public void testConfigOff() throws GeneralSecurityException, IOException, JSONException {
- int minTemp = -1;
- JSONObject data = new JSONObject();
-
- // Set up
- CloudiotPubsubExampleServer.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- CloudiotPubsubExampleServer.createDevice(PROJECT_ID, CLOUD_REGION, REGISTRY_ID, DEVICE_ID);
-
- data.put("temperature", minTemp);
-
- CloudiotPubsubExampleServer server = new CloudiotPubsubExampleServer();
- server.updateDeviceConfig(PROJECT_ID, CLOUD_REGION, REGISTRY_ID, DEVICE_ID, data);
- String got = bout.toString();
- Assert.assertTrue(got.contains("off"));
- Assert.assertTrue(got.contains("-1"));
- Assert.assertTrue(got.contains("test-device-"));
-
- // Clean up
- CloudiotPubsubExampleServer.deleteDevice(DEVICE_ID, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- CloudiotPubsubExampleServer.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-}
diff --git a/iot/api-client/generate_keys.sh b/iot/api-client/generate_keys.sh
deleted file mode 100755
index e9beedc3dd6..00000000000
--- a/iot/api-client/generate_keys.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# Copyright 2017 Google Inc.
-#
-# 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.
-
-openssl req -x509 -newkey rsa:2048 -keyout rsa_private.pem -nodes -out \
- rsa_cert.pem -subj "/CN=unused"
-openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem
-openssl ec -in ec_private.pem -pubout -out ec_public.pem
-openssl pkcs8 -topk8 -inform PEM -outform DER -in rsa_private.pem \
- -nocrypt > rsa_private_pkcs8
-openssl pkcs8 -topk8 -inform PEM -outform DER -in ec_private.pem \
- -nocrypt > ec_private_pkcs8
diff --git a/iot/api-client/manager/README.md b/iot/api-client/manager/README.md
deleted file mode 100644
index 771ced674cc..00000000000
--- a/iot/api-client/manager/README.md
+++ /dev/null
@@ -1,406 +0,0 @@
-# Cloud IoT Core Java Device Management example
-
-
-
-
-This sample app demonstrates device management for Google Cloud IoT Core.
-
-Note that before you can run the sample, you must configure a Google Cloud
-PubSub topic for Cloud IoT as described in [the parent README](../README.md).
-
-Before running the samples, you can set the `GOOGLE_CLOUD_PROJECT` and
-`GOOGLE_APPLICATION_CREDENTIALS` environment variables to avoid passing them to
-the sample every time you run it.
-
-## Setup
-Run the following command to install the libraries and build the sample with
-Maven:
-
- mvn clean compile assembly:single
-
-## Running the sample
-
-The following description summarizes the sample usage:
-
- usage: DeviceRegistryExample [--cloud_region ] --command
- [--ec_public_key_file ] --project_id --pubsub_topic
- --registry_name [--rsa_certificate_file ]
-
- Cloud IoT Core Commandline Example (Device / Registry management):
-
- --cloud_region GCP cloud region (default us-central1).
- --command Command to run:
- create-iot-topic
- create-rsa
- create-es
- create-unauth
- create-registry
- delete-device
- delete-registry
- get-device
- get-registry
- list-devices
- list-registries
- patch-device-es
- patch-device-rsa
- --ec_public_key_file Path to ES256 public key file.
- --project_id GCP cloud project name.
- --pubsub_topic Pub/Sub topic to create registry in.
- --registry_name Name for your Device Registry.
- --rsa_certificate_file Path to RS256 certificate file.
-
-https://cloud.google.com/iot-core
-
-We recommend using the Maven **exec** plugin for invoking the sample.
-
-For example, if your project ID is `blue-jet-123`, your service account
-credentials are stored in your home folder in creds.json and you have generated
-your credentials using the shell script provided in the parent folder, you can
-run the sample as:
-
-
- mvn exec:exec -Dmanager \
- -Dcr=--cloud_region=us-central1 \
- -Dproject_id=blue-jet-123 \
- -Drname=--registry_name=my-registry \
- -Dcmd=list-devices
-
-The full set of parameters passable to the exec wrapper are as follows:
-
- mvn exec:exec -Dmanager \
- -Dpst=--pubsub_topic= \
- -Decf=--ec_public_key_file= \
- -Drsaf=--rsa_certificate_file= \
- -Dcr=--cloud_region= \
- -Dproject_id= \
- -Drname=--registry_name= \
- -Ddid=--device_id= \
- -Dgid=--gateway_id= \
- -Ddata=--data= \
- -Dconf=--configuration= \
- -Dv=--version= \
- -Dm=--member= \
- -Dr=--role= \
- -Dcmd=--command=
-
-## Usage Examples
-
-Create a PubSub topic, `hello-java`, for the project, `blue-jet-123`:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dcmd=create-iot-topic \
- -Dpst=--pubsub_topic=hello-java
-
-Create an ES device:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=--pubsub_topic=hello-java \
- -Dcr=--cloud_region=us-central1 \
- -Drname=--registry_name=hello-java \
- -Decf=--ec_public_key_file ../ec_public.pem \
- -Ddid=--device_id=java-device-0 \
- -Dcmd=create-es
-
-Create an RSA device:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=-pubsub_topic=hello-java \
- -Drname=-registry_name=hello-java \
- -Drsaf=-rsa_certificate_file=../rsa_cert.pem \
- -Ddid=-device_id=java-device-1 \
- -Dcmd=create-rsa
-
-Create a device without authorization:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=--pubsub_topic=hello-java \
- -Drname=--registry_name=hello-java \
- -Ddid=--device_id=java-device-3 \
- -Dcmd=create-unauth
-
-Create a device registry:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=--pubsub_topic=hello-java \
- -Drname=--registry_name=hello-java \
- -Dcmd=create-registry
-
-Delete a device registry:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=--pubsub_topic=hello-java \
- -Drname=--registry_name=hello-java \
- -Dcmd=delete-registry
-
-Get a device registry:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-343 \
- -Dcmd=get-registry \
- -Drname=--registry_name="hello-java"
-
-List devices:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=--pubsub_topic=hello-java \
- -Drname=--registry_name=hello-java \
- -Dcmd=list-devices
-
-List device registries:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=--pubsub_topic=hello-java \
- -Drname=--registry_name=hello-java \
- -Dcmd=list-registries
-
-Patch a device with ES:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=--pubsub_topic=hello-java \
- -Drname=--registry_name=hello-java \
- -Decf=--ec_public_key_file=../ec_public.pem \
- -Ddid=--device_id=java-device-1 \
- -Dcmd=patch-device-es
-
-Patch a device with RSA:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Dpst=--pubsub_topic=hello-java \
- -Drname=--registry_name=hello-java \
- -Drsaf=--rsa_certificate_file=../rsa_cert.pem \
- -Ddid=--device_id=java-device-0 \
- -Dcmd=patch-device-rsa
-
-Create a gateway with RSA credentials:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Drname=--registry_name=your-registry \
- -Drsaf=--rsa_certificate_file=../rsa_cert.pem \
- -Dgid=--gateway_id=java-gateway-0 \
- -Dcmd=create-gateway
-
-Create a gateway with EC credentials:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Drname=--registry_name=your-registry-name \
- -Decf=--ec_public_key_file=resources/ec_public.pem \
- -Dgid=--gateway_id=java-gateway-1 \
- -Dcmd=create-gateway
-
-
-Bind a device to a gateway:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Drname=--registry_name=your-registry \
- -Dgid=--gateway_id=java-gateway-0 \
- -Ddid=--device_id=java-device-0 \
- -Dcmd=bind-device-to-gateway
-
-Unbind a device to a gateway:
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Drname=-registry_name=your-registry \
- -Dgid=-gateway_id=java-gateway-0 \
- -Ddid=-device_id=java-device-0 \
- -Dcmd=unbind-device-from-gateway
-
-List gateways in a registry.
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Drname=--registry_name=your-registry \
- -Dcmd=list-gateways
-
-List devices bound to a gateway.
-
- mvn exec:exec -Dmanager \
- -Dproject_id=blue-jet-123 \
- -Drname=--registry_name=your-registry \
- -Dgid=--gateway_id=your-gateway-id \
- -Dcmd=list-devices-for-gateway
-
-
-# Cloud IoT Core Java HTTP example
-
-This sample app publishes data to Cloud Pub/Sub using the HTTP bridge provided
-as part of Google Cloud IoT Core.
-
-Note that before you can run the sample, you must configure a Google Cloud
-PubSub topic for Cloud IoT Core and register a device as described in the
-[parent README](../README.md).
-
-## Setup
-
-Run the following command to install the dependencies using Maven:
-
- mvn clean compile
-
-## Running the sample
-
-The following command summarizes the sample usage:
-
-```
- mvn exec:exec -Dhttp \
- -Dproject_id=YOUR-PROJECT-ID \
- -Dregistry_id=YOUR-REGISTRY-ID \
- -Ddevice_id=YOUR-DEVICE-ID \
- -Dalgorithm=RS256|ES256 \
- -Dprivate_key_file="../path/to/your_private_pkcs8" \
- -Dcr=-cloud_region=us-central1 | asia-east1 | europe-west1 \
- -Dhba=http_bridge_address=https://cloudiotdevice.googleapis.com \
- -Dapiv=-api_version=v1 \
- -Dexp=-token_exp_minutes=60 \
- -Dmt=-message_type=state | event
-```
-
-For example, if your project ID is `blue-jet-123`, the Cloud region associated
-with your device registry is europe-west1, and you have generated your
-credentials using the [`generate_keys.sh`](../generate_keys.sh) script
-provided in the parent folder, you can run the sample as:
-
-```
- mvn exec:exec -Dhttp \
- -Dproject_id=blue-jet-123 \
- -Dregistry_id=my-registry \
- -Ddevice_id=my-java-device \
- -Dalgorithm=RS256 \
- -Dprivate_key_file=../rsa_private_pkcs8 \
- -Dcr=-cloud_region=asia-east1
-```
-
-To publish state messages, run the sample as follows:
-
-```
- mvn exec:exec -Dhttp \
- -Dproject_id=blue-jet-123 \
- -Dregistry_id=my-registry \
- -Ddevice_id=my-java-device \
- -Dalgorithm=RS256 \
- -Dprivate_key_file=../rsa_private_pkcs8 \
- -Dcr=-cloud_region=us-central1 \
- -Dmt=message_type=state
-```
-
-
-## Reading the messages written by the sample client
-
-1. Create a subscription to your topic.
-
-```
- gcloud pubsub subscriptions create \
- projects/your-project-id/subscriptions/my-subscription \
- --topic device-events
-```
-
-2. Read messages published to the topic
-
-```
- gcloud pubsub subscriptions pull --auto-ack \
- projects/my-iot-project/subscriptions/my-subscription
-```
-
-# Cloud IoT Core Java MQTT example
-
-This sample app publishes data to Cloud Pub/Sub using the MQTT bridge provided
-as part of Google Cloud IoT Core.
-
-Note that before you can run the sample, you must configure a Google Cloud
-PubSub topic for Cloud IoT Core and register a device as described in the
-[parent README](../README.md).
-
-## Setup
-
-Run the following command to install the dependencies using Maven:
-
- mvn clean compile
-
-## Running the sample
-
-The following example shows you how to invoke the sample using the `mvn exec`:
-
- mvn exec:exec -Dmqtt \
- -Dproject_id=YOUR-PROJECT-ID \
- -Dregistry_id=YOUR-REGISTRY-ID \
- -Ddevice_id=YOUR-DEVICE-ID \
- -Dalgorithm=RS256|ES256 \
- -Dprivate_key_file=../path/to/your_private_pkcs8
- -Dcmd=-command=listen-for-config-messages
- -Dgid=-gateway_id=YOUR-GATEWAY-ID
- -Dcr=-cloud_region=us-central1 | asia-east1 | europe-west1
- -Dexp=-token_exp_minutes=60
- -Dmhn=mqtt_bridge_hostname=mqtt.googleapis.com
- -Dmp=-mqtt_bridge_port=443 | 8883
- -Dmt=-message_type=state | event
- -Dtd=-telemetry_data=YOUR-CUSTOM-DATA
- -Dwt=-wait_time=3600
-
-For example, if your project ID is `blue-jet-123`, your device registry is
-located in the `asia-east1` region, and you have generated your
-credentials using the [`generate_keys.sh`](../generate_keys.sh) script
-provided in the parent folder, you can run the sample as:
-
-Run mqtt example:
-
- mvn exec:exec -Dmqtt \
- -Dproject_id=blue-jet-123 \
- -Dcloud_region=asia-east1 \
- -Dregistry_id=my-registry \
- -Ddevice_id=my-test-device \
- -Dalgorithm=RS256 \
- -Dprivate_key_file="../path/to/your_private_pkcs8"
-
-Listen for configuration messages:
-
- mvn exec:exec -Dmqtt \
- -Dproject_id=blue-jet-123 \
- -Dregistry_id=my-registry \
- -Ddevice_id=my-test-device \
- -Dalgorithm=RS256 \
- -Dprivate_key_file="../path/to/your_private_pkcs8"
- -Dgid=-gateway_id=YOUR-GATEWAY-ID \
- -Dmhn-mqtt_bridge_hostname=mqtt.googleapis.com \
- -Dmp=-mqtt_bridge_port=443 \
- -Dcmd=-command=listen-for-config-messages
-
-Send data on behalf of device:
-
- mvn exec:exec -Dmqtt \
- -Dcr=-cloud_region=us-central1 \
- -Ddevice_id=java-device-0 \
- -Dregistry_id=my-registry \
- -Dgid=-gateway_id=test-gateway \
- -Dprivate_key_file=../your_private_pkcs8 \
- -Dalgorithm=RS256 \
- -Dtd=-telemetry_data="your telemetry msg" \
- -Dmhn=-mqtt_bridge_hostname=mqtt.googleapis.com \
- -Dmt=-message_type='event' \
- -Dmp=mqtt_bridge_port=443 \
- -Dcmd=-command=send-data-from-bound-device
-
-
-## Reading the messages written by the sample client
-
-1. Create a subscription to your topic.
-
- gcloud pubsub subscriptions create \
- projects/your-project-id/subscriptions/my-subscription \
- --topic device-events
-
-2. Read messages published to the topic
-
- gcloud pubsub subscriptions pull --auto-ack \
- projects/my-iot-project/subscriptions/my-subscription
diff --git a/iot/api-client/manager/pom.xml b/iot/api-client/manager/pom.xml
deleted file mode 100644
index 878caba5ba2..00000000000
--- a/iot/api-client/manager/pom.xml
+++ /dev/null
@@ -1,301 +0,0 @@
-
-
- 4.0.0
- com.example.iot
- cloudiot-manager-demo
- jar
- 1.0
- cloudiot-manager-demo
- http://maven.apache.org
-
-
-
- com.google.cloud.samples
- shared-configuration
- 1.2.0
-
-
-
- 1.8
- 1.8
-
-
-
-
-
- libraries-bom
- com.google.cloud
- import
- pom
- 26.22.0
-
-
-
-
-
-
- org.eclipse.paho
- org.eclipse.paho.client.mqttv3
- 1.2.5
-
-
- org.json
- json
- 20230618
-
-
- io.jsonwebtoken
- jjwt
- 0.9.1
-
-
- com.google.apis
- google-api-services-cloudiot
- v1-rev20230328-2.0.0
-
-
- com.google.cloud
- google-cloud-pubsub
-
-
- com.google.cloud
- google-cloud-core
-
-
- com.google.auth
- google-auth-library-oauth2-http
-
-
- com.google.guava
- guava
-
-
- com.google.api-client
- google-api-client
-
-
- commons-cli
- commons-cli
- 1.5.0
-
-
- com.google.api-client
- google-api-client-jackson2
-
-
- com.google.http-client
- google-http-client-jackson2
-
-
-
-
- javax.xml.bind
- jaxb-api
- 2.4.0-b180830.0359
-
-
- com.sun.xml.bind
- jaxb-core
- 4.0.3
-
-
- com.sun.xml.bind
- jaxb-impl
- 4.0.3
-
-
- javax.activation
- activation
- 1.1.1
-
-
-
-
- junit
- junit
- 4.13.2
- test
-
-
- com.google.truth
- truth
- 1.1.5
- test
-
-
-
-
-
-
-
- maven-assembly-plugin
-
-
-
- com.example.cloudiot.Manage
-
-
-
- jar-with-dependencies
-
-
-
-
-
-
-
-
- manager
-
-
- manager
-
-
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
- 3.1.0
-
-
-
- exec
-
-
-
-
- java
-
- -classpath
-
- com.example.cloud.iot.examples.DeviceRegistryExample
- -project_id=${project_id}
- -command=${cmd}
- ${pst}
- ${ecf}
- ${rsaf}
- ${cr}
- ${rname}
- ${did}
- ${gid}
- ${data}
- ${conf}
- ${v}
- ${m}
- ${r}
-
-
-
-
-
-
-
- http
-
-
- http
-
-
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
- 3.1.0
-
-
-
- exec
-
-
-
-
- java
-
- -classpath
-
- com.example.cloud.iot.examples.HttpExample
- -project_id=${project_id}
- -registry_id=${registry_id}
- -device_id=${device_id}
- -algorithm=${algorithm}
- -private_key_file=${private_key_file}
- ${cr}
- ${hba}
- ${apiv}
- ${exp}
- ${mt}
-
-
-
-
-
-
-
- mqtt
-
-
- mqtt
-
-
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
- 3.1.0
-
-
-
- exec
-
-
-
-
- java
-
- -classpath
-
- com.example.cloud.iot.examples.MqttExample
- -project_id=${project_id}
- -registry_id=${registry_id}
- -device_id=${device_id}
- -algorithm=${algorithm}
- -private_key_file=${private_key_file}
- ${cr}
- ${cmd}
- ${gid}
- ${exp}
- ${mhn}
- ${mp}
- ${mt}
- ${td}
- ${wt}
-
-
-
-
-
-
-
-
diff --git a/iot/api-client/manager/resources/README.md b/iot/api-client/manager/resources/README.md
deleted file mode 100644
index 27fbefe8215..00000000000
--- a/iot/api-client/manager/resources/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Test public certificate files
-
-The certificates in this folder are only provided for testing and should not be
-used for registering your devices. Instructions and a shell script are in the
-parent folder for getting started.
diff --git a/iot/api-client/manager/resources/ec_public.pem b/iot/api-client/manager/resources/ec_public.pem
deleted file mode 100644
index 349669b701f..00000000000
--- a/iot/api-client/manager/resources/ec_public.pem
+++ /dev/null
@@ -1,4 +0,0 @@
------BEGIN PUBLIC KEY-----
-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEebpcLYtZKxVxbPoRwD9lkY0fIZtZ
-Qc9IufEIZwHqefIa4uN1gHnKMBtt18oOpZPNgy+rvHRa87rHLgKmno1jkQ==
------END PUBLIC KEY-----
diff --git a/iot/api-client/manager/resources/rsa_cert.pem b/iot/api-client/manager/resources/rsa_cert.pem
deleted file mode 100644
index 2a260397c6a..00000000000
--- a/iot/api-client/manager/resources/rsa_cert.pem
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICnjCCAYYCCQDSa54hWD0A9zANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZ1
-bnVzZWQwHhcNMjEwMTIwMTgyNDU1WhcNMjMxMDE3MTgyNDU1WjARMQ8wDQYDVQQD
-DAZ1bnVzZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDK/f8CUKks
-L4Z6bCWKBuC+rpLbIQvt9FRISiox6bXMZVEMdF5gFC6qrWO94p8AuztXlHWFHWgk
-WYi6AhgtFZzcb2iSyCTVf1sPC1ZdQqX6mZqWdeP1iaNhcq8+ISTp0H2UyTr/TezQ
-Gh6mrz3YcgBsSW5YnsRyUXLVFk1Pi7ud00syCcSIwmC/ZNTPGGMtSYR33Jjek6wN
-FVEZCfaVxDAZcNXUMW24/GuIiixfyr/fZGdui5ATuPH3vMbwGJboD+Riiuhkjw3F
-fLdhwkhh655JL16F852qnlw2x810d+XX/CBUgMCUfARSuR0crzPqZ+Hdcv92+ZBG
-bPdw1vAj1EQZAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEwDFXUv3te26dTSKO70
-fi8VFU+RYLNnu5NS1hMYCtFK+Fy0zCmAcvhbF4O4xq8o/kHlm461zwv2QH2XJZP2
-jCQkYNSrOP6NcWpuy28PXHWYa9Naym2vliw1uP5ee3r2tVKAYBKsGNuRURdXRcHb
-mU7rWSb3isY/3ldikZJmFmNM1XpeTMfi/JA4hAT5XJW2HM/4/dxLKcFkAMbvUMfg
-qrgTvOguKxCUb6xRZv61DEv4AzxBO8iZtY7AKmpfWERVTXxnvyle8mEIbJiaQynF
-3WTjtzOrYES/CyWU1x8LONEnZAU/Y6fNO8VWpPUScHXe4sIwtJE1B+lYi23btyGn
-RmQ=
------END CERTIFICATE-----
diff --git a/iot/api-client/manager/resources/rsa_private.pem b/iot/api-client/manager/resources/rsa_private.pem
deleted file mode 100644
index e5495e0c947..00000000000
--- a/iot/api-client/manager/resources/rsa_private.pem
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDK/f8CUKksL4Z6
-bCWKBuC+rpLbIQvt9FRISiox6bXMZVEMdF5gFC6qrWO94p8AuztXlHWFHWgkWYi6
-AhgtFZzcb2iSyCTVf1sPC1ZdQqX6mZqWdeP1iaNhcq8+ISTp0H2UyTr/TezQGh6m
-rz3YcgBsSW5YnsRyUXLVFk1Pi7ud00syCcSIwmC/ZNTPGGMtSYR33Jjek6wNFVEZ
-CfaVxDAZcNXUMW24/GuIiixfyr/fZGdui5ATuPH3vMbwGJboD+Riiuhkjw3FfLdh
-wkhh655JL16F852qnlw2x810d+XX/CBUgMCUfARSuR0crzPqZ+Hdcv92+ZBGbPdw
-1vAj1EQZAgMBAAECggEAXRzxkrBJSZlrSFC/T3ckNJODjby06iv/VUGf5VFdMSrw
-aJQgjlXzqhrq+7kuUnmQGPZiifMZSENBsoEvcc7OK1d3Uo04SC6pKFd9AD6IQFGh
-VY8yR/kg1pxywj8V3aLjWBKOW3n1POgeUztjVRvGEeYFFeWOGxo9YH1gbTKdlyD5
-4V/I+hyvRFkhqRW9RN1IPToB49gqilS9rrwThC3jFKoiFNQRQ0EDMHKC8CZVh8fU
-u2xfTXQ29p1RB67lRAb62+5yq28eT2UQZjoZZl1HgPqfa1E4XljCGNdAGGxhZJeT
-i4eoNcApdQYlqNpHDRgv8lxc7V+YGbh/iYwPHuAIAQKBgQDmc/CT1EHsuEGV88lK
-I4YdyDqUvdV6yvq8lcEMFPnpjaZOgUMaqwUgJXugBpP0tNgOTSQbwIq8ZVruDEr6
-QaAD2IfMoJhlPqSNn4UEnyR419EfJPcgE3o4DUM76z/ZO6sqjCBQX4solLZUhJTh
-5XqNb8MOxtahVZGOHPfBvmk+gQKBgQDhfr6DAIQeyyqevfOrfJFWE3ggUPVjXE3p
-sRFFp0CVG4bBCRBwDEKwY12uggtvKUa8duAq0Y7gVtrXgHWRc95V7eP8ognjlmZC
-J2KMvJtTTm9/P1OgUj1CRviHHZN1blcOYj7sLxQwOamm7nPw19EztNM36nb89q0+
-1W8BnMtpmQKBgQCmigjEvDK8IFf9RsUjl9J3OVjkXt+ksoVKvapZ0drc5mnV9+IH
-pqm4ln3lontP71Tn2OWMTLO1/EUfHLEec0hxHwzcWv5mxENkuXAGa/+OeOB+cldI
-zeqYETWSWqq0kUNcJxG/I5zMQdQV9g4lxZGwHqFGz3kR9GWQ3uxJDhK+gQKBgG3M
-8aeIkM0N0OsLQ6O1PG/VeyEBSvve7nFkryxjjKcOiEdmyoJE9hQ9zlgzKq4uQyty
-FyXCdPf4UwesnZL+AL2G4QUbQgV4LsL3up0dGeUuxEwJ4ganBP1I4aupUyxTVkDC
-xjDrm8D/0wReCEa2UEAFRPRtTxNOan22IB+A4evBAoGBAJXKnfBGI+qMyn6EEK8Y
-iB9RsRE/CVLNgubXHJ2RfVPgrFKctHT64K92o+82W/NXaSGfSI60VyGgKE1e8QxS
-fBNq9NICrbr0QF9bwdZnQ/uu+HKK9qrdQlJ8iGP6cJwrDEI1mTti6VxbCaw24sJX
-l3YZXit1Z0NLcndYHTq+eJ31
------END PRIVATE KEY-----
diff --git a/iot/api-client/manager/resources/rsa_private_pkcs8 b/iot/api-client/manager/resources/rsa_private_pkcs8
deleted file mode 100644
index b2f21e29a69..00000000000
Binary files a/iot/api-client/manager/resources/rsa_private_pkcs8 and /dev/null differ
diff --git a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/DeviceRegistryExample.java b/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/DeviceRegistryExample.java
deleted file mode 100644
index 483aefcfc37..00000000000
--- a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/DeviceRegistryExample.java
+++ /dev/null
@@ -1,1363 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.examples;
-
-import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
-import com.google.api.client.http.HttpRequestInitializer;
-import com.google.api.client.json.JsonFactory;
-import com.google.api.client.json.gson.GsonFactory;
-import com.google.api.services.cloudiot.v1.CloudIot;
-import com.google.api.services.cloudiot.v1.CloudIotScopes;
-import com.google.api.services.cloudiot.v1.model.BindDeviceToGatewayRequest;
-import com.google.api.services.cloudiot.v1.model.BindDeviceToGatewayResponse;
-import com.google.api.services.cloudiot.v1.model.Device;
-import com.google.api.services.cloudiot.v1.model.DeviceConfig;
-import com.google.api.services.cloudiot.v1.model.DeviceCredential;
-import com.google.api.services.cloudiot.v1.model.DeviceRegistry;
-import com.google.api.services.cloudiot.v1.model.DeviceState;
-import com.google.api.services.cloudiot.v1.model.EventNotificationConfig;
-import com.google.api.services.cloudiot.v1.model.GatewayConfig;
-import com.google.api.services.cloudiot.v1.model.GetIamPolicyRequest;
-import com.google.api.services.cloudiot.v1.model.ListDeviceStatesResponse;
-import com.google.api.services.cloudiot.v1.model.ListDevicesResponse;
-import com.google.api.services.cloudiot.v1.model.ModifyCloudToDeviceConfigRequest;
-import com.google.api.services.cloudiot.v1.model.PublicKeyCredential;
-import com.google.api.services.cloudiot.v1.model.SendCommandToDeviceRequest;
-import com.google.api.services.cloudiot.v1.model.SetIamPolicyRequest;
-import com.google.api.services.cloudiot.v1.model.UnbindDeviceFromGatewayRequest;
-import com.google.api.services.cloudiot.v1.model.UnbindDeviceFromGatewayResponse;
-import com.google.auth.http.HttpCredentialsAdapter;
-import com.google.auth.oauth2.GoogleCredentials;
-import com.google.cloud.Role;
-import com.google.cloud.pubsub.v1.TopicAdminClient;
-import com.google.common.io.Files;
-import com.google.iam.v1.Binding;
-import com.google.pubsub.v1.Topic;
-import com.google.pubsub.v1.TopicName;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Paths;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.cli.HelpFormatter;
-
-/**
- * Example of using Cloud IoT device manager API to administer devices, registries and projects.
- *
- * This example uses the Device Manager API to create, retrieve, disable, list and delete Cloud
- * IoT devices and registries, using both RSA and eliptic curve keys for authentication.
- *
- * To start, follow the instructions on the Developer Guide at cloud.google.com/iot to create a
- * service_account.json file and Cloud Pub/Sub topic as discussed in the guide. You will then need
- * to point to the service_account.json file as described in
- * https://developers.google.com/identity/protocols/application-default-credentials#howtheywork
- *
- * Before running the example, we have to create private and public keys, as described in
- * cloud.google.com/iot. Since we are interacting with the device manager, we will only use the
- * public keys. The private keys are used to sign JWTs to authenticate devices. See the MQTT
- * client example for more information.
- *
- * Finally, compile and run the example with:
- *
- *
- *
- * $ mvn clean compile assembly:single
- * mvn exec:exec -Dmanager \
- * -Dcr=--cloud_region=us-central1 \
- * -Dproject_id=blue-jet-123 \
- * -Drname=--registry_name=my-registry \
- * -Dcmd=list-devices
- *
- *
- */
-public class DeviceRegistryExample {
-
- static final String APP_NAME = "DeviceRegistryExample";
-
- /** Creates a topic and grants the IoT service account access. */
- protected static Topic createIotTopic(String projectId, String topicId) throws Exception {
- // Create a new topic
- final TopicName topicName = TopicName.of(projectId, topicId);
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- final Topic topic = topicAdminClient.createTopic(topicName);
- final String topicString = topicName.toString();
- // add role -> members binding
- // create updated policy
- topicAdminClient.setIamPolicy(
- topicString,
- com.google.iam.v1.Policy.newBuilder(topicAdminClient.getIamPolicy(topicString))
- .addBindings(
- Binding.newBuilder()
- .addMembers("serviceAccount:cloud-iot@system.gserviceaccount.com")
- .setRole(Role.owner().toString())
- .build())
- .build());
-
- System.out.println("Setup topic / policy for: " + topic.getName());
- return topic;
- }
- }
-
- // [START iot_create_registry]
- /** Create a registry for Cloud IoT. */
- protected static void createRegistry(
- String cloudRegion, String projectId, String registryName, String pubsubTopicPath)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String projectPath = "projects/" + projectId + "/locations/" + cloudRegion;
- final String fullPubsubPath = "projects/" + projectId + "/topics/" + pubsubTopicPath;
-
- DeviceRegistry registry = new DeviceRegistry();
- EventNotificationConfig notificationConfig = new EventNotificationConfig();
- notificationConfig.setPubsubTopicName(fullPubsubPath);
- List notificationConfigs = new ArrayList();
- notificationConfigs.add(notificationConfig);
- registry.setEventNotificationConfigs(notificationConfigs);
- registry.setId(registryName);
-
- DeviceRegistry reg =
- service.projects().locations().registries().create(projectPath, registry).execute();
- System.out.println("Created registry: " + reg.getName());
- }
- // [END iot_create_registry]
-
- // [START iot_delete_registry]
- /** Delete this registry from Cloud IoT. */
- protected static void deleteRegistry(String cloudRegion, String projectId, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- System.out.println("Deleting: " + registryPath);
- service.projects().locations().registries().delete(registryPath).execute();
- }
- // [END iot_delete_registry]
-
- /**
- * clearRegistry
- *
- *
- * - Registries can't be deleted if they contain devices,
- *
- Gateways (a type of device) can't be deleted if they have bound devices
- *
- Devices can't be deleted if bound to gateways...
- *
- *
- * To completely remove a registry, you must unbind all devices from gateways, then remove all
- * devices in a registry before removing the registry. As pseudocode:
- * ForAll gateways
- * ForAll devicesBoundToGateway
- * unbindDeviceFromGateway
- * ForAll devices
- * Delete device by ID
- * Delete registry
- *
- */
- // [START iot_clear_registry]
- protected static void clearRegistry(String cloudRegion, String projectId, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- CloudIot.Projects.Locations.Registries regAlias = service.projects().locations().registries();
- CloudIot.Projects.Locations.Registries.Devices devAlias = regAlias.devices();
-
- ListDevicesResponse listGatewaysRes =
- devAlias.list(registryPath).setGatewayListOptionsGatewayType("GATEWAY").execute();
- List gateways = listGatewaysRes.getDevices();
-
- // Unbind all devices from all gateways
- if (gateways != null) {
- System.out.println("Found " + gateways.size() + " devices");
- for (Device g : gateways) {
- String gatewayId = g.getId();
- System.out.println("Id: " + gatewayId);
-
- ListDevicesResponse res =
- devAlias
- .list(registryPath)
- .setGatewayListOptionsAssociationsGatewayId(gatewayId)
- .execute();
- List deviceNumIds = res.getDevices();
-
- if (deviceNumIds != null) {
- System.out.println("Found " + deviceNumIds.size() + " devices");
- for (Device device : deviceNumIds) {
- String deviceId = device.getId();
- System.out.println(String.format("ID: %s", deviceId));
-
- // Remove any bindings from the device
- UnbindDeviceFromGatewayRequest request = new UnbindDeviceFromGatewayRequest();
- request.setDeviceId(deviceId);
- request.setGatewayId(gatewayId);
- regAlias.unbindDeviceFromGateway(registryPath, request).execute();
- }
- } else {
- System.out.println("Gateway has no bound devices.");
- }
- }
- }
-
- // Remove all devices from the regsitry
- List devices = devAlias.list(registryPath).execute().getDevices();
-
- if (devices != null) {
- System.out.println("Found " + devices.size() + " devices");
- for (Device d : devices) {
- String deviceId = d.getId();
- String devicePath = String.format("%s/devices/%s", registryPath, deviceId);
- service.projects().locations().registries().devices().delete(devicePath).execute();
- }
- }
-
- // Delete the registry
- service.projects().locations().registries().delete(registryPath).execute();
- }
- // [END iot_clear_registry]
-
- // [START iot_list_devices]
- /** Print all of the devices in this registry to standard out. */
- protected static void listDevices(String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- List devices =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .list(registryPath)
- .execute()
- .getDevices();
-
- if (devices != null) {
- System.out.println("Found " + devices.size() + " devices");
- for (Device d : devices) {
- System.out.println("Id: " + d.getId());
- if (d.getConfig() != null) {
- // Note that this will show the device config in Base64 encoded format.
- System.out.println("Config: " + d.getConfig().toPrettyString());
- }
- System.out.println();
- }
- } else {
- System.out.println("Registry has no devices.");
- }
- }
- // [END iot_list_devices]
-
- // [START iot_create_es_device]
- /** Create a device that is authenticated using ES256. */
- protected static void createDeviceWithEs256(
- String deviceId,
- String publicKeyFilePath,
- String projectId,
- String cloudRegion,
- String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
- final String key =
- Files.asCharSource(new File(publicKeyFilePath), StandardCharsets.UTF_8).read();
- publicKeyCredential.setKey(key);
- publicKeyCredential.setFormat("ES256_PEM");
-
- DeviceCredential devCredential = new DeviceCredential();
- devCredential.setPublicKey(publicKeyCredential);
-
- System.out.println("Creating device with id: " + deviceId);
- Device device = new Device();
- device.setId(deviceId);
- device.setCredentials(Collections.singletonList(devCredential));
-
- Device createdDevice =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .create(registryPath, device)
- .execute();
-
- System.out.println("Created device: " + createdDevice.toPrettyString());
- }
- // [END iot_create_es_device]
-
- // [START iot_create_rsa_device]
- /** Create a device that is authenticated using RS256. */
- protected static void createDeviceWithRs256(
- String deviceId,
- String certificateFilePath,
- String projectId,
- String cloudRegion,
- String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
- String key = Files.asCharSource(new File(certificateFilePath), StandardCharsets.UTF_8).read();
- publicKeyCredential.setKey(key);
- publicKeyCredential.setFormat("RSA_X509_PEM");
-
- DeviceCredential devCredential = new DeviceCredential();
- devCredential.setPublicKey(publicKeyCredential);
-
- System.out.println("Creating device with id: " + deviceId);
- Device device = new Device();
- device.setId(deviceId);
- device.setCredentials(Collections.singletonList(devCredential));
- Device createdDevice =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .create(registryPath, device)
- .execute();
-
- System.out.println("Created device: " + createdDevice.toPrettyString());
- }
- // [END iot_create_rsa_device]
-
- // [START iot_create_unauth_device]
- /**
- * Create a device that has no credentials.
- *
- * This is a valid way to construct a device, however until it is patched with a credential the
- * device will not be able to connect to Cloud IoT.
- */
- protected static void createDeviceWithNoAuth(
- String deviceId, String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- "projects/" + projectId + "/locations/" + cloudRegion + "/registries/" + registryName;
-
- System.out.println("Creating device with id: " + deviceId);
- Device device = new Device();
- device.setId(deviceId);
- device.setCredentials(new ArrayList());
- Device createdDevice =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .create(registryPath, device)
- .execute();
-
- System.out.println("Created device: " + createdDevice.toPrettyString());
- }
- // [END iot_create_unauth_device]
-
- // [START iot_delete_device]
- /** Delete the given device from the registry. */
- protected static void deleteDevice(
- String deviceId, String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- System.out.println("Deleting device " + devicePath);
- service.projects().locations().registries().devices().delete(devicePath).execute();
- }
- // [END iot_delete_device]
-
- // [START iot_get_device]
- /** Retrieves device metadata from a registry. * */
- protected static Device getDevice(
- String deviceId, String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- System.out.println("Retrieving device " + devicePath);
- return service.projects().locations().registries().devices().get(devicePath).execute();
- }
- // [END iot_get_device]
-
- // [START iot_get_device_state]
- /** Retrieves device metadata from a registry. * */
- protected static List getDeviceStates(
- String deviceId, String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- System.out.println("Retrieving device states " + devicePath);
-
- ListDeviceStatesResponse resp =
- service.projects().locations().registries().devices().states().list(devicePath).execute();
-
- return resp.getDeviceStates();
- }
- // [END iot_get_device_state]
-
- // [START iot_get_registry]
- /** Retrieves registry metadata from a project. * */
- protected static DeviceRegistry getRegistry(
- String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- return service.projects().locations().registries().get(registryPath).execute();
- }
- // [END iot_get_registry]
-
- // [START iot_get_device_configs]
- /** List all of the configs for the given device. */
- protected static void listDeviceConfigs(
- String deviceId, String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- System.out.println("Listing device configs for " + devicePath);
- List deviceConfigs =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .configVersions()
- .list(devicePath)
- .execute()
- .getDeviceConfigs();
-
- for (DeviceConfig config : deviceConfigs) {
- System.out.println("Config version: " + config.getVersion());
- System.out.println("Contents: " + config.getBinaryData());
- System.out.println();
- }
- }
- // [END iot_get_device_configs]
-
- // [START iot_list_registries]
- /** Lists all of the registries associated with the given project. */
- protected static void listRegistries(String projectId, String cloudRegion)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String projectPath = "projects/" + projectId + "/locations/" + cloudRegion;
-
- List registries =
- service
- .projects()
- .locations()
- .registries()
- .list(projectPath)
- .execute()
- .getDeviceRegistries();
-
- if (registries != null) {
- System.out.println("Found " + registries.size() + " registries");
- for (DeviceRegistry r : registries) {
- System.out.println("Id: " + r.getId());
- System.out.println("Name: " + r.getName());
- if (r.getMqttConfig() != null) {
- System.out.println("Config: " + r.getMqttConfig().toPrettyString());
- }
- System.out.println();
- }
- } else {
- System.out.println("Project has no registries.");
- }
- }
- // [END iot_list_registries]
-
- // [START iot_patch_es]
- /** Patch the device to add an ES256 key for authentication. */
- protected static void patchEs256ForAuth(
- String deviceId,
- String publicKeyFilePath,
- String projectId,
- String cloudRegion,
- String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
- String key = Files.asCharSource(new File(publicKeyFilePath), StandardCharsets.UTF_8).read();
- publicKeyCredential.setKey(key);
- publicKeyCredential.setFormat("ES256_PEM");
-
- DeviceCredential devCredential = new DeviceCredential();
- devCredential.setPublicKey(publicKeyCredential);
-
- Device device = new Device();
- device.setCredentials(Collections.singletonList(devCredential));
-
- Device patchedDevice =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .patch(devicePath, device)
- .setUpdateMask("credentials")
- .execute();
-
- System.out.println("Patched device is " + patchedDevice.toPrettyString());
- }
- // [END iot_patch_es]
-
- // [START iot_patch_rsa]
- /** Patch the device to add an RSA256 key for authentication. */
- protected static void patchRsa256ForAuth(
- String deviceId,
- String publicKeyFilePath,
- String projectId,
- String cloudRegion,
- String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
- String key = Files.asCharSource(new File(publicKeyFilePath), StandardCharsets.UTF_8).read();
- publicKeyCredential.setKey(key);
- publicKeyCredential.setFormat("RSA_X509_PEM");
-
- DeviceCredential devCredential = new DeviceCredential();
- devCredential.setPublicKey(publicKeyCredential);
-
- Device device = new Device();
- device.setCredentials(Collections.singletonList(devCredential));
-
- Device patchedDevice =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .patch(devicePath, device)
- .setUpdateMask("credentials")
- .execute();
-
- System.out.println("Patched device is " + patchedDevice.toPrettyString());
- }
- // [END iot_patch_rsa]
-
- // [START iot_set_device_config]
- /** Set a device configuration to the specified data (string, JSON) and version (0 for latest). */
- protected static void setDeviceConfiguration(
- String deviceId,
- String projectId,
- String cloudRegion,
- String registryName,
- String data,
- long version)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- ModifyCloudToDeviceConfigRequest req = new ModifyCloudToDeviceConfigRequest();
- req.setVersionToUpdate(version);
-
- // Data sent through the wire has to be base64 encoded.
- Base64.Encoder encoder = Base64.getEncoder();
- String encPayload = encoder.encodeToString(data.getBytes(StandardCharsets.UTF_8.name()));
- req.setBinaryData(encPayload);
-
- DeviceConfig config =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .modifyCloudToDeviceConfig(devicePath, req)
- .execute();
-
- System.out.println("Updated: " + config.getVersion());
- }
- // [END iot_set_device_config]
-
- // [START iot_get_iam_policy]
- /** Retrieves IAM permissions for the given registry. */
- protected static void getIamPermissions(String projectId, String cloudRegion, String registryName)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- com.google.api.services.cloudiot.v1.model.Policy policy =
- service
- .projects()
- .locations()
- .registries()
- .getIamPolicy(registryPath, new GetIamPolicyRequest())
- .execute();
-
- System.out.println("Policy ETAG: " + policy.getEtag());
-
- if (policy.getBindings() != null) {
- for (com.google.api.services.cloudiot.v1.model.Binding binding : policy.getBindings()) {
- System.out.println(String.format("Role: %s", binding.getRole()));
- System.out.println("Binding members: ");
- for (String member : binding.getMembers()) {
- System.out.println(String.format("\t%s", member));
- }
- }
- } else {
- System.out.println(String.format("No policy bindings for %s", registryName));
- }
- }
- // [END iot_get_iam_policy]
-
- // [START iot_set_iam_policy]
- /** Sets IAM permissions for the given registry. */
- protected static void setIamPermissions(
- String projectId, String cloudRegion, String registryName, String member, String role)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- com.google.api.services.cloudiot.v1.model.Policy policy =
- service
- .projects()
- .locations()
- .registries()
- .getIamPolicy(registryPath, new GetIamPolicyRequest())
- .execute();
-
- List bindings = policy.getBindings();
-
- boolean addNewRole = true;
- if (bindings != null) {
- for (com.google.api.services.cloudiot.v1.model.Binding binding : bindings) {
- if (binding.getRole().equals(role)) {
- List members = binding.getMembers();
- members.add(member);
- binding.setMembers(members);
- addNewRole = false;
- }
- }
- } else {
- bindings = new ArrayList<>();
- }
-
- if (addNewRole) {
- com.google.api.services.cloudiot.v1.model.Binding bind =
- new com.google.api.services.cloudiot.v1.model.Binding();
- bind.setRole(role);
- List members = new ArrayList<>();
- members.add(member);
- bind.setMembers(members);
-
- bindings.add(bind);
- }
-
- policy.setBindings(bindings);
- SetIamPolicyRequest req = new SetIamPolicyRequest().setPolicy(policy);
-
- policy = service.projects().locations().registries().setIamPolicy(registryPath, req).execute();
-
- System.out.println("Policy ETAG: " + policy.getEtag());
- for (com.google.api.services.cloudiot.v1.model.Binding binding : policy.getBindings()) {
- System.out.println(String.format("Role: %s", binding.getRole()));
- System.out.println("Binding members: ");
- for (String mem : binding.getMembers()) {
- System.out.println(String.format("\t%s", mem));
- }
- }
- }
- // [END iot_set_iam_policy]
-
- /** Send a command to a device. * */
- // [START iot_send_command]
- protected static void sendCommand(
- String deviceId, String projectId, String cloudRegion, String registryName, String data)
- throws GeneralSecurityException, IOException {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryName, deviceId);
-
- SendCommandToDeviceRequest req = new SendCommandToDeviceRequest();
-
- // Data sent through the wire has to be base64 encoded.
- Base64.Encoder encoder = Base64.getEncoder();
- String encPayload = encoder.encodeToString(data.getBytes(StandardCharsets.UTF_8.name()));
- req.setBinaryData(encPayload);
- System.out.printf("Sending command to %s%n", devicePath);
-
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .sendCommandToDevice(devicePath, req)
- .execute();
-
- System.out.println("Command response: sent");
- }
- // [END iot_send_command]
-
- protected static void bindDeviceToGateway(
- String projectId, String cloudRegion, String registryName, String deviceId, String gatewayId)
- throws GeneralSecurityException, IOException {
- // [START iot_bind_device_to_gateway]
- createDevice(projectId, cloudRegion, registryName, deviceId);
-
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- BindDeviceToGatewayRequest request = new BindDeviceToGatewayRequest();
- request.setDeviceId(deviceId);
- request.setGatewayId(gatewayId);
-
- BindDeviceToGatewayResponse response =
- service
- .projects()
- .locations()
- .registries()
- .bindDeviceToGateway(registryPath, request)
- .execute();
-
- System.out.println(String.format("Device bound: %s", response.toPrettyString()));
- // [END iot_bind_device_to_gateway]
- }
-
- protected static void unbindDeviceFromGateway(
- String projectId, String cloudRegion, String registryName, String deviceId, String gatewayId)
- throws GeneralSecurityException, IOException {
- // [START iot_unbind_device_from_gateway]
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- UnbindDeviceFromGatewayRequest request = new UnbindDeviceFromGatewayRequest();
- request.setDeviceId(deviceId);
- request.setGatewayId(gatewayId);
-
- UnbindDeviceFromGatewayResponse response =
- service
- .projects()
- .locations()
- .registries()
- .unbindDeviceFromGateway(registryPath, request)
- .execute();
-
- System.out.println(String.format("Device unbound: %s", response.toPrettyString()));
- // [END iot_unbind_device_from_gateway]
- }
-
- /** Create a device to bind to a gateway. */
- protected static void createDevice(
- String projectId, String cloudRegion, String registryName, String deviceId)
- throws GeneralSecurityException, IOException {
- // [START iot_create_device]
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- List devices =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .list(registryPath)
- .setFieldMask("config,gatewayConfig")
- .execute()
- .getDevices();
-
- if (devices != null) {
- System.out.println("Found " + devices.size() + " devices");
- for (Device d : devices) {
- if ((d.getId() != null && d.getId().equals(deviceId))
- || (d.getName() != null && d.getName().equals(deviceId))) {
- System.out.println("Device exists, skipping.");
- return;
- }
- }
- }
-
- System.out.println("Creating device with id: " + deviceId);
- Device device = new Device();
- device.setId(deviceId);
-
- GatewayConfig gwConfig = new GatewayConfig();
- gwConfig.setGatewayType("NON_GATEWAY");
- gwConfig.setGatewayAuthMethod("ASSOCIATION_ONLY");
-
- device.setGatewayConfig(gwConfig);
- Device createdDevice =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .create(registryPath, device)
- .execute();
-
- System.out.println("Created device: " + createdDevice.toPrettyString());
- // [END iot_create_device]
- }
-
- /** Create a gateway to bind devices to. */
- protected static void createGateway(
- String projectId,
- String cloudRegion,
- String registryName,
- String gatewayId,
- String certificateFilePath,
- String algorithm)
- throws GeneralSecurityException, IOException {
- // [START iot_create_gateway]
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- System.out.println("Creating gateway with id: " + gatewayId);
- Device device = new Device();
- device.setId(gatewayId);
-
- GatewayConfig gwConfig = new GatewayConfig();
- gwConfig.setGatewayType("GATEWAY");
- gwConfig.setGatewayAuthMethod("ASSOCIATION_ONLY");
-
- String keyFormat = "RSA_X509_PEM";
- if ("ES256".equals(algorithm)) {
- keyFormat = "ES256_PEM";
- }
-
- PublicKeyCredential publicKeyCredential = new PublicKeyCredential();
-
- byte[] keyBytes = java.nio.file.Files.readAllBytes(Paths.get(certificateFilePath));
- publicKeyCredential.setKey(new String(keyBytes, StandardCharsets.US_ASCII));
- publicKeyCredential.setFormat(keyFormat);
- DeviceCredential deviceCredential = new DeviceCredential();
- deviceCredential.setPublicKey(publicKeyCredential);
-
- device.setGatewayConfig(gwConfig);
- device.setCredentials(Collections.singletonList(deviceCredential));
- Device createdDevice =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .create(registryPath, device)
- .execute();
-
- System.out.println("Created gateway: " + createdDevice.toPrettyString());
- // [END iot_create_gateway]
- }
-
- protected static void listGateways(String projectId, String cloudRegion, String registryName)
- throws IOException, GeneralSecurityException {
- // [START iot_list_gateways]
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- List gateways =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .list(registryPath)
- .setGatewayListOptionsGatewayType("GATEWAY")
- .execute()
- .getDevices();
-
- if (gateways != null) {
- System.out.println("Found " + gateways.size() + " devices");
- for (Device d : gateways) {
- System.out.println("Id: " + d.getId());
- if (d.getConfig() != null) {
- // Note that this will show the device config in Base64 encoded format.
- System.out.println("Config: " + d.getGatewayConfig().toPrettyString());
- }
- System.out.println();
- }
- } else {
- System.out.println("Registry has no devices.");
- }
- // [END iot_list_gateways]
- }
-
- /** List devices bound to a gateway. */
- protected static void listDevicesForGateway(
- String projectId, String cloudRegion, String registryName, String gatewayId)
- throws IOException, GeneralSecurityException {
- // [START iot_list_devices_for_gateway]
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName(APP_NAME)
- .build();
-
- final String registryPath =
- String.format(
- "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);
-
- List deviceNumIds =
- service
- .projects()
- .locations()
- .registries()
- .devices()
- .list(registryPath)
- .setGatewayListOptionsAssociationsGatewayId(gatewayId)
- .execute()
- .getDevices();
-
- if (deviceNumIds != null) {
- System.out.println("Found " + deviceNumIds.size() + " devices");
- for (Device device : deviceNumIds) {
- System.out.println(String.format("ID: %s", device.getId()));
- }
- } else {
- System.out.println("Gateway has no bound devices.");
- }
- // [END iot_list_devices_for_gateway]
- }
-
- /** Entry poit for CLI. */
- protected static void mainCreate(DeviceRegistryExampleOptions options) throws Exception {
- if ("create-iot-topic".equals(options.command)) {
- System.out.println("Create IoT Topic:");
- createIotTopic(options.projectId, options.pubsubTopic);
- } else if ("create-es".equals(options.command)) {
- System.out.println("Create ES Device:");
- createDeviceWithEs256(
- options.deviceId,
- options.ecPublicKeyFile,
- options.projectId,
- options.cloudRegion,
- options.registryName);
- } else if ("create-rsa".equals(options.command)) {
- System.out.println("Create RSA Device:");
- createDeviceWithRs256(
- options.deviceId,
- options.rsaCertificateFile,
- options.projectId,
- options.cloudRegion,
- options.registryName);
- } else if ("create-unauth".equals(options.command)) {
- System.out.println("Create Unauth Device");
- createDeviceWithNoAuth(
- options.deviceId, options.projectId, options.cloudRegion, options.registryName);
- } else if ("create-registry".equals(options.command)) {
- System.out.println("Create registry");
- createRegistry(
- options.cloudRegion, options.projectId, options.registryName, options.pubsubTopic);
- } else if ("create-gateway".equals(options.command)) {
- System.out.println("Bind device to gateway:");
- String algorithm = "ES256";
- String certificateFilePath = options.ecPublicKeyFile;
- if (options.rsaCertificateFile != null) {
- algorithm = "RS256";
- certificateFilePath = options.rsaCertificateFile;
- }
-
- createGateway(
- options.projectId,
- options.cloudRegion,
- options.registryName,
- options.gatewayId,
- certificateFilePath,
- algorithm);
- }
- }
-
- protected static void mainGet(DeviceRegistryExampleOptions options) throws Exception {
- if ("get-device".equals(options.command)) {
- System.out.println("Get device");
- System.out.println(
- getDevice(options.deviceId, options.projectId, options.cloudRegion, options.registryName)
- .toPrettyString());
- } else if ("get-iam-permissions".equals(options.command)) {
- System.out.println("Get iam permissions");
- getIamPermissions(options.projectId, options.cloudRegion, options.registryName);
- } else if ("get-device-state".equals(options.command)) {
- System.out.println("Get device state");
- List states =
- getDeviceStates(
- options.deviceId, options.projectId, options.cloudRegion, options.registryName);
- for (DeviceState state : states) {
- System.out.println(state.toPrettyString());
- }
- } else if ("get-registry".equals(options.command)) {
- System.out.println("Get registry");
- System.out.println(getRegistry(options.projectId, options.cloudRegion, options.registryName));
- }
- }
-
- public static void main(String[] args) throws Exception {
- DeviceRegistryExampleOptions options = DeviceRegistryExampleOptions.fromFlags(args);
- if (options == null) {
- // Could not parse.
- System.out.println("Issue parsing the options");
- return;
- }
-
- if (options.command.startsWith("create")) {
- mainCreate(options);
- }
-
- if (options.command.startsWith("get")) {
- mainGet(options);
- }
-
- if ("clear-registry".equals(options.command)) {
- System.out.println("Clear registry");
- clearRegistry(options.cloudRegion, options.projectId, options.registryName);
- } else if ("delete-device".equals(options.command)) {
- System.out.println("Delete device");
- deleteDevice(options.deviceId, options.projectId, options.cloudRegion, options.registryName);
- } else if ("delete-registry".equals(options.command)) {
- System.out.println("Delete registry");
- deleteRegistry(options.cloudRegion, options.projectId, options.registryName);
- } else if ("list-devices".equals(options.command)) {
- System.out.println("List devices");
- listDevices(options.projectId, options.cloudRegion, options.registryName);
- } else if ("list-registries".equals(options.command)) {
- System.out.println("List registries");
- listRegistries(options.projectId, options.cloudRegion);
- } else if ("patch-device-es".equals(options.command)) {
- System.out.println("Patch device with ES");
- patchEs256ForAuth(
- options.deviceId,
- options.ecPublicKeyFile,
- options.projectId,
- options.cloudRegion,
- options.registryName);
- } else if ("patch-device-rsa".equals(options.command)) {
- System.out.println("Patch device with RSA");
- patchRsa256ForAuth(
- options.deviceId,
- options.rsaCertificateFile,
- options.projectId,
- options.cloudRegion,
- options.registryName);
- } else if ("set-config".equals(options.command)) {
- if (options.deviceId == null) {
- System.out.println("Specify device_id for the device you are updating.");
- } else {
- System.out.println("Setting device configuration");
- setDeviceConfiguration(
- options.deviceId,
- options.projectId,
- options.cloudRegion,
- options.registryName,
- options.configuration,
- options.version);
- }
- } else if ("set-iam-permissions".equals(options.command)) {
- if (options.member == null || options.role == null) {
- System.out.println("Specify member and role for the policy you are updating.");
- } else {
- System.out.println("Setting iam permissions");
- setIamPermissions(
- options.projectId,
- options.cloudRegion,
- options.registryName,
- options.member,
- options.role);
- }
- } else if ("bind-device-to-gateway".equals(options.command)) {
- System.out.println("Bind device to gateway:");
- bindDeviceToGateway(
- options.projectId,
- options.cloudRegion,
- options.registryName,
- options.deviceId,
- options.gatewayId);
- } else if ("unbind-device-from-gateway".equals(options.command)) {
- System.out.println("Unbind device from gateway:");
- unbindDeviceFromGateway(
- options.projectId,
- options.cloudRegion,
- options.registryName,
- options.deviceId,
- options.gatewayId);
- } else if ("list-gateways".equals(options.command)) {
- System.out.println("Listing gateways: ");
- listGateways(options.projectId, options.cloudRegion, options.registryName);
- } else if ("list-devices-for-gateway".equals(options.command)) {
- System.out.println("Listing devices for a gateway: ");
- listDevicesForGateway(
- options.projectId, options.cloudRegion, options.registryName, options.gatewayId);
- } else if ("send-command".equals(options.command)) {
- System.out.println("Sending command to device:");
- sendCommand(
- options.deviceId,
- options.projectId,
- options.cloudRegion,
- options.registryName,
- options.commandData);
- } else {
- String header = "Cloud IoT Core Commandline Example (Device / Registry management): \n\n";
- String footer = "\nhttps://cloud.google.com/iot-core";
-
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp("DeviceRegistryExample", header, options.options, footer, true);
- }
- }
-}
diff --git a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/DeviceRegistryExampleOptions.java b/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/DeviceRegistryExampleOptions.java
deleted file mode 100644
index 71d367dbf68..00000000000
--- a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/DeviceRegistryExampleOptions.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.examples;
-
-import javax.annotation.Nullable;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** Command line options for the Device Manager example. */
-public class DeviceRegistryExampleOptions {
- static final String helpMessage = "Showing help";
- static final Options options = new Options();
- String projectId;
- String ecPublicKeyFile = null;
- String rsaCertificateFile = null;
- String cloudRegion = "us-central1";
- String command = "help";
- String commandData = "Specify with --data";
- String configuration = "Specify with -configuration";
- String deviceId; // Default to UUID?
- String gatewayId;
- String pubsubTopic;
- String registryName;
- String member;
- String role;
- long version = 0;
-
- /** Construct an DeviceRegistryExampleOptions class from command line flags. */
- public static @Nullable DeviceRegistryExampleOptions fromFlags(String... args) {
- // Required arguments
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("command")
- .hasArg()
- .desc(
- "Command to run:"
- + "\n\tclear-registry"
- + "\n\tcreate-iot-topic" // TODO: Descriptions or too verbose?
- + "\n\tcreate-rsa"
- + "\n\tcreate-es"
- + "\n\tcreate-unauth"
- + "\n\tcreate-registry"
- + "\n\tdelete-device"
- + "\n\tdelete-registry"
- + "\n\tget-device"
- + "\n\tget-device-state"
- + "\n\tget-iam-permissions"
- + "\n\tget-registry"
- + "\n\tlist-devices"
- + "\n\tlist-registries"
- + "\n\tpatch-device-es"
- + "\n\tpatch-device-rsa"
- + "\n\tset-config"
- + "\n\tset-iam-permissions"
- + "\n\tsend-command"
- + "\n\tcreate-gateway"
- + "\n\tbind-device-to-gateway"
- + "\n\tunbind-device-from-gateway"
- + "\n\tlist-gateways"
- + "\n\tlist-devices-for-gateway")
- .required()
- .build());
-
- // Optional arguments.
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("pubsub_topic")
- .hasArg()
- .desc("Pub/Sub topic to create registry in.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("ec_public_key_file")
- .hasArg()
- .desc("Path to ES256 public key file.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("rsa_certificate_file")
- .hasArg()
- .desc("Path to RS256 certificate file.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("cloud_region")
- .hasArg()
- .desc("GCP cloud region.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("project_id")
- .hasArg()
- .desc("GCP cloud project name.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("registry_name")
- .hasArg()
- .desc("Name for your Device Registry.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("device_id")
- .hasArg()
- .desc("Name for your Device.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("gateway_id")
- .hasArg()
- .desc("Name for your Device.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("data")
- .hasArg()
- .desc("The command data (string or JSON) to send to the specified device.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("configuration")
- .hasArg()
- .desc("The configuration (string or JSON) to set the specified device to.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("version")
- .hasArg()
- .desc("The configuration version to send on the device (0 is latest).")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("member")
- .hasArg()
- .desc("The member used for setting IAM permissions.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("role")
- .hasArg()
- .desc("The role (e.g. 'roles/viewer') used when setting IAM permissions.")
- .build());
-
- CommandLineParser parser = new DefaultParser();
- CommandLine commandLine;
- try {
- commandLine = parser.parse(options, args);
-
- DeviceRegistryExampleOptions res = new DeviceRegistryExampleOptions();
-
- res.command = commandLine.getOptionValue("command");
- if ("help".equals(res.command) || "".equals(res.command)) {
- throw new ParseException(String.format("%s, you entered %s", helpMessage, res.command));
- }
-
- if (commandLine.hasOption("cloud_region")) {
- res.cloudRegion = commandLine.getOptionValue("cloud_region");
- }
- if (commandLine.hasOption("data")) {
- res.commandData = commandLine.getOptionValue("data");
- }
- if (commandLine.hasOption("device_id")) {
- res.deviceId = commandLine.getOptionValue("device_id");
- }
-
- if (commandLine.hasOption("device_id")) {
- res.gatewayId = commandLine.getOptionValue("gateway_id");
- }
-
- if (commandLine.hasOption("project_id")) {
- res.projectId = commandLine.getOptionValue("project_id");
- } else {
- try {
- res.projectId = System.getenv("GOOGLE_CLOUD_PROJECT");
- } catch (NullPointerException npe) {
- res.projectId = System.getenv("GCLOUD_PROJECT");
- }
- }
-
- if (commandLine.hasOption("pubsub_topic")) {
- res.pubsubTopic = commandLine.getOptionValue("pubsub_topic");
- } else {
- // TODO: Get from environment variable
- }
-
- if (commandLine.hasOption("ec_public_key_file")) {
- res.ecPublicKeyFile = commandLine.getOptionValue("ec_public_key_file");
- }
- if (commandLine.hasOption("rsa_certificate_file")) {
- res.rsaCertificateFile = commandLine.getOptionValue("rsa_certificate_file");
- }
- if (commandLine.hasOption("cloud_region")) {
- res.cloudRegion = commandLine.getOptionValue("cloud_region");
- }
- if (commandLine.hasOption("registry_name")) {
- res.registryName = commandLine.getOptionValue("registry_name");
- }
- if (commandLine.hasOption("device_id")) {
- res.deviceId = commandLine.getOptionValue("device_id");
- }
- if (commandLine.hasOption("gateway_id")) {
- res.gatewayId = commandLine.getOptionValue("gateway_id");
- }
- if (commandLine.hasOption("configuration")) {
- res.configuration = commandLine.getOptionValue("configuration");
- }
- if (commandLine.hasOption("version")) {
- res.version = Long.parseLong(commandLine.getOptionValue("version"));
- }
- if (commandLine.hasOption("member")) {
- res.member = commandLine.getOptionValue("member");
- }
- if (commandLine.hasOption("role")) {
- res.role = commandLine.getOptionValue("role");
- }
-
- return res;
- } catch (ParseException e) {
- String header = "Cloud IoT Core Commandline Example (Device / Registry management): \n\n";
- String footer = "\nhttps://cloud.google.com/iot-core";
-
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp("DeviceRegistryExample", header, options, footer, true);
-
- System.err.println(e.getMessage());
- return null;
- }
- }
-
- public String toString() {
- return options.toString();
- }
-}
diff --git a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExample.java b/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExample.java
deleted file mode 100644
index 5b8c759d303..00000000000
--- a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExample.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.examples;
-
-// [START iot_http_includes]
-import com.google.api.client.http.ByteArrayContent;
-import com.google.api.client.http.GenericUrl;
-import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
-import com.google.api.client.http.HttpHeaders;
-import com.google.api.client.http.HttpRequest;
-import com.google.api.client.http.HttpRequestFactory;
-import com.google.api.client.http.HttpRequestInitializer;
-import com.google.api.client.http.HttpResponse;
-import com.google.api.client.http.HttpTransport;
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.client.json.JsonFactory;
-import com.google.api.client.json.JsonObjectParser;
-import com.google.api.client.json.gson.GsonFactory;
-import com.google.api.client.util.ExponentialBackOff;
-import com.google.common.io.CharStreams;
-import io.jsonwebtoken.JwtBuilder;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.security.KeyFactory;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.time.Instant;
-import java.util.Base64;
-import java.util.Date;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-// [END iot_http_includes]
-
-/**
- * Java sample of connecting to Google Cloud IoT Core vice via HTTP, using JWT.
- *
- * This example connects to Google Cloud IoT Core via HTTP Bridge, using a JWT for device
- * authentication. After connecting, by default the device publishes 100 messages at a rate of one
- * per second, and then exits. You can change The behavior to set state instead of events by using
- * flag -message_type to 'state'.
- *
- * To run this example, follow the instructions in the README located in the sample's parent
- * folder.
- */
-public class HttpExample {
- static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
- static final JsonFactory JSON_FACTORY = new GsonFactory();
- static final long MINUTES_PER_HOUR = 60;
-
- // [START iot_http_jwt]
- /** Create a RSA-based JWT for the given project id, signed with the given private key. */
- private static String createJwtRsa(String projectId, String privateKeyFile) throws Exception {
- Instant now = Instant.now();
- // Create a JWT to authenticate this device. The device will be disconnected after the token
- // expires, and will have to reconnect with a new token. The audience field should always be set
- // to the GCP project id.
- JwtBuilder jwtBuilder =
- Jwts.builder()
- .setIssuedAt(Date.from(now))
- .setExpiration(Date.from(now.plusSeconds(20 * 60)))
- .setAudience(projectId);
-
- byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory kf = KeyFactory.getInstance("RSA");
-
- return jwtBuilder.signWith(SignatureAlgorithm.RS256, kf.generatePrivate(spec)).compact();
- }
-
- /** Create an ES-based JWT for the given project id, signed with the given private key. */
- private static String createJwtEs(String projectId, String privateKeyFile) throws Exception {
- Instant now = Instant.now();
- // Create a JWT to authenticate this device. The device will be disconnected after the token
- // expires, and will have to reconnect with a new token. The audience field should always be set
- // to the GCP project id.
- JwtBuilder jwtBuilder =
- Jwts.builder()
- .setIssuedAt(Date.from(now))
- .setExpiration(Date.from(now.plusSeconds(20 * 60)))
- .setAudience(projectId);
-
- byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory kf = KeyFactory.getInstance("EC");
-
- return jwtBuilder.signWith(SignatureAlgorithm.ES256, kf.generatePrivate(spec)).compact();
- }
- // [END iot_http_jwt]
-
- // [START iot_http_getconfig]
- /** Publish an event or state message using Cloud IoT Core via the HTTP API. */
- protected static void getConfig(
- String urlPath,
- String token,
- String projectId,
- String cloudRegion,
- String registryId,
- String deviceId,
- String version)
- throws IOException {
- // Build the resource path of the device that is going to be authenticated.
- String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryId, deviceId);
- urlPath = urlPath + devicePath + "/config?local_version=" + version;
-
- HttpRequestFactory requestFactory =
- HTTP_TRANSPORT.createRequestFactory(
- new HttpRequestInitializer() {
- @Override
- public void initialize(HttpRequest request) {
- request.setParser(new JsonObjectParser(JSON_FACTORY));
- }
- });
-
- final HttpRequest req = requestFactory.buildGetRequest(new GenericUrl(urlPath));
- HttpHeaders heads = new HttpHeaders();
-
- heads.setAuthorization(String.format("Bearer %s", token));
- heads.setContentType("application/json; charset=UTF-8");
- heads.setCacheControl("no-cache");
-
- req.setHeaders(heads);
- ExponentialBackOff backoff =
- new ExponentialBackOff.Builder()
- .setInitialIntervalMillis(500)
- .setMaxElapsedTimeMillis(900000)
- .setMaxIntervalMillis(6000)
- .setMultiplier(1.5)
- .setRandomizationFactor(0.5)
- .build();
- req.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(backoff));
- HttpResponse res = req.execute();
- System.out.println(res.getStatusCode());
- System.out.println(res.getStatusMessage());
- try (InputStream in = res.getContent()) {
- System.out
- .println(CharStreams.toString(new InputStreamReader(in, StandardCharsets.UTF_8.name())));
- }
- }
- // [END iot_http_getconfig]
-
- // [START iot_http_publish]
- /** Publish an event or state message using Cloud IoT Core via the HTTP API. */
- protected static void publishMessage(
- String payload,
- String urlPath,
- String messageType,
- String token,
- String projectId,
- String cloudRegion,
- String registryId,
- String deviceId)
- throws IOException, JSONException {
- // Build the resource path of the device that is going to be authenticated.
- String devicePath =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryId, deviceId);
- String urlSuffix = "event".equals(messageType) ? "publishEvent" : "setState";
-
- // Data sent through the wire has to be base64 encoded.
- Base64.Encoder encoder = Base64.getEncoder();
-
- String encPayload = encoder.encodeToString(payload.getBytes(StandardCharsets.UTF_8.name()));
-
- urlPath = urlPath + devicePath + ":" + urlSuffix;
-
- final HttpRequestFactory requestFactory =
- HTTP_TRANSPORT.createRequestFactory(
- new HttpRequestInitializer() {
- @Override
- public void initialize(HttpRequest request) {
- request.setParser(new JsonObjectParser(JSON_FACTORY));
- }
- });
-
- HttpHeaders heads = new HttpHeaders();
- heads.setAuthorization(String.format("Bearer %s", token));
- heads.setContentType("application/json; charset=UTF-8");
- heads.setCacheControl("no-cache");
-
- // Add post data. The data sent depends on whether we're updating state or publishing events.
- JSONObject data = new JSONObject();
- if ("event".equals(messageType)) {
- data.put("binary_data", encPayload);
- } else {
- JSONObject state = new JSONObject();
- state.put("binary_data", encPayload);
- data.put("state", state);
- }
-
- ByteArrayContent content =
- new ByteArrayContent(
- "application/json", data.toString().getBytes(StandardCharsets.UTF_8.name()));
-
- final HttpRequest req = requestFactory.buildGetRequest(new GenericUrl(urlPath));
- req.setHeaders(heads);
- req.setContent(content);
- req.setRequestMethod("POST");
- ExponentialBackOff backoff =
- new ExponentialBackOff.Builder()
- .setInitialIntervalMillis(500)
- .setMaxElapsedTimeMillis(900000)
- .setMaxIntervalMillis(6000)
- .setMultiplier(1.5)
- .setRandomizationFactor(0.5)
- .build();
- req.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(backoff));
-
- HttpResponse res = req.execute();
- System.out.println(res.getStatusCode());
- System.out.println(res.getStatusMessage());
- }
- // [END iot_http_publish]
-
- // [START iot_http_run]
- /** Parse arguments and publish messages. */
- protected static void main(String[] args) throws Exception {
- HttpExampleOptions options = HttpExampleOptions.fromFlags(args);
-
- if (options == null) {
- // Could not parse the flags.
- System.exit(1);
- }
-
- // Create the corresponding JWT depending on the selected algorithm.
- String token;
- Instant iat = Instant.now();
- if ("RS256".equals(options.algorithm)) {
- token = createJwtRsa(options.projectId, options.privateKeyFile);
- } else if ("ES256".equals(options.algorithm)) {
- token = createJwtEs(options.projectId, options.privateKeyFile);
- } else {
- throw new IllegalArgumentException(
- "Invalid algorithm " + options.algorithm + ". Should be one of 'RS256' or 'ES256'.");
- }
-
- String urlPath = String.format("%s/%s/", options.httpBridgeAddress, options.apiVersion);
- System.out.format("Using URL: '%s'%n", urlPath);
-
- // Show the latest configuration
- getConfig(
- urlPath,
- token,
- options.projectId,
- options.cloudRegion,
- options.registryId,
- options.deviceId,
- "0");
-
- // Publish numMessages messages to the HTTP bridge.
- for (int i = 1; i <= options.numMessages; ++i) {
- String payload = String.format("%s/%s-payload-%d", options.registryId, options.deviceId, i);
- System.out.format(
- "Publishing %s message %d/%d: '%s'%n",
- options.messageType, i, options.numMessages, payload);
-
- // Refresh the authentication token if the token has expired.
- long secsSinceRefresh = (Instant.now().toEpochMilli() - iat.toEpochMilli()) / 1000;
- if (secsSinceRefresh > (options.tokenExpMins * MINUTES_PER_HOUR)) {
- System.out.format("\tRefreshing token after: %d seconds%n", secsSinceRefresh);
- iat = Instant.now();
-
- if ("RS256".equals(options.algorithm)) {
- token = createJwtRsa(options.projectId, options.privateKeyFile);
- } else if ("ES256".equals(options.algorithm)) {
- token = createJwtEs(options.projectId, options.privateKeyFile);
- }
- }
-
- publishMessage(
- payload,
- urlPath,
- options.messageType,
- token,
- options.projectId,
- options.cloudRegion,
- options.registryId,
- options.deviceId);
-
- if ("event".equals(options.messageType)) {
- // Frequently send event payloads (every second)
- Thread.sleep(1000);
- } else {
- // Update state with low frequency (once every 5 seconds)
- Thread.sleep(5000);
- }
- }
- System.out.println("Finished loop successfully. Goodbye!");
- }
- // [END iot_http_run]
-}
diff --git a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExampleOptions.java b/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExampleOptions.java
deleted file mode 100644
index 0ab17364e18..00000000000
--- a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExampleOptions.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.examples;
-
-import javax.annotation.Nullable;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** Command line options for the HTTP example. */
-public class HttpExampleOptions {
- static final Options options = new Options();
- String projectId;
- String registryId;
- String deviceId;
- String privateKeyFile;
- String algorithm;
- String cloudRegion = "us-central1";
- int numMessages = 100;
- int tokenExpMins = 20;
- String httpBridgeAddress = "https://cloudiotdevice.googleapis.com";
- String apiVersion = "v1";
- String messageType = "event";
-
- /** Construct an HttpExampleOptions class from command line flags. */
- public static @Nullable HttpExampleOptions fromFlags(String... args) {
- // Required arguments
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("project_id")
- .hasArg()
- .desc("GCP cloud project name.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("registry_id")
- .hasArg()
- .desc("Cloud IoT Core registry id.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("device_id")
- .hasArg()
- .desc("Cloud IoT Core device id.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("private_key_file")
- .hasArg()
- .desc("Path to private key file.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("algorithm")
- .hasArg()
- .desc("Encryption algorithm to use to generate the JWT. Either 'RS256' or 'ES256'.")
- .required()
- .build());
-
- // Optional arguments.
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("cloud_region")
- .hasArg()
- .desc("GCP cloud region.")
- .build());
- options.addOption(
- Option.builder()
- .type(Number.class)
- .longOpt("num_messages")
- .hasArg()
- .desc("Number of messages to publish.")
- .build());
- options.addOption(
- Option.builder()
- .type(Number.class)
- .longOpt("token_exp_minutes")
- .hasArg()
- .desc("Minutes to JWT token refresh (token expiration time).")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("http_bridge_address")
- .hasArg()
- .desc("HTTP bridge address.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("api_version")
- .hasArg()
- .desc("The version to use of the API.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("message_type")
- .hasArg()
- .desc("Indicates whether message is a telemetry event or a device state message")
- .build());
-
- CommandLineParser parser = new DefaultParser();
- CommandLine commandLine;
- try {
- commandLine = parser.parse(options, args);
- HttpExampleOptions res = new HttpExampleOptions();
-
- res.projectId = commandLine.getOptionValue("project_id");
- res.registryId = commandLine.getOptionValue("registry_id");
- res.deviceId = commandLine.getOptionValue("device_id");
- res.privateKeyFile = commandLine.getOptionValue("private_key_file");
- res.algorithm = commandLine.getOptionValue("algorithm");
- if (commandLine.hasOption("cloud_region")) {
- res.cloudRegion = commandLine.getOptionValue("cloud_region");
- }
- if (commandLine.hasOption("num_messages")) {
- res.numMessages = ((Number) commandLine.getParsedOptionValue("num_messages")).intValue();
- }
- if (commandLine.hasOption("token_exp_minutes")) {
- res.tokenExpMins =
- ((Number) commandLine.getParsedOptionValue("token_exp_minutes")).intValue();
- }
- if (commandLine.hasOption("http_bridge_address")) {
- res.httpBridgeAddress = commandLine.getOptionValue("http_bridge_address");
- }
- if (commandLine.hasOption("api_version")) {
- res.apiVersion = commandLine.getOptionValue("api_version");
- }
- if (commandLine.hasOption("message_type")) {
- res.messageType = commandLine.getOptionValue("message_type");
- }
- return res;
- } catch (ParseException e) {
- System.err.println(e.getMessage());
- return null;
- }
- }
-
- public String toString() {
- return options.toString();
- }
-}
diff --git a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/MqttExample.java b/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/MqttExample.java
deleted file mode 100644
index 18e2444ef7d..00000000000
--- a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/MqttExample.java
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.examples;
-
-// [START iot_mqtt_includes]
-
-import io.jsonwebtoken.JwtBuilder;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.time.Instant;
-import java.util.Date;
-import java.util.Properties;
-import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
-import org.eclipse.paho.client.mqttv3.MqttCallback;
-import org.eclipse.paho.client.mqttv3.MqttClient;
-import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
-import org.eclipse.paho.client.mqttv3.MqttException;
-import org.eclipse.paho.client.mqttv3.MqttMessage;
-import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
-
-// [END iot_mqtt_includes]
-
-/**
- * Java sample of connecting to Google Cloud IoT Core vice via MQTT, using JWT.
- *
- * This example connects to Google Cloud IoT Core via MQTT, using a JWT for device
- * authentication. After connecting, by default the device publishes 100 messages to the device's
- * MQTT topic at a rate of one per second, and then exits. To set state instead of publishing
- * telemetry events, set the `-message_type` flag to `state.`
- *
- * To run this example, first create your credentials and register your device as described in
- * the README located in the sample's parent folder.
- *
- * After you have registered your device and generated your credentials, compile and run with the
- * corresponding algorithm flag, for example:
- *
- *
- * $ mvn compile
- * $ mvn exec:exec -Dmqtt \
- * -Dproject_id=blue-jet-123 \
- * -Dregistry_id=my-registry \
- * -Ddevice_id=my-test-device \
- * -Dalgorithm=RS256 \
- * -Dprivate_key_file="../path/to/your_private_pkcs8"
- *
- */
-public class MqttExample {
- // [START iot_mqtt_jwt]
- // [START iot_mqtt_configcallback]
- static MqttCallback mCallback;
- static long MINUTES_PER_HOUR = 60;
-
- /** Create a Cloud IoT Core JWT for the given project id, signed with the given RSA key. */
- private static String createJwtRsa(String projectId, String privateKeyFile)
- throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
- Instant now = Instant.now();
- // Create a JWT to authenticate this device. The device will be disconnected after the token
- // expires, and will have to reconnect with a new token. The audience field should always be set
- // to the GCP project id.
- JwtBuilder jwtBuilder =
- Jwts.builder()
- .setIssuedAt(Date.from(now))
- .setExpiration(Date.from(now.plusSeconds(20 * 60)))
- .setAudience(projectId);
-
- byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory kf = KeyFactory.getInstance("RSA");
-
- return jwtBuilder.signWith(SignatureAlgorithm.RS256, kf.generatePrivate(spec)).compact();
- }
- // [END iot_mqtt_jwt]
-
- /** Create a Cloud IoT Core JWT for the given project id, signed with the given ES key. */
- private static String createJwtEs(String projectId, String privateKeyFile)
- throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
- Instant now = Instant.now();
- // Create a JWT to authenticate this device. The device will be disconnected after the token
- // expires, and will have to reconnect with a new token. The audience field should always be set
- // to the GCP project id.
- JwtBuilder jwtBuilder =
- Jwts.builder()
- .setIssuedAt(Date.from(now))
- .setExpiration(Date.from(now.plusSeconds(20 * 60)))
- .setAudience(projectId);
-
- byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
- KeyFactory kf = KeyFactory.getInstance("EC");
-
- return jwtBuilder.signWith(SignatureAlgorithm.ES256, kf.generatePrivate(spec)).compact();
- }
-
- /** Connects the gateway to the MQTT bridge. */
- protected static MqttClient startMqtt(
- String mqttBridgeHostname,
- int mqttBridgePort,
- String projectId,
- String cloudRegion,
- String registryId,
- String gatewayId,
- String privateKeyFile,
- String algorithm)
- throws NoSuchAlgorithmException, IOException, MqttException, InterruptedException,
- InvalidKeySpecException {
- // [START iot_gateway_start_mqtt]
-
- // Build the connection string for Google's Cloud IoT Core MQTT server. Only SSL
- // connections are accepted. For server authentication, the JVM's root certificates
- // are used.
- final String mqttServerAddress =
- String.format("ssl://%s:%s", mqttBridgeHostname, mqttBridgePort);
-
- // Create our MQTT client. The mqttClientId is a unique string that identifies this device. For
- // Google Cloud IoT Core, it must be in the format below.
- final String mqttClientId =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- projectId, cloudRegion, registryId, gatewayId);
-
- MqttConnectOptions connectOptions = new MqttConnectOptions();
- // Note that the Google Cloud IoT Core only supports MQTT 3.1.1, and Paho requires that we
- // explictly set this. If you don't set MQTT version, the server will immediately close its
- // connection to your device.
- connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
-
- Properties sslProps = new Properties();
- sslProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
- connectOptions.setSSLProperties(sslProps);
-
- // With Google Cloud IoT Core, the username field is ignored, however it must be set for the
- // Paho client library to send the password field. The password field is used to transmit a JWT
- // to authorize the device.
- connectOptions.setUserName("unused");
-
- if ("RS256".equals(algorithm)) {
- connectOptions.setPassword(createJwtRsa(projectId, privateKeyFile).toCharArray());
- } else if ("ES256".equals(algorithm)) {
- connectOptions.setPassword(createJwtEs(projectId, privateKeyFile).toCharArray());
- } else {
- throw new IllegalArgumentException(
- "Invalid algorithm " + algorithm + ". Should be one of 'RS256' or 'ES256'.");
- }
-
- System.out.println(String.format("%s", mqttClientId));
-
- // Create a client, and connect to the Google MQTT bridge.
- try (MqttClient client =
- new MqttClient(mqttServerAddress, mqttClientId, new MemoryPersistence())) {
- // Both connect and publish operations may fail. If they do, allow retries but with an
- // exponential backoff time period.
- long initialConnectIntervalMillis = 500L;
- long maxConnectIntervalMillis = 6000L;
- long maxConnectRetryTimeElapsedMillis = 900000L;
- float intervalMultiplier = 1.5f;
-
- long retryIntervalMs = initialConnectIntervalMillis;
- long totalRetryTimeMs = 0;
-
- while (totalRetryTimeMs < maxConnectRetryTimeElapsedMillis && !client.isConnected()) {
- try {
- client.connect(connectOptions);
- } catch (MqttException e) {
- int reason = e.getReasonCode();
-
- // If the connection is lost or if the server cannot be connected, allow retries, but with
- // exponential backoff.
- System.out.println("An error occurred: " + e.getMessage());
- if (reason == MqttException.REASON_CODE_CONNECTION_LOST
- || reason == MqttException.REASON_CODE_SERVER_CONNECT_ERROR) {
- System.out.println("Retrying in " + retryIntervalMs / 1000.0 + " seconds.");
- Thread.sleep(retryIntervalMs);
- totalRetryTimeMs += retryIntervalMs;
- retryIntervalMs *= intervalMultiplier;
- if (retryIntervalMs > maxConnectIntervalMillis) {
- retryIntervalMs = maxConnectIntervalMillis;
- }
- } else {
- throw e;
- }
- }
- }
-
- attachCallback(client, gatewayId);
-
- // The topic gateways receive error updates on. QoS must be 0.
- String errorTopic = String.format("/devices/%s/errors", gatewayId);
- System.out.println(String.format("Listening on %s", errorTopic));
-
- client.subscribe(errorTopic, 0);
-
- return client;
- // [END iot_gateway_start_mqtt]
- }
- }
-
- protected static void sendDataFromDevice(
- MqttClient client, String deviceId, String messageType, String data)
- throws MqttException, UnsupportedEncodingException {
- // [START send_data_from_bound_device]
- if (!"events".equals(messageType) && !"state".equals(messageType)) {
- System.err.println("Invalid message type, must ether be 'state' or events'");
- return;
- }
- final String dataTopic = String.format("/devices/%s/%s", deviceId, messageType);
- MqttMessage message = new MqttMessage(data.getBytes(StandardCharsets.UTF_8.name()));
- message.setQos(1);
- client.publish(dataTopic, message);
- System.out.println("Data sent");
- // [END send_data_from_bound_device]
- }
-
- /** Sends data on behalf of a bound device using the Gateway. */
- protected static void sendDataFromBoundDevice(
- String mqttBridgeHostname,
- short mqttBridgePort,
- String projectId,
- String cloudRegion,
- String registryName,
- String gatewayId,
- String privateKeyFile,
- String algorithm,
- String deviceId,
- String messageType,
- String telemetryData)
- throws MqttException, IOException, InvalidKeySpecException, InterruptedException,
- NoSuchAlgorithmException {
- // [START send_data_from_bound_device]
- MqttClient client =
- startMqtt(
- mqttBridgeHostname,
- mqttBridgePort,
- projectId,
- cloudRegion,
- registryName,
- gatewayId,
- privateKeyFile,
- algorithm);
- attachDeviceToGateway(client, deviceId);
- sendDataFromDevice(client, deviceId, messageType, telemetryData);
- detachDeviceFromGateway(client, deviceId);
- // [END send_data_from_bound_device]
- }
-
- protected static void listenForConfigMessages(
- String mqttBridgeHostname,
- short mqttBridgePort,
- String projectId,
- String cloudRegion,
- String registryName,
- String gatewayId,
- String privateKeyFile,
- String algorithm,
- String deviceId)
- throws MqttException, IOException, InvalidKeySpecException, InterruptedException,
- NoSuchAlgorithmException {
- // Connect the Gateway
- MqttClient client =
- startMqtt(
- mqttBridgeHostname,
- mqttBridgePort,
- projectId,
- cloudRegion,
- registryName,
- gatewayId,
- privateKeyFile,
- algorithm);
- // Connect the bound device and listen for configuration messages.
- attachDeviceToGateway(client, deviceId);
- attachCallback(client, deviceId);
-
- detachDeviceFromGateway(client, deviceId);
- }
-
- protected static void attachDeviceToGateway(MqttClient client, String deviceId)
- throws MqttException, UnsupportedEncodingException {
- // [START iot_attach_device]
- final String attachTopic = String.format("/devices/%s/attach", deviceId);
- System.out.println(String.format("Attaching: %s", attachTopic));
- String attachPayload = "{}";
- MqttMessage message = new MqttMessage(attachPayload.getBytes(StandardCharsets.UTF_8.name()));
- message.setQos(1);
- client.publish(attachTopic, message);
- // [END iot_attach_device]
- }
-
- /** Detaches a bound device from the Gateway. */
- protected static void detachDeviceFromGateway(MqttClient client, String deviceId)
- throws MqttException, UnsupportedEncodingException {
- // [START iot_detach_device]
- final String detachTopic = String.format("/devices/%s/detach", deviceId);
- System.out.println(String.format("Detaching: %s", detachTopic));
- String attachPayload = "{}";
- MqttMessage message = new MqttMessage(attachPayload.getBytes(StandardCharsets.UTF_8.name()));
- message.setQos(1);
- client.publish(detachTopic, message);
- // [END iot_detach_device]
- }
-
- protected static void mqttDeviceDemo(MqttExampleOptions options)
- throws NoSuchAlgorithmException, IOException, InvalidKeySpecException, MqttException,
- InterruptedException {
- // Build the connection string for Google's Cloud IoT Core MQTT server. Only SSL
- // connections are accepted. For server authentication, the JVM's root certificates
- // are used.
- final String mqttServerAddress =
- String.format("ssl://%s:%s", options.mqttBridgeHostname, options.mqttBridgePort);
-
- // Create our MQTT client. The mqttClientId is a unique string that identifies this device. For
- // Google Cloud IoT Core, it must be in the format below.
- final String mqttClientId =
- String.format(
- "projects/%s/locations/%s/registries/%s/devices/%s",
- options.projectId, options.cloudRegion, options.registryId, options.deviceId);
-
- MqttConnectOptions connectOptions = new MqttConnectOptions();
- // Note that the Google Cloud IoT Core only supports MQTT 3.1.1, and Paho requires that we
- // explictly set this. If you don't set MQTT version, the server will immediately close its
- // connection to your device.
- connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
-
- Properties sslProps = new Properties();
- sslProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
- connectOptions.setSSLProperties(sslProps);
-
- // With Google Cloud IoT Core, the username field is ignored, however it must be set for the
- // Paho client library to send the password field. The password field is used to transmit a JWT
- // to authorize the device.
- connectOptions.setUserName("unused");
-
- Instant iat = Instant.now();
- if ("RS256".equals(options.algorithm)) {
- connectOptions.setPassword(
- createJwtRsa(options.projectId, options.privateKeyFile).toCharArray());
- } else if ("ES256".equals(options.algorithm)) {
- connectOptions.setPassword(
- createJwtEs(options.projectId, options.privateKeyFile).toCharArray());
- } else {
- throw new IllegalArgumentException(
- "Invalid algorithm " + options.algorithm + ". Should be one of 'RS256' or 'ES256'.");
- }
-
- // [START iot_mqtt_publish]
- // Create a client, and connect to the Google MQTT bridge.
- MqttClient client = new MqttClient(mqttServerAddress, mqttClientId, new MemoryPersistence());
-
- // Both connect and publish operations may fail. If they do, allow retries but with an
- // exponential backoff time period.
- long initialConnectIntervalMillis = 500L;
- long maxConnectIntervalMillis = 6000L;
- long maxConnectRetryTimeElapsedMillis = 900000L;
- float intervalMultiplier = 1.5f;
-
- long retryIntervalMs = initialConnectIntervalMillis;
- long totalRetryTimeMs = 0;
-
- while (totalRetryTimeMs < maxConnectRetryTimeElapsedMillis && !client.isConnected()) {
- try {
- client.connect(connectOptions);
- } catch (MqttException e) {
- int reason = e.getReasonCode();
-
- // If the connection is lost or if the server cannot be connected, allow retries, but with
- // exponential backoff.
- System.out.println("An error occurred: " + e.getMessage());
- if (reason == MqttException.REASON_CODE_CONNECTION_LOST
- || reason == MqttException.REASON_CODE_SERVER_CONNECT_ERROR) {
- System.out.println("Retrying in " + retryIntervalMs / 1000.0 + " seconds.");
- Thread.sleep(retryIntervalMs);
- totalRetryTimeMs += retryIntervalMs;
- retryIntervalMs *= intervalMultiplier;
- if (retryIntervalMs > maxConnectIntervalMillis) {
- retryIntervalMs = maxConnectIntervalMillis;
- }
- } else {
- throw e;
- }
- }
- }
-
- attachCallback(client, options.deviceId);
-
- // Publish to the events or state topic based on the flag.
- String subTopic = "event".equals(options.messageType) ? "events" : options.messageType;
-
- // The MQTT topic that this device will publish telemetry data to. The MQTT topic name is
- // required to be in the format below. Note that this is not the same as the device registry's
- // Cloud Pub/Sub topic.
- String mqttTopic = String.format("/devices/%s/%s", options.deviceId, subTopic);
-
- // Publish numMessages messages to the MQTT bridge, at a rate of 1 per second.
- for (int i = 1; i <= options.numMessages; ++i) {
- String payload = String.format("%s/%s-payload-%d", options.registryId, options.deviceId, i);
- System.out.format(
- "Publishing %s message %d/%d: '%s'%n",
- options.messageType, i, options.numMessages, payload);
-
- // Refresh the connection credentials before the JWT expires.
- // [START iot_mqtt_jwt_refresh]
- long secsSinceRefresh = (Instant.now().toEpochMilli() - iat.toEpochMilli()) / 1000;
- if (secsSinceRefresh > (options.tokenExpMins * MINUTES_PER_HOUR)) {
- System.out.format("\tRefreshing token after: %d seconds%n", secsSinceRefresh);
- iat = Instant.now();
- if ("RS256".equals(options.algorithm)) {
- connectOptions.setPassword(
- createJwtRsa(options.projectId, options.privateKeyFile).toCharArray());
- } else if ("ES256".equals(options.algorithm)) {
- connectOptions.setPassword(
- createJwtEs(options.projectId, options.privateKeyFile).toCharArray());
- } else {
- throw new IllegalArgumentException(
- "Invalid algorithm " + options.algorithm + ". Should be one of 'RS256' or 'ES256'.");
- }
- client.disconnect();
- client.connect(connectOptions);
- attachCallback(client, options.deviceId);
- }
- // [END iot_mqtt_jwt_refresh]
-
- // Publish "payload" to the MQTT topic. qos=1 means at least once delivery. Cloud IoT Core
- // also supports qos=0 for at most once delivery.
- MqttMessage message = new MqttMessage(payload.getBytes(StandardCharsets.UTF_8.name()));
- message.setQos(1);
- client.publish(mqttTopic, message);
-
- if ("event".equals(options.messageType)) {
- // Send telemetry events every second
- Thread.sleep(1000);
- } else {
- // Note: Update Device state less frequently than with telemetry events
- Thread.sleep(5000);
- }
- }
-
- // Wait for commands to arrive for about two minutes.
- for (int i = 1; i <= options.waitTime; ++i) {
- System.out.print('.');
- Thread.sleep(1000);
- }
- System.out.println("");
-
- // Disconnect the client if still connected, and finish the run.
- if (client.isConnected()) {
- client.disconnect();
- }
-
- System.out.println("Finished loop successfully. Goodbye!");
- client.close();
- // [END iot_mqtt_publish]
- }
-
- /** Attaches the callback used when configuration changes occur. */
- protected static void attachCallback(MqttClient client, String deviceId)
- throws MqttException, UnsupportedEncodingException {
- mCallback =
- new MqttCallback() {
- @Override
- public void connectionLost(Throwable cause) {
- // Do nothing...
- }
-
- @Override
- public void messageArrived(String topic, MqttMessage message) {
- try {
- String payload = new String(message.getPayload(), StandardCharsets.UTF_8.name());
- System.out.println("Payload : " + payload);
- // TODO: Insert your parsing / handling of the configuration message here.
- //
- } catch (UnsupportedEncodingException uee) {
- System.err.println(uee);
- }
- }
-
- @Override
- public void deliveryComplete(IMqttDeliveryToken token) {
- // Do nothing;
- }
- };
-
- String commandTopic = String.format("/devices/%s/commands/#", deviceId);
- System.out.println(String.format("Listening on %s", commandTopic));
-
- String configTopic = String.format("/devices/%s/config", deviceId);
- System.out.println(String.format("Listening on %s", configTopic));
-
- client.subscribe(configTopic, 1);
- client.subscribe(commandTopic, 1);
- client.setCallback(mCallback);
- }
- // [END iot_mqtt_configcallback]
-
- /** Parse arguments, configure MQTT, and publish messages. */
- public static void main(String[] args) throws Exception {
- // [START iot_mqtt_configuremqtt]
- MqttExampleOptions options = MqttExampleOptions.fromFlags(args);
- if (options == null) {
- // Could not parse.
- System.exit(1);
- }
-
- if ("listen-for-config-messages".equals(options.command)) {
- System.out.println(
- String.format("Listening for configuration messages for %s:", options.deviceId));
- listenForConfigMessages(
- options.mqttBridgeHostname,
- options.mqttBridgePort,
- options.projectId,
- options.cloudRegion,
- options.registryId,
- options.gatewayId,
- options.privateKeyFile,
- options.algorithm,
- options.deviceId);
- } else if ("send-data-from-bound-device".equals(options.command)) {
- System.out.println("Sending data on behalf of device:");
- sendDataFromBoundDevice(
- options.mqttBridgeHostname,
- options.mqttBridgePort,
- options.projectId,
- options.cloudRegion,
- options.registryId,
- options.gatewayId,
- options.privateKeyFile,
- options.algorithm,
- options.deviceId,
- options.messageType,
- options.telemetryData);
- } else {
- System.out.println("Starting mqtt demo:");
- mqttDeviceDemo(options);
- }
- // [END iot_mqtt_configuremqtt]
- }
-}
diff --git a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/MqttExampleOptions.java b/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/MqttExampleOptions.java
deleted file mode 100644
index cb7683e9524..00000000000
--- a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/MqttExampleOptions.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.examples;
-
-import javax.annotation.Nullable;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** Command line options for the MQTT example. */
-public class MqttExampleOptions {
- static final Options options = new Options();
- String projectId;
- String registryId;
- String command = "mqtt-demo";
- String deviceId;
- String gatewayId;
- String privateKeyFile;
- String algorithm;
- String cloudRegion = "us-central1";
- int numMessages = 100;
- int tokenExpMins = 20;
- String telemetryData = "Specify with -telemetry_data";
-
- String mqttBridgeHostname = "mqtt.googleapis.com";
- short mqttBridgePort = 8883;
- String messageType = "event";
- int waitTime = 120;
-
- /** Construct an MqttExampleOptions class from command line flags. */
- public static @Nullable MqttExampleOptions fromFlags(String... args) {
- // Required arguments
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("project_id")
- .hasArg()
- .desc("GCP cloud project name.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("registry_id")
- .hasArg()
- .desc("Cloud IoT Core registry id.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("device_id")
- .hasArg()
- .desc("Cloud IoT Core device id.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("gateway_id")
- .hasArg()
- .desc("The identifier for the Gateway.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("private_key_file")
- .hasArg()
- .desc("Path to private key file.")
- .required()
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("algorithm")
- .hasArg()
- .desc("Encryption algorithm to use to generate the JWT. Either 'RS256' or 'ES256'.")
- .required()
- .build());
-
- // Optional arguments.
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("command")
- .hasArg()
- .desc(
- "Command to run:"
- + "\n\tlisten-for-config-messages"
- + "\n\tsend-data-from-bound-device")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("telemetry_data")
- .hasArg()
- .desc("The telemetry data (string or JSON) to send on behalf of the delegated device.")
- .build());
-
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("cloud_region")
- .hasArg()
- .desc("GCP cloud region.")
- .build());
- options.addOption(
- Option.builder()
- .type(Number.class)
- .longOpt("num_messages")
- .hasArg()
- .desc("Number of messages to publish.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("mqtt_bridge_hostname")
- .hasArg()
- .desc("MQTT bridge hostname.")
- .build());
- options.addOption(
- Option.builder()
- .type(Number.class)
- .longOpt("token_exp_minutes")
- .hasArg()
- .desc("Minutes to JWT token refresh (token expiration time).")
- .build());
- options.addOption(
- Option.builder()
- .type(Number.class)
- .longOpt("mqtt_bridge_port")
- .hasArg()
- .desc("MQTT bridge port.")
- .build());
- options.addOption(
- Option.builder()
- .type(String.class)
- .longOpt("message_type")
- .hasArg()
- .desc("Indicates whether the message is a telemetry event or a device state message")
- .build());
- options.addOption(
- Option.builder()
- .type(Number.class)
- .longOpt("wait_time")
- .hasArg()
- .desc("Wait time (in seconds) for commands.")
- .build());
-
- CommandLineParser parser = new DefaultParser();
- CommandLine commandLine;
- try {
- commandLine = parser.parse(options, args);
- MqttExampleOptions res = new MqttExampleOptions();
-
- res.projectId = commandLine.getOptionValue("project_id");
- res.registryId = commandLine.getOptionValue("registry_id");
- res.deviceId = commandLine.getOptionValue("device_id");
- res.privateKeyFile = commandLine.getOptionValue("private_key_file");
- res.algorithm = commandLine.getOptionValue("algorithm");
- if (commandLine.hasOption("command")) {
- res.command = commandLine.getOptionValue("command");
- }
- if (commandLine.hasOption("gateway_id")) {
- res.gatewayId = commandLine.getOptionValue("gateway_id");
- }
- if (commandLine.hasOption("wait_time")) {
- res.waitTime = ((Number) commandLine.getParsedOptionValue("wait_time")).intValue();
- }
- if (commandLine.hasOption("cloud_region")) {
- res.cloudRegion = commandLine.getOptionValue("cloud_region");
- }
- if (commandLine.hasOption("telemetry_data")) {
- res.telemetryData = commandLine.getOptionValue("telemetry_data");
- }
- if (commandLine.hasOption("num_messages")) {
- res.numMessages = ((Number) commandLine.getParsedOptionValue("num_messages")).intValue();
- }
- if (commandLine.hasOption("token_exp_minutes")) {
- res.tokenExpMins =
- ((Number) commandLine.getParsedOptionValue("token_exp_minutes")).intValue();
- }
- if (commandLine.hasOption("mqtt_bridge_hostname")) {
- res.mqttBridgeHostname = commandLine.getOptionValue("mqtt_bridge_hostname");
- }
- if (commandLine.hasOption("mqtt_bridge_port")) {
- res.mqttBridgePort =
- ((Number) commandLine.getParsedOptionValue("mqtt_bridge_port")).shortValue();
- }
- if (commandLine.hasOption("message_type")) {
- res.messageType = commandLine.getOptionValue("message_type");
- }
- return res;
- } catch (ParseException e) {
- System.err.println(e.getMessage());
- return null;
- }
- }
-
- public String toString() {
- return options.toString();
- }
-}
diff --git a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/RetryHttpInitializerWrapper.java b/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/RetryHttpInitializerWrapper.java
deleted file mode 100644
index dcbb6df53e5..00000000000
--- a/iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/RetryHttpInitializerWrapper.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.examples;
-
-import com.google.api.client.auth.oauth2.Credential;
-import com.google.api.client.http.HttpBackOffIOExceptionHandler;
-import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
-import com.google.api.client.http.HttpRequest;
-import com.google.api.client.http.HttpRequestInitializer;
-import com.google.api.client.http.HttpResponse;
-import com.google.api.client.http.HttpUnsuccessfulResponseHandler;
-import com.google.api.client.util.ExponentialBackOff;
-import com.google.api.client.util.Sleeper;
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.util.logging.Logger;
-
-/**
- * RetryHttpInitializerWrapper will automatically retry upon RPC failures, preserving the
- * auto-refresh behavior of the Google Credentials.
- */
-public class RetryHttpInitializerWrapper implements HttpRequestInitializer {
-
- /** A private logger. */
- private static final Logger LOG = Logger.getLogger(RetryHttpInitializerWrapper.class.getName());
-
- /** One minutes in milliseconds. */
- private static final int ONE_MINUTE_MILLIS = 60 * 1000;
-
- /**
- * Intercepts the request for filling in the "Authorization" header field, as well as recovering
- * from certain unsuccessful error codes wherein the Credential must refresh its token for a
- * retry.
- */
- private final Credential wrappedCredential;
-
- /** A sleeper; you can replace it with a mock in your test. */
- private final Sleeper sleeper;
-
- /**
- * A constructor.
- *
- * @param wrappedCredential Credential which will be wrapped and used for providing auth header.
- */
- public RetryHttpInitializerWrapper(final Credential wrappedCredential) {
- this(wrappedCredential, Sleeper.DEFAULT);
- }
-
- /**
- * A protected constructor only for testing.
- *
- * @param wrappedCredential Credential which will be wrapped and used for providing auth header.
- * @param sleeper Sleeper for easy testing.
- */
- RetryHttpInitializerWrapper(final Credential wrappedCredential, final Sleeper sleeper) {
- this.wrappedCredential = Preconditions.checkNotNull(wrappedCredential);
- this.sleeper = sleeper;
- }
-
- /** Initializes the given request. */
- @Override
- public final void initialize(final HttpRequest request) {
- request.setReadTimeout(2 * ONE_MINUTE_MILLIS); // 2 minutes read timeout
- final HttpUnsuccessfulResponseHandler backoffHandler =
- new HttpBackOffUnsuccessfulResponseHandler(new ExponentialBackOff()).setSleeper(sleeper);
- request.setInterceptor(wrappedCredential);
- request.setUnsuccessfulResponseHandler(
- new HttpUnsuccessfulResponseHandler() {
- @Override
- public boolean handleResponse(
- final HttpRequest request, final HttpResponse response, final boolean supportsRetry)
- throws IOException {
- if (wrappedCredential.handleResponse(request, response, supportsRetry)) {
- // If credential decides it can handle it, the return code or message indicated
- // something specific to authentication, and no backoff is desired.
- return true;
- } else if (backoffHandler.handleResponse(request, response, supportsRetry)) {
- // Otherwise, we defer to the judgment of our internal backoff handler.
- LOG.info(request.getUrl().toString().replaceAll("[\r\n]", ""));
- return true;
- } else {
- return false;
- }
- }
- });
- request.setIOExceptionHandler(
- new HttpBackOffIOExceptionHandler(new ExponentialBackOff()).setSleeper(sleeper));
- }
-
- public String toString() {
- return "";
- }
-}
diff --git a/iot/api-client/manager/src/test/java/com/example/cloud/iot/examples/ManagerIT.java b/iot/api-client/manager/src/test/java/com/example/cloud/iot/examples/ManagerIT.java
deleted file mode 100644
index d8e48dc932e..00000000000
--- a/iot/api-client/manager/src/test/java/com/example/cloud/iot/examples/ManagerIT.java
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.cloud.iot.examples;
-
-import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
-import com.google.api.client.http.HttpRequestInitializer;
-import com.google.api.client.json.JsonFactory;
-import com.google.api.client.json.gson.GsonFactory;
-import com.google.api.services.cloudiot.v1.CloudIot;
-import com.google.api.services.cloudiot.v1.CloudIotScopes;
-import com.google.api.services.cloudiot.v1.model.DeviceRegistry;
-import com.google.auth.http.HttpCredentialsAdapter;
-import com.google.auth.oauth2.GoogleCredentials;
-import com.google.cloud.pubsub.v1.TopicAdminClient;
-import com.google.pubsub.v1.Topic;
-import com.google.pubsub.v1.TopicName;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.UUID;
-import org.eclipse.paho.client.mqttv3.MqttClient;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for iot "Management" sample. */
-@RunWith(JUnit4.class)
-@SuppressWarnings("checkstyle:abbreviationaswordinname")
-public class ManagerIT {
- private static final String CLOUD_REGION = "us-central1";
- private static final String ES_PATH = "resources/ec_public.pem";
- private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT");
- private static final String REGISTRY_ID =
- "java-reg-"
- + UUID.randomUUID().toString().substring(0, 10) + "-"
- + System.currentTimeMillis();
- private static final String RSA_PATH = "resources/rsa_cert.pem";
- private static final String PKCS_PATH = "resources/rsa_private_pkcs8";
- private static final String TOPIC_ID =
- "java-pst-"
- + UUID.randomUUID().toString().substring(0, 10) + "-" + System.currentTimeMillis();
- private static final String MEMBER = "group:dpebot@google.com";
- private static final String ROLE = "roles/viewer";
- private static Topic topic;
- private static boolean hasCleared = false;
- private ByteArrayOutputStream bout;
- private PrintStream out;
- private DeviceRegistryExample app;
-
- @Before
- public void setUp() throws Exception {
- if (!hasCleared) {
- clearTestRegistries(); // Remove old / unused registries
- hasCleared = true;
- }
-
- bout = new ByteArrayOutputStream();
- System.setOut(new PrintStream(bout, true, StandardCharsets.UTF_8.name()));
- }
-
- @After
- public void tearDown() throws Exception {
- System.setOut(null);
- }
-
- public void clearTestRegistries() throws Exception {
- GoogleCredentials credential =
- GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
- JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
- HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
- final CloudIot service =
- new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
- .setApplicationName("TEST")
- .build();
-
- final String projectPath = "projects/" + PROJECT_ID + "/locations/" + CLOUD_REGION;
-
- List registries =
- service
- .projects()
- .locations()
- .registries()
- .list(projectPath)
- .execute()
- .getDeviceRegistries();
-
- if (registries != null) {
- for (DeviceRegistry r : registries) {
- String registryId = r.getId();
- if (registryId.startsWith("java-reg-")) {
- long currMilliSecs = System.currentTimeMillis();
- long regMilliSecs =
- Long.parseLong(registryId.substring("java-reg-".length() + 11, registryId.length()));
- long diffMilliSecs = currMilliSecs - regMilliSecs;
- // remove registries which are older than one week.
- if (diffMilliSecs > (1000 * 60 * 60 * 24 * 7)) {
- System.out.println("Remove Id: " + r.getId());
- DeviceRegistryExample.clearRegistry(CLOUD_REGION, PROJECT_ID, registryId);
- }
- }
- // Also remove the current test registry
- try {
- DeviceRegistryExample.clearRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- } catch (com.google.api.client.googleapis.json.GoogleJsonResponseException gjre) {
- if (gjre.getStatusCode() == 404) {
- // Expected, the registry resource is available for creation.
- } else {
- throw gjre;
- }
- }
- }
- } else {
- System.out.println("Project has no registries.");
- }
- }
-
- @Ignore
- @Test
- public void testPatchRsa() throws Exception {
- final String deviceName = "patchme-device-rsa";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithNoAuth(
- deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.patchRsa256ForAuth(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Created device: {"));
- } finally {
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testPatchEs() throws Exception {
- final String deviceName = "patchme-device-es";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithNoAuth(
- deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.patchEs256ForAuth(
- deviceName, ES_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Created device: {"));
- } finally {
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testCreateDeleteUnauthDevice() throws Exception {
- final String deviceName = "noauth-device";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithNoAuth(deviceName, PROJECT_ID, CLOUD_REGION,
- REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Created device: {"));
- } finally {
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testCreateDeleteEsDevice() throws Exception {
- final String deviceName = "es-device";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithEs256(
- deviceName, ES_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.getDeviceStates(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Created device: {"));
- } finally {
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testCreateDeleteRsaDevice() throws Exception {
- final String deviceName = "rsa-device";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.getDeviceStates(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Created device: {"));
- } finally {
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testCreateGetDevice() throws Exception {
- final String deviceName = "rsa-device";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.getDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Created device: {"));
- Assert.assertTrue(got.contains("Retrieving device"));
- } finally {
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testCreateConfigureDevice() throws Exception {
- final String deviceName = "rsa-device-config";
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.setDeviceConfiguration(
- deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID, "some-test-data", 0L);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Updated: 2"));
- } finally {
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testCreateListDevices() throws Exception {
- final String deviceName = "rsa-device";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.listDevices(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Created device: {"));
- Assert.assertTrue(got.contains("Found"));
- } finally {
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testCreateGetRegistry() throws Exception {
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.getRegistry(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertFalse(got.contains("eventNotificationConfigs"));
- } finally {
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testGetIam() throws Exception {
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.getIamPermissions(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("ETAG"));
- } finally {
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testSetIam() throws Exception {
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.setIamPermissions(PROJECT_ID, CLOUD_REGION, REGISTRY_ID, MEMBER, ROLE);
- DeviceRegistryExample.getIamPermissions(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("ETAG"));
- } finally {
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- // HTTP device tests
-
- @Ignore
- @Test
- public void testHttpDeviceEvent() throws Exception {
- final String deviceName = "rsa-device-http-event";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.listDevices(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- // Device bootstrapped, time to connect and run.
- String[] testArgs = {
- "-project_id=" + PROJECT_ID,
- "-registry_id=" + REGISTRY_ID,
- "-device_id=" + deviceName,
- "-private_key_file=" + PKCS_PATH,
- "-num_messages=1",
- "-message_type=event",
- "-algorithm=RS256"
- };
- com.example.cloud.iot.examples.HttpExample.main(testArgs);
- // End device test.
-
- // Assertions
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("200"));
- Assert.assertTrue(got.contains("OK"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testHttpDeviceState() throws Exception {
- final String deviceName = "rsa-device-http-state";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.listDevices(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- // Device bootstrapped, time to connect and run.
- String[] testArgs = {
- "-project_id=" + PROJECT_ID,
- "-registry_id=" + REGISTRY_ID,
- "-device_id=" + deviceName,
- "-private_key_file=" + PKCS_PATH,
- "-num_messages=1",
- "-message_type=state",
- "-algorithm=RS256"
- };
- com.example.cloud.iot.examples.HttpExample.main(testArgs);
- // End device test.
-
- // Assertions
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("200"));
- Assert.assertTrue(got.contains("OK"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testHttpDeviceConfig() throws Exception {
- final String deviceName = "rsa-device-http-state";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.listDevices(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- // Device bootstrapped, time to connect and run.
- String[] testArgs = {
- "-project_id=" + PROJECT_ID,
- "-registry_id=" + REGISTRY_ID,
- "-device_id=" + deviceName,
- "-private_key_file=" + PKCS_PATH,
- "-num_messages=1",
- "-message_type=event",
- "-algorithm=RS256"
- };
- com.example.cloud.iot.examples.HttpExample.main(testArgs);
- // End device test.
-
- // Assertions
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("200"));
- Assert.assertTrue(got.contains("OK"));
- Assert.assertTrue(got.contains("\"binaryData\": \"\""));
-
- } finally {
- // Clean up
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- // MQTT device tests
- @Ignore
- @Test
- public void testMqttDeviceConfig() throws Exception {
- final String deviceName = "rsa-device-mqtt-config";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.listDevices(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- // Device bootstrapped, time to connect and run.
- String[] testArgs = {
- "-project_id=" + PROJECT_ID,
- "-registry_id=" + REGISTRY_ID,
- "-device_id=" + deviceName,
- "-private_key_file=" + PKCS_PATH,
- "-message_type=events",
- "-num_messages=1",
- "-algorithm=RS256"
- };
- com.example.cloud.iot.examples.MqttExample.main(testArgs);
- // End device test.
-
- // Assertions
- String got = bout.toString(StandardCharsets.UTF_8.name());
- System.out.println(got);
- Assert.assertTrue(got.contains("Payload :"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testMqttDeviceCommand() throws Exception {
- final String deviceName = "rsa-device-mqtt-commands";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- // Device bootstrapped, time to connect and run.
- String[] testArgs = {
- "-project_id=" + PROJECT_ID,
- "-registry_id=" + REGISTRY_ID,
- "-cloud_region=" + CLOUD_REGION,
- "-device_id=" + deviceName,
- "-private_key_file=" + PKCS_PATH,
- "-wait_time=" + 10,
- "-algorithm=RS256"
- };
-
- Thread deviceThread =
- new Thread() {
- public void run() {
- try {
- com.example.cloud.iot.examples.MqttExample.main(testArgs);
- } catch (Exception e) {
- // TODO: Fail
- System.out.println("Failure on Exception");
- }
- }
- };
- deviceThread.start();
-
- Thread.sleep(500); // Give the device a chance to connect
- com.example.cloud.iot.examples.DeviceRegistryExample.sendCommand(
- deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID, "me want cookie!");
-
- deviceThread.join();
- // End device test.
-
- // Assertions
- String got = bout.toString(StandardCharsets.UTF_8.name());
- System.out.println(got);
- Assert.assertTrue(got.contains("Finished loop successfully."));
- Assert.assertTrue(got.contains("me want cookie"));
- Assert.assertFalse(got.contains("Failure on Exception"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testMqttDeviceEvents() throws Exception {
- final String deviceName = "rsa-device-mqtt-events";
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.listDevices(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- // Device bootstrapped, time to connect and run.
- String[] testArgs = {
- "-project_id=" + PROJECT_ID,
- "-registry_id=" + REGISTRY_ID,
- "-device_id=" + deviceName,
- "-private_key_file=" + PKCS_PATH,
- "-message_type=events",
- "-num_messages=1",
- "-algorithm=RS256"
- };
- com.example.cloud.iot.examples.MqttExample.main(testArgs);
- // End device test.
-
- // Assertions
- String got = bout.toString(StandardCharsets.UTF_8.name());
- //
- // Finished loop successfully. Goodbye!
-
- Assert.assertTrue(got.contains("Publishing events message 1"));
- Assert.assertTrue(got.contains("Finished loop successfully. Goodbye!"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testMqttDeviceState() throws Exception {
- final String deviceName = "rsa-device-mqtt-state";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createDeviceWithRs256(
- deviceName, RSA_PATH, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.listDevices(PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
-
- // Device bootstrapped, time to connect and run.
- String[] testArgs = {
- "-project_id=" + PROJECT_ID,
- "-registry_id=" + REGISTRY_ID,
- "-device_id=" + deviceName,
- "-private_key_file=" + PKCS_PATH,
- "-message_type=state",
- "-num_messages=10",
- "-algorithm=RS256"
- };
- com.example.cloud.iot.examples.MqttExample.main(testArgs);
- // End device test.
-
- // Assertions
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("Publishing state message 1"));
- Assert.assertTrue(got.contains("Finished loop successfully. Goodbye!"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testGatewayListenForDevice() throws Exception {
- final String gatewayName = "rsa-listen-gateway";
- final String deviceName = "rsa-listen-device";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createGateway(
- PROJECT_ID, CLOUD_REGION, REGISTRY_ID, gatewayName, RSA_PATH, "RS256");
- DeviceRegistryExample.createDevice(PROJECT_ID, CLOUD_REGION, REGISTRY_ID, deviceName);
- DeviceRegistryExample.bindDeviceToGateway(
- PROJECT_ID, CLOUD_REGION, REGISTRY_ID, deviceName, gatewayName);
-
- Thread deviceThread =
- new Thread() {
- public void run() {
- try {
- MqttExample.listenForConfigMessages(
- "mqtt.googleapis.com",
- (short) 443,
- PROJECT_ID,
- CLOUD_REGION,
- REGISTRY_ID,
- gatewayName,
- PKCS_PATH,
- "RS256",
- deviceName);
- } catch (Exception e) {
- // TODO: Fail
- System.out.println("Failure on Exception");
- }
- }
- };
- deviceThread.start();
- Thread.sleep(3000); // Give the device a chance to connect / receive configurations
- deviceThread.join();
-
- // Assertions
- String got = bout.toString(StandardCharsets.UTF_8.name());
- System.out.println(got);
- Assert.assertTrue(got.contains("Payload"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.unbindDeviceFromGateway(
- PROJECT_ID, CLOUD_REGION, REGISTRY_ID, deviceName, gatewayName);
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteDevice(gatewayName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testErrorTopic() throws Exception {
- final String gatewayName = "rsa-listen-gateway-test";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createGateway(
- PROJECT_ID, CLOUD_REGION, REGISTRY_ID, gatewayName, RSA_PATH, "RS256");
- MqttClient client =
- MqttExample.startMqtt(
- "mqtt.googleapis.com",
- (short) 443,
- PROJECT_ID,
- CLOUD_REGION,
- REGISTRY_ID,
- gatewayName,
- PKCS_PATH,
- "RS256");
-
- Thread deviceThread =
- new Thread() {
- public void run() {
- try {
- MqttExample.attachDeviceToGateway(client, "garbage-device");
- MqttExample.attachCallback(client, "garbage-device");
- } catch (Exception e) {
- // TODO: Fail
- StringBuilder builder = new StringBuilder();
- builder.append("Failure on exception: ").append(e);
- System.out.println(builder);
- }
- }
- };
-
- deviceThread.start();
- Thread.sleep(4000);
-
- String got = bout.toString(StandardCharsets.UTF_8.name());
- Assert.assertTrue(got.contains("error_type"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.deleteDevice(gatewayName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-
- @Ignore
- @Test
- public void testSendDataForBoundDevice() throws Exception {
- final String gatewayName = "rsa-send-gateway";
- final String deviceName = "rsa-send-device";
-
- try {
- topic = DeviceRegistryExample.createIotTopic(PROJECT_ID, TOPIC_ID);
- DeviceRegistryExample.createRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID, TOPIC_ID);
- DeviceRegistryExample.createGateway(
- PROJECT_ID, CLOUD_REGION, REGISTRY_ID, gatewayName, RSA_PATH, "RS256");
- DeviceRegistryExample.createDevice(PROJECT_ID, CLOUD_REGION, REGISTRY_ID, deviceName);
- DeviceRegistryExample.bindDeviceToGateway(
- PROJECT_ID, CLOUD_REGION, REGISTRY_ID, deviceName, gatewayName);
-
- Thread deviceThread =
- new Thread() {
- public void run() {
- try {
- MqttExample.sendDataFromBoundDevice(
- "mqtt.googleapis.com",
- (short) 443,
- PROJECT_ID,
- CLOUD_REGION,
- REGISTRY_ID,
- gatewayName,
- PKCS_PATH,
- "RS256",
- deviceName,
- "state",
- "Cookies are delish");
- } catch (Exception e) {
- // TODO: Fail
- System.out.println("Failure on Exception");
- }
- }
- };
- deviceThread.start();
- Thread.sleep(3000); // Give the device a chance to connect / receive configurations
- deviceThread.join();
-
- // Assertions
- String got = bout.toString("UTF-8");
- System.out.println(got);
- Assert.assertTrue(got.contains("Data sent"));
-
- } finally {
- // Clean up
- DeviceRegistryExample.unbindDeviceFromGateway(
- PROJECT_ID, CLOUD_REGION, REGISTRY_ID, deviceName, gatewayName);
- DeviceRegistryExample.deleteDevice(deviceName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteDevice(gatewayName, PROJECT_ID, CLOUD_REGION, REGISTRY_ID);
- DeviceRegistryExample.deleteRegistry(CLOUD_REGION, PROJECT_ID, REGISTRY_ID);
- }
-
- try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
- topicAdminClient.deleteTopic(TopicName.of(PROJECT_ID, TOPIC_ID));
- }
- }
-}