Skip to Content
Technical Articles

Create Workflow MTAR application with custom UI using Business App Studio

At first, I will introduce the components of that long title. These components are also parts of the solution I will be describing here.

Lets take it from the end.

Cloud Foundry

Cloud Foundry is one of two available environments in SAP Cloud Platform. And I have to say, that it is newer and preferable one. New customers should be onboarded automatically to CF environment – even when NEO should still be supported – according to the blog post. Most of new products and features are delivered on this environment, but on the other hand – not everything which is available on NEO are supported or available on CF.

It is important to know, that Cloud Foundry is based on multi container service architecture. I won`t dive deeper, but it just means, that whole application is built from different services tied together like lego. And the description how to put all the pieces together is part of MTAR application.

Multi Target Application (MTA)

Multi target application repository or in short MTAR is an way how to develop applications in decentralized, container based environment of Cloud Foundry. MTAR application consists of applications (or modules) and services (or resources) and (optionally) from other components like parameters etc.

The heart of every MTA is configuration stored in a file mta.yaml. This configuration describes how the whole application is build and deployed to the CF. As previous sentence implied – there is two step procedure how to get application running.

  • Build process – goes through the mta.yaml, and for the every application (module) runs (according to module type) its building procedure. The result is file (archive) with extension mtar, which contains all necessary information and sources which are needed to deploy our MTA. This step is performed by MTA build tool
  • Deploy process – is how the application gets to the CF environment. It is performed by CF CLI tool.

Business Application Studio

Business Application Studio is the new standard for developing business applications on SAP Cloud Platform Cloud Foundry. It is successor and evolution of WebIDE Full Stack. As WebIDE Full Stack was based on a open source project Eclipse CHE, the new Business App Studio is based on new Eclipse Theia. The biggest difference is, that WebIDE is hosted only on NEO environment and therefore you have to prepare destinations and connection in order to develop on CF environment, new Business Application Studio is hosted as an individual isolated container hosted on CF environment. You can also create (on trial account) two development spaces, but only one can run at a time.

And why multiple spaces?

Because you can add different extension modules in development space when you create one. One dev space can be dedicated to work with CAPM and Fiori and the other one to workflows (and Fiori too). At least I got that kinds.

It is also important to notice, that Business App Studio has UI almost same as famous Visual Studio Code from Microsoft. And what I like most – you have access to the linux terminal there.

You can find more information in official help pages and here is also nice comparison of WebIDE vs Business App Studio.

Only negative I have found on Business App Studio is its name – it is too long and as far as I know, nobody came with nice shortcut or nickname. Business Application Studio is not that sexy as WebIDE. Or do you know some better way how to refer it?

Prerequisites

I assume, that you have at least that requirements:

This post will not teach you how to work with Business App Studio or why do we add the things to the project. There are really good tutorials on that topics already done – like this one on SAPUI5 App with Business App Studio or Creating MTA or Start with workflow.

What I WILL show you, is how to use all that knowledge and build/deploy MTA application with workflow module and custom UI using Business App Studio.

Get our feet wet…

At first we need to create new workspace. As we are in Business App Studio, we will use terminal and CLI.

cd /home/user/projects

after that, create basic MTA scaffolding using yeoman.

yo basic-multitarget-application
Note: yeoman is web scaffolding tool. It is preinstalled (including basic UI5 and MTA generators) in App studio and it uses so called generators to create scaffolding of different projects. In this case we used generator named basic-multitarget-application to create – surprise… empty MTA application.

Fill the attributes of project. In this case it is only name of the project.

Name: WF-custom-ui

Open new project as a workspace – in a menu File / Open Workspace and there choose your newly created project.

It is really just basic MTA application – just two files:

  • .gitignore
  • mta.yaml

If you look into mta.yaml, you can see, that even there it is just bare minimum.

_schema-version: "3.2"
ID: WF-custom-ui
version: 0.0.1

Now it time to add other modules of our application. At first, add workflow module.

yo @workflow/workflow-module

and fill required attributes.

Name:                 workflow
Workflow name:        workflow_service
Workflow description: Workflow tutorial for custom UI
Overwrite mta.yaml:   y
Note: This generator can create whole MTA project, this is why it asks for overwrite mta.yaml. But I wanted to show you also how to create empty MTA project.

Now several things happened. Workflow editor has opened and you can see graphical representation of workflow process. And when you take a look at project folder, you can see, that a lot of files was added.

If you look into mta.yaml now, you can see, that one module named workflow was added and also resource for that module, named workflow_mta appeared.

_schema-version: "3.2"
ID: WF-custom-ui
version: 0.0.1
modules:
  - name: workflow
    type: com.sap.application.content
    path: workflow
    requires:
      - name: workflow_mta
        parameters:
          content-target: true
resources:
  - name: workflow_mta
    parameters:
      service-plan: lite
      service: workflow
    type: org.cloudfoundry.managed-service
Note: This will create new managed service for workflow. If you want to use your existing service, change the name of service to your name and type to org.cloudfoundry.existing.service. Also don`t forget to change service-plan to lite if you are on trial account.

