Skip to content

Commit

Permalink
File management & firmware update features (#53)
Browse files Browse the repository at this point in the history
* Refactored some models

* Uniformed models

* Reworking Downloader

* Chunk size splitting

* Working towards the end of session

* Execute all callback calls on executor

* Return success

* The bit receive logic

* Analyze current hash for every

* Moved currentChunk increase

* Simple test single chunk

* Check status & report properly

* Fix Travis build

* More Travis build fixes

* Bump to Bionic

* Test ctor to separate into multiple chunks

* Fixed first abort

* More abort and abort tests

* Most basic flow confirmed

* Change to 2 threads for calls

* More tests & refactor

* Forgot sleeps

* Runnable instances

* Happy flow multiple chunks

* Extend the sleep timing

* Fixed the state issues

* One chunk fail and redo test

* Test where we rewind

* Started work on UrlFileDownload session

* Fixed wrap of DownloadTask

* Implemented download logic

* Unit tests for UrlFileDownloadSession

* Started work on FileSystemManagement

* Working on FileSystemManagement

* Create file method

* Finished FileSystemManagement

* Finished protocol code, onto testing

* Assembled everything, but can't debug

* Init/delete/purge/lists work, can't get binary response/abort message

* Working with executors

* Working transfer, left to resolve last chunk

* Fixed tests

* Publish file list after deletions

* Working last chunk

* Check for already existing file, and check hash

* Extra logging for users to be aware of file transfers

* Expanded FileSystemManagement test to 100%

* Unpruned enums

* Better handling of IOExceptions

* Fix topic in this error message

* No more 16 retries, max 4

* Setup constructor mocking

* Working on Unit Tests for FM

* Started the FirmwareUpdateProtocol

* Fully working example of FirmwareUpdate & FirmwareInstaller

* Add the example file

* Smore more tests

* Half-way there for FM

* Some fixes

* Sleeps

* Finished small handles

* Finished FM tests

* Firmware update tests

* Done some requested changes

* Renamed files & moved publishes to connect

* Move DEFAULT_FILE location as final class value

* General reformat

* More requested changes

* More changes

* Fixed tests

* Fully updated FirmwareUpdate

* Fixed tests

* Status after abort fix

* Custom URL file downloader

* Refactored SessionState out

* Fixed tests & abort while downloading

* Reformat code

* Added README.md

* Reorder methods & fix readme

* Ignore the version file in management

Co-authored-by: Astrihale <[email protected]>
  • Loading branch information
Nenad Vuletić and Astrihale authored Nov 9, 2020
1 parent e86f706 commit 526452f
Show file tree
Hide file tree
Showing 41 changed files with 4,723 additions and 633 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@
/captures
/out
.gradletasknamecache

*ssl*/
files/
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# We will use Ubuntu 18.04 (bionic beaver). List of options:
# https://docs.travis-ci.com/user/reference/overview/#linux
dist: xenial
dist: bionic

# This enables the 'defaults' to test java applications:
language: java
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ repositories {
}

dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.4'
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
implementation 'commons-codec:commons-codec:1.11'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.0'
implementation 'org.slf4j:slf4j-api:1.7.26'
Expand Down
74 changes: 72 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
```
----

[![Build Status](https://travis-ci.com/Wolkabout/WolkConnect-Java.svg?branch=master)](https://travis-ci.com/Wolkabout/WolkConnect-Java)

WolkAbout Java Connector for connecting devices to [WolkAbout IoT Platform](https://demo.wolkabout.com/#/login).

Supported device communication protocols:
Expand Down Expand Up @@ -232,7 +234,6 @@ final Wolk wolk = Wolk.builder()
.sslCertification("ca.crt")
.deviceKey("device_key")
.password("some_password")
.build()
.enableKeepAliveService(false)
.build();
```
Expand All @@ -244,6 +245,75 @@ This timestamp will be saved and updated for each response, and can be accessed
```java
long platformTimestamp = wolk.getPlatformTimestamp();
```

### File management & firmware update

*Note:* These features will be available in a later release.
To enable these features, you need to invoke the methods in the builder.

##### File Management

```java
final Wolk wolk = Wolk.builder()
.mqtt()
.host("ssl://api-demo.wolkabout.com:8883")
.sslCertification("ca.crt")
.deviceKey("device_key")
.password("some_password")
.enableFileManagement()
.build();

/** You can use
enableFileManagement() - use everything default
enableFileManagement(String fileManagementLocation) - use a specific file location
enableFileManagement(UrlFileDownloader urlFileDownloader) - use a custom url file downloader
enableFileManagement(String fileManagementLocation, UrlFileDownloader urlFileDownloader) - use both custom **/
```

You might want to implement a custom `UrlFileDownloader` object. This allows you to inject custom logic for downloading
the file, based on the given URL. The default HTTP location will just target the request with GET method, without any
arguments/headers.

The [interface](https://github.com/Wolkabout/WolkConnect-Java/blob/master/src/main/java/com/wolkabout/wolk/filemanagement/UrlFileDownloader.java)
looks like this:
```java
public interface UrlFileDownloader {
Map.Entry<FileTransferStatus, FileTransferError> downloadFile(String fileUrl);
}
```

##### Firmware Update
*Very important note* - if you have not enabled the file management, this will enable it. You can pass arguments through
this call to, to configure the file management in the way you want.

```java
final FirmwareInstaller firmwareInstaller = ...;
String firmwareVersion = ...;

final Wolk wolk = Wolk.builder()
.mqtt()
.host("ssl://api-demo.wolkabout.com:8883")
.sslCertification("ca.crt")
.deviceKey("device_key")
.password("some_password")
.enableFirmwareUpdate(firmwareInstaller, firmwareVersion)
.build();

/** You can use
enableFirmwareUpdate(FirmwareInstaller firmwareInstaller, String firmwareVersion) - use default file management, and pass the firmware installer and firmware version
enableFirmwareUpdate(String fileManagementLocation, String firmwareVersion, FirmwareInstaller firmwareInstaller) - configure the file management with the location
enableFirmwareUpdate(UrlFileDownloader urlFileDownloader, String firmwareVersion, FirmwareInstaller firmwareInstaller) - configure the file management with the url file downloader
enableFirmwareUpdate(String fileManagementLocation, UrlFileDownloader urlFileDownloader, String firmwareVersion, FirmwareInstaller firmwareInstaller) - configure the file management with everything custom **/
```

You do need to implement a object from `FirmwareInstaller` interface. This allows you to implement some logic for your
use case to handle the incoming firmware update initialization messages, abort messages and to provide a firmware version.

The [interface](https://github.com/Wolkabout/WolkConnect-Java/blob/master/src/main/java/com/wolkabout/wolk/firmwareupdate/FirmwareInstaller.java)
looks like this:
```java
public interface FirmwareInstaller {
boolean onInstallCommandReceived(String fileName);
void onAbortCommandReceived();
String onFirmwareVersion();
}
```
5 changes: 3 additions & 2 deletions src/main/java/com/wolkabout/wolk/MqttBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class MqttBuilder {

private static final String FACTORY_TYPE = "X.509";

private WeakReference<Wolk.Builder> wolkBuilder;
private final WeakReference<Wolk.Builder> wolkBuilder;

/**
* URL of the MQTT broker. Must start with "ssl://" or "tcp://"
Expand Down Expand Up @@ -212,7 +212,8 @@ private Certificate getCertificate(String certName) throws GeneralSecurityExcept
}
}

private TrustManagerFactory getTrustManagerFactory(Certificate certificate, String ca) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
private TrustManagerFactory getTrustManagerFactory(Certificate certificate, String ca)
throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
// Creating a KeyStore containing our trusted CAs
final String keyStoreType = KeyStore.getDefaultType();
final KeyStore keyStore = KeyStore.getInstance(keyStoreType);
Expand Down
Loading

0 comments on commit 526452f

Please sign in to comment.