Skip to Content
Technical Articles

Understanding the nuts and bolts of SAP Fiori Development in the Cloud Foundry Environment

In this post, I demonstrate how existing SAPUI5 apps can be seamlessly integrated into the Fiori Launchpad on Cloud Foundry. This integration will go beyond just embedding the web app but also include the usage of the UI5 Flexibility Services.

Updates:

23rd July: UI5 flexibility for key users is now available on the trial landscape as well.

22nd September: Added paragraph for SaaS subscriptions

I already wrote about the integration of non-ui5 web apps in the Fiori Launchpad in a previous #CloudFoundryFun post. With that approach, a website or web app can be embedded in an iframe into the Launchpad. But that also brings a disadvantage; the iframe detaches the embedded web app from the Launchpad. Without this connection, the web app cannot use features of the Shell control or the UI5 Flexibility services. If you want to use these features, you’ll need to implement the web app with SAPUI5 or reuse the Fiori Element templates (sap.fe.templates).

Tile%20of%20the%20sample%20app%20in%20the%20FLP%20Sandbox

Tile of the demo app in the Fiori Launchpad

There is already a great post that explains all the necessary steps to create such an application using the SAP Web IDE. And you can use the easy-ui5 generator to create a similar app without having to deal with boilerplate code. This can be done with the SAP Business Application Studio or any other local IDE. 

This post, one the other hand, focuses on this boilerplate code. It will explain all the components and snippets that differentiate a Fiori Launchpad application from a regular SAPUI5 app – in other words: What is needed to convert a SAPUI5 web app to a Fiori Launchpad app. My friend and colleague DJ Adams invited me to his show #HandsOnSAPDev where I spoke about the same topic; you can find the recording on YouTube.

 

My%20guest%20appearance%20at%20%23HandsOnSAPDev

My guest appearance at #HandsOnSAPDev

 

The Fiori Launchpad

The SAP Fiori launchpad is a shell that hosts SAP Fiori apps and provides the apps with services such as navigation, personalization, embedded support, and application configuration.

To efficiently implement Fiori apps, developers need a (sandbox) system that they can use during the development process. For this post’s content, I will explain two ways to simulate this shell, which we will also use later.

Mocking the Fiori Launchpad with static resources

This approach is quite simple and, therefore, ideal for beginners. You just need to add another script to the index.html file and configure the Fiori Launchpad. With this, you can quickly mock the Fiori Launchpad locally within minutes. The disadvantage of this mock is that it is just that – a mock. While you can define plugins, they won’t work as there is no backend system connected to them. Furthermore, you are always logged in as the “default user”.

Opened%20Sample%20App%20in%20the%20FLP%20Sandbox

The sandbox mock with the “Default User”

Testing with a service instance

This approach provides the full Fiori Launchpad experience. Once connected to the approuter, the portal service can read the information of the current user and expose the full functionality of the Fiori Launchpad – including plugins and shell services. The CommonDataModel.json configuration file defines the properties of the Fiori Launchpad.

Using this approach is Cloud-Foundry-easy. You just need to provision a service instance (service: portal, plan: standard) and connect this service instance to your approuter. A deployer module will configure the service based on the configuration file. This module is a Cloud Foundry task and part of the MTA project, as we will see later.

The full (Software as a) Service

The previous approach helps you to create a fully functional Fiori Launchpad experience that can be created by any developer without special roles and permissions. The developer can configure the development sandbox (apps, catalogs, etc.) freely in a text file – the so-called CommonDataModel.json.

For production use-cases, however, you need an admin who will use the Site Manager UI. In this UI, the admin can manage all sites (Site Directory) and content (Content Manager) to assigned roles to apps and apps to group. These features are delivery by two SAP Cloud Platform services, which are both offered as a subscription on the subaccount-level:

Please refer to this post if you want to learn more about the similarities and differences between them

UI5 Flexibility Services