Next step is to add html5 module, which will contain custom UI for user task. Also very easy done using yeoman.

yo fiori-module

and fill attributes

Module name: customUI
Template: SAPUI5 Application
Application: Standalone Approuter
Authentication: yes
Namespace: ui.tutorial
Karma tests: no
View name: Main
Data service: No
Note: you can explore other options like other templates, adding data service or managed application. These options are chosen to keep tutorial simple. If you want to know more about other options, don`t hesitate to ask in comments.

After that last option, a lot of things happened again. Generator started to download all necessary npm packages to create SAPUI5 application, a lot of rows was added to the mta.yaml and two new directories appeared in the project.

Let`s look to the mta.yaml again.

_schema-version: "3.2"
ID: WF-custom-ui
version: 0.0.1
modules:
- name: workflow
  type: com.sap.application.content
  path: workflow
  requires:
  - name: workflow_mta
    parameters:
      content-target: true
- name: wf-custom-ui-approuter
  type: approuter.nodejs
  path: wf-custom-ui-approuter
  requires:
  - name: WF-custom-ui_html_repo_runtime
  - name: uaa_WF-custom-ui
  parameters:
    disk-quota: 256M
    memory: 256M
- name: WF-custom-ui_ui_deployer
  type: com.sap.application.content
  path: .
  requires:
  - name: WF-custom-ui_html_repo_host
    parameters:
      content-target: true
  build-parameters:
    build-result: resources
    requires:
    - artifacts:
      - customUI-content.zip
      name: customUI
      target-path: resources/
- name: customUI
  type: html5
  path: customUI
  build-parameters:
    builder: custom
    commands:
    - npm run build
    supported-platforms: []
resources:
- name: workflow_mta
  type: org.cloudfoundry.managed-service
  parameters:
    service: workflow
    service-plan: standard
- name: WF-custom-ui_html_repo_runtime
  type: org.cloudfoundry.managed-service
  parameters:
    service: html5-apps-repo
    service-plan: app-runtime
- name: WF-custom-ui_html_repo_host
  type: org.cloudfoundry.managed-service
  parameters:
    service: html5-apps-repo
    service-plan: app-host
- name: uaa_WF-custom-ui
  type: org.cloudfoundry.managed-service
  parameters:
    path: ./xs-security.json
    service: xsuaa
    service-name: WF-custom-ui-xsuaa-service
    service-plan: application
build-parameters:
  before-all:
  - builder: custom
    commands:
    - npm install

Three new modules appeared. It is interesting, because it was just two folders added. If you look better, you will see, that that third module is module for UI deployer. This module is interesting by itself and I will return to it later. But now lets look to the HTML5 module.

- name: customUI
  type: html5
  path: customUI
  build-parameters:
    builder: custom
    commands:
    - npm run build
    supported-platforms: []

Despite the fact, that we just created that module almost without any effort, that is nothing special here. path customUI corresponds with newly created directory and custom builder will run command npm run build on a build time.

Let`s take a look also on ./customUI/package.json file, which contains implementation of that build command.

{
  "name": "customui",
  "version": "0.0.1",
  "devDependencies": {
    "@sapui5/ts-types": "1.71.x",
    "@ui5/cli": "2.2.6",
    "@sap/ui5-builder-webide-extension": "1.0.x",
    "bestzip": "2.1.4",
    "rimraf": "3.0.2"
  },
  "scripts": {
    "build": "npm run clean && ui5 build --include-task=generateManifestBundle generateCachebusterInfo && npm run zip",
    "zip": "cd dist && npx bestzip ../customUI-content.zip *",
    "clean": "npx rimraf customUI-content.zip dist"
  },
  "ui5": {
    "dependencies": [
      "@sap/ui5-builder-webide-extension"
    ]
  }
}

As you can see in a scripts object, that build command is in fact composed of 3 commands joined by && operator.

At first it will clear file customUI-content.zip from the directory dist. This will ensure, that all build process will create new and fresh content.

After that, UI5 build command is performed, which will generate the content of UI5 application itself. By default it will create that content into dist directory, will create component-preload.js file and uglify its content – in order to optimize the performance of application. You can find more about UI5 builder here.

And the final step will create zip archive out of the application. This is necessary, because new way of deploying HTML5 apps to runtime repository of SCP CF. More on that in deployer part.

One more thing is necessary here in UI5 module. You must add routing to the workflow services so application could access workflow API.

Open ./customUI/xs-app.json file and add new route

        {
            "source": "^/bpmworkflowruntime/(.*)$",
            "target": "/$1",
            "service": "com.sap.bpm.workflow",
            "endpoint": "workflow_rest_url",
            "authenticationType": "xsuaa"
        },

The whole file will look like this

{
    "welcomeFile": "/index.html",
    "authenticationMethod": "route",
    "logout": {
        "logoutEndpoint": "/do/logout"
    },
    "routes": [
        {
            "source": "^/bpmworkflowruntime/(.*)$",
            "target": "/$1",
            "service": "com.sap.bpm.workflow",
            "endpoint": "workflow_rest_url",
            "authenticationType": "xsuaa"
        },
        {
            "source": "^(.*)$",
            "target": "$1",
            "service": "html5-apps-repo-rt",
            "authenticationType": "xsuaa"
        }
    ]
}

Second new module is application router.

- name: wf-custom-ui-approuter
  type: approuter.nodejs
  path: wf-custom-ui-approuter
  requires:
  - name: WF-custom-ui_html_repo_runtime
  - name: uaa_WF-custom-ui
  parameters:
    disk-quota: 256M
    memory: 256M

Also created without any big effort by the generator. Just standard application router so we have access point to our MTA.

Third new module is deployer.

- name: WF-custom-ui_ui_deployer
  type: com.sap.application.content
  path: .
  requires:
  - name: WF-custom-ui_html_repo_host
    parameters:
      content-target: true
  build-parameters:
    build-result: resources
    requires:
    - artifacts:
      - customUI-content.zip
      name: customUI
      target-path: resources/

Lets look closely at this module. UI Deployer is module, which ensures, that your new UI5 (or Vue, React or event plaint HTML) will be deployed to the application runtime service. But in fact this application in not part of functionality of MTA itself and is more or less useless during the life of application.

The old way was to deploy nodeJS application which run during the deployment process, deploys the HTML5 app and after that it stopped itself. But anyway, this app was visible among deployed Applications and took from limit of applications on that subaccount.

This new way ensures that no additional application is created and UI module is deployed during the deployment process by CF builder.

In order to function properly, you have to configure that module.

Type have to be set to com.sap.application.content. This ensures, that proper builder is run.

And also you have to set the dependencies, because this module can deploy UI module only after that UI module was built.

And here comes build-parameters.

  • build-result parameter sets the directory from where application should be deployed
  • requires directive tells, that this module depends on other modules. In this case, it depends on customUI module.
  • target-path tells where to put zip archive with that UI module
  • artifacts directive contains the list of ZIP archives which should be deployed for this UI module.

If you look a little bit higher on a customUI module – on its build command, you can see, that the last part of that build command was command to prepare ZIP archive out of application itself. It was necessary to prepare that ZIP because new deployer requires already archived resources.

You can find more about that new deployer in this very interesting video by Marius Obert from UI5Con

The last module we need is launchpad module – so we can access Workflow tiles and My Inbox application. You can add that also with yeoman.

yo @sapflp/launchpad-module

Fill attributes

Module name: flp
Create launchpad site: yes

Let`s look at new launchpad module

- name: flp
  type: com.sap.portal.content
  path: flp
  requires:
  - name: portal_resources_WF-custom-ui
  - name: WF-custom-ui_html_repo_host
  - name: WF-custom-ui_ui_deployer
  - name: uaa_WF-custom-ui
  parameters:
    buildpack: https://github.com/cloudfoundry/nodejs-buildpack/releases/download/v1.6.51/nodejs-buildpack-cflinuxfs3-v1.6.51.zip
    memory: 128M
    stack: cflinuxfs3

As you can see, the new module has name flp, its path in a project targets to the directory ./flp and has standard launchpad parameters. But it is missing information in the requires area.

You need to declare workflow service as a resource, so the workflow tiles will get access to the workflow api.

Workflow resource in that MTA has name workflow_mta so new definition of the module will be

- name: flp
  type: com.sap.portal.content
  path: flp
  requires:
  - name: portal_resources_WF-custom-ui
  - name: WF-custom-ui_html_repo_host
  - name: WF-custom-ui_ui_deployer
  - name: uaa_WF-custom-ui
  - name: workflow_mta
  parameters:
    buildpack: https://github.com/cloudfoundry/nodejs-buildpack/releases/download/v1.6.51/nodejs-buildpack-cflinuxfs3-v1.6.51.zip
    memory: 128M
    stack: cflinuxfs3

Add same resource also to the approuter module

- name: wf-custom-ui-approuter
  type: approuter.nodejs
  path: wf-custom-ui-approuter
  requires:
  - name: WF-custom-ui_html_repo_runtime
  - name: uaa_WF-custom-ui
  - name: portal_resources_WF-custom-ui
  - name: workflow_mta
  parameters:
    disk-quota: 256M
    memory: 256M

We also need to add launchpad content – 3 tiles – My Inbox, Workflow definitions and Workflow Instances.

Open ./flp/portal-site/CommonDataModel.json and add there following content

{
	"_version": "3.0.0",
	"identification": {
		"id": "f23bee19-fdd3-4690-8c99-3b5df3409b5e-1569475133992",
		"entityType": "bundle"
	},
	"payload": {
		"catalogs": [{
			"_version": "3.0.0",
			"identification": {
				"id": "defaultCatalogId",
				"title": "{{title}}",
				"entityType": "catalog",
				"i18n": "i18n/defaultCatalogId.properties"
			},
			"payload": {
				"viz": []
			}
		}],
		"groups": [{
			"_version": "3.0.0",
			"identification": {
				"id": "defaultGroupId",
				"title": "{{title}}",
				"entityType": "group",
				"i18n": "i18n/defaultGroupId.properties"
			},
			"payload": {
				"viz": [{
					"id": "com.sap.bpm.monitorworkflow-0-1569475771450",
					"appId": "com.sap.bpm.monitorworkflow",
					"vizId": "bpmworkflowmonitor-DisplayInstances"
				}, {
					"id": "com.sap.bpm.monitorworkflow-1-1569475771450",
					"appId": "com.sap.bpm.monitorworkflow",
					"vizId": "bpmworkflowmonitor-DisplayDefinitions"
				}, {
					"id": "cross.fnd.fiori.inbox-2-1569475771450",
					"appId": "cross.fnd.fiori.inbox",
					"vizId": "WorkflowTask-DisplayMyInbox"
				}]
			}
		}],
		"sites": [{
			"_version": "3.0.0",
			"identification": {
				"id": "3a2a1ec5-91b5-4bb6-83ed-7716fe8d895d-1569475133992",
				"entityType": "site",
				"title": "SAP Fiori launchpad site on Cloud Foundry",
				"description": "SAP Fiori launchpad site on Cloud Foundry, deployed from SAP Web IDE"
			},
			"payload": {
				"config": {
					"ushellConfig": {
						"renderers": {
							"fiori2": {
								"componentData": {
									"config": {
										"applications": {
											"Shell-home": {}
										}
									}
								}
							}
						}
					}
				},
				"groupsOrder": ["defaultGroupId"],
				"sap.cloud.portal": {
					"config": {
						"theme.id": "sap_fiori_3",
						"theme.active": ["sap_fiori_3", "sap_belize_hcb", "sap_belize_hcw"]
					}
				}
			}
		}]
	}
}
Note: if you want edit CommonDataModel.json in text mode, you have to right click on that file and choose Open With…/Code Editor

The last thing which is missing, is to add usert task to the workflow and assign our custom UI to that task.

Open ./workflow/workflows/workflow_service.workflow 

and select User Task

and add it to the workflow

Select UserTask1 and on the Details tab put some Subject – eg. My Custom Task. On that same tab put your email to the Users text field. You should put there email which is connected to actually used account. If you will use some other email – you wont see workitem in your My Inbox.

On the third tab named User interface select type as SAPUI5 Component. Next fill HTML5 App Name. As you probably know (if you took those tutorials I recommended), you have to find app id from ./customUI/webapp/manifest.json and from there sap.app.id but without all dots. In this case it will be uitutorialcustomUI.

Value for the last mandatory field – SAPUI5 Component can be found in Component.js –  ui.tutorial.customUI in this case.

