Skip to Content
Technical Articles

Cross-MTA Dependencies. Custom UI5 Library Reference Example.

While there is a lot of good information available on cross-MTA dependancies, I thought it would be useful to create a complete working example for loading a custom UI5 library cross-MTA.

To demonstrate the cross-MTA capability I will create two MTA’s containing UI5 applications

  • Provider
  • Consumer

The provider will contain a custom UI5 library, and the consumer will access the library hosted by the provider.

Using this approach your custom UI5 library’s will only need to be deployed once and may be accessed by any other UI5 application as needed.

 

As I focus on this scenario alone and only touch on the properties and configuration options available, further reading to gain a complete understanding can be found via the SAP reference: https://help.sap.com/viewer/4505d0bdaf4948449b7f7379d24d0f0d/2.0.04/en-US/33548a721e6548688605049792d55295.html#loio33548a721e6548688605049792d55295__section_gfg_1tx_nv

The full source code used for this blog is available via github: https://github.com/bigsmity/crossmta.ui5

This configuration was created on cloud platform and also tested with on-premise HANA 2.0 SPS 04.

 

The solution

I created the top level MTA “crossmta.ui5” solely to place all the source in the same github repository via webide. It serves no other purpose.

 

The file structure:

 

Provider

 

For both the provider and consumer we will create an MTA and SAPUI5 Application from the templates in webide. The file structure for the provider is shown below:

 

Next we create the a UI5 library by adding a library.js and .library file to the provider UI5 application. For this demo we will not add any controls to the library, but simply add a console.log() to display the library’s initialization.

 

provider library.js

sap.ui.define([], function() {
    "use strict";

    jQuery.sap.declare("crossmta.provider");
    
    /**
     * @alias crossmta.provider
     */
    sap.ui.getCore().initLibrary({

        name: "crossmta.provider",
        version: "1.0.0",
        dependencies: ["sap.ui.core"],
        types: [],
        interfaces: [],
        controls: [],
        elements: [],
        noLibraryCSS: true
    });
    
	console.log("crossmta.provider. Loaded.");

    return crossmta.provider;

}, false);

 

Next we need to setup the mta.yaml for the provider. The provides segment is added to indicate that this module will be made available to other modules. The name variable will be used in the consumer MTA to link the two together.

    provides:
      - name: provider-ref
        public: true
        properties: 
          url: '${default-url}'

 

provider mta.yaml

ID: crossmta.provider
_schema-version: '2.1'
version: 0.0.1
modules:
  - name: provider
    type: html5
    path: provider
    properties:
      CORS:
        - uriPattern: .
          allowedMethods:
            - GET
            - POST
          allowedOrigin:
            - host: '*.ondemand.com'
    parameters:
      disk-quota: 512M
      memory: 256M
    build-parameters:
      builder: grunt
    requires:
      - name: uaa_crossmta.provider
      - name: dest_crossmta.provider
    provides:
      - name: provider-ref
        public: true
        properties: 
          url: '${default-url}'
resources:
  - name: uaa_crossmta.provider
    parameters:
      path: ./xs-security.json
      service-plan: application
      service: xsuaa
    type: org.cloudfoundry.managed-service
  - name: dest_crossmta.provider
    parameters:
      service-plan: lite
      service: destination
    type: org.cloudfoundry.managed-service

 

Now the provider configuration is complete. Build and then deploy the MTA.

 

Consumer

 

The consumer is setup the same as the provider with an MTA and SAPUI5 Application from the templates in webide:

 

 

There is a little more to configure in the mta.yaml file for the consumer. First a resource reference must be added to the provider module.

resources:
  - name: provider-lib
    type: configuration
    parameters:
      provider-nid: mta
      provider-id: crossmta.provider:provider-ref
      version: '>=0.0.1'

 

provider-nid: Will always be “mta”

provider-id: This is made from two properties previously set in the providers mta.yaml

  1. The ID property in the top of the providers mta.yaml file. in this case “crossmta.provider”
  2. The module/provides/name property in the provider’s mta.yaml. In this case “provider-ref”

These two properties are concatenated with a “:”

pattern: <property 1>:<property 2>

value: crossmta.provider:provider-ref

 

Next we must specify that the consumer requires the provider resource. This is also used to configure the destination required for consumer.

    requires:
      - name: provider-lib
        group: destinations
        properties:
          name: provider-dest
          url: '~{url}/provider'
          forwardAuthToken: true

 

consumer mta.yaml

ID: crossmta.consumer
_schema-version: '2.1'
version: 0.0.1
modules:
  - name: consumer
    type: html5
    path: consumer
    properties:
      CORS:
        - uriPattern: .
          allowedMethods:
            - GET
            - POST
          allowedOrigin:
            - host: '*.ondemand.com'
    parameters:
      disk-quota: 512M
      memory: 256M
    build-parameters:
      builder: grunt
    requires:
      - name: uaa_crossmta.consumer
      - name: dest_crossmta.consumer
      - name: provider-lib
        group: destinations
        properties:
          name: provider-dest
          url: '~{url}/provider'
          forwardAuthToken: true
