Designing UI5 Apps as Business Solution for SAP Build Work Zone – Part 1

Estimated read time 32 min read

Content Navigation

Part 1: A simple UI5 app that runs in the SAP Build Work Zone Service (Current post)

Part 2: Multiple Apps with a Shared Reuse Library (Planned)

Part 3: Splitting bigger projects(Planned)

 

Introduction

This guide give you technical insights into UI5 apps in the SAP BTP that run in the SAP Build Work Zone service.
You will learn how to structure complex UI5 applications to avoid common pitfalls.
This is an updated version of my former blog series Designing UI5 Apps for SAP Launchpad Service (Parts 1 – 4). Technology has evolved and there is a new mechanism to integrate business solutions as content providers into the SAP Build Work Zone Service. Therefore, I have reworked the blog series to use the new methods.
You should already be familiar with:

SAPUI5 and UI5 ToolingSAP UI5 App DescriptorSAP Business Application StudioSAP Fiori toolsMulti Target Applications (MTA) especially the syntax of mta.yamlHTML5 Repository and Managed Application Router and xs-app.jsonSAP Authorization and Trust Management Service (XSUAA) and xs-security.jsonDestination service and destinationsDeveloping HTML5 Applications and Extensions

This guide will not go into details about the following:

Templating tools for UI5 projects and MTADeveloping service backends e.g., with CAPConfiguration of launchpad sitesOData and SAPSAP Fiori elements

All discussed samples are published in a Github repository.

Related Blogs

Using UI5 Libraries in CF approuter (Wouter Lemaire)SAP Fiori Development with SAP Business Application Studio (Yuval Morad)Achieve Separate Lifecycles for Managed Approuter Applications with SAP Business Application Studio (Yuval Morad)Cross-MTA Dependencies. Custom UI5 Library Reference Example. (Bradley Smith)Developing HTML5 Business Solutions as Content ProvidersDevelop a Multitenant CAP Application Following the SAP BTP Developer’s GuideSAP Build Work Zone: Federation of HTML5 Business Solutions

 

A Simple UI5 app that runs in the SAP Build Work Zone Service

This first post will focus on a simple deployment which only contains one standalone UI5 app that fetches data from a backend.
This app can run standalone, but it is also a Business Solution which can run in the SAP Fiori launchpad provided by SAP Build Work Zone. To integrate it in the launchpad it is a Content Provider for the Common Data Model (CDM). It defines a unique SAP Cloud Service name as key for the CDM content.

The sample code can be found in the Github repository.

Deployed Content

Let’s start by having a look at all the parts of an app deployment.

 

After deploying your application, you can find 4 service instances in your Cloud Foundry space and 2 destinations in your subaccount:

An XSUAA instance that controls security-relevant settings and defines authorization scopes for the application backend. It also controls the authentication to your app.An HTML5 Application Repository Service app-host containing an HTML5 app. The HTML5 repository takes care of storing and serving all the static content of your app. This includes all js, html and other files that form the runnable source code of your app. An app-host is a container for an atomic deployment and can contain multiple apps.
It contains:The app sources including the following highlighted files:A manifest.json as part of the UI5 app, which describes the app and specifies, for example, the app IDAn xs-app.json which defines routes of your app for example, to connect to your backendA cdm.json (Common Data Model), which defines how the app will be integrated into the launchpad by defining apps, catalogs, groups, roles, etc.Credentials of the XSUAA instance. This is used at runtime to connect the XSUAA to the managed app router.
If this is present, the app will automatically be connected to the managed app router and served from it.
Formerly it has been required to create destinations for the XSUAA and the app-host to make it available to the managed app router. However, the new approach simplifies this.An HTML5 Application Repository Service app-runtime which is only needed to provide access to the cdm.json for the integration of the app into the launchpad2 destinations in the subaccount for the integration into the launchpad:A design time destination which contains the credentials of the HTML5 app-runtime instance and a URL to read the cdm.jsonA runtime destination which contains a URL to access the app at runtimeA destination service instance with 2 destinations. It does not its contain own destinations and is purely required during deployment.

MTA Project Structure

The deployment of this is described in the mta.yaml of the project. It is structured as follows:

4 resources that represent the created service instances. They are all created by this MTA and are therefore managed services.1 module for the UI5 app. Most build steps are defined in the package.json. The build result is a zip file.2 modules that deploy application content to the service instances:The HTML5 App Deployer that pushes the app to the app-host. It deploys the build results of the app and the cdm.json and binds the XSUAA to it. It also creates a simple destination for the consumed OData ServiceThe destination deployer creates the destinations. It requires the destination service resource as content target and the app-runtime to fetch the service credentials.
The configuration defines the destinations and adds some additional properties.