Right now, you should have everything you need to build and deploy the MTA.

So do it.

Build is done by command line tool called MBT. Run this command in a terminal.

mbt build

When the build process finished correctly, you should see

INFO finished building the "WF-custom-ui_ui_deployer" module

among other messages. Build process created new directory called MTA_ARCHIVES and in that folder you should find file called WF-custom-ui_0.0.1.mtar

Now its time to deploy that project. This time you must use another command line tool – CF and specifically its plugin Multirepo.

cf deploy mta_archives/WF-custom-ui_0.0.1.mtar 

After a while you should see terminal full of messages and among them should be Process finished which indicates, that everything went fine.

So, application is now succesfully deployed on the cloud foundry space. Let`s take a look in a cockpit. Go to the space, into which you deployed app and look at the Applications page. You should see two apps (if you hadn`t deployed other apps before).

App router si started and flp, which is stopped. FLP app is just deployer of content (CommonDataModel.json) and it finished its task during deploy process and stopped itself to save resources. As I described higher, UI deployer isn`t nodejs app so it isn`t here and UI app also isn`t nodejs app.

Now take a look at Service Instances page

Here you can see all services declared in resources part of mta.yaml. Service column identifies type of service (also seen in Service Marketplace tiles) and Plan column – is plan which you set at mta.yaml. Referencing Applications contains all the backwar references. Backward because we set that bindings in mta.yaml at modules level and here it is shown from resources level.

So everything seems ok, lets look into launchpad. On the Applications page open app router. On Overview page open link in section Application routes.

This link should open new tab in browser and show launchpad on it.

Note: If you see error instead of number 0 on My Inbox tile – you are probably missing roles. Refer to the tutorial, how to create that roles.

Create new workflow instance in a Monitor Workflows tile.

After that you should see 1 task in My Inbox tile

And as you can see – it is our customUI fiori application. It is just barebone application created from template right now, but you can develop it as you need and interact with Approver as you need. Information how to create basic functionality in your app, including adding Approve and Reject actions, can be found in this SAP Help page.

Conclusion

This post is a little bit longer then I expected and for sure it could be much longer if I would dive deeper in the details of each individual steps. But I believe that amount of information contained here should help you with creation of bare bone MTA application with workflow, launchpad and custom UI for user task of workflow.

In case that I am wrong, and you will miss some information or I left out some piece and you will stuck in some step – write me in the comments and we can work it out.

I also created github repository containg the project sources created during the writing of this blog. You can clone it and use it as a template for workflow MTA with custom UI.


Disclaimer: I posted this blog post also on my personal blog. You can find it on https://vbalko.blogspot.com/2020/09/create-workflow-mtar-application-with.html

All pictures on this blog was created by myself.

4 Comments
You must be Logged on to comment or reply to a post.
  • Hello Vladimir,

    Great content and nicely explained.

    For people starting with WF on Cloud Foundry, this is definitely a must read as it guides you through every component needed to have a full tour of WF, from workflow itself to its hosting on a portal service and even Custom UI rendering.

    It helped me a lot for some issues encountered.

    Best regards,

    Jérémy.

     

  • Hi Vladimir,

    Thank you so much for this blog. It helped me to configure my CAP project easily in Business application studio.

    But I have an issue with custom user task.. when I tried to launch an user task with UI5 component in my inbox, getting an error that, Cannot create componentcom.sap.customUIfor smart template rendering. Showing standard task in the detail screen as a fallback: failed to load Component.js from /Component.js: 404 – Not Found -. But I can launch the UI5 app using app router without any issue. Any idea? Your help is appreciated.

    • Hello Sudha Kantamneni

      Http error 404 means that the resource does not exists on an URL which you specified. It can be a lot of reasons, but few of them are most probable.

      1. application is not deployed in an application runtime and therefore my inbox cannot find it on a url you have provided to the UI task in WF
      2. URL you have provided into UI task in WF is not correct – as I write in blog – look into manifest.json into sap.app.id value. Concatenate that value and remove all dots. For example if your sap.app.id value is com.example.myApp, the HTML5 App Name shoul be comexamplemyApp

      If I would be assigned to resolve that problem, I would at first look into Networks tab in Chrome developer tools (Ctrl+Shift+I) and find the network call for that component. Analyse that call if it looks same as your call from app router (if you said, that it works from app router).

      Also check if app is deployed in app runtime by

      cf html5-list -d -u -a -n 

      Try that steps and if that would not help, we can investigate further.