This is a technical article on the creation of an IoT Application using one of the templates available in Leonardo IoT.
Let us start with the prerequisites and the initial setup to enable us to create such an application.
1. Initial Setup and Prerequisites:
- Access to one of the Global Accounts and Sub-Account on Cloud Foundry (Canary Home), along with space access inside the sub-account. This is where different applications and services will be deployed. Space Developer and Space Manager access is also required which enables the user to deploy applications and services in this space.
- Access to another account on Neo environment. This is required for the web-IDE development, since Web-IDE is only supported on Neo currently. Navigate to services inside this account and make sure that "SAP Web IDE Full-Stack" is enabled.
- Navigate to this service from the "Go To Service" link available in the Neo account for SAP Web IDE Full-Stack. Refer the image below -
- This opens the Web-IDE. Under Settings tab, Click on "Cloud Foundry" and enter the CF end-point and choose the org and space where the applications need to be deployed.
- Click on Extensions (below Cloud Foundry) and make sure that SAP Leonardo IoT, Storyboard, Layout Editor and SAP Fiori Launchpad Site is enabled. SAP Leonardo IoT extension allows you to use the IoT templates and create applications using this template.
- Click on Tools in the toolbar and click on "Update IoT Destinations". This is where user needs to enter the space credentials like client id, client secret, authentication url, etc. Make sure "Add Smart Business Destinations" is checked before you proceed.
- Navigate to your sub-account and click on Subscriptions. Make sure that your sub-account is subscribed to one of the SAP Leonardo IoT Application. This is where all the backend artefact needs to be created. Click on "Go To Application" to access the Thing Engineering OData Applications to create a package, thing type, property set types and properties inside the PSTs.
This completes the initial setup which is required in order to continue with the SaaS Application development and deployment on CF.
The steps required for configuring the Web IDE are also mentioned in the following
Help document.
2. Developing the Application using Web-IDE
2.1 Creation of Multi-Target Application
Open your workspace and create a New -> Project from Template. Select "Multi-Target Application" from the list. Give a name of the application and proceed, this name is taken as the Application ID and a default application version is created. Before clicking on Finish, make sure you check "Use HTML5 Application Repository". This is required since your HTML5 applications are going to be deployed and consumed through the html repository service.
This creates 2 packages inside the application folder -
- appRouter - The approuter takes care of the authentication and routing of calls that are fired from the launchpad or the applications deployed along with the launchpad. The service calls that are not specific to any applications deployed along with the launchpad are expected to be defined here.To understand details of how approuter works, here is the github repository URL.
- ui_deployer - This is another node module application that takes care of putting the html5 content under this application folder and then deploying the content in the application repository.
This also creates a deployment descriptor, called mta.yaml which takes care of deploying the multi-target application.
2.2 Creation of IoT Application
Right click on the project name and create a New -> HTML5 Module inside this folder and select SAPUI5 Application which creates a placeholder for our IoT Application. Proceed and give a module name and namespace. The namespace needs to be unique for any application that is created and deployed on this space.
Proceed and finish completing this module. This creates a module which has a folder named webapp inside it. We will be replacing this folder by the IoT Application's webapp content.
This will create another package inside the project folder which contains the SAPUI5 Application. After this HTML5 Module is created, the Web IDE adds an entry into the deployment descriptor (mta.yaml) as well.
Let us create the IoT Application next -
Right click on the Workspace and create a New -> Project from Template and choose IoT Application. Click on Next and give a project name, namespace and Title. The namespace needs to be same as given in the HTML5 Module above since we will replace the content.
Click on Next and select the service
IOTAS-ADVANCEDLIST-THING-ODATA. To select the property sets, select the Thing Type for which this application is being created and select all the PSTs under this thing type. Click on Next. By default, all the pages in will be selected. Depending on the use case, user can uncheck the pages that are not required in the application. Clicking on Next gives an option to update the property bindings in the editor itself. Again, depending on a specific scenario user can update the property bindings and then proceed with the creation of this application.
Once this application is created, replace the webapp folder of HTML5 module which was created inside MTAR Application by the webapp folder created inside the IoT Application.
2.3 Creation of Launchpad Site
Right click on the project folder again and create a New -> SAP Fiori Launchpad Site Module and proceed with the creation.
This will create another package which contains the configuration of your SAP Fiori Launchpad Site. For example, details like the UI5 version to use, theme available, default theme, the tiles to be shown, Shell services to be used, etc are defined in this package.
2.4 Create cross navigation target in html5 app
Open the manifest.json in the code editor and make sure that the "_version" is "1.12.0" or above and the "sap.app._version" is "1.3.0" or above. The navigation target can be created in versions that are higher than "1.2.0" only. After this, switch to the descriptor editor of manifest.json and go to
"Navigation" tab and add a Semantic Object and Action. Refer the image below:
This entry also needs to be maintained in the CommonDataModel.json file located inside the portal-site folder under flp package.
Open the CommonDataModel.json file using Launchpad editor. You can see 2 tabs, Groups and Site Settings. Under Groups, there is a "Default Group Title" where user can configure tiles. You can click on "+" icon and add the inbound navigation that was defined in manifest.json in the previous step.
The application is ready to be built and deployed. However, there are some more changes which will be required to run this application, which we will go through in the below sections.
The title, subTitle can be added in the i18n properties file and proper text can be given for the same.
2.5 Build and Deploy
Right-click on the project and Build.
This creates a folder called "mta_archives" inside the project which contains the mtar which needs to be deployed. Right click on this mtar and deploy by entering the org and space details.
This will deploy the complete mtar including all the 4 modules and will create any services that are required for the deployment as mentioned in the mta.yaml file.
You can find the URL of the application in the console. Use that to launch this application. You can see the launchpad with one tile which you just configured.
2.6 Re-structuring the applications for efficient deployment
As explained in the above section, we have a total of 4 different modules created, which you can see in the mta.yaml. Each of these modules are for different purposes and the build and deployment of these modules takes around 5 minutes. Also, during each deployment the launchpad becomes unavailable and if multiple developers are working on the same launchpad, it causes downtime for everyone.
In this section, we try to de-couple the applications and re-structure it for an efficient deployment.
We will keep the approuter and the flp together, since these modules need not be deployed each and every time there are changes to the code.
Create a new folder in the project called, "
*_flp_approuter", just for easier understanding, and paste the folders of approuter and ui_deployer inside this folder, along with xs-security.json. Create a file called mta.yaml inside this folder. This new deployment descriptor is only for the approuter and flp.
Also, since there can be multiple ui applications, move the HTML5 application inside another folder called ui, for a better understanding of the structure.
This is how the application structure will look like after restructuring:
2.6.1 mta.yaml of flp_approuter
The approuter and flp module needs to be moved from the main yaml to the new yaml file created inside flp_approuter.
Note that, <<tenant_name>>, <<provider_space_identifier>> and <<iotae_service>> are just place holders that need to be replaced.
The host used below is just a standard that is usually followed, its not mandatory to use the same format as shown below. iotae_service is the instance name of the subscribed service from the provider space which is used to talk to different end-points available in Leonardo IoT.
ID: Sample
_schema-version: '3.1'
version: 0.0.1
modules:
- name: sample_appRouter
type: javascript.nodejs
path: sample_appRouter
parameters:
disk-quota: 256M
memory: 256M
requires:
- name: sample_html5_repo_runtime
- name: uaa_sample
- name: portal_resources_sample
- name: <<iotae_service>>
- name: sapui52
group: destinations
properties:
strictSSL: false
forwardAuthToken: true
name: sapui52
url: '~{url}'
- name: IOTAS_CONTROLS
group: destinations
properties:
strictSSL: false
forwardAuthToken: true
name: IOTAS_CONTROLS
url: '~{url}'
- name: flp_sample
type: com.sap.portal.content
path: flp
parameters:
stack: cflinuxfs3
memory: 128M
buildpack: 'https://github.com/cloudfoundry/nodejs-buildpack/releases/download/v1.6.39/nodejs-buildpack-cflinuxfs3-v1.6.39.zip'
execute-app: false
requires:
- name: portal_resources_sample
- name: uaa_sample
- name: sample_html5_repo_host
resources:
- name: sample_html5_repo_runtime
parameters:
service-plan: app-runtime
service: html5-apps-repo
type: org.cloudfoundry.managed-service
- name: sample_html5_repo_host
type: org.cloudfoundry.existing-service
- name: uaa_sample
parameters:
path: ./xs-security.json
service-plan: application
service: xsuaa
type: org.cloudfoundry.managed-service
- name: portal_resources_sample
parameters:
service-plan: standard
service: portal
type: org.cloudfoundry.managed-service
- name: sapui52
properties:
url: 'https://sapui5.hana.ondemand.com'
- name: <<iotae_service>>
type: org.cloudfoundry.existing-service
- name: IOTAS_CONTROLS
properties:
url: 'https://sapuiiot-stakeholder.cfapps.sap.hana.ondemand.com'
The URL of the IOTAS_CONTROLS that is mentioned here is for canary environment only. If you are deploying applications on eu10, use the URL as "
https://sapuiiot.cfapps.eu10.hana.ondemand.com", otherwise accessing the iot controls would give an error: 502 (Bad Gateway)
2.6.2 Update the main mta.yaml
The main mta.yaml only needs 2 modules, which are HTML5 app and ui_deployer. The following sample shows the what could be the possible content of this yaml file. If there is another HTML5 application added in this project, that also would be added just like the first HTML5 module.
Note that the html5-apps-repo service with plan app-host is used in the above yaml (inside flp_approuter) as an
existing-service, and not managed-service, which means, the ui_deployer (having this service as a managed-service) needs to be deployed before the deployment of approuter and flp.
ID: sampleapps
_schema-version: '3.1'
parameters:
deploy_mode: html5-repo
version: 0.0.1
modules:
- name: iotapplication
type: html5
path: ui/iotapplication
build-parameters:
builder: grunt
- name: sample_ui_deployer
type: com.sap.html5.application-content
path: sample_ui_deployer
requires:
- name: sample_html5_repo_host
build-parameters:
requires:
- name: iotapplication
artifacts:
- './*'
target-path: resources/iotapplication
resources:
- name: sample_html5_repo_host
parameters:
service-plan: app-host
service: html5-apps-repo
type: org.cloudfoundry.managed-service
2.7 Building and Deployment
The Web-IDE does not support the deployment of this structure directly, since there are 2 deployment descriptors. Due to this, we need to export this project and use another editor that can help with the building and deployment of this project.
To build these applications on your local system, there are couple of pre-requisites. Follow the below steps to build and deploy the mtars individually.
- Download and configure CLI plugin for Multi-Target Application Operation.
- Register CF Community Repository in CF CLI by executing the below command
cf add-plugin-repo CF-Community https://plugins.cloudfoundry.org
- Install the Plugin from CF Community Repository using below command
cf install-plugin multiapps
- Deploy the recently build mtar, by using the command
cf deploy <<multi_target_app.mtar>>
Follow the build and deployment process for both ui_deployer and flp_approuter.
2.8 Necessary changes in Application
After the application is built and deployed, if you try to access the tile by clicking on it, you will see a bunch of errors. There are few changes that are required to make this application work.
2.8.1 Changes in xs-app.json of HTML5 Application
Instead of using destinations in the xs-app.json, we can also use service end-points, which means each entry of xs-app.json will be modified as shown below:
{
"source": "^/IOTAS-ADVANCEDLIST-THING-ODATA/(.*)$",
"destination": "IOTAS-ADVANCEDLIST-THING-ODATA",
"target": "$1",
"csrfProtection": false
}
will be modified to
{
"source": "^/IOTAS-ADVANCEDLIST-THING-ODATA/(.*)",
"target": "$1",
"authenticationType": "xsuaa",
"service": "com.sap.leonardo.iot",
"endpoint": "advancedlist-thing-sap"
}
The end-points can be found from the service keys of the iotae service instance which is bound to the approuter. (represented in the manifest as <<iotae_service>>)
Also, the route which exists in the xs-app.json needs to remain at the end of all other routes. This entry is to serve the content inside the UI5 Application.
{
"source": "^(.*)$",
"target": "$1",
"service": "html5-apps-repo-rt",
"authenticationType": "xsuaa"
}
2.8.2 Changes in xs-app.json of Approuter
After adding the IOTAS_CONTROLS route in the xs-app of approuter, the json will look like below.
{
"welcomeFile": "/cp.portal",
"authenticationMethod": "route",
"logout": {
"logoutEndpoint": "/do/logout"
},
"routes": [{
"source": "^/resources/sap/ui/iot/(.*)$",
"destination": "IOTAS_CONTROLS",
"target": "/sap/ui/iot/$1",
"csrfProtection": false
}]
}
2.8.3 Accessing IoT Controls and Templates
After updating the routes, accessing of IoT controls is enabled, but there needs to be a register statement added in the Component.js of the HTML5 Application which will redirect the calls to these runtime controls to the route defined above.
In the Component.js add the following line at the beginning of this file:
jQuery.sap.registerModulePath("sap.ui.iot", "/resources/sap/ui/iot/");
Also, the following line needs to be removed from the manifest.json:
"sap.ui.iot": {}
This change is required since, the UI5 resources are loaded from the UI5 library by default and since the entry "sap.ui.iot" is maintained in the manifest.json, a call to load the library-preload.js will be fired on the ui5 library which will fail. This happens because manifest is loaded before Component.js. Hence, we add an entry in Component.js and remove this from the manifest.json for the IoT controls to load properly.
Once these changes are done, build and deploy both the multi-target applications again to see the latest changes. The flp and approuter need not be deployed every time. Any change done in the HTML5 application only affects the ui_deployer and thus, only that application needs to be deployed after changes.
Only changes that will be required after this would be specific to the customer scenarios and the user can make all such changes directly in the Web-IDE to run and test, after which the same content can be used to deploy to CF from the local setup that has been explained in this article.
All the changes are made in the following Github repository too for a sample application:
sample-iot-application
Please reply in the comments and feel free to drop in any feedback. I will be more than happy to make changes to this article so that it helps in the implementation of such IoT Applications.