The HTML5 App Deployer collects the zip of the UI5 app module and the cdm.json. During deployment it pushes them to the app-host. It requires the app-host resource as the content target and additionally the XSUAA instance.
During deployment, the deploy service will create a service key for the XSUAA and push the credentials to the app-host.

– name: btp-samples-cdm-simple-app-app-content
type: com.sap.application.content
path: .
requires:
– name: btp-samples-cdm-simple-app-repo-host
parameters:
content-target: true
– name: btp-samples-cdm-simple-app-uaa

You can declare destinations bound to this app-host as part of the parameters. Here a destination for the simple OData service (northwind) is provided. Formerly destinations could only be provided as account-level destinations or via instances of the destination service. This new option allows you to deploy a self-contained app-host.

 

parameters:
config:
destinations:
– name: northwind
url: https://services.odata.org/V3/Northwind/Northwind.svc/

Under build-parameters it declares a build dependency to the UI5 app to include the produced zip and additionally provides custom build steps to include the cdm.json file.

build-parameters:
builder: custom
commands:
– mkdir -p resources
– cp workzone/cdm.json resources/cdm.json
build-result: resources
requires:
– name: btpsamplescdmsimpleapp
artifacts:
– btpsamplescdmsimpleapp.zip
target-path: resources/

The module of the app itself configures the build via node.js commands.

– name: btpsamplescdmsimpleapp
type: html5
path: simple.app
build-parameters:
build-result: dist
builder: custom
commands:
– npm install
– npm run build:cf
supported-platforms: []

The XSUAA resource includes the xs-security.json, which can define authorization scopes and roles:

– name: btp-samples-cdm-simple-app-uaa
type: org.cloudfoundry.managed-service
parameters:
path: ./xs-security.json
service: xsuaa
service-plan: application
service-name: btp-samples-cdm-simple-app-xsuaa-srv

The configuration of the destination resource creates a simple hardcoded destination for the launchpad runtime integration:
NOTE: Please replace the placeholder {YOURDOMAIN} with the tenant subdomain of your subaccount. Currently deploy service does not offer to fill this automatically.
Formerly this service had to be configured with HTML5Runtime_enabled: true to enable the consumption by managed app router. However, this is no longer needed. Also, the destination is now created on subaccount level and not on instance level because the SAP Build Work Zone integration can only use subaccount destinations.

– name: btp-samples-cdm-simple-app-dest-srv
type: org.cloudfoundry.managed-service
parameters:
config:
init_data:
subaccount:
destinations:
– Authentication: NoAuthentication
Name: btp-samples-cdm-simple-app-rt
ProxyType: Internet
Type: HTTP
URL: https://{YOURDOMAIN}.launchpad.${default-domain}
existing_destinations_policy: update
version: 1.0.0
service: destination
service-name: btp-samples-cdm-simple-app-dest-srv
service-plan: lite

The destination deployer module requires the destination service instance as target module and the HTML5 app-runtime instance. It specifies creating service keys which will provide the credentials for the destinations. This is only needed to get credentials for deployment as the destinations are created on subaccount level.

– name: btp-samples-cdm-simple-app-dest-content
type: com.sap.application.content
requires:
– name: btp-samples-cdm-simple-app-dest-srv
parameters:
content-target: true
– name: btp-samples-cdm-simple-app-repo-runtime
parameters:
service-key:
name: btp-samples-cdm-simple-app-repo-runtime-key

Then it defines the destinations for the launchpad runtime integration to be created in the sub account.
Here the value of the ServiceInstanceName property is the instance name and not the MTA resource name as it is the case above.
The URL overrides the URL from the service instance because it appends the SAP Cloud Service name of the business solution which is the key to retrieve the CDM content:

parameters:
content:
subaccount:
destinations:
– Name: btp-samples-cdm-simple-app-dt
ServiceInstanceName: btp-samples-cdm-simple-app-html5-rt-srv
ServiceKeyName: btp-samples-cdm-simple-app-repo-runtime-key
URL: https://html5-apps-repo-rt.${default-domain}/applications/cdm/btp.samples.cdm.simple.app
existing_destinations_policy: ignore
build-parameters:
no-source: true

The UI5 App

Build

The UI5 app is built with UI5 Tooling. The build is controlled via the package.json and the ui5-deploy.yaml and produces a zip for the HTML5 App deployer module packager.

Routings

There is an xs-app.json file that defines routings to backend services.
Here the simple OData service path is forwarded via the northwind destination, which is created by the MTA, without any authentication.
Usually you would connect it to an SAP BTP cloud service and define an additional authentication flow like OAuth2UserTokenExchange.

{
“welcomeFile”: “/index.html”,
“authenticationMethod”: “route”,
“logout”: {
“logoutEndpoint”: “/logout”,
“logoutPage”: “/logout-page.html”
},
“routes”: [
{
“source”: “^/northwind/(.*)$”,
“target”: “/$1”,
“authenticationType”: “none”,
“destination”: “northwind”
},
{
“source”: “^(.*)$”,
“target”: “$1”,
“service”: “html5-apps-repo-rt”,
“authenticationType”: “xsuaa”
}
]
}

There is a special route for the index.html which is also specified as welcomeFile. This route disables browser caching to ensure the page is reloaded and an authentication flow can be triggered if necessary. This is only needed for running standalone.

{
“source”: “^/index.html”,
“service”: “html5-apps-repo-rt”,
“cacheControl”: “no-cache, no-store, must-revalidate”
},

Another special route is for the logout-page.html which is also used in the logout configuration. It disables authentication for the page to prevent another login flow from being triggered after logout.

{
“source”: “^/logout-page.html$”,
“service”: “html5-apps-repo-rt”,
“authenticationType”: “none”
},

All other content is served from the HTML5 repository without further logic

{
“source”: “^(.*)$”,
“target”: “$1”,
“service”: “html5-apps-repo-rt”,
“authenticationType”: “xsuaa”
}

You can test the app locally via the UI5 Tooling. It provides a local middleware which is configured in ui5.yaml.
Here similar routings are configured. For example, the same OData service is connected. See Use Custom Middlewares  for more details.

server:
customMiddleware:
– name: fiori-tools-proxy
afterMiddleware: compression
configuration:
ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted
backend:
– path: /northwind
pathPrefix: /
url: https://services.odata.org/V3/Northwind/Northwind.svc/
ui5:
path:
– /resources
– /test-resources
url: https://ui5.sap.com
version: # The UI5 version, for instance, 1.78.1. Empty means latest version

To start the local test just run the start script in the package.json.
There is also a start-local script which runs the app in a local launchpad.

App Descriptor

It has a manifest.json file that defines a unique sap.app/id and application sap.app/type for it.
Having unique IDs for all apps in your subaccount is important to avoid conflicts.

“sap.app”: {
“id”: “btp.samples.cdm.simple.app”,
“type”: “application”,
“i18n”: “i18n/i18n.properties”,
“title”: “{{appTitle}}”,
“description”: “{{appDescription}}”,
“applicationVersion”: {
“version”: “1.0.0”
}
}

An entry under sap.app/crossNavigation/inbounds defines the tile and navigation for the launchpad. It is important to use unique values here to avoid conflicts with other apps which are deployed in the same subaccount.

“crossNavigation”: {
“inbounds”: {
“btp-samples-cdm-simple-app-inbound”: {
“signature”: {
“parameters”: {},
“additionalParameters”: “allowed”
},
“semanticObject”: “simpleApp”,
“action”: “display”,
“title”: “{{flpTitle}}”,
“subTitle”: “{{flpSubtitle}}”
}
}
}

The OData service URL is specified under sap.app/dataSources. It points to the routed source defined in xs-app.json. Please note that this is a relative path, which is resolved relative to the app. The reason for this is explained below under Automatic URL resolution.

“dataSources”: {
“mainService”: {
“uri”: “northwind”,
“type”: “OData”
}
}

It also specifies sap.cloud/service with the same service name as specified for the design time destinations in the mta.yaml.
Note that this has a different meaning than the sap.app/id although it has the same value in this sample. This uniquely identifies your business solution for the SAP Build Work Zone service. It must be unique
Currently it is required to set public: true>

“sap.cloud”: {
“public”: true,
“service”: “btp.samples.cdm.simple.app”
}

The Common Data Model

The CDM data is defined in the cdm.json. It defines 3 main entities:

A catalog which can be browsed in the app finder tool of the launchpad. It lists the launchable tiles of the app by pointing to the defined inbound in the manifest.json.”viz”: [
{
“appId”: “btp.samples.cdm.simple.app”,
“vizId”: “btp-samples-cdm-simple-app-inbound”
}
]A group which is shown on the launchpad directly. It also lists the app as inbound.A role which includes the app, the catalog, and the group. There will be a corresponding role collection created automatically which can be assigned to users.

Note: Soon groups will be replaced with pages and spaces, so this content has to be updated.

 

Running the Deployed App

Deploying the App

To deploy the app, you have to build the MTA and then deploy it to your Cloud Foundry space.
SAP Business Application Studio simplifies this for you because the build tool and the deployer are already set up.
The deployment itself will run quite fast because only service instances and content are deployed. There is no CF application at all.

Running Standalone

After the deployment, the app can be run standalone from its index.html via the managed approuter. You can find it in the SAP BTP cockpit on the HTML5 Applications page under your subaccount. Its URL will look like this:

https://<tenant subdomain>.launchpad.cfapps.<landscape host>/<destination instance GUID>.<service name (. removed)>.<App ID (. removed)>-<App version>/index.html
The app-host instance GUID and app version are optional. Example for a URL:
https://xyz.launchpad.cfapps.eu10.ondemand.com/btpsamplescdmsimpleapp.btpsamplescdmsimpleapp-1.0.0/index.html