resources:
  - name: uaa_crossmta.consumer
    parameters:
      path: ./xs-security.json
      service-plan: application
      service: xsuaa
    type: org.cloudfoundry.managed-service
  - name: dest_crossmta.consumer
    parameters:
      service-plan: lite
      service: destination
    type: org.cloudfoundry.managed-service
  - name: provider-lib
    type: configuration
    parameters:
      provider-nid: mta
      provider-id: crossmta.provider:provider-ref
      version: '>=0.0.1'

 

Now a route needs to be set in the xs-app.json file of the consumer to redirect our requests to the destination. The route to add is:

"routes": [
  	{
  		"source": "^/provider-dest/(.*)$",
  		"destination": "provider-dest",
  		"target": "$1"
  	},

 

consumer xs-app.json

{
  "welcomeFile": "/consumer/index.html",
  "authenticationMethod": "route",
  "logout": {
    "logoutEndpoint": "/do/logout"
  },
  "routes": [
  	{
  		"source": "^/provider-dest/(.*)$",
  		"destination": "provider-dest",
  		"target": "$1"
  	},
    {
      "source": "^/consumer/(.*)$",
      "target": "$1",
      "localDir": "webapp"
    }
  ]
}

 

To complete the consumer application a call to load the library can be added to the Component.js.

sap.ui.getCore().loadLibrary("crossmta.provider", "/provider-dest");

The namespace and url matching the route source pattern are added as parameters to the loadLibrary function.

 

consumer Component.js

sap.ui.getCore().loadLibrary("crossmta.provider", "/provider-dest");

sap.ui.define([
	"sap/ui/core/UIComponent",
	"sap/ui/Device",
	"crossmta/consumer/consumer/model/models"
], function (UIComponent, Device, models) {
	"use strict";

	return UIComponent.extend("crossmta.consumer.consumer.Component", {

		metadata: {
			manifest: "json"
		},

		/**
		 * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
		 * @public
		 * @override
		 */
		init: function () {
			// call the base component's init function
			UIComponent.prototype.init.apply(this, arguments);

			// enable routing
			this.getRouter().initialize();

			// set the device model
			this.setModel(models.createDeviceModel(), "device");
		}
	});
});

 

Now the consumer configuration is complete. Build and then deploy the MTA.

 

We can check our configuration in the User-Provided Variables tab of the consumer application in the cloud platform cockpit.

You will notice that the there is a group called “destinations” containing the name of your destination and the url of the deployed provider module.

[ {
"forwardAuthToken" : true,
"name" : "provider-dest",
"url" : "https://pxxxxxxxxxxtrial-trial-dev-provider.cfapps.eu10.hana.ondemand.com/provider"
} ]

 

Finally we run the consumer UI5 application and open the development tools by pressing F12.

You will now see “crossmta.provider. Loaded.” in the console window. Looking further into the network traffic you will be able to see the library.js file loaded via the destination.

Congratulations, you now have cross mta functionality for your UI5 library’s.

 

 

 

 

3 Comments
You must be Logged on to comment or reply to a post.
  • Dear Bradley,

    Great blog! Thank you.

     

    You mentioned that you tested following configuration on SAP Hana 2.0 SPS04.

    Unfortunately, I receive following error during project build on SAP Hana 2.0 SPS 05:

    [ERROR] Invalid mta.yaml. Make sure that the declared type html5 of module provider matches the actual module type com.sap.hcp.html5.
    Do you have any idea how to fix it?
    Best
    Mateusz
    • Hi Mateusz,

      Unfortunately I have not yet worked in SPS05. From the error it appears to be complaining about the module type ‘html5’, and is expecting ‘com.sap.hcp.html5’. This is confusing as the error is referencing a HCP type which is unexpected for XSA.

      https://help.sap.com/viewer/ea72206b834e4ace9cd834feed6c0e09/Cloud/en-US/f1caa871360c40e7be7ce4264ab9c336.html

      As a starting point you may wish to create a new html5 app from template in web ide to see what value it places in the module type field.

      Further to this you may wish to check all of your indentation in the mta.yaml or download the source from github to compare to yours.

      Best of luck,

      Brad.

      • Hi Brandley,

        Thank you for your reply.

        This error is unclear and strange. I downloaded your code (cossmta.ui5) from gitlab and I receive same error (on SAP Hana 2.0 SPS 05).

         

        I made another try with creating SAP UI5 library and I receive following error:

        08:23:09 (DIBuild) npm ERR! code E404
        npm ERR! 404 Not Found - GET https://xxxxx-sap-di-local-npm-registry.dssvmddhdb01.dq.palturai.com:30033/@sap%2fdi.code-validation.xml - no such package available
        npm ERR! 404
        npm ERR! 404 '@sap/di.code-validation.xml@1.1.16' is not in the npm registry.
        npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
        npm ERR! 404 It was specified as a dependency of 'kantwertkantwertlibrary'
        npm ERR! 404
        npm ERR! 404 Note that you can also install from a
        npm ERR! 404 tarball, folder, http url, or git url.

        di-local-npm-registry is configured well and works fine for another packages. As UPSTREAM_LINK following link is specified: http://registry.npmjs.org/

         

        Do you have any idea what is wrong there?

         

        Best

        Mateusz