The UI5 flexibility services make it possible to tailor standard apps to the individual needs of the end-users. These adoptions are applied per-user (aka personalization) or per-group (aka key user adaptions). These services fulfill the demand that the business apps need the flexibility to rearrange UI elements and display or hide information depending on the user’s individual needs and the domain they are working in.

For this, it’s crucial to use stable IDs for all controls so that the modifications can be tracked and stored reliably. The UI5 support assistant can help you in case you are not sure if all of your IDs are stable.

The flex services have been available for a while now. While the LREP (layered repository) enables these services in ABAP systems, the following two services do this in non-ABAP systems:

UI5 Flexibility Personalization Service

The name already suggests that this service stores the customizations of an individual user.

The interaction with this service typically happens in a WYSIWYG-matter. E.g., when end-users rearrange the element in the Overview page, save their filter variants in list reports, select the content of smart links in the context popover. Additionally to this “in-place” personalization, users can select the “Personalize App” item in the user action menu to show and hide entire sections of the object pages.

This sample application mocks the filter variant feature of the smart filter bar. All other mentioned personalization features can be tested in this second sample application.

Consuming this service is quite easy. If you already use the portal service, you won’t have to do anything! It makes much sense to use personalization service combined with the Fiori Launchpad. Which is why the personalization service is already “stacked” on top of the portal service. All you need to do is integrating your app in the FLP.

 

UI5 Flexibility for Key Users

Different target groups are using the service for key users, and regular end-users might not even be aware of this service. The service is only visible selected domain experts – the key users. With this domain knowledge, they know which smart filter variants are especially useful for their business and which views are essential. With the right role collection assigned, they can save filters that are reusable by all end-users. Besides this, key users are also able to customize object pages. They can change labels, hide or add new fields and fragments. The latter feature can be tested with this demo app when you select “Adapt UI” from the user action menu. These features take work off application developers and enable quick iterations when fine-tuning business applications.

This service is available since June 15th and can be used for both – standalone apps and Fiori apps that are part of the Fiori Launchpad. For this reason, developers need to provide the service and wire it up with the web application. The following hands-on will explain all the necessary steps to do this.

 

Hands-on: Integrate a SAPUI5 App in the Fiori Launchpad

0 Preparation

Before we get to the fun part, we need to install some necessary tools for cloud development on SAP Cloud Platform (if you haven’t done so already):

In either case, you also need to Prepare the Portal Environment for Creating Sites

1 Clone the UI5 sample app

Clone the sample app from the SAP organization or fork it and clone your fork. Open the project in the Business Application Studio. In case you are using a local IDE, open the project with this IDE.

git clone https://github.com/SAP/openui5-sample-app
code openui5-sample-app

2 Modify the UI5 sample app

2.1 Change the web app descriptor

The default manifest is missing a couple of configurations. Replace the current file with the following content to add properties like the version number, title, and description. This new file also contains a default route and an inbound navigation intent that the Fiori Launchpad uses to open the app.