All routings in xs-app.json are relative to this. For example, the OData service is under
https://uicsconsumertest.launchpad.cfapps.sap.hana.ondemand.com/btpsamplescdmsimpleapp.btpsamplescdmsimpleapp-1.0.0/northwind/
There is no way to install a routing directly in the app router root. Therefore, it is important that you always use paths that are relative to the app location.

The index.html which is located next to the app defines the resource mapping for it and points to the same folder:

<script id=”sap-ui-bootstrap”
src=”https://ui5.sap.com/resources/sap-ui-cachebuster/sap-ui-core.js”
data-sap-ui-resourceroots='{
“btp.samples.cdm.simple.app”: “./”
}’
data-sap-ui-libraries=”sap.m” >
</script>

The index.html loads UI5 via a public CDN URL which has cachebuster enabled. This ensures the best startup performance, because the resources will be fetched from the closest location and cached in the browser cache.

Automatic URL resolution

Inside the manifest.json the data source path is automatically resolved relative to the app.

Beware that there are other locations where this automatic resolution does not happen.
For example, this applies when you do an AJAX request via coding or specify a URL in a control property like the src of an image.
Our app contains an image control in the header area that shows a logo from a local file to demonstrate this.
Here the browser would resolve a URL relative to the document location which is the index.html. Using simple hardcoded URLs works only, as long as the app is located next to the index.html.
I’ll explain why this configuration can cause issues and how to resolve them below under Calculating URLs for application resources correctly.

Running in the SAP Build Work Zone Service

To run the app in the SAP Build Work Zone Service, you must configure it first and assign it to a user role. You can find more details on the needed steps here:

Manage Content Providers (HTML5 Business Solutions): Register the content provider of the business solution.
Use the destinations btp-samples-cdm-simple-app-dt for Design-Time and btp-samples-cdm-simple-app-rt for Runtime.
After the import has been completed, you can find the CDM content in the Content Manager.Assign Roles to Site and Users to Roles: Assign the Role BTP Sample Simple app to your site and assign the corresponding role collection to your user.

After everything is set up the app can be launched directly using a URL with this pattern:
https://<tenant subdomain>.launchpad.cfapps.<landscape host>/site?siteId=<site ID>#<semantic object>-<action>, for example:
https://xyz.launchpad.cfapps.eu10.hana.ondemand.com/site?siteId=df526ffe-2a32-464e-8fc5-5d5db908334e#cdmsimpleApp-display

 

As you can see, the URL points to a completely different path than where the app can be found. Also, the startup HTML page does not contain the resource mapping as in the standalone case.
In order to launch the app, the platform provides all needed URLs. This information is retrieved via a request which looks like
/<SAP Cloud Service (. removed)>.fdcCache_<App-Host Id (- replaced by _)>/~<cache token>~/apps/<sap.app/id>/ui5AppInfo.json
For example, it could be /btpsamplescdmsimpleapp.fdcCache_0463f3b8_2b98_4506_9f2a_3ba694119e7f/~101024080424+0000~/apps/btp.samples.cdm.simple.app/ui5AppInfo.json
You can find this in the network trace when starting the app.
In this data you can find a similar URL as when running the app standalone, but it has an additional cache token, which is the unique deploy ID of the content in the HTML5 app-host.

{
“name”: “btp.samples.cdm.simple.app”,
“url”: “/0463f3b8-2b98-4506-9f2a-3ba694119e7f.btp-samples-cdm-simple-app.btpsamplescdmsimpleapp/~99b1ee12-60e7-4db6-9657-e19f87f397a1~/”,
“manifest”: true,
“asyncHints”: {
“libs”: [{
“name”: “sap.f”,
“lazy”: false
}, {
“name”: “sap.m”,
“lazy”: false
}, {
“name”: “sap.ui.fl”,
“lazy”: false
}],
“components”: []
},
“messages”: [],
“version”: “1.0.0”
}

Calculating URLs for application resources correctly

As mentioned before, hardcoded URLs at some places would not be resolved correctly. For example, the data source URL in the manifest.json is resolved relative to the source folder of the application automatically. However, this does not happen everywhere. For example, URLs in views are not resolved by UI5 automatically. If they are hard coded they would be rendered without changes and the browser would resolve them relative to the document location in the address bar. This would not result in the correct URL for fetching the logo image.
Therefore the URL is calculated relative to the application namespace in the Master.controller.js as follows:

sap.ui.require.toUrl(“btp/samples/simple/app/images/logo_ui5.png”)

You can apply the same principle to any other call you make, for example any REST call that you trigger from your coding.
This way, your app is independent of the location from which users launch it.

 

Next Steps

Now you are ready to plan your first simple app project.
However, usually you need more apps and reuse components.
Stay curious. Part 2 of this blog is just around the corner.

 

​ Content NavigationPart 1: A simple UI5 app that runs in the SAP Build Work Zone Service (Current post)Part 2: Multiple Apps with a Shared Reuse Library (Planned)Part 3: Splitting bigger projects(Planned) IntroductionThis guide give you technical insights into UI5 apps in the SAP BTP that run in the SAP Build Work Zone service.You will learn how to structure complex UI5 applications to avoid common pitfalls.This is an updated version of my former blog series Designing UI5 Apps for SAP Launchpad Service (Parts 1 – 4). Technology has evolved and there is a new mechanism to integrate business solutions as content providers into the SAP Build Work Zone Service. Therefore, I have reworked the blog series to use the new methods.You should already be familiar with:SAPUI5 and UI5 ToolingSAP UI5 App DescriptorSAP Business Application StudioSAP Fiori tools- Multi Target Applications (MTA) especially the syntax of mta.yamlHTML5 Repository and Managed Application Router and xs-app.jsonSAP Authorization and Trust Management Service (XSUAA) and xs-security.jsonDestination service and destinationsDeveloping HTML5 Applications and ExtensionsThis guide will not go into details about the following:Templating tools for UI5 projects and MTADeveloping service backends e.g., with CAPConfiguration of launchpad sitesOData and SAPSAP Fiori elementsAll discussed samples are published in a Github repository.Related BlogsUsing UI5 Libraries in CF approuter (Wouter Lemaire)SAP Fiori Development with SAP Business Application Studio (Yuval Morad)Achieve Separate Lifecycles for Managed Approuter Applications with SAP Business Application Studio (Yuval Morad)Cross-MTA Dependencies. Custom UI5 Library Reference Example. (Bradley Smith)Developing HTML5 Business Solutions as Content ProvidersDevelop a Multitenant CAP Application Following the SAP BTP Developer’s GuideSAP Build Work Zone: Federation of HTML5 Business Solutions A Simple UI5 app that runs in the SAP Build Work Zone ServiceThis first post will focus on a simple deployment which only contains one standalone UI5 app that fetches data from a backend.This app can run standalone, but it is also a Business Solution which can run in the SAP Fiori launchpad provided by SAP Build Work Zone. To integrate it in the launchpad it is a Content Provider for the Common Data Model (CDM). It defines a unique SAP Cloud Service name as key for the CDM content.The sample code can be found in the Github repository.Deployed ContentLet’s start by having a look at all the parts of an app deployment. After deploying your application, you can find 4 service instances in your Cloud Foundry space and 2 destinations in your subaccount:An XSUAA instance that controls security-relevant settings and defines authorization scopes for the application backend. It also controls the authentication to your app.An HTML5 Application Repository Service app-host containing an HTML5 app. The HTML5 repository takes care of storing and serving all the static content of your app. This includes all js, html and other files that form the runnable source code of your app. An app-host is a container for an atomic deployment and can contain multiple apps.It contains:The app sources including the following highlighted files:A manifest.json as part of the UI5 app, which describes the app and specifies, for example, the app IDAn xs-app.json which defines routes of your app for example, to connect to your backendA cdm.json (Common Data Model), which defines how the app will be integrated into the launchpad by defining apps, catalogs, groups, roles, etc.Credentials of the XSUAA instance. This is used at runtime to connect the XSUAA to the managed app router.If this is present, the app will automatically be connected to the managed app router and served from it.Formerly it has been required to create destinations for the XSUAA and the app-host to make it available to the managed app router. However, the new approach simplifies this.An HTML5 Application Repository Service app-runtime which is only needed to provide access to the cdm.json for the integration of the app into the launchpad2 destinations in the subaccount for the integration into the launchpad:A design time destination which contains the credentials of the HTML5 app-runtime instance and a URL to read the cdm.jsonA runtime destination which contains a URL to access the app at runtimeA destination service instance with 2 destinations. It does not its contain own destinations and is purely required during deployment.MTA Project StructureThe deployment of this is described in the mta.yaml of the project. It is structured as follows:4 resources that represent the created service instances. They are all created by this MTA and are therefore managed services.1 module for the UI5 app. Most build steps are defined in the package.json. The build result is a zip file.2 modules that deploy application content to the service instances:The HTML5 App Deployer that pushes the app to the app-host. It deploys the build results of the app and the cdm.json and binds the XSUAA to it. It also creates a simple destination for the consumed OData ServiceThe destination deployer creates the destinations. It requires the destination service resource as content target and the app-runtime to fetch the service credentials.The configuration defines the destinations and adds some additional properties.The HTML5 App Deployer collects the zip of the UI5 app module and the cdm.json. During deployment it pushes them to the app-host. It requires the app-host resource as the content target and additionally the XSUAA instance.During deployment, the deploy service will create a service key for the XSUAA and push the credentials to the app-host.- name: btp-samples-cdm-simple-app-app-content
type: com.sap.application.content
path: .
requires:
– name: btp-samples-cdm-simple-app-repo-host
parameters:
content-target: true
– name: btp-samples-cdm-simple-app-uaaYou can declare destinations bound to this app-host as part of the parameters. Here a destination for the simple OData service (northwind) is provided. Formerly destinations could only be provided as account-level destinations or via instances of the destination service. This new option allows you to deploy a self-contained app-host. parameters:
config:
destinations:
– name: northwind
url: https://services.odata.org/V3/Northwind/Northwind.svc/Under build-parameters it declares a build dependency to the UI5 app to include the produced zip and additionally provides custom build steps to include the cdm.json file. build-parameters:
builder: custom
commands:
– mkdir -p resources
– cp workzone/cdm.json resources/cdm.json
build-result: resources
requires:
– name: btpsamplescdmsimpleapp
artifacts:
– btpsamplescdmsimpleapp.zip
target-path: resources/The module of the app itself configures the build via node.js commands.- name: btpsamplescdmsimpleapp
type: html5
path: simple.app
build-parameters:
build-result: dist
builder: custom
commands:
– npm install
– npm run build:cf
supported-platforms: []The XSUAA resource includes the xs-security.json, which can define authorization scopes and roles:- name: btp-samples-cdm-simple-app-uaa
type: org.cloudfoundry.managed-service
parameters:
path: ./xs-security.json
service: xsuaa
service-plan: application
service-name: btp-samples-cdm-simple-app-xsuaa-srvThe configuration of the destination resource creates a simple hardcoded destination for the launchpad runtime integration:NOTE: Please replace the placeholder {YOURDOMAIN} with the tenant subdomain of your subaccount. Currently deploy service does not offer to fill this automatically.Formerly this service had to be configured with HTML5Runtime_enabled: true to enable the consumption by managed app router. However, this is no longer needed. Also, the destination is now created on subaccount level and not on instance level because the SAP Build Work Zone integration can only use subaccount destinations.- name: btp-samples-cdm-simple-app-dest-srv
type: org.cloudfoundry.managed-service
parameters:
config:
init_data:
subaccount:
destinations:
– Authentication: NoAuthentication
Name: btp-samples-cdm-simple-app-rt
ProxyType: Internet
Type: HTTP
URL: https://{YOURDOMAIN}.launchpad.${default-domain}
existing_destinations_policy: update
version: 1.0.0
service: destination
service-name: btp-samples-cdm-simple-app-dest-srv
service-plan: liteThe destination deployer module requires the destination service instance as target module and the HTML5 app-runtime instance. It specifies creating service keys which will provide the credentials for the destinations. This is only needed to get credentials for deployment as the destinations are created on subaccount level.- name: btp-samples-cdm-simple-app-dest-content
type: com.sap.application.content
requires:
– name: btp-samples-cdm-simple-app-dest-srv
parameters:
content-target: true
– name: btp-samples-cdm-simple-app-repo-runtime
parameters:
service-key:
name: btp-samples-cdm-simple-app-repo-runtime-keyThen it defines the destinations for the launchpad runtime integration to be created in the sub account.Here the value of the ServiceInstanceName property is the instance name and not the MTA resource name as it is the case above.The URL overrides the URL from the service instance because it appends the SAP Cloud Service name of the business solution which is the key to retrieve the CDM content: parameters:
content:
subaccount:
destinations:
– Name: btp-samples-cdm-simple-app-dt
ServiceInstanceName: btp-samples-cdm-simple-app-html5-rt-srv
ServiceKeyName: btp-samples-cdm-simple-app-repo-runtime-key
URL: https://html5-apps-repo-rt.${default-domain}/applications/cdm/btp.samples.cdm.simple.app
existing_destinations_policy: ignore
build-parameters:
no-source: trueThe UI5 AppBuildThe UI5 app is built with UI5 Tooling. The build is controlled via the package.json and the ui5-deploy.yaml and produces a zip for the HTML5 App deployer module packager.RoutingsThere is an xs-app.json file that defines routings to backend services.Here the simple OData service path is forwarded via the northwind destination, which is created by the MTA, without any authentication.Usually you would connect it to an SAP BTP cloud service and define an additional authentication flow like OAuth2UserTokenExchange.{
“welcomeFile”: “/index.html”,
“authenticationMethod”: “route”,
“logout”: {
“logoutEndpoint”: “/logout”,
“logoutPage”: “/logout-page.html”
},
“routes”: [
{
“source”: “^/northwind/(.*)$”,
“target”: “/$1”,
“authenticationType”: “none”,
“destination”: “northwind”
},
{
“source”: “^(.*)$”,
“target”: “$1”,
“service”: “html5-apps-repo-rt”,
“authenticationType”: “xsuaa”
}
]
}There is a special route for the index.html which is also specified as welcomeFile. This route disables browser caching to ensure the page is reloaded and an authentication flow can be triggered if necessary. This is only needed for running standalone. {
“source”: “^/index.html”,
“service”: “html5-apps-repo-rt”,
“cacheControl”: “no-cache, no-store, must-revalidate”
},Another special route is for the logout-page.html which is also used in the logout configuration. It disables authentication for the page to prevent another login flow from being triggered after logout. {
“source”: “^/logout-page.html$”,
“service”: “html5-apps-repo-rt”,
“authenticationType”: “none”
}, All other content is served from the HTML5 repository without further logic {
“source”: “^(.*)$”,
“target”: “$1”,
“service”: “html5-apps-repo-rt”,
“authenticationType”: “xsuaa”
}You can test the app locally via the UI5 Tooling. It provides a local middleware which is configured in ui5.yaml.Here similar routings are configured. For example, the same OData service is connected. See Use Custom Middlewares  for more details.server:
customMiddleware:
– name: fiori-tools-proxy
afterMiddleware: compression
configuration:
ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted
backend:
– path: /northwind
pathPrefix: /
url: https://services.odata.org/V3/Northwind/Northwind.svc/
ui5:
path:
– /resources
– /test-resources
url: https://ui5.sap.com
version: # The UI5 version, for instance, 1.78.1. Empty means latest versionTo start the local test just run the start script in the package.json.There is also a start-local script which runs the app in a local launchpad.App DescriptorIt has a manifest.json file that defines a unique sap.app/id and application sap.app/type for it.Having unique IDs for all apps in your subaccount is important to avoid conflicts. “sap.app”: {
“id”: “btp.samples.cdm.simple.app”,
“type”: “application”,
“i18n”: “i18n/i18n.properties”,
“title”: “{{appTitle}}”,
“description”: “{{appDescription}}”,
“applicationVersion”: {
“version”: “1.0.0”
}
}An entry under sap.app/crossNavigation/inbounds defines the tile and navigation for the launchpad. It is important to use unique values here to avoid conflicts with other apps which are deployed in the same subaccount. “crossNavigation”: {
“inbounds”: {
“btp-samples-cdm-simple-app-inbound”: {
“signature”: {
“parameters”: {},
“additionalParameters”: “allowed”
},
“semanticObject”: “simpleApp”,
“action”: “display”,
“title”: “{{flpTitle}}”,
“subTitle”: “{{flpSubtitle}}”
}
}
}The OData service URL is specified under sap.app/dataSources. It points to the routed source defined in xs-app.json. Please note that this is a relative path, which is resolved relative to the app. The reason for this is explained below under Automatic URL resolution.”dataSources”: {
“mainService”: {
“uri”: “northwind”,
“type”: “OData”
}
}It also specifies sap.cloud/service with the same service name as specified for the design time destinations in the mta.yaml.Note that this has a different meaning than the sap.app/id although it has the same value in this sample. This uniquely identifies your business solution for the SAP Build Work Zone service. It must be uniqueCurrently it is required to set public: true>”sap.cloud”: {
“public”: true,
“service”: “btp.samples.cdm.simple.app”
}The Common Data ModelThe CDM data is defined in the cdm.json. It defines 3 main entities:A catalog which can be browsed in the app finder tool of the launchpad. It lists the launchable tiles of the app by pointing to the defined inbound in the manifest.json.”viz”: [
{
“appId”: “btp.samples.cdm.simple.app”,
“vizId”: “btp-samples-cdm-simple-app-inbound”
}
]A group which is shown on the launchpad directly. It also lists the app as inbound.A role which includes the app, the catalog, and the group. There will be a corresponding role collection created automatically which can be assigned to users.Note: Soon groups will be replaced with pages and spaces, so this content has to be updated. Running the Deployed AppDeploying the AppTo deploy the app, you have to build the MTA and then deploy it to your Cloud Foundry space.SAP Business Application Studio simplifies this for you because the build tool and the deployer are already set up.The deployment itself will run quite fast because only service instances and content are deployed. There is no CF application at all.Running StandaloneAfter the deployment, the app can be run standalone from its index.html via the managed approuter. You can find it in the SAP BTP cockpit on the HTML5 Applications page under your subaccount. Its URL will look like this:https://<tenant subdomain>.launchpad.cfapps.<landscape host>/<destination instance GUID>.<service name (. removed)>.<App ID (. removed)>-<App version>/index.htmlThe app-host instance GUID and app version are optional. Example for a URL:https://xyz.launchpad.cfapps.eu10.ondemand.com/btpsamplescdmsimpleapp.btpsamplescdmsimpleapp-1.0.0/index.htmlAll routings in xs-app.json are relative to this. For example, the OData service is underhttps://uicsconsumertest.launchpad.cfapps.sap.hana.ondemand.com/btpsamplescdmsimpleapp.btpsamplescdmsimpleapp-1.0.0/northwind/There is no way to install a routing directly in the app router root. Therefore, it is important that you always use paths that are relative to the app location.The index.html which is located next to the app defines the resource mapping for it and points to the same folder:<script id=”sap-ui-bootstrap”
src=”https://ui5.sap.com/resources/sap-ui-cachebuster/sap-ui-core.js”
data-sap-ui-resourceroots='{
“btp.samples.cdm.simple.app”: “./”
}’
data-sap-ui-libraries=”sap.m” >
</script>The index.html loads UI5 via a public CDN URL which has cachebuster enabled. This ensures the best startup performance, because the resources will be fetched from the closest location and cached in the browser cache.Automatic URL resolutionInside the manifest.json the data source path is automatically resolved relative to the app.Beware that there are other locations where this automatic resolution does not happen.For example, this applies when you do an AJAX request via coding or specify a URL in a control property like the src of an image.Our app contains an image control in the header area that shows a logo from a local file to demonstrate this.Here the browser would resolve a URL relative to the document location which is the index.html. Using simple hardcoded URLs works only, as long as the app is located next to the index.html.I’ll explain why this configuration can cause issues and how to resolve them below under Calculating URLs for application resources correctly.Running in the SAP Build Work Zone ServiceTo run the app in the SAP Build Work Zone Service, you must configure it first and assign it to a user role. You can find more details on the needed steps here:Manage Content Providers (HTML5 Business Solutions): Register the content provider of the business solution.Use the destinations btp-samples-cdm-simple-app-dt for Design-Time and btp-samples-cdm-simple-app-rt for Runtime.After the import has been completed, you can find the CDM content in the Content Manager.Assign Roles to Site and Users to Roles: Assign the Role BTP Sample Simple app to your site and assign the corresponding role collection to your user.After everything is set up the app can be launched directly using a URL with this pattern:https://<tenant subdomain>.launchpad.cfapps.<landscape host>/site?siteId=<site ID>#<semantic object>-<action>, for example:https://xyz.launchpad.cfapps.eu10.hana.ondemand.com/site?siteId=df526ffe-2a32-464e-8fc5-5d5db908334e#cdmsimpleApp-display As you can see, the URL points to a completely different path than where the app can be found. Also, the startup HTML page does not contain the resource mapping as in the standalone case.In order to launch the app, the platform provides all needed URLs. This information is retrieved via a request which looks like/<SAP Cloud Service (. removed)>.fdcCache_<App-Host Id (- replaced by _)>/~<cache token>~/apps/<sap.app/id>/ui5AppInfo.jsonFor example, it could be /btpsamplescdmsimpleapp.fdcCache_0463f3b8_2b98_4506_9f2a_3ba694119e7f/~101024080424+0000~/apps/btp.samples.cdm.simple.app/ui5AppInfo.jsonYou can find this in the network trace when starting the app.In this data you can find a similar URL as when running the app standalone, but it has an additional cache token, which is the unique deploy ID of the content in the HTML5 app-host.{
“name”: “btp.samples.cdm.simple.app”,
“url”: “/0463f3b8-2b98-4506-9f2a-3ba694119e7f.btp-samples-cdm-simple-app.btpsamplescdmsimpleapp/~99b1ee12-60e7-4db6-9657-e19f87f397a1~/”,
“manifest”: true,
“asyncHints”: {
“libs”: [{
“name”: “sap.f”,
“lazy”: false
}, {
“name”: “sap.m”,
“lazy”: false
}, {
“name”: “sap.ui.fl”,
“lazy”: false
}],
“components”: []
},
“messages”: [],
“version”: “1.0.0”
}Calculating URLs for application resources correctlyAs mentioned before, hardcoded URLs at some places would not be resolved correctly. For example, the data source URL in the manifest.json is resolved relative to the source folder of the application automatically. However, this does not happen everywhere. For example, URLs in views are not resolved by UI5 automatically. If they are hard coded they would be rendered without changes and the browser would resolve them relative to the document location in the address bar. This would not result in the correct URL for fetching the logo image.Therefore the URL is calculated relative to the application namespace in the Master.controller.js as follows:sap.ui.require.toUrl(“btp/samples/simple/app/images/logo_ui5.png”)You can apply the same principle to any other call you make, for example any REST call that you trigger from your coding.This way, your app is independent of the location from which users launch it. Next StepsNow you are ready to plan your first simple app project.However, usually you need more apps and reuse components.Stay curious. Part 2 of this blog is just around the corner.   Read More Technology Blogs by SAP articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author