|
1 | 1 | # Quickstart Guide
|
| 2 | + |
| 3 | +## Prerequesites |
| 4 | + |
| 5 | +- A running **cloud.iO services** instance. See the getting started guide: [Deploy cloud hosted infrastructure](/deploy/deploy). |
| 6 | +- Java JDK 11+ installed. |
| 7 | + |
| 8 | +Please, enter your cloud.iO servers **hostname**: |
| 9 | +<div class="container"> |
| 10 | +<table> |
| 11 | + <tr> |
| 12 | + <th>Hostname</th> |
| 13 | + </tr> |
| 14 | + <tr> |
| 15 | + <td><input id="hostname" |
| 16 | + class="form-control" |
| 17 | + type="text" |
| 18 | + placeholder="http://127.0.0.1:8080"></td> |
| 19 | + </tr> |
| 20 | + </table> |
| 21 | +</div> |
| 22 | + |
| 23 | +## Set the CORS policy |
| 24 | + |
| 25 | +This guide will send HTTP REST commands to your **cloud.iO** server. To allow a webpage to communicate with the **cloud.iO** server, |
| 26 | +you have to set up its **CORS policy** (more information about **CORS** can be found [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)). |
| 27 | + |
| 28 | +- To do this, connect to the cloud.iO Swagger UI at |
| 29 | +<body> |
| 30 | + |
| 31 | + <a id="swagger_url" target="_blank" href="your_server_ip:8080/swagger-ui/index.html#/Cors Management/postOrigin">your_server_ip:8080/swagger-ui/index.html#/CorsManagement/postOrigin</a> |
| 32 | +</body> |
| 33 | +- Click *"Try it out"*, add "\*" in the origin field, then click *"Execute"*: |
| 34 | + |
| 35 | +<p align="center"> |
| 36 | + <br> |
| 37 | + <img src="getting_started/_media/cors_1.png" style="width:30%" /> |
| 38 | + <br> |
| 39 | +</p> |
| 40 | + |
| 41 | +- You will be asked to log in. Use your **admin login**. |
| 42 | +- Verify that the server responds with a *204* HTTP code: |
| 43 | + |
| 44 | +<p align="center"> |
| 45 | + <br> |
| 46 | + <img src="getting_started/_media/cors_2.png" style="width:40%" /> |
| 47 | + <br> |
| 48 | +</p> |
| 49 | + |
| 50 | +!> All origins are now accepted. It is recommended to not use this CORS configuration in a production environnement. |
| 51 | + |
| 52 | +Check that everything is correctly set up by testing the connection with the server: |
| 53 | + |
| 54 | +<div class="container"> |
| 55 | + <table> |
| 56 | + <tr> |
| 57 | + <th>Username</th> |
| 58 | + <th>Password</th> |
| 59 | + </tr> |
| 60 | + <tr> |
| 61 | + <td><input id="username" |
| 62 | + class="form-control" |
| 63 | + type="text" |
| 64 | + placeholder="admin"> </td> |
| 65 | + <td><input id="password" |
| 66 | + class="form-control" |
| 67 | + type="password" |
| 68 | + placeholder="password"> </td> |
| 69 | + </tr> |
| 70 | + </table> |
| 71 | + <div class="form-group"> |
| 72 | + <button id="btn-test" |
| 73 | + class="btn btn-success btn-lg float-right" |
| 74 | + type="submit"> |
| 75 | + Test |
| 76 | + </button> |
| 77 | + </div> |
| 78 | +</div> |
| 79 | + |
| 80 | +## Get the certificates |
| 81 | +You can now **create** an new **endpoint** and generate its **certificates** by clicking the button below: |
| 82 | +<div class="form-group"> |
| 83 | + <button id="btn-certs" |
| 84 | + class="btn btn-success btn-lg float-right" |
| 85 | + type="submit"> |
| 86 | + Get certificates |
| 87 | + </button> |
| 88 | +</div> |
| 89 | + |
| 90 | +## Run the example endpoint java |
| 91 | + |
| 92 | +This section describes how to run your very first cloud.iO endpoint. This endpoint implements a simple counter that increments its value every 1s. |
| 93 | +- **Clone** or **download** the [cloudio-endpoint-java-example](https://github.com/cloudio-project/cloudio-endpoint-java-example) repository. |
| 94 | +- To be able to get the [cloudio-endpoint-java](https://github.com/cloudio-project/cloudio-endpoint-java) library, you'll need to fill the *gradle.properties* file with your Github **username** and |
| 95 | +a **personal access token**. Don't know how to generate a github **personal access token**? Go to [the Github documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token). |
| 96 | +- Extract the certificates in *cloudio-endpoint-java-example/src/main/resources/cloud.io/*. |
| 97 | +- Complete the *clientCert* and *authorityCert* path in *cloudio-endpoint-java-example/src/main/resources/cloud.io/example.properties*. |
| 98 | +- Run the demo endpoint<br>Linux: |
| 99 | +```bash |
| 100 | +./gradlew build |
| 101 | +./gradlew run |
| 102 | +``` |
| 103 | +<br>Windows: |
| 104 | +```bash |
| 105 | +gradlew.bat build |
| 106 | +gradlew.bat run |
| 107 | +``` |
| 108 | + |
| 109 | +You should now see the log *"Endpoint is online"* in the console. |
| 110 | + |
| 111 | +## Read the data |
| 112 | +If not done automatically at the previous step, please entre your endpoint **UUID** below. |
| 113 | +By hitting the start button, you will enable the polling of the attribute *myNode/myObject/myMeasure* value. |
| 114 | +<div class="container"> |
| 115 | + <table> |
| 116 | + <tr> |
| 117 | + <th>UUID</th> |
| 118 | + </tr> |
| 119 | + <tr> |
| 120 | + <td><input id="uuid" |
| 121 | + class="form-control" |
| 122 | + type="text" |
| 123 | + placeholder="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"> </td> |
| 124 | + </tr> |
| 125 | + </table> |
| 126 | + <div class="form-group"> |
| 127 | + <button id="btn-read" |
| 128 | + class="btn btn-success btn-lg float-right" |
| 129 | + type="submit">Start</button> |
| 130 | + <output id="attribute"><b>/myNode/myObject/myMeasure:</b> </output> |
| 131 | + </div> |
| 132 | +</div> |
| 133 | +<iframe id="download_frame" style="display:none;"></iframe> |
| 134 | + |
| 135 | + |
| 136 | +> Note: For performance reasons, the attributes values are stored every 3s in influxDB, that's why you can't see every value changes. |
| 137 | +If necessary, you can connect through Stomp/Websocket or MQTT to get notified on every change. |
| 138 | + |
| 139 | +<script type="text/javascript"> |
| 140 | + |
| 141 | + $(document).ready(function () { |
| 142 | + var timer = null; |
| 143 | + |
| 144 | + $("#btn-test").click(function () { |
| 145 | + var host = $("#hostname").val(); |
| 146 | + var user = $("#username").val(); |
| 147 | + var pass = $("#password").val(); |
| 148 | + if(!host) |
| 149 | + alert("Hostname cannot be empty!"); |
| 150 | + else if(!user) |
| 151 | + alert("Username cannot be empty!"); |
| 152 | + else if(!pass) |
| 153 | + alert("Password cannot be empty!"); |
| 154 | + else{ |
| 155 | + var formData = {}; |
| 156 | + $.ajax({ |
| 157 | + url : host + "/api/v1/account", |
| 158 | + type: "GET", |
| 159 | + data : formData, |
| 160 | + crossDomain: true, |
| 161 | + headers: { |
| 162 | + "Authorization": "Basic " + btoa(user + ":" + pass) |
| 163 | + }, |
| 164 | + success: function(data, textStatus, jqXHR) |
| 165 | + { |
| 166 | + alert("Connection successful!"); |
| 167 | + }, |
| 168 | + error: function (jqXHR, textStatus, errorThrown) |
| 169 | + { |
| 170 | + alert("Error while trying to connect"); |
| 171 | + } |
| 172 | + }); |
| 173 | + } |
| 174 | + }); |
| 175 | + $("#hostname").on("input", function () { |
| 176 | + $("#swagger_url").text($("#hostname").val() + "/swagger-ui/index.html#/Cors Management/postOrigin").show(); |
| 177 | + $("#swagger_url").attr("href", $("#swagger_url").text()); |
| 178 | + }); |
| 179 | + |
| 180 | + $("#btn-certs").click(function () { |
| 181 | + var host = $("#hostname").val(); |
| 182 | + var user = $("#username").val(); |
| 183 | + var pass = $("#password").val(); |
| 184 | + var uuid = ""; |
| 185 | + |
| 186 | + if(!host) |
| 187 | + alert("Hostname cannot be empty!"); |
| 188 | + else if(!user) |
| 189 | + alert("Username cannot be empty!"); |
| 190 | + else if(!pass) |
| 191 | + alert("Password cannot be empty!"); |
| 192 | + else{ |
| 193 | + var formData = {}; |
| 194 | + $.ajax({ |
| 195 | + url : host + "/api/v1/endpoints?friendlyName=quickstart", |
| 196 | + type: "POST", |
| 197 | + data : formData, |
| 198 | + crossDomain: true, |
| 199 | + headers: { |
| 200 | + "Authorization": "Basic " + btoa(user + ":" + pass) |
| 201 | + }, |
| 202 | + success: function(data, textStatus, jqXHR) |
| 203 | + { |
| 204 | + uuid = data.uuid; |
| 205 | + $("#uuid").val(uuid); |
| 206 | + |
| 207 | + set_properties(host, user, pass, uuid); |
| 208 | + }, |
| 209 | + error: function (jqXHR, textStatus, errorThrown) |
| 210 | + { |
| 211 | + alert("Error while creating endpoint"); |
| 212 | + } |
| 213 | + }); |
| 214 | + } |
| 215 | + }); |
| 216 | + |
| 217 | + $("#btn-read").click(function () { |
| 218 | + var host = $("#hostname").val(); |
| 219 | + var user = $("#username").val(); |
| 220 | + var pass = $("#password").val(); |
| 221 | + var uuid = $("#uuid").val(); |
| 222 | + |
| 223 | + if($("#btn-read").text() === "Start"){ |
| 224 | + if(!host) |
| 225 | + alert("Hostname cannot be empty!"); |
| 226 | + else if(!user) |
| 227 | + alert("Username cannot be empty!"); |
| 228 | + else if(!pass) |
| 229 | + alert("Password cannot be empty!"); |
| 230 | + else if(!uuid) |
| 231 | + alert("UUID cannot be empty!"); |
| 232 | + else{ |
| 233 | + $("#btn-read").html("Stop"); |
| 234 | + timer = setInterval(function(){ |
| 235 | + const attr = read_attribute(host, user, pass, uuid + "/myNode/myObject/myMeasure", display_my_measure); |
| 236 | + }, 3000); |
| 237 | + } |
| 238 | + } |
| 239 | + else{ |
| 240 | + $("#btn-read").html("Start"); |
| 241 | + clearInterval(timer); |
| 242 | + timer = null; |
| 243 | + } |
| 244 | + }); |
| 245 | + }); |
| 246 | + function read_attribute(host, user, pass, attr, _callback) { |
| 247 | + var formData = {}; |
| 248 | + $.ajax({ |
| 249 | + url : host + "/api/v1/data/" + attr, |
| 250 | + type: "GET", |
| 251 | + data : formData, |
| 252 | + crossDomain: true, |
| 253 | + headers: { |
| 254 | + "Authorization": "Basic " + btoa(user + ":" + pass) |
| 255 | + }, |
| 256 | + success: function(data, textStatus, jqXHR) |
| 257 | + { |
| 258 | + console.log(data); |
| 259 | + _callback(attr, data); |
| 260 | + }, |
| 261 | + error: function (jqXHR, textStatus, errorThrown) |
| 262 | + { |
| 263 | + alert("Error while trying to reading data"); |
| 264 | + } |
| 265 | + }); |
| 266 | + } |
| 267 | + |
| 268 | + function display_my_measure(id, value) { |
| 269 | + console.log(id + ": " + value.value); |
| 270 | + $("#attribute").html("<b>myNode/myObject/myMeasure:</b> " + value.value); |
| 271 | + } |
| 272 | + |
| 273 | + function set_properties(host, user, pass, uuid) { |
| 274 | + var tab = host.replace("http://", "").replace("https://", "").split(":"); |
| 275 | + var formData = { |
| 276 | + "customProperties": { |
| 277 | + "ch.hevs.cloudio.endpoint.hostUri": "ssl://" + tab[0], |
| 278 | + "ch.hevs.cloudio.endpoint.ssl.authorityCert": "file:/C:/Users/.../cloudio-endpoint-java-example/src/main/resources/cloud.io/authority.jks", |
| 279 | + "ch.hevs.cloudio.endpoint.ssl.clientCert": "file:/C:/Users/.../cloudio-endpoint-java-example/src/main/resources/cloud.io/" + uuid + ".p12", |
| 280 | + "ch.hevs.cloudio.endpoint.ssl.verifyHostname": "false" |
| 281 | + } |
| 282 | + }; |
| 283 | + console.log(formData); |
| 284 | + $.ajax({ |
| 285 | + url : host + "/api/v1/endpoints/" + uuid + "/provisionToken", |
| 286 | + type: "POST", |
| 287 | + data : JSON.stringify(formData), |
| 288 | + crossDomain: true, |
| 289 | + headers: { |
| 290 | + "Authorization": "Basic " + btoa(user + ":" + pass), |
| 291 | + "Content-Type": "application/json" |
| 292 | + }, |
| 293 | + success: function(data, textStatus, jqXHR) |
| 294 | + { |
| 295 | + get_certificates(host, data); |
| 296 | + }, |
| 297 | + error: function (jqXHR, textStatus, errorThrown) |
| 298 | + { |
| 299 | + alert("Error while trying to generate certificates"); |
| 300 | + } |
| 301 | + }); |
| 302 | + } |
| 303 | + |
| 304 | + function get_certificates(host, token){ |
| 305 | + |
| 306 | + fetch(host + "/api/v1/provision/" + token + "?propertiesFileName=example", {headers: {"Accept": "application/java-archive"}}) |
| 307 | + .then(resp => resp.blob()) |
| 308 | + .then(blob => { |
| 309 | + const url = window.URL.createObjectURL(blob); |
| 310 | + const a = document.createElement('a'); |
| 311 | + a.style.display = 'none'; |
| 312 | + a.href = url; |
| 313 | + // the filename you want |
| 314 | + a.download = 'quickstart-certificates.jar'; |
| 315 | + document.body.appendChild(a); |
| 316 | + a.click(); |
| 317 | + window.URL.revokeObjectURL(url); |
| 318 | + }) |
| 319 | + .catch(() => alert('Error while downloading the certificates!')); |
| 320 | + } |
| 321 | + |
| 322 | +</script> |
| 323 | + |
0 commit comments