{
	"_version": "1.12.0",
	"sap.app": {
		"id": "sap.ui.demo.todo",
		"type": "application",
		"i18n": "i18n/i18n.properties",
		"applicationVersion": {
			"version": "1.0.0"
		},
		"title": "{{ToDoList}}",
		"description": "{{ToDoList}}",
		"crossNavigation": {
			"inbounds": {
				"intent1": {
					"signature": {
						"parameters": {},
						"additionalParameters": "allowed"
					},
					"semanticObject": "data",
					"action": "display",
					"title": "Sample App",
					"icon": "sap-icon://add"
				}
			}
		}
	},
	"sap.ui": {
		"technology": "UI5",
		"icons": {},
		"deviceTypes": {
			"desktop": true,
			"tablet": true,
			"phone": true
		}
	},
	"sap.ui5": {
		"rootView": {
			"viewName": "sap.ui.demo.todo.view.App",
			"type": "XML",
			"async": true,
			"id": "app"
		},
		"flexEnabled": true,
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"dependencies": {
			"minUI5Version": "1.75.0",
			"libs": {
				"sap.ui.core": {},
				"sap.m": {},
				"sap.f": {},
				"sap.ui.unified": {}
			}
		},
		"models": {
			"i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "sap.ui.demo.todo.i18n.i18n",
					"supportedLocales": [
						"en",
						"de"
					],
					"fallbackLocale": "en"
				}
			},
			"": {
				"type": "sap.ui.model.json.JSONModel",
				"uri": "model/todoitems.json"
			}
		},
		"resources": {
			"css": [
				{
					"uri": "css/styles.css"
				}
			]
		},
		"routing": {
			"config": {
				"routerClass": "sap.m.routing.Router",
				"viewType": "XML",
				"viewPath": "sap.ui.demo.todo.view.App",
				"controlId": "app",
				"controlAggregation": "pages",
				"async": true
			},
			"routes": [
				{
					"name": "RouteMainView",
					"pattern": "",
					"target": [
						"TargetMainView"
					]
				}
			],
			"targets": {
				"TargetMainView": {
					"viewType": "XML",
					"viewLevel": 1,
					"viewId": "app",
					"viewName": "MainView"
				}
			}
		}
	}
}

2.2 Remove header and add an Object Page

The sample app includes a page header that won’t be necessary any longer as the Fiori Launchpad comes with a header. Remove <customHeader> and add another page to test the personalization service later:

<mvc:View xmlns:mvc="sap.ui.core.mvc" 
	xmlns:core="sap.ui.core" 
	xmlns="sap.m" 
	xmlns:uxap="sap.uxap" 
	xmlns:layout="sap.ui.layout" 
	xmlns:f="sap.f" controllerName="sap.ui.demo.todo.controller.App" displayBlock="true">
	<App>
		<Page showHeader="false">
			<content>
				<f:DynamicPage >
				.....
				</f:DynamicPage>
			</content>

			<uxap:ObjectPageLayout id="ProductDetail">
				<uxap:sections>
					<uxap:ObjectPageSection id="sec1" title="Section 1">
						<uxap:subSections>
							<uxap:ObjectPageSubSection id="subSection1" title="">
								<uxap:blocks>
									<Label id="sec1Label" text="Label 1" />
								</uxap:blocks>
							</uxap:ObjectPageSubSection>
						</uxap:subSections>
					</uxap:ObjectPageSection>
					<uxap:ObjectPageSection id="sec2" title="Section 2">
						<uxap:subSections>
							<uxap:ObjectPageSubSection id="subSection2" title="">
								<uxap:blocks>
									<Label id="sec2Label" text="Label 2" />
								</uxap:blocks>
							</uxap:ObjectPageSubSection>
						</uxap:subSections>
					</uxap:ObjectPageSection>
				</uxap:sections>
			</uxap:ObjectPageLayout>
		</Page>
	</App>
</mvc:View>

2.3 Replace an index.html with Fiori Sandbox

For preliminary testing, we want to leverage the FLP Sandbox resources. To do so, replace the current index.html file, which starts the web app as a standalone app, with this sandbox environment.

<!DOCTYPE html>
<html>

<head>
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title>Fiori Launchpad Sandbox</title>

	<script>
		window["sap-ushell-config"] = {
            defaultRenderer: "fiori2",
            bootstrapPlugins: {
                "KeyUserPlugin": {
                    "component": "sap.ushell.plugins.rta"
                },
                "PersonalizePlugin": {
                    "component": "sap.ushell.plugins.rta-personalize"
                }
            },
            applications: {
                "show-demo": {
                    title: "Demo App",
                    icon: "sap-icon://add",
                    additionalInformation: "SAPUI5.Component=sap.ui.demo.todo",
                    applicationType: "URL",
                    url: "./",
                    navigationMode: "embedded"
                },
            }
        };
	</script>

	<script id="sap-ui-bootstrap" src="https://sapui5.hana.ondemand.com/test-resources/sap/ushell/bootstrap/sandbox.js">
	</script>

	<script id="sap-ui-bootstrap" src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
		data-sap-ui-resourceroots='{
                "sap.ui.demo.todo": "./"
            }' data-sap-ui-theme="sap_fiori_3" data-sap-ui-compatVersion="edge" data-sap-ui-async="true"
		data-sap-ui-frameOptions="allow">
	</script>


	<script>
		sap.ui.getCore().attachInit(() => sap.ushell.Container.createRenderer().placeAt("content"));
	</script>
