MauroRiboniMX_0-1704882159732.png

SDK: Licensing Demo using REST API

MauroRiboniMX
Contributor
Disclaimer

The goal is to provide an application that is able to implement a basic licensing mechanism to be able to integrate an app with the ctrlX AUTOMATION licensing system. This guide is covering just the case with the ctrlX COREvirtual. It is the DevelopR that has to adapt this to his needs with the real license code and so on. 

This guide is not intended to be a substitution of the official documentation which can be found here: Licensing Documentation. It's meant to be a help for the people who have a similar setup and might want to start from a demo.

Requirements
  • ctrlX COREvirtual
  • SDK Environment 
  • Service2Service authentication Link To How-to the guide will start from this 😃
Step 1: Add the license info in the Package Manifest

This step is not the actual technical license check but will improve the usability of the app. Inserting these info in the Package Manifest we enhance our app with the graphical info, in the app install page, with the needed licenses to run the app.

Lincenses UI userLincenses UI user

Step 2: Add the right plugs and slot in the snapcraft.yaml

There is the possibility to use a unix socket to bind our process directly there. In this example I have used the standard rest API. Anyway to implement this feature we need to add the following plug.

Custom PlugsCustom Plugs

The Picture shows also the "datalayer" plug which is needed to interact with the datalayer. The licensing-service plug allows the system to create a socketfile there. 

Step 3: Implement the algorithm

The important APIs to take into consideration are the following and are listed in the official documentation, can be tested directly on the core with swagger and plus we have a dedicated section here: Swagger online. 

REST API callsREST API calls

The workflow is the following:

  1. Whenever we boot the device the app should ask for the license with the "acquire license" API. The answer will contain an ID that should be kept to release the license in a second time. In this case we can start the app normally otherwise we block the app.
  2. If the app is removed we need to use the Release License API to release the license. 
  3. When the app is restarted we don't know if it's a fresh boot of the device, the app crashed or whatsoever so better to repeat point 2 and then point 1 anytime. 

In this demo I save the ID in a file located in $SNAP_DATA and I create a file named "licensed" just to register that the app is correctly licensed. This process is achieved using a python script:

Licensing Python CodeLicensing Python Code

I remove the proxy setting for this script, in this way I am avoiding to use the proxy for local host and I can't have problems with such configurations. The script to unlicense the app is the following:

Unlicensing python scriptUnlicensing python script

If we find the "licensed" file we read the ID contained and we release the license. We then remove also the file itself. 
In case the app is removed we take advantage of the "remove hook" functionality which is a script called automatically when the app starts. Here is the documentation Hooks Explaination.

Remove HookRemove Hook

The hook just calls the "unlicense.py" script. The app is normally started with a launch.wrapper script which unlicenses the app and license it again, checking the file with the id presence.

Wrapper structureWrapper structure

Step 4: go productive

Convert the pervious algorithm to "requests-unixsocket" in order to communicate without HTTP rest api but binding directly to the license file. 

As stated this is just an example on how someone can implement this functionality. The example is just a demo and it is not complete. 

Have Fun 😎

MauroRiboniMX
MauroRiboniMX
Hello, I am Mauro a ctrlX DEVELOPR at night and an Application Engineer during the day 😎 . Ask me anything about ctrlX AUTOMATION but my best topics are IoT, AI, SDK and Communication!
Must Read
Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist