From d9cc735293571c551e5bfabec2b588130e2a5693 Mon Sep 17 00:00:00 2001 From: meredithslota Date: Thu, 10 Aug 2023 09:12:10 -0700 Subject: [PATCH 1/3] chore(iot): update README.md for IoT deprecation --- iot/README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/iot/README.md b/iot/README.md index 3668c1477db..409b19aaf0b 100644 --- a/iot/README.md +++ b/iot/README.md @@ -1,7 +1 @@ -# Deprecation Notice - -*

Google Cloud IoT Core will be retired as of August 16, 2023.

- -*

Hence, the samples in this directory are archived and are no more maintained.

- -*

If you are customer with an assigned Google Cloud account team, contact your account team for more information.

\ No newline at end of file +Cloud IoT Core was retired on August 16, 2023. After August 15, 2023, the documentation for IoT Core is no longer be available. See https://cloud.google.com/iot-core for a host of partner-led solutions, built on Google Cloud, that meet the needs of IoT customers. From 36f3ae26b1ebc71871a16a25b009487e3da49b24 Mon Sep 17 00:00:00 2001 From: meredithslota Date: Thu, 10 Aug 2023 09:13:11 -0700 Subject: [PATCH 2/3] chore(iot): remove IoT samples after deprecation --- iot/api-client/README.md | 24 - iot/api-client/codelab/README.md | 24 - iot/api-client/codelab/manager/README.md | 82 - iot/api-client/codelab/manager/pom.xml | 145 -- .../cloud/iot/examples/MqttCommandsDemo.java | 497 ------ .../iot/examples/MqttExampleOptions.java | 199 --- .../examples/RetryHttpInitializerWrapper.java | 103 -- .../example/cloud/iot/examples/ManagerIT.java | 90 -- iot/api-client/codelab/send_cmds_async.sh | 36 - iot/api-client/end-to-end-example/README.md | 126 -- iot/api-client/end-to-end-example/pom.xml | 129 -- .../cloud/iot/endtoend/CleanUpHelper.java | 110 -- .../CloudiotPubsubExampleMqttDevice.java | 272 ---- ...loudiotPubsubExampleMqttDeviceOptions.java | 163 -- .../endtoend/CloudiotPubsubExampleServer.java | 333 ---- .../CloudiotPubsubExampleServerOptions.java | 79 - .../endtoend/RetryHttpInitializerWrapper.java | 103 -- .../CloudiotPubsubExampleServerTest.java | 148 -- iot/api-client/generate_keys.sh | 24 - iot/api-client/manager/README.md | 406 ----- iot/api-client/manager/pom.xml | 301 ---- iot/api-client/manager/resources/README.md | 5 - .../manager/resources/ec_public.pem | 4 - iot/api-client/manager/resources/rsa_cert.pem | 17 - .../manager/resources/rsa_private.pem | 28 - .../manager/resources/rsa_private_pkcs8 | Bin 1218 -> 0 bytes .../iot/examples/DeviceRegistryExample.java | 1363 ----------------- .../DeviceRegistryExampleOptions.java | 266 ---- .../cloud/iot/examples/HttpExample.java | 314 ---- .../iot/examples/HttpExampleOptions.java | 170 -- .../cloud/iot/examples/MqttExample.java | 557 ------- .../iot/examples/MqttExampleOptions.java | 220 --- .../examples/RetryHttpInitializerWrapper.java | 107 -- .../example/cloud/iot/examples/ManagerIT.java | 871 ----------- 34 files changed, 7316 deletions(-) delete mode 100644 iot/api-client/README.md delete mode 100644 iot/api-client/codelab/README.md delete mode 100644 iot/api-client/codelab/manager/README.md delete mode 100644 iot/api-client/codelab/manager/pom.xml delete mode 100644 iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/MqttCommandsDemo.java delete mode 100644 iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/MqttExampleOptions.java delete mode 100644 iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/RetryHttpInitializerWrapper.java delete mode 100644 iot/api-client/codelab/manager/src/test/java/com/example/cloud/iot/examples/ManagerIT.java delete mode 100755 iot/api-client/codelab/send_cmds_async.sh delete mode 100644 iot/api-client/end-to-end-example/README.md delete mode 100644 iot/api-client/end-to-end-example/pom.xml delete mode 100644 iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CleanUpHelper.java delete mode 100644 iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleMqttDevice.java delete mode 100644 iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleMqttDeviceOptions.java delete mode 100644 iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServer.java delete mode 100644 iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServerOptions.java delete mode 100644 iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/RetryHttpInitializerWrapper.java delete mode 100644 iot/api-client/end-to-end-example/src/test/java/com/example/cloud/iot/endtoend/CloudiotPubsubExampleServerTest.java delete mode 100755 iot/api-client/generate_keys.sh delete mode 100644 iot/api-client/manager/README.md delete mode 100644 iot/api-client/manager/pom.xml delete mode 100644 iot/api-client/manager/resources/README.md delete mode 100644 iot/api-client/manager/resources/ec_public.pem delete mode 100644 iot/api-client/manager/resources/rsa_cert.pem delete mode 100644 iot/api-client/manager/resources/rsa_private.pem delete mode 100644 iot/api-client/manager/resources/rsa_private_pkcs8 delete mode 100644 iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/DeviceRegistryExample.java delete mode 100644 iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/DeviceRegistryExampleOptions.java delete mode 100644 iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExample.java delete mode 100644 iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/HttpExampleOptions.java delete mode 100644 iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/MqttExample.java delete mode 100644 iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/MqttExampleOptions.java delete mode 100644 iot/api-client/manager/src/main/java/com/example/cloud/iot/examples/RetryHttpInitializerWrapper.java delete mode 100644 iot/api-client/manager/src/test/java/com/example/cloud/iot/examples/ManagerIT.java diff --git a/iot/api-client/README.md b/iot/api-client/README.md deleted file mode 100644 index 4414f649b5b..00000000000 --- a/iot/api-client/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Cloud IoT Core Java Samples - - -Open in Cloud Shell - -This folder contains Java samples that demonstrate an overview of the -Google Cloud IoT Core platform. - -## Quickstart - -1. From the [Google Cloud IoT Core section](https://console.cloud.google.com/iot/) - of the Google Cloud console, create a device registry. -2. Use the [`generate_keys.sh`](generate_keys.sh) script to generate your signing keys: - - ./generate_keys.sh - -3. Add a device using the file `rsa_cert.pem`, specifying RS256_X509 and using the - text copy of the public key starting with the ----START---- block of the certificate. - - cat rsa_cert.pem - -4. Connect a device using the HTTP or MQTT device samples in the [manager](./manager) folder. - -5. Programmattically control device configuration and using the device manager sample in the [manager](./manager) folder. diff --git a/iot/api-client/codelab/README.md b/iot/api-client/codelab/README.md deleted file mode 100644 index 8d1e7f4e912..00000000000 --- a/iot/api-client/codelab/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Java Codelabs - - -Open in Cloud Shell - -This folder contains Java samples that demonstrate an overview of the -Google Cloud IoT Core platform. - -## Quickstart - -1. From the [Google Cloud IoT Core section](https://console.cloud.google.com/iot/) - of the Google Cloud console, create a device registry. -2. Use the [`generate_keys.sh`](generate_keys.sh) script to generate your signing keys: - - ./generate_keys.sh - -3. Add a device using the file `rsa_cert.pem`, specifying RS256_X509 and using the - text copy of the public key starting with the ----START---- block of the certificate. - - cat rsa_cert.pem - -4. Connect a device using the HTTP or MQTT device samples in the [manager](./manager) folder. - -5. Programmattically control device configuration and using the device manager sample in the [manager](./manager) folder. diff --git a/iot/api-client/codelab/manager/README.md b/iot/api-client/codelab/manager/README.md deleted file mode 100644 index 0adda07f852..00000000000 --- a/iot/api-client/codelab/manager/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# Cloud IoT Core Commands Java Codelab - - -Open in Cloud Shell - -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: MqttCommandsDemo [--cloud_region ] --project_id - --registry_id --device_id - - Cloud IoT Core Commandline Example (MQTT Device / Commands codelab): - - --cloud_region GCP cloud region (default us-central1). - --private_key_file Path to RS256 private key file. - --algorithm Encryption algorithm to use to generate the JWT. - --project_id GCP cloud project name. - --registry_id Name for your Device Registry. - --device_id ID for your Device. - -https://cloud.google.com/iot-core - -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: - -# 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 command summarizes the sample usage: - - mvn exec:java \ - -Dexec.mainClass="com.example.cloud.iot.examples.MqttCommandsDemo" \ - -Dexec.args="-project_id=my-iot-project \ - -registry_id=my-registry \ - -cloud_region=us-central1 \ - -device_id=my-device \ - -private_key_file=rsa_private_pkcs8 \ - -algorithm=RS256" - -Run mqtt example: - - mvn exec:java \ - -Dexec.mainClass="com.example.cloud.iot.examples.MqttCommandsDemo" \ - -Dexec.args="-project_id=blue-jet-123 \ - -registry_id=my-registry \ - -cloud_region=asia-east1 \ - -device_id=my-device \ - -private_key_file=../rsa_private_pkcs8 \ - -algorithm=RS256" - diff --git a/iot/api-client/codelab/manager/pom.xml b/iot/api-client/codelab/manager/pom.xml deleted file mode 100644 index c040c6f4513..00000000000 --- a/iot/api-client/codelab/manager/pom.xml +++ /dev/null @@ -1,145 +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.21.0 - - - - - - - com.googlecode.lanterna - lanterna - 3.1.1 - - - - 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.guava - guava - - - commons-cli - commons-cli - 1.5.0 - - - - - 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 - - - - - - diff --git a/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/MqttCommandsDemo.java b/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/MqttCommandsDemo.java deleted file mode 100644 index 4f560d3fc58..00000000000 --- a/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/MqttCommandsDemo.java +++ /dev/null @@ -1,497 +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.examples; - -import com.googlecode.lanterna.Symbols; -import com.googlecode.lanterna.TerminalPosition; -import com.googlecode.lanterna.TerminalSize; -import com.googlecode.lanterna.TextCharacter; -import com.googlecode.lanterna.TextColor; -import com.googlecode.lanterna.graphics.TextGraphics; -import com.googlecode.lanterna.input.KeyStroke; -import com.googlecode.lanterna.input.KeyType; -import com.googlecode.lanterna.screen.Screen; -import com.googlecode.lanterna.screen.TerminalScreen; -import com.googlecode.lanterna.terminal.DefaultTerminalFactory; -import com.googlecode.lanterna.terminal.Terminal; -import io.jsonwebtoken.JwtBuilder; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import java.io.IOException; -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; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -public class MqttCommandsDemo { - - static MqttCallback mCallback; - static Thread mGUIthread; - static final String APP_NAME = "MqttCommandsDemo"; - - /** 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(); - } - - /** 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(); - } - - /** Attaches the callback used when configuration changes occur. */ - public static void attachCallback(MqttClient client, String deviceId, Screen mainScreen) - throws MqttException { - mCallback = - new MqttCallback() { - private TextColor mainBgColor = new TextColor.ANSI.RGB(255, 255, 255); - private TextColor myColor; - - @Override - public void connectionLost(Throwable cause) { - // Do nothing... - } - - @Override - public void messageArrived(String topic, MqttMessage message) throws Exception { - String payload = new String(message.getPayload()); - System.out.println("Payload : " + payload); - // 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; - } - if (isJsonValid(payload)) { - JSONObject data = null; - data = new JSONObject(payload); - - // [begin command respond code] - - // [end command respond code] - } - } - - @Override - public void deliveryComplete(IMqttDeliveryToken token) { - // Do nothing; - } - - /** - * Get the color from a string name - * - * @param col name of the color - * @return White if no color is given, otherwise the Color object - */ - TextColor getColor(String col) { - switch (col.toLowerCase()) { - case "black": - myColor = TextColor.ANSI.BLACK; - break; - case "blue": - myColor = TextColor.ANSI.BLUE; - break; - case "cyan": - myColor = TextColor.ANSI.CYAN; - break; - case "green": - myColor = TextColor.ANSI.GREEN; - break; - case "yellow": - myColor = TextColor.ANSI.YELLOW; - break; - case "magneta": - myColor = TextColor.ANSI.MAGENTA; - break; - case "red": - myColor = TextColor.ANSI.RED; - break; - case "white": - myColor = TextColor.ANSI.WHITE; - break; - default: - myColor = TextColor.ANSI.BLACK; - break; - } - return myColor; - } - - public boolean isValidColor(JSONObject data, TextColor mainBgColor) throws JSONException { - return data.get("color") instanceof String - && !mainBgColor.toColor().equals(getColor((String) data.get("color"))); - } - }; - - // [begin code section] - - // [end code section] - - String configTopic = String.format("/devices/%s/config", deviceId); - System.out.println(String.format("Listening on %s", configTopic)); - - client.subscribe(configTopic, 1); - client.setCallback(mCallback); - } - - public static void mqttDeviceDemo( - String projectId, - String cloudRegion, - String registryId, - String deviceId, - String privateKeyFile, - String algorithm, - String mqttBridgeHostname, - short mqttBridgePort, - String messageType, - int waitTime) - 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", 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, 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"); - - if (algorithm.equals("RS256")) { - connectOptions.setPassword(createJwtRsa(projectId, privateKeyFile).toCharArray()); - } else if (algorithm.equals("ES256")) { - connectOptions.setPassword(createJwtEs(projectId, privateKeyFile).toCharArray()); - } else { - throw new IllegalArgumentException( - "Invalid algorithm " + 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 (!client.isConnected() && totalRetryTimeMs < maxConnectRetryTimeElapsedMillis) { - 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; - } - } - } - - // Publish to the events or state topic based on the flag. - String subTopic = messageType.equals("event") ? "events" : 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", deviceId, subTopic); - - DefaultTerminalFactory defaultTerminalFactory = new DefaultTerminalFactory(); - Screen screen = null; - Terminal terminal = defaultTerminalFactory.createTerminal(); - screen = new TerminalScreen(terminal); - - attachCallback(client, deviceId, screen); - - // Wait for commands to arrive for about two minutes. - for (int i = 1; i <= 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(); - System.exit(0); - // [END iot_mqtt_publish] - } - - public static void startGui(Screen screen, TextColor theColor) throws IOException { - - try { - /* - You can use the DefaultTerminalFactory to create a Screen, this will generally give you the - TerminalScreen implementation that is probably what you want to use. Please see - VirtualScreen for more details on a separate implementation that allows you to create a - terminal surface that is bigger than the physical size of the terminal emulator the software - is running in. Just to demonstrate that a Screen sits on top of a Terminal, - we are going to create one manually instead of using DefaultTerminalFactory. - */ - - /* - Screens will only work in private mode and while you can call methods to mutate its state, - before you can make any of these changes visible, you'll need to call startScreen() - which will prepare and setup the terminal. - */ - screen.startScreen(); - System.out.println("Starting the terminal..."); - /* - Let's turn off the cursor for this tutorial - */ - screen.setCursorPosition(null); - - /* - Now let's draw some random content in the screen buffer - */ - - TerminalSize terminalSize = screen.getTerminalSize(); - for (int column = 0; column < terminalSize.getColumns(); column++) { - for (int row = 0; row < terminalSize.getRows(); row++) { - screen.setCharacter( - column, - row, - new TextCharacter( - ' ', - TextColor.ANSI.DEFAULT, - // This will pick a random background color - theColor)); - } - } - - /* - So at this point, we've only modified the back buffer in the screen, nothing is visible yet. - In order to move the content from the back buffer to the front buffer and refresh the - screen, we need to call refresh() - */ - screen.refresh(); - System.out.println("Starting the terminal..."); - /* - Ok, now we loop and keep modifying the screen until the user exits by pressing escape on - the keyboard or the input stream is closed. When using the Swing/AWT bundled emulator, - if the user closes the window this will result in an EOF KeyStroke. - */ - while (true) { - KeyStroke keyStroke = screen.pollInput(); - if (keyStroke != null - && (keyStroke.getKeyType() == KeyType.Escape - || keyStroke.getKeyType() == KeyType.EOF)) { - break; - } - - /* - Screens will automatically listen and record size changes, but you have to let the Screen - know when is a good time to update its internal buffers. Usually you should do this at the - start of your "drawing" loop, if you have one. This ensures that the dimensions of the - buffers stays constant and doesn't change while you are drawing content. The method - doReizeIfNecessary() will check if the terminal has been resized since last time it - was called (or since the screen was created if this is the first time calling) and - update the buffer dimensions accordingly. It returns null if the terminal - has not changed size since last time. - */ - TerminalSize newSize = screen.doResizeIfNecessary(); - if (newSize != null) { - terminalSize = newSize; - } - /* - Just like with Terminal, it's probably easier to draw using TextGraphics. - Let's do that to put a little box with information on the size of the terminal window - */ - String sizeLabel = "Terminal Size: " + terminalSize; - TerminalPosition labelBoxTopLeft = new TerminalPosition(1, 1); - TerminalSize labelBoxSize = new TerminalSize(sizeLabel.length() + 2, 3); - TerminalPosition labelBoxTopRightCorner = - labelBoxTopLeft.withRelativeColumn(labelBoxSize.getColumns() - 1); - TextGraphics textGraphics = screen.newTextGraphics(); - // This isn't really needed as we are overwriting everything below anyway, but just for - // demonstrative purpose - textGraphics.fillRectangle(labelBoxTopLeft, labelBoxSize, ' '); - - /* - Draw horizontal lines, first upper then lower - */ - textGraphics.drawLine( - labelBoxTopLeft.withRelativeColumn(1), - labelBoxTopLeft.withRelativeColumn(labelBoxSize.getColumns() - 2), - Symbols.DOUBLE_LINE_HORIZONTAL); - textGraphics.drawLine( - labelBoxTopLeft.withRelativeRow(2).withRelativeColumn(1), - labelBoxTopLeft.withRelativeRow(2).withRelativeColumn(labelBoxSize.getColumns() - 2), - Symbols.DOUBLE_LINE_HORIZONTAL); - - /* - Manually do the edges and (since it's only one) the vertical lines, - first on the left then on the right - */ - textGraphics.setCharacter(labelBoxTopLeft, Symbols.DOUBLE_LINE_TOP_LEFT_CORNER); - textGraphics.setCharacter(labelBoxTopLeft.withRelativeRow(1), Symbols.DOUBLE_LINE_VERTICAL); - textGraphics.setCharacter( - labelBoxTopLeft.withRelativeRow(2), Symbols.DOUBLE_LINE_BOTTOM_LEFT_CORNER); - textGraphics.setCharacter(labelBoxTopRightCorner, Symbols.DOUBLE_LINE_TOP_RIGHT_CORNER); - textGraphics.setCharacter( - labelBoxTopRightCorner.withRelativeRow(1), Symbols.DOUBLE_LINE_VERTICAL); - textGraphics.setCharacter( - labelBoxTopRightCorner.withRelativeRow(2), Symbols.DOUBLE_LINE_BOTTOM_RIGHT_CORNER); - - /* - Finally put the text inside the box - */ - textGraphics.putString(labelBoxTopLeft.withRelative(1, 1), sizeLabel); - - /* - Ok, we are done and can display the change. Let's also be nice and allow the OS - to schedule other threads so we don't clog up the core completely. - */ - screen.refresh(); - Thread.yield(); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (screen != null) { - try { - /* - The close() call here will restore the terminal by exiting from private mode which - was done in the call to startScreen() - */ - screen.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - screen.stopScreen(); - } - - public static boolean isJsonValid(String data) { - try { - new JSONObject(data); - } catch (JSONException ex) { - // edited, to include @Arthur's comment - // e.g. in case JSONArray is valid as well... - try { - new JSONArray(data); - } catch (JSONException ex1) { - return false; - } - } - return true; - } - - public static void main(String[] args) throws Exception { - MqttExampleOptions options = MqttExampleOptions.fromFlags(args); - if (options == null) { - // Could not parse. - System.exit(1); - } - System.out.println("Starting mqtt demo:"); - mqttDeviceDemo( - options.projectId, - options.cloudRegion, - options.registryId, - options.deviceId, - options.privateKeyFile, - options.algorithm, - options.mqttBridgeHostname, - options.mqttBridgePort, - "state", - options.waitTime); - } -} diff --git a/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/MqttExampleOptions.java b/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/MqttExampleOptions.java deleted file mode 100644 index 3b7d646dfbf..00000000000 --- a/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/MqttExampleOptions.java +++ /dev/null @@ -1,199 +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.examples; - -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 { - String projectId; - String registryId; - String command = "mqtt-demo"; - String deviceId; - String gatewayId; - String privateKeyFile; - String algorithm; - String cloudRegion = "us-central1"; - int tokenExpMins = 20; - String mqttBridgeHostname = "mqtt.googleapis.com"; - short mqttBridgePort = 8883; - String messageType = "event"; - int waitTime = 150; - - /** Construct an MqttExampleOptions class from command line flags. */ - public static MqttExampleOptions fromFlags(String[] args) { - Options options = new Options(); - // 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(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("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; - } - } -} diff --git a/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/RetryHttpInitializerWrapper.java b/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/RetryHttpInitializerWrapper.java deleted file mode 100644 index d565dcd41a3..00000000000 --- a/iot/api-client/codelab/manager/src/main/java/com/example/cloud/iot/examples/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.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("Retrying " + request.getUrl().toString()); - return true; - } else { - return false; - } - } - }); - request.setIOExceptionHandler( - new HttpBackOffIOExceptionHandler(new ExponentialBackOff()).setSleeper(sleeper)); - } -} diff --git a/iot/api-client/codelab/manager/src/test/java/com/example/cloud/iot/examples/ManagerIT.java b/iot/api-client/codelab/manager/src/test/java/com/example/cloud/iot/examples/ManagerIT.java deleted file mode 100644 index 652287e403a..00000000000 --- a/iot/api-client/codelab/manager/src/test/java/com/example/cloud/iot/examples/ManagerIT.java +++ /dev/null @@ -1,90 +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.examples; - -import com.googlecode.lanterna.TextColor; -import com.googlecode.lanterna.screen.Screen; -import com.googlecode.lanterna.screen.TerminalScreen; -import com.googlecode.lanterna.terminal.DefaultTerminalFactory; -import com.googlecode.lanterna.terminal.Terminal; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -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 "Management" sample. */ -@RunWith(JUnit4.class) -@SuppressWarnings("checkstyle:abbreviationaswordinname") -public class ManagerIT { - private ByteArrayOutputStream bout; - private PrintStream out; - - @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 testTerminal() throws Exception { - // Set up - Screen screen = null; - DefaultTerminalFactory defaultTerminalFactory = new DefaultTerminalFactory(); - try (Terminal terminal = defaultTerminalFactory.createTerminal()) { - screen = new TerminalScreen(terminal); - - Screen finalScreen = screen; - Thread deviceThread = - new Thread( - () -> { - try { - MqttCommandsDemo.startGui(finalScreen, new TextColor.RGB(255, 255, 255)); - } catch (IOException e) { - e.printStackTrace(); - } - }); - - deviceThread.join(3000); - System.out.println(terminal.getTerminalSize().toString()); - // Assertions - Assert.assertTrue(terminal.getTerminalSize().toString().contains("x")); - Assert.assertTrue(terminal.getTerminalSize().toString().contains("{")); - Assert.assertTrue(terminal.getTerminalSize().toString().contains("}")); - } catch (IOException e) { - // Don't fail when GUI not available: "/dev/tty (No such device or address)" - System.out.println(e.getMessage()); - } - } - - @Test - public void testJsonValid() { - // Assertions - Assert.assertTrue(MqttCommandsDemo.isJsonValid("{test:true}")); - Assert.assertFalse(MqttCommandsDemo.isJsonValid("{test:false")); - } -} diff --git a/iot/api-client/codelab/send_cmds_async.sh b/iot/api-client/codelab/send_cmds_async.sh deleted file mode 100755 index f1cfd2d25b1..00000000000 --- a/iot/api-client/codelab/send_cmds_async.sh +++ /dev/null @@ -1,36 +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. -# - -#!/bin/bash -# Listing the device ids. - -color=$1 -echo "Changing background color 3 MQTT devices into $color" - -for deviceId in 1 2 3 -do - echo "gcloud iot devices commands send --command-data={color:$color} --device=mqtt-device-$deviceId --region=us-central1 --registry=my-registry" > device-send-command-script-$deviceId.sh - chmod u+x device-send-command-script-$deviceId.sh -done -#call 3 scripts async -./device-send-command-script-1.sh & ./device-send-command-script-2.sh & ./device-send-command-script-3.sh & -sleep 5s -#Clean up -for deviceId in 1 2 3 -do - rm ./device-send-command-script-$deviceId.sh -done -exit 0 diff --git a/iot/api-client/end-to-end-example/README.md b/iot/api-client/end-to-end-example/README.md deleted file mode 100644 index 01f797eaa88..00000000000 --- a/iot/api-client/end-to-end-example/README.md +++ /dev/null @@ -1,126 +0,0 @@ -# Google Cloud IoT Core Java Samples - - -Open in Cloud Shell - -This directory contains samples for Google Cloud IoT Core. [Google Cloud IoT Core](https://cloud.google.com/iot/docs/ "Google Cloud IoT Core") allows developers to easily integrate Publish and Subscribe functionality with devices and programmatically manage device authorization. - -## Prerequisites - -### Java - -We recommend using [Java 8 JDK](https://java.com/en/download) for this example. - -### Download Maven - -These samples use the [Apache Maven][maven] build system. Before getting -started, be sure to [download][maven-download] and [install][maven-install] it. -When you use Maven as described here, it will automatically download the needed -client libraries. - -[maven]: https://maven.apache.org -[maven-download]: https://maven.apache.org/download.cgi -[maven-install]: https://maven.apache.org/install.html - -### Create a Project in the Google Cloud Platform Console - -If you haven't already created a project, create one now. Projects enable you to -manage all Google Cloud Platform resources for your app, including deployment, -access control, billing, and services. - -1. Open the [Cloud Platform Console][cloud-console]. -2. In the drop-down menu at the top, select **Create a project**. -3. Give your project a name. -4. Make a note of the project ID, which might be different from the project - name. The project ID is used in commands and in configurations. - -[cloud-console]: https://console.cloud.google.com/ - -## Setup - -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. - -For example, on most *nix systems you can do this as: - - export GOOGLE_CLOUD_PROJECT=your-project-id - export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json" - - -### Authentication - -This sample requires you to have authentication setup. Refer to the [Authentication Getting Started Guide](https://cloud.google.com/docs/authentication/getting-started "Google Cloud IoT Core") for instructions on setting up credentials for applications. - -Run the following command to install the libraries and build the sample with Maven: - - mvn clean compile assembly:single - - -Before you begin, you will need to create the Google Cloud PubSub message queue, create a subscription to it, create a device registry, and add a device to the registry. - -1. Create the PubSub topic as: - - gcloud pubsub topics create java-e2e - -2. Create the subscription: - - gcloud pubsub subscriptions create java-e2e-sub --topic=java-e2e - -3. Create the device registry: - - gcloud iot registries create java-ed2e-registry --event-notification-config=topic=java-e2e --region=us-central1 - -4. Run the `generate_keys.sh` shell script: - - ../generate_keys.sh - -5. Add a device to the registry using the keys you generated: - - gcloud iot devices create device-id --registry=java-ed2e-sub --region=us-central1 --public-key=path=./rsa_cert.pem,type=RS256 - - -## Samples - -### Server - - -Open in Cloud Shell - -To run this sample: - - mvn exec:java \ - -Dexec.mainClass="com.example.cloud.iot.endtoend.CloudiotPubsubExampleServer" \ - -Dexec.args="-project_id= \ - -pubsub_subscription=" - -### Device - - -Open in Cloud Shell - -To run this sample: - - mvn exec:java \ - -Dexec.mainClass="com.example.cloud.iot.endtoend.CloudiotPubsubExampleMqttDevice" \ - -Dexec.args="-project_id= \ - -registry_id= \ - -device_id= \ - -private_key_file= \ - -algorithm=" - -For example, if your project ID is `blue-jet-123`, your device registry id is -`my-registry`, your device id is `my-device` 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:java \ - -Dexec.mainClass="com.example.cloud.iot.endtoend.CloudiotPubsubExampleMqttDevice" \ - -Dexec.args="-project_id=blue-jet-123 \ - -registry_id=my-registry \ - -device_id=my-device \ - -private_key_file=../rsa_private_pkcs8 \ - -algorithm=RS256" diff --git a/iot/api-client/end-to-end-example/pom.xml b/iot/api-client/end-to-end-example/pom.xml deleted file mode 100644 index 0f4422d6f95..00000000000 --- a/iot/api-client/end-to-end-example/pom.xml +++ /dev/null @@ -1,129 +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.21.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.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.http-client - google-http-client-jackson2 - - - - - junit - junit - 4.13.2 - test - - - com.google.truth - truth - 1.1.5 - test - - - - - - - maven-assembly-plugin - - - - com.example.cloudiot.Manage - - - - jar-with-dependencies - - - - - - diff --git a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CleanUpHelper.java b/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CleanUpHelper.java deleted file mode 100644 index 82eeb65a011..00000000000 --- a/iot/api-client/end-to-end-example/src/main/java/com/example/cloud/iot/endtoend/CleanUpHelper.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2020 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 static com.example.cloud.iot.endtoend.CloudiotPubsubExampleServer.APP_NAME; - -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.auth.http.HttpCredentialsAdapter; -import com.google.auth.oauth2.GoogleCredentials; -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.util.List; - -public class CleanUpHelper { - protected static List getRegisteries(String project, String cloudRegion) - throws IOException, GeneralSecurityException { - 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 = String.format("projects/%s/locations/%s", project, cloudRegion); - - List 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 - - -Open in Cloud Shell - -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 7958fe0e264..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.21.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 b2f21e29a690d1c9ca0c29e27bfea5dd101719d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1218 zcmV;z1U>sOf&{(-0RS)!1_>&LNQUrs4#*Aqyhl|0)hbn0LuOU0#KJS-jl2i6;T-p_Lami8F1Cq zF>Sc~Ylw<0U&_DVWM^)RkQ2D^_q@jN7?$V{d)KvAJpk1|L3Al966!ao(=qT^T+j$3*4Jm?-% zJ7ZNF#u4TP73Gc_8a-frU~Mv;mmvA!U#uS8iPsTI9M-AFw;0pr*zid4O>yc2{i z;}ohQ6x0zzK?5*yg779)hsV^rY+p@uHujxS2d?Er2Kw9Xa;tA1Ph}8hIvHkNM}YdD zYf(5}Si%_BKp1RcWS5hRhp08cDRl-VsM<#j7%%c%T5ZmNfkPUr1t2ARpazrlwAcV3JL^B$JF6;;AW&b6D3rET zgp}dsdW~bpskoMX<)V8}?^Ng5 z<%~?TwfsdN9I+mANO2zw+*X;EVl3J>?kwaW35x*mx z%t6!@_6{Y*k+2@2M$dT>^ktCV>`4w1zJUUPfNjk2r-+cv4bbZgL!-4kZ`FGt0ZRMc z?r~(VEMttP4v0r)%7R4p6g|#ZGb*kwLo0F@CBk&~_)`b0os#|ly@ufh8$tzmF2eV^ zogEqFF2qa;;s&P#{Yc@fsZ%UdRzSkWFzcJZ|I-9s2u8M0Km|nfZBG+UYJIjKAAsTO z!2*GS0F}y}@J1u*jLLq55U&`BA5pOpKM7LJg67v8osoT0;H*-dv~>F5uXdyFHe2&o zX(69Tj-T gJ7VcvTM4W-;=)&#b{SqPb!S6Ma(7rAI=*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)); - } - } -} From dc98c7a8e68d532782a47bded2fe38e0eb12e329 Mon Sep 17 00:00:00 2001 From: meredithslota Date: Thu, 10 Aug 2023 09:15:41 -0700 Subject: [PATCH 3/3] chore(iot): remove IoT entries in blunderbuss.yml --- .github/blunderbuss.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 0eeeeea93ef..af7f5b0575b 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -26,11 +26,6 @@ assign_issues_by: - 'api: clouderrorreporting' to: - simonz130 -- labels: - - 'api: cloudiot' - to: - - attilagargyan - - simoncsaba-g - labels: - 'api: bigtable' - 'api: datastore' @@ -78,11 +73,6 @@ assign_prs_by: - 'api: clouderrorreporting' to: - simonz130 -- labels: - - 'api: cloudiot' - to: - - attilagargyan - - simoncsaba-g - labels: - 'api: bigtable' - 'api: datastore'