</head>

<body class="sapUiBody" id="content"></body>

</html>

2.4 Run it

Run the app locally to see the sample app in the FLP Sandbox

cd openui5-sample-app/
yarn install
yarn start

The App Studio will show a popup that asks whether you want to expose the open port. Confirm this question and access the index.html file. For local IDEs: Access http://localhost:8080/index.html with the browser of your choice.

You’ll see an FLP Sandbox that contains one app:

Tile%20of%20the%20sample%20app%20in%20the%20FLP%20Sandbox

Tile of the sample app in the FLP Sandbox

Opened%20Sample%20App%20in%20the%20FLP%20Sandbox

Opened sample app in the FLP Sandbox

All changes in this step can be found here.

3 Convert the sample app to a Cloud Foundry project and add the portal service

For this conversion, we need to add a few more modules and tie them together in the overall project files.

3.1 Add routing definition to the web app

The web app shall be stored in the HTML5 Application Repository. This repository has the requirement that each web app needs to contain a webapp/xs-app.json file, which includes at least the following lines.

{
  "welcomeFile": "flpSandbox.html",
  "routes": [{
    "source": "^(.*)",
    "target": "$1",
    "authenticationType": "xsuaa",
    "service": "html5-apps-repo-rt"
  }]
}

3.2 Add the application router module

The approuter will be used as a single entry point for your web application and is connected to the HTML5 application repository. Create the approuter/package.json module descriptor.

{
  "name": "demo",
  "version": "0.0.1",
  "engines": {
    "node": "12.x.x"
  },
  "scripts": {
    "start": "node node_modules/@sap/approuter/approuter.js"
  },
  "dependencies": {
    "@sap/approuter": "^7.1.0"
  }
}

The only other file of this module contains its configuration. Create another file approuter/xs-app.json with the following content.

{
  "welcomeFile": "/cp.portal",
  "authenticationMethod": "none",
  "logout": {
    "logoutEndpoint": "/do/logout"
  },
  "routes": [ ]
}

3.3 Add the deployer module

The approuter will serve the sample app from the HTML5 Application Repository. The deployer module will take the minified app and upload it to this repository. Create the following deployer/package.json file. This is all you need to do to set this deployed module up.

{
    "name": "webapp-deployer",
    "engines": {
        "node": "12.x.x"
    },
    "dependencies": {
        "@sap/html5-app-deployer": "2.1.0"
    },
    "scripts": {
        "start": "node node_modules/@sap/html5-app-deployer/index.js"
    }
}

3.4 Add the launchpad module

Like the previous module, there needs to be an application (better: task) that uploads the Launchpad configuration to the service instance and applies it. This app is defined in the launchpad/package.json file:

{
  "name": "launchpad-site-content",
  "description": "Portal site content deployer package",
  "engines": {
    "node": "12.X"
  },
  "dependencies": {
    "@sap/portal-cf-content-deployer": "3.32.0-20200312112659"
  },
  "scripts": {
    "start": "node node_modules/@sap/portal-cf-content-deployer/src/index.js"
  }
}

And the following configuration is described in launchpad/portal-site/CommonDataModel.json.

