The CloudLink Cloud-Link Storage App is a Gluon code sample. Refer to the Gluon website for a full list of Gluon code samples.
In this tutorial, we’ll explain how you can make use of and combine local and cloud storage with the Gluon CloudLink Data Storage service.
Before you start, make sure to check the list of prerequisites for each platform.
Note: This tutorial will use NetBeans IDE, but it works as well on IntelliJ and Eclipse.
Code: The code for this project can be found in the samples repository at GitHub.
The sample is located under the directory cloudlink-cloudfirst-storage
.
The reader can clone this repository or create the entire project from scratch, based on the following steps.
Creating the project
Please check this tutorial to learn how to create a new Gluon project in NetBeans. Alternatively, you can also use the Gluon Mobile Maven Archetype to create a new project.
As this is a follow up of
the Notes sample, so you can also clone the original Notes sample, refactoring the main package to com.gluonhq.samples.cloudfirst
and the application class to CloudFirstStorage
.
The model package
The model package contains the Note
and Model
classes, exactly the same as in the Notes sample. We’ll override the Note::equals
method in order to compare lists later on.
Make sure these classes are present in the reflection list:
<reflectionList>
<list>com.gluonhq.samples.cloudfirst.views.NotesPresenter</list>
<list>com.gluonhq.samples.cloudfirst.views.EditionPresenter</list>
<list>com.gluonhq.samples.cloudfirst.model.Model</list>
<list>com.gluonhq.samples.cloudfirst.model.Note</list>
</reflectionList>
The service
In the original Notes sample, we created a service that used Gluon CloudLink to persist the notes we created and/or edited locally on the device. On the other hand, the PushNotes sample added cloud persistence.
In this sample we’ll show how Gluon CloudLink can be used to persist data both locally on the device and on the cloud.
For this, we need a DataClient
object:
Gluon Cloudlink can be used in different operation modes to store data on either the device, the cloud, or both. OperationMode.CLOUD_FIRST
mode is used to store data in both device and cloud. It also provides seamless syncing capabilities without any user interference.
public class Service {
private DataClient dataClient;
@PostConstruct
public void postConstruct() {
dataClient = DataClientBuilder.create()
.operationMode(OperationMode.CLOUD_FIRST)
.build();
}
}
The DataClient
object uses a DataProvider
as an entry point to retrieve a GluonObservableList
.
For that, we need to supply a proper ListDataReader
, a valid entity with the ability to read a list of objects.
The DataClient
instance already has a method: createListDataReader()
. All it needs is an identifier (NOTES
), and the object class to be read (Note.class
).
This is how we set the data client:
public class Service {
private static final String NOTES = "notes-cloudfirst";
private GluonObservableList<Note> notes;
private DataClient dataClient;
@PostConstruct
public void postConstruct() {
...
notes = retrieveNotes();
}
private GluonObservableList<Note> retrieveNotes() {
return DataProvider.retrieveList(
dataClient.createListDataReader(NOTES, Note.class,
SyncFlag.LIST_WRITE_THROUGH,
SyncFlag.OBJECT_WRITE_THROUGH));
}
}
Finally, this is the service class:
public class Service {
private static final String NOTES = "notes-cloudfirst";
private GluonObservableList<Note> notes;
private DataClient dataClient;
@PostConstruct
public void postConstruct() {
dataClient = DataClientBuilder.create()
.operationMode(OperationMode.CLOUD_FIRST)
.build();
notes = retrieveNotes();
}
private GluonObservableList<Note> retrieveNotes() {
// Retrieve notes from cloud or local storage
return DataProvider.retrieveList(
dataClient.createListDataReader(NOTES, Note.class,
SyncFlag.LIST_WRITE_THROUGH,
SyncFlag.OBJECT_WRITE_THROUGH));
}
public Note addNote(Note note) {
notes.add(note);
return note;
}
public void removeNote(Note note) {
notes.remove(note);
}
public GluonObservableList<Note> getNotes() {
return notes;
}
}
Check Operation Mode for other cloud strategies.
Before we can inject this service in our presenters, make sure you add this class to the reflection list as well:
<reflectionList>
...
<list>com.gluonhq.samples.cloudfirst.service.Service</list>
</reflectionList>
Registering the app
The DataClient
uses a key, and a secret token, specific for the application. Those tokens are used for signing the requests made to Gluon CloudLink.
To obtain a key and secret, you need a valid subscription to Gluon CloudLink. You can get it here (there is also a 30-day free trial).
Sign up and get a valid account on Gluon CloudLink, and a link to access the Gluon Dashboard.
Open the Dashboard in your browser, and sign in using the Gluon account credentials provided to create the account.
Go to the Credentials link, and you will
find a pair of application key/secret tokens. Click on the download button to download the file gluoncloudlink_config.json
, and then store it under your project src/main/resources/
folder.
The content of the file is a JSON object with the key and secret that will grant access to Gluon CloudLink:
{
"gluonCredentials": {
"applicationKey" : "f88XXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"applicationSecret": "7fbXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
}
Running the app
After updating the project, let’s run it on desktop.
HotSpot
Before creating a native image, let’s run first the app on HotSpot with the regular JDK 11+, as this will be faster to spot and fix any possible issue.
Run:
mvn gluonfx:run
and create the first note:
We can verify now if the note is stored locally (under <user>./gluon/notes-cloudfirst
), and in the cloud running the Dashboard application in the browser.
Sign in with your credentials and go to the Data Management link, you will be able to see the actual content of the notes list:
Native image
If that works, we can now test the native image on desktop (Linux, MacOS or Windows):
mvn gluonfx:build gluonfx:nativerun
After it ends the native compilation, the app should start and show the existing note. You can try editing it or adding a new one.
Deploy on mobile
Once we have accomplished all the previous steps, it is time to target the application for mobile platforms like Android and iOS.
These steps are already documented in the client docs for each IDE. We will refer to the NetBeans section.
-
For Android: Create & install an Android native image
-
For iOS: Create & install an iOS native image
Android
On a Linux machine, plug an Android device and run:
mvn -Pandroid gluonfx:build gluonfx:package gluonfx:install gluonfx:nativerun
You should get the application running on the device:
When running the app, we’ll see an empty list first, as the local storage was empty. However, immediately the note created before from the desktop app will be retrieved from the cloud and will start to show up. The same will be added to the Mobile’s local storage.
Now, if we remove the note from the CloudLink Dashboard, we will still see the note briefly in the app because of the (local) note, until the lists are synchronized and note is also removed locally.
Conclusion
During this tutorial we have accomplished several tasks:
-
Modified the basic Gluon Mobile sample to add both local and cloud persistence with
DataClient
andGluonObservableList
. -
Use the Gluon Cloudlink Dashboard web application to track changes in those persisted lists and objects.
-
Built a native image of the app and deploy it to mobile platforms.
If you have made it this far, congratulations, we hope this sample, and the documentation was helpful to you! In case you have any questions, your first stop should be the Gluon support page, where you can access the CloudLink latest documentation. Gluon also recommends the community to support each other over at the Gluon StackOverflow page. Finally, Gluon offers commercial support as well, to kick start your projects.