1
- /**
2
- * Copyright 2017, Google, Inc.
3
- *
4
- * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5
- * except in compliance with the License. You may obtain a copy of the License at
6
- *
7
- * <p>http://www.apache.org/licenses/LICENSE-2.0
8
- *
9
- * <p>Unless required by applicable law or agreed to in writing, software distributed under the
10
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11
- * express or implied. See the License for the specific language governing permissions and
12
- * limitations under the License.
13
- */
1
+ /*
2
+ Copyright 2017, Google, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
14
17
15
18
package com .google .cloud .iot .examples ;
16
19
20
+ // [START cloudiotcore_http_imports]
17
21
import io .jsonwebtoken .JwtBuilder ;
18
22
import io .jsonwebtoken .Jwts ;
19
23
import io .jsonwebtoken .SignatureAlgorithm ;
24
+ import java .io .IOException ;
25
+ import java .io .UnsupportedEncodingException ;
20
26
import java .net .HttpURLConnection ;
27
+ import java .net .ProtocolException ;
21
28
import java .net .URL ;
22
29
import java .nio .file .Files ;
23
30
import java .nio .file .Paths ;
24
31
import java .security .KeyFactory ;
25
32
import java .security .spec .PKCS8EncodedKeySpec ;
26
33
import java .util .Base64 ;
27
34
import org .joda .time .DateTime ;
35
+ import org .json .JSONException ;
28
36
import org .json .JSONObject ;
37
+ // [END cloudiotcore_http_imports]
29
38
30
39
/**
31
40
* Java sample of connecting to Google Cloud IoT Core vice via HTTP, using JWT.
39
48
* folder.
40
49
*/
41
50
public class HttpExample {
42
- /** Create a Cloud IoT Core JWT for the given project id, signed with the given private key. */
51
+ // [START cloudiotcore_http_createjwt]
52
+ /** Create a RSA-based JWT for the given project id, signed with the given private key. */
43
53
private static String createJwtRsa (String projectId , String privateKeyFile ) throws Exception {
44
54
DateTime now = new DateTime ();
45
55
// Create a JWT to authenticate this device. The device will be disconnected after the token
@@ -58,6 +68,7 @@ private static String createJwtRsa(String projectId, String privateKeyFile) thro
58
68
return jwtBuilder .signWith (SignatureAlgorithm .RS256 , kf .generatePrivate (spec )).compact ();
59
69
}
60
70
71
+ /** Create an ES-based JWT for the given project id, signed with the given private key. */
61
72
private static String createJwtEs (String projectId , String privateKeyFile ) throws Exception {
62
73
DateTime now = new DateTime ();
63
74
// Create a JWT to authenticate this device. The device will be disconnected after the token
@@ -75,28 +86,60 @@ private static String createJwtEs(String projectId, String privateKeyFile) throw
75
86
76
87
return jwtBuilder .signWith (SignatureAlgorithm .ES256 , kf .generatePrivate (spec )).compact ();
77
88
}
89
+ // [END cloudiotcore_http_createjwt]
78
90
79
- public static void main (String [] args ) throws Exception {
80
- HttpExampleOptions options = HttpExampleOptions .fromFlags (args );
81
- if (options == null ) {
82
- // Could not parse the flags.
83
- System .exit (1 );
84
- }
85
-
91
+ // [START cloudiotcore_http_publishmessage]
92
+ /** Publish an event or state message using Cloud IoT Core via the HTTP API. */
93
+ public static void publishMessage (String payload , String urlPath , String messageType ,
94
+ String token , String projectId , String cloudRegion , String registryId , String deviceId )
95
+ throws UnsupportedEncodingException , IOException , JSONException , ProtocolException {
86
96
// Build the resource path of the device that is going to be authenticated.
87
97
String devicePath =
88
98
String .format (
89
99
"projects/%s/locations/%s/registries/%s/devices/%s" ,
90
- options .projectId , options .cloudRegion , options .registryId , options .deviceId );
100
+ projectId , cloudRegion , registryId , deviceId );
101
+ String urlSuffix = messageType .equals ("event" ) ? "publishEvent" : "setState" ;
91
102
92
- // This describes the operation that is going to be perform with the device.
93
- String urlSuffix = options .messageType .equals ("event" ) ? "publishEvent" : "setState" ;
103
+ // Data sent through the wire has to be base64 encoded.
104
+ Base64 .Encoder encoder = Base64 .getEncoder ();
105
+
106
+ String encPayload = encoder .encodeToString (payload .getBytes ("UTF-8" ));
94
107
95
- String urlPath =
96
- String .format (
97
- "%s/%s/%s:%s" , options .httpBridgeAddress , options .apiVersion , devicePath , urlSuffix );
98
108
URL url = new URL (urlPath );
99
- System .out .format ("Using URL: '%s'\n " , urlPath );
109
+ HttpURLConnection httpCon = (HttpURLConnection ) url .openConnection ();
110
+ httpCon .setDoOutput (true );
111
+ httpCon .setRequestMethod ("POST" );
112
+
113
+ // Add headers.
114
+ httpCon .setRequestProperty ("authorization" , String .format ("Bearer %s" , token ));
115
+ httpCon .setRequestProperty ("content-type" , "application/json; charset=UTF-8" );
116
+ httpCon .setRequestProperty ("cache-control" , "no-cache" );
117
+
118
+ // Add post data. The data sent depends on whether we're updating state or publishing events.
119
+ JSONObject data = new JSONObject ();
120
+ if (messageType .equals ("event" )) {
121
+ data .put ("binary_data" , encPayload );
122
+ } else {
123
+ JSONObject state = new JSONObject ();
124
+ state .put ("binary_data" , encPayload );
125
+ data .put ("state" , state );
126
+ }
127
+ httpCon .getOutputStream ().write (data .toString ().getBytes ("UTF-8" ));
128
+ httpCon .getOutputStream ().close ();
129
+
130
+ System .out .println (httpCon .getResponseCode ());
131
+ System .out .println (httpCon .getResponseMessage ());
132
+ }
133
+ // [END cloudiotcore_http_publishmessage]
134
+
135
+ // [START cloudiotcore_http_run]
136
+ /** Parse arguments and publish messages. */
137
+ public static void main (String [] args ) throws Exception {
138
+ HttpExampleOptions options = HttpExampleOptions .fromFlags (args );
139
+ if (options == null ) {
140
+ // Could not parse the flags.
141
+ System .exit (1 );
142
+ }
100
143
101
144
// Create the corresponding JWT depending on the selected algorithm.
102
145
String token ;
@@ -109,41 +152,18 @@ public static void main(String[] args) throws Exception {
109
152
"Invalid algorithm " + options .algorithm + ". Should be one of 'RS256' or 'ES256'." );
110
153
}
111
154
112
- // Data sent through the wire has to be base64 encoded.
113
- Base64 .Encoder encoder = Base64 .getEncoder ();
114
-
115
155
// Publish numMessages messages to the HTTP bridge.
116
156
for (int i = 1 ; i <= options .numMessages ; ++i ) {
117
157
String payload = String .format ("%s/%s-payload-%d" , options .registryId , options .deviceId , i );
118
158
System .out .format (
119
159
"Publishing %s message %d/%d: '%s'\n " ,
120
160
options .messageType , i , options .numMessages , payload );
121
- String encPayload = encoder .encodeToString (payload .getBytes ("UTF-8" ));
122
-
123
- HttpURLConnection httpCon = (HttpURLConnection ) url .openConnection ();
124
- httpCon .setDoOutput (true );
125
- httpCon .setRequestMethod ("POST" );
126
161
127
- // Adding headers.
128
- httpCon .setRequestProperty ("Authorization" , String .format ("Bearer %s" , token ));
129
- httpCon .setRequestProperty ("Content-Type" , "application/json; charset=UTF-8" );
130
-
131
- // Adding the post data. The structure of the data send depends on whether it is event or a
132
- // state message.
133
- JSONObject data = new JSONObject ();
134
- if (options .messageType .equals ("event" )) {
135
- data .put ("binary_data" , encPayload );
136
- } else {
137
- JSONObject state = new JSONObject ();
138
- state .put ("binary_data" , encPayload );
139
- data .put ("state" , state );
140
- }
141
- httpCon .getOutputStream ().write (data .toString ().getBytes ("UTF-8" ));
142
- httpCon .getOutputStream ().close ();
162
+ String urlPath = String .format ("%s/%s/" , options .httpBridgeAddress , options .apiVersion );
163
+ System .out .format ("Using URL: '%s'\n " , urlPath );
143
164
144
- // This will perform the connection as well.
145
- System .out .println (httpCon .getResponseCode ());
146
- System .out .println (httpCon .getResponseMessage ());
165
+ publishMessage (payload , urlPath , options .messageType , token , options .projectId ,
166
+ options .cloudRegion , options .registryId , options .deviceId );
147
167
148
168
if (options .messageType .equals ("event" )) {
149
169
// Frequently send event payloads (every second)
@@ -155,4 +175,5 @@ public static void main(String[] args) throws Exception {
155
175
}
156
176
System .out .println ("Finished loop successfully. Goodbye!" );
157
177
}
178
+ // [END cloudiotcore_http_run]
158
179
}
0 commit comments