{
	"_version": "3.0.0",
	"identification": {
	  "id": "c9aae627-9601-4a11-83c3-41b94a3c8026-1576776549699",
	  "entityType": "bundle"
	},
	"payload": {
	  "catalogs": [
		{
		  "_version": "3.0.0",
		  "identification": {
			"id": "defaultCatalogId",
			"title": "Catalog Title",
			"entityType": "catalog",
			"i18n": "i18n/i18n.properties"
		  },
		  "payload": {
			"viz": [
			  {
				"id": "sap.ui.demo.todo",
				"vizId": "data-display"
			  }
			]
		  }
		}
	  ],
	  "groups": [{
        "_version": "3.0.0",
        "identification": {
          "id": "defaultGroupId",
          "title": "Group",
          "entityType": "group"
        },
        "payload": {
          "viz": [
            {
              "id": "sap.ui.demo.todo-1",
			  "appId": "sap.ui.demo.todo",
			  "vizId": "data-display"
            }
          ]
        }
      }],
	  "sites": [
		{
		  "_version": "3.0.0",
		  "identification": {
			"id": "b9ad73bb-384c-4740-b39a-7f0fad5e6acc-1576776549700",
			"entityType": "site",
			"title": "SAP Fiori launchpad site on Cloud Foundry",
			"description": ""
		  },
		  "payload": {
			"config": {
			  "ushellConfig": {
				"bootstrapPlugins": {
					"PersonalizePlugin": {
                    	"component": "sap.ushell.plugins.rta-personalize"
					}
				},
				"renderers": {
				  "fiori2": {
					"componentData": {
					  "config": {
						"applications": {
						  "Shell-home": {}
						}
					  }
					}
				  }
				}
			  }
			},
			"groupsOrder": [
			  "defaultGroupId"
			],
			"sap.cloud.portal": {
			  "config": {
				"theme.id": "sap_fiori_3",
				"theme.active": [
				  "sap_fiori_3"
				]
			  }
			}
		  }
		}
	  ]
	}
  }

3.5 Configure the XSUAA service instance

The xsuaa service instance manages the application security details and needs multiple parameters to be set up correctly. Add this configuration to the xs-security.json file, which will be referenced by the xsuaa service instance in the next sub-step.

{
  "xsappname": "sample",
  "tenant-mode": "dedicated",
  "description": "Security profile of called application",
  "scopes": [
    {
      "name": "uaa.user",
      "description": "UAA"
    }
  ],
  "role-templates": [
    {
      "name": "Token_Exchange",
      "description": "UAA",
      "scope-references": [
        "uaa.user"
      ]
    }
  ]
}

3.6 Tie it all together

Add the following mta.yaml project descriptor to the root level of the project. This file contains all of the modules mentioned above, as well as the service instances that are hooked up to them.

ID: sample
_schema-version: 3.2.0
description: Enter description here
version: 0.2.0
parameters:
  enable-parallel-deployments: true

modules:
  - name: sample
    type: nodejs
    path: approuter
    parameters:
      disk-quota: 512M
      memory: 512M
    requires:
      - name: sample_uaa
      - name: sample_html5_repo_runtime
      - name: sample_portal
  - name: sample_deployer
    type: com.sap.html5.application-content
    path: deployer
    requires:
      - name: sample_html5_repo_host
    build-parameters:
      builder: custom
      commands:
        - npm run build:ui --prefix ..
  - name: sample_launchpad_deployer
    type: com.sap.portal.content
    path: launchpad
    deployed-after:
      - sample_deployer
    requires:
      - name: sample_portal
      - name: sample_html5_repo_host
      - name: sample_uaa

resources:
  - name: sample_uaa
    type: org.cloudfoundry.managed-service
    parameters:
      path: ./xs-security.json
      service-plan: application
      service: xsuaa
  - name: sample_html5_repo_runtime
    type: org.cloudfoundry.managed-service
    parameters:
      service-plan: app-runtime
      service: html5-apps-repo
  - name: sample_html5_repo_host
    type: org.cloudfoundry.managed-service
    parameters:
      service-plan: app-host
      service: html5-apps-repo
      config:
        sizeLimit: 1
  - name: sample_portal
    type: org.cloudfoundry.managed-service
    parameters:
      service-plan: standard
      service: portal

