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.

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:

pom.xml
<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.

Service.java
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:

Service.java
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:

Service.java
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:

pom.xml
<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.

Dashboard

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.

Configuration File

The content of the file is a JSON object with the key and secret that will grant access to Gluon CloudLink:

src/main/resources/gluoncloudlink_config.json
{
  "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 javafx:run

and create the first note:

Notes View

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:

Dashboard Data view

Native image

If that works, we can now test the native image on desktop (Linux, MacOS or Windows):

mvn client:build client:run

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.

Android

On a Linux machine, plug an Android device and run:

mvn -Pandroid client:build client:package client:install client:run

You should get the application running on the device:

Android app

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.

iOS

On MacOS, plug an iOS device and run:

mvn -Pios client:build client:run

You should get the application running on the device:

iOS app

Conclusion

During this tutorial we have accomplished several tasks:

  • Modified the basic Gluon Mobile sample to add both local and cloud persistence with DataClient and GluonObservableList.

  • 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.