Last but not least, add the following dependencies and build/deploy scripts to allow a smooth deployment.

{
  "scripts": {
    ...
    "build:mta": "mbt build",
    "deploy:cf": "cross-var cf deploy mta_archives/sample_$npm_package_version.mtar",
    "deploy": "run-s build:mta deploy:cf",
    "build:ui": "ui5 build --clean-dest --include-task=generateManifestBundle --dest deployer/resources/webapp"
  },	  
  "devDependencies": {
    ...
    "cross-var": "^1.1.0",
    "mbt": "1.0.14",
    "npm-run-all": "^4.1.5"
  }
}

3.7 Deploy the web application to the Fiori Launchpad

Click the CF connector on the bottom-left corner of the App Studio (or run cf login) to connect to your Cloud Foundry endpoint. Execute the following commands to trigger the build and deployment of your code:

cd openui5-sample-app
yarn install
yarn run deploy

3.8 Test the personalization service

You can find the URL of the portal page in the terminal output once the deployment finished – access this URL. And click on the tile that represents the sample app.

The%20integrated%20sample%20app

The integrated sample app

Select “Personalize App” from the user action menu and scroll down to the Object Page.

User%20action%20menu

User action menu

Now you can remove entire sections and save your modification.

Removal%20of%20an%20section

Removal of a section

Test the personalization from a different browser to see that it has been persisted. The section will still be visible when you log in with another user.

All changes in this step can be found here.

4 Integrate the key user service

Needed%20entitlement%20for%20step%204

Needed entitlement for step 4

4.1 Add service to the project descriptor

Add a service instance of the key user service to the mta.yaml descriptor. Define the service instance and link it to the approuter.

...
modules:

  - name: sample
    ...
    requires:
      - name: sample_flexibility_keyuser

resources:
  ...
  - name: sample_flexibility_keyuser
    parameters:
      service-plan: keyuser
      service: ui5-flexibility-keyuser
    type: org.cloudfoundry.managed-service

4.2 Add new route

We already linked the key user service instance to the approuter module. Now we have to define the route which forwards traffic to the service (in the xs-app.json file).

{
  "welcomeFile": "/cp.portal",
  "authenticationMethod": "none",
  "logout": {
    "logoutEndpoint": "/do/logout"
  },
  "routes": [{
      "source": "^/keyuser/(.*)$",
      "target": "$1",
      "service": "com.sap.ui.flex.cf.keyuser",
      "endpoint": "keyuser"
    }]
}

4.3 Add service to the portal

The approuter is now ready to accept incoming “key user changes”. Change the configuration of the portal service in launchpad/portal-site/CommonDataModel.json to activate the key user plugin in the Fiori Launchpad and to set the corresponding connector up.

{
  ...
  "payload": {
    "sites": {
      "payload": {
        "config": {
           "ushellConfig": {
             "bootstrapPlugins": {
               "KeyUserPlugin": {
                 "component": "sap.ushell.plugins.rta"
               },
               ...
         ...
         "sap.cloud.portal": {
           "config": {
             ...
             "flexibilityServices": [{
               "connector": "KeyUserConnector",
               "url": "/keyuser"
             }]
...

4.4 Redeploy the application to SAP Cloud Platform

yarn run deploy

4.5 Add a role to your user

Browse to the SAP Cloud Cockpit (or to the production landscape) and navigate to your subaccount. Under Security, click on Role Collections and click the New Role Collection button. Choose any name for this role collection.

Adding%20the%20new%20role%20collection%20%26%23x60%3BDeveloper%26%23x60%3B

Adding the new role collection “Developer”

Click Add Role and select the application identifier that starts with “ui5-flexibility-keyuser”, the suffix might vary in your account. Confirm with Save.

Add%20the%20scope%20to%20the%20role%20collection

Add the scope to the role collection

Go back to the subaccount and select Trust Configuration and the SAP ID Service.

Navigate%20to%20the%20default%20IdP%20%28SAP%20ID%20Service%29

Navigate to the default IdP (SAP ID Service)

Search for your user by entering the associated email address, click Assign Role Collection, and choose the role collection you just created.

Assign%20the%20role%20collection%20to%20your%20user

Assign the role collection to your user

4.6 Key user

Navigate to the Fiori Launchpad app and log out and back in again to ensure the new role collection takes effect. Now you can select Adapt UI from the user action menu.

Switch%20to%20the%20key-user%20mode

Switch%20to%20the%20key%20user%20mode

Switch to the key user mode

The UI will change into the key user mode, and you can remove the only fragment of the To-Do app. Use the activation icon on the top-left to activate the change and click Save & Exit to return to the standard application mode.

Activate%20the%20key%20user%20changes%20for%20all%20users

Activate the key user changes for all users

You can now ask a friend to access the same web app. Your friend won’t see the To-Do list now because the key user changes apply to everyone.

All changes in this step can be found here.

Summary

In this post, you have learned:

  • How to deploy the UI5 sample app to the Fiori Launchpad on Cloud Foundry
  • About the different options to mock the Fiori Launchpad environment
  • What functionality is offered by the UI5 Flexibility services
  • How to leverage Cloud Foundry services to create a Fiori Launchpad app with SAPUI5
  • How to establish a route that redirects traffic to a Cloud Foundry service instance

Did you like this post? If so, you might also like this post that can be seen as “Advanced concepts of Fiori Development in SAP Cloud Platform

Next Steps

  • Have a look at your entire codebase as a whole and familiarize yourself with it 
  • (or on GitHub)
  • Embed your SAPUI5 apps in the Fiori Launchpad on CF
  • Use easy-ui5 to bootstrap Fiori Apps in one-step (+ tutorial)
  • Learn more about the UI5 Flexibility services
21 Comments
You must be Logged on to comment or reply to a post.
  • Hi Marius Obert,

    Thanks for the information. I tried to change the FLP setting using the CommanDataModel.json file. But its changing only in the run time FLP configuration. But i want to change the theme setting of FLP which is created in the site manager by using the portal services. I tried to give the sitedirectory Launchapad ID. But its not working.

  • Amazing!! One of my new favourite bookmarks for ui5 dev!!
    As always, thanks a lot for your contribution Marius, this simplify a lot the cf services functionality understanding.

  • Thank you for this post. It helps me understand basic structure of Cloud Foundry app.

    I have a small question.

    In approuter/xs-app.json, you specified ‘/cp.portal’ as welcome file.

    Where does this file (or folder) come from?

    • This is a very good question! You are right, this route comes somewhat magically into play here.
      You can run “cf html5-list -a <approuter>” (given that you installed the CLI plugin) to see the full content of the HTML5 app repo.

      There, you will see that there is a web app named “cpportal” which has been inserted during the deployment phase and the route redirects traffic to this web app.

  • Hello Marius,

    Thanks for this blog ! It works like a charm and when using the specific approuter, I’m able to retrieve my application and place in my portal site at subaccount level.

    Now, what if instead of using an approuter specific to my application, I want to use the approuter managed by SAP Cloud Platform ?

    I’ve created the project as an MTA module, then inside it I ran this command@sap/fiori-elements to generate a Fiori Elements module.

    Then, this command npm run deploy to generate the mta for deploy.

    I thought adjusting the mta by deleting the approuter and pointing to the subaccount approuter would do the trick but it’s not. The project has no issue to be deployed, I can see it in the HTML5 Applications on subaccount level and it’s event recognized in the content provider on portal.

    BUT, when i try to open the application from the portal, i get this:

    com/test/myapp/Component.js’ from /comtestmyapp/~220920083911+0000~/Component.js: 502 – Bad Gateway

    Here’s my mta.yaml

    _schema-version: "3.2"
    ID: myapp
    version: 0.0.1
    modules:
    - name: myApp-destination-content
      type: com.sap.application.content
      requires:
      - name: uaa_myApp
        parameters:
          service-key:
            name: uaa_myApp-key
      - name: myApp_html_repo_host
        parameters:
          service-key:
            name: myApp_html_repo_host-key
      - name: myApp-destination-service
        parameters:
          content-target: true
      parameters:
        content:
          subaccount:
            destinations:
            - Name: com_test_myApp_myApp_html_repo_host
              ServiceInstanceName: myApp-html5-app-host-service
              ServiceKeyName: myApp_html_repo_host-key
              sap.cloud.service: com.test.myapp
            - Authentication: OAuth2UserTokenExchange
              Name: com_test_myapp_uaa_myApp
              ServiceInstanceName: myApp-xsuaa-service
              ServiceKeyName: uaa_myApp-key
              sap.cloud.service: com.test.myapp
            existing_destinations_policy: update
      build-parameters:
        no-source: true
    - name: myApp_ui_deployer
      type: com.sap.application.content
      path: .
      requires:
      - name: myApp_html_repo_host
        parameters:
          content-target: true
      build-parameters:
        build-result: resources
        requires:
        - artifacts:
          - comtestlyapp.zip
          name: comtestmyapp
          target-path: resources/
    - name: comtestmyapp
      type: html5
      path: myapp
      build-parameters:
        build-result: dist
        builder: custom
        commands:
        - npm install
        - npm run build:cf
        supported-platforms: []
    resources:
    - name: myApp-destination-service
      type: org.cloudfoundry.managed-service
      parameters:
        service: destination
        service-name: myApp-destination-service
        service-plan: lite
    - name: myApp_html_repo_host
      type: org.cloudfoundry.managed-service
      parameters:
        service: html5-apps-repo
        service-name: myApp-html5-app-host-service
        service-plan: app-host
    - name: uaa_myApp
      type: org.cloudfoundry.managed-service
      parameters:
        path: ./xs-security.json
        service: xsuaa
        service-name: myApp-xsuaa-service
        service-plan: application
    build-parameters:
      before-all:
      - builder: custom
        commands:
        - npm install

    and my xs-app.json

    {
        "welcomeFile": "/manifest.json",
        "authenticationMethod": "route",
        "routes": [
          {
            "source": "^/sap/(.*)$",
            "target": "/sap/$1",
            "destination": "GATEWAY_PP",
            "authenticationType": "xsuaa",
            "csrfProtection": false
          },
          {
            "source": "^(.*)$",
            "target": "$1",
            "service": "html5-apps-repo-rt",
            "authenticationType": "none"
          }
        ]
      }
    

    Do you have any ideas what could be wrong ?

  • Hi Marius,

    This worked well for me. But if I want to add another app to the same lauchpad_portal, what are the things that remain the same or in other words, what files/configuration is common between both the application.

     

    Thanks,

    Badhusha

    • Hi,

      this is a good question. There’s not a lot of code that you need to adapt. It is important that both web apps have a unique ID to be able to differentiate them and then you need to add the second ID to the CommonDataModel file to include it to the Fiori Launchpad.

      You can use easy-ui5 to create an FLP web app and then you can use the sub-generator to add a second web app to the same project.

      • So this means both the apps should be in the current directory, in my case it will be like

        -ExampleApp
             – approuter
             – launchpad
             – uimodule1
             – uimodule2
             – deployer
             – mta.yaml

        or can we just refer the webapp’s unique id in the CommonDataModel.json, after the HTML5 applications are deployed in the Repository ?

    • Hi Manu,

      yes, this is absolutely possible! For this reason, we offer the service as a separate service on SAP Cloud Platform. The integration would then work differently but I need to confess that I haven’t done this yet. So I’m not sure how the setup would look.