Skip to Content
Product Information

Using SaaS Provisioning Service to develop Multitenant application on SAP Cloud Platform, Cloud Foundry Environment

In the context of Cloud Computing, Multitenancy allows an application provider to serve applications and services to multiple tenants – a set of users. End users of the application access it through a URL dedicated to that tenant.

A tenant-aware application has the capability to separate data securely per tenant, can share resources across the tenants, and can serve features from a single code repository.

This blog elaborates on the process to build a multitenant application on SAP Cloud Platform in the Cloud Foundry environment. For multitenancy on the Neo environment, please see this blog.

Understanding Software as a Service (SaaS) Provisioning service

In the SAP Cloud Platform Cloud Foundry environment service marketplace, we can see SaaS Provisioning service as shown in the image below.

To make our SaaS Application available to multiple tenants we must set up a registry for our application. The SaaS Provisioning service is where we, as a SaaS Application provider, register our app. The SaaS Provisioning service enables us to automate the subscription process. It also maintains a list of all dependencies and subscriptions of an application.

A SaaS Application provider creates a subaccount to deploy the application. Inside this subaccount, the provider creates a space and deploys the SaaS Application. The provider then registers the application with a SaaS registry. The SaaS registry service on SAP Cloud Platform creates a new entry. Through this service, any sub-account, within the same global account, will see an entry of the provider application in the subscriptions tiles. The consumer then can subscribe to the application by just a click of a button. Each subaccount has a unique subdomain and identity zone id.

 

Understanding the concept through an example

Let’s look at how one can use SaaS Provisioning service to build a simple ‘Hello World’ multitenant application.

There is a SaaS Application provider – Provider ZZZ. Provider ZZZ would like to build an application that displays a hello message. The hello message will display the logged in user’s name and the tenant from which the user has logged in – as shown in the image

 

As ZZZ, we will build a ‘Hello World’ application to display the ‘hello message’. Also, since each tenant will access the application from a unique URL, we will build an app router app to resolve the URL, authorize the request and forward the request to our application.

Overview of the Steps Involved

1.     Develop A SaaS Application

In our application’s default end-point (GET – ‘/’) we will return a hello statement displaying the username, tenant subdomain, and tenant identity zone.

We deploy this application on our (provider’s) sub-account and test the application. Once we are satisfied with the development, we add the configurations required to make our application available across tenants.

 

2.     Add Configurations For Multitenancy

To make our application available to SaaS Provisioning service and to automate the subscription process we must add the following configuration to our SaaS Application.

The SaaS Provisioning service requires us to define the following API end-points.

  • PUT – ‘callback/v1.0/tenants/*
    • To onboard a tenant, i.e. when a consumer subscribes to the application
  • DELETE – ‘callback/v1.0/tenants/*’
    • To off-board a tenant, i.e. when a consumer unsubscribes to the application

Each consumer accesses the SaaS Application through a unique URL. To ensure that these requests come to the target application, we define a tenant host pattern for our app router app in the MTA.yaml file. Click here for the detailed documentation.

We specify the SaaS Application name, description, app category while creating a SaaS Provisioning service instance. We mention these details in a config.json

{

  "appId": "<XS-App Name>",

  "displayName": "Hello World",

  "description": "A sample hello world app to explain the concepts of Multitenancy",

  "category": "Provider ZZZ",

  "appUrls": {

    "onSubscription": "<Your back-end app URL>/callback/v1.0/tenants/{tenantId}"

  }

}

 

3.     Register the SaaS Application to SaaS Provisioning

Upon completing our configuration, we create a SaaS Provisioning service and bind it to our SaaS Application. To complete this set of actions we require Cloud Foundry Command Line Interface.

We start this process by creating a new SaaS Provisioning service instance.

cf cs saas-registry application <Service name> -c <Path to config.js file>

Next, we bind our SaaS Application to the newly created SaaS Provisioning service instance.

cf bs <SaaS Provider Application Name> <SaaS Provisioning Service Name>

Once we bind our application to this service instance we will be prompted to restage our application. To do so, we execute the following command.

cf restage mt-hw-node-app

 

4.     Subscription of the SaaS Application by a Consumer

A consumer can subscribe to the application either through the SAP Cloud Platform Cockpit or through REST APIs.

Subscription through SAP Cloud Platform Cockpit

In your global account, create a new subaccount and go to the Subscriptions tab. The SaaS registry service shows the applications that have been registered with it. Here, you will find the provider’s application.

Click on the application tile and click on the subscribe button.

Subscription through REST APIs

You will require a client that can make REST API calls (such as Postman).

We first get the application authorization token. Using your Cloud Foundry Command Line Interface tool execute the following command

cf env <Name Of You SaaS App>

Create a new request in your client with the following setup. Copy the corresponding values from the environment variables.

HTTP Method – POST

URL – <"System-Provided"."VCAP_Services"."saas-registry"."credentials"."url">

Parameters

Key: grant_type

Value: client_credentials

Authentication Type – Basic Authentication

Username - <"System-Provided"."VCAP_Services"."saas-registry"."credentials"."clientId">

Password - <"System-Provided"."VCAP_Services"."saas-registry"."credentials"."clientSecret">

You will receive the following as a response.

{

  "access_token": "xxxxxx",

  "token_type": "bearer",

  "expires_in": 43199,

  "scope": "yyyyyy",

  "jti": "zzzzz"

}

We use the access_token returned to call the subscription API in the next step.

HTTP Method – PUT

URL - <"System-Provided"."VCAP_Services"."saas-registry"."credentials"."tenant_onboarding_url">/api/v2.0/subscription/tenants/{tenantId}

tenantId – Tenant Zone Identity

Parameters

Key: jobUuid

Value: A newly generated GUID

Authentication Type – OAuth 2.0

Access Token – Access token copied from the response of the earlier API

In upcoming blogs, we will take a look at the different APIs that can be used.

 

5.     Mapping Consumers’ Routes

In the last step, the provider needs to add a new route to ensure that a consumer’s request goes to the app router.

You can now launch the app for the consumer

In upcoming blogs, we will take a closer look at methods that we can adopt to automate the process of route mapping.

 

 

Please find the code for a ‘Hello World’ sample application here. This application has been developed using node.js. For further information and a step by step guide, please go through the Readme.MD file. If you prefer a video, please check out this playlist by SAP HANA Academy.

 

Now that you have an understanding of SaaS Provisioning and steps involved in building a multitenant application you can go through this blog to see how can we achieve multitenancy at persistence layer through SAP Cloud Platform, Cloud Foundry environment. The blog explains the concepts through a sample product inventory management application. To gain a deeper understanding of the architecture please read this blog.

24 Comments
You must be Logged on to comment or reply to a post.
  • Why is it necessary for tenant to be in the same global account as the provider when we use saas registry? Is there a config mode that needs to be changed to allow subscription of tenants from other global accounts?

    • Hi Tejas,

      Thank you for your question.

      The service instance of your saas registry is accessible only within a global account. Thus, your provider and subscriber sub-account must be a part of the same global account.

      No, there currently is no configuration that you can add that can allow you to subscribe to applications across Global Accounts.

      I hope this answers your query.

    • Hi Tejas,

      to add some details here: this is only the case for applications built by partners or customers.

      If apps are commercialized with the SAP Cloud Platform, then they are also available within all other global accounts as soon as the global account is entitled to use this application.

      Hope that helps.

      Best regards,

      Jan

      • Hi Jan,

        Reading through SAP Cloud Platform documentation I found the same info as Sandeep is saying “SaaS provisiooned application is visible inside same global account.”

        Can you point to documentation where I can find information how to  “Commercialize app with the SAP Cloud Platform”?

        I am aware of “Managed Service” (and OSB API) but it is not “SaaS provisioning Service” (as described in this blog).

        BR
        Zdenko

         

  • Hi Sandeep,

    Are we supposed to add the route tenantId+appurl  to access the app? in my case, I have done this way but while trying to access the Tenant ID in the subscriber application, I’m getting tenant ID of the dev space where app deployed.

    I’m not sure if this is because of the app route that I have created after SaaS subscription or anything missing while provisioning/subscribing the app.

     

    Best regards,

    Gopal

    • Hi Gopal,

      Thank you for your question.

      You are expected to add construct your onSubscription URL in the following format:

      var tenantAppURL = https:\/\/ + <subdomain name of the consumer+ <name of your application+ <CF App Domain>;

      Please note that this is required only for those services which have to be multi-tenant. You need not do this for the app-router application.

      For code specific details please refer to the sample app included in the blog.

      I hope this answers your query.

  • Hi SANDEEP TDS

    Thanks for the post.

    How would you implement a similar approach for a Fiori Launchpad module with some HTML5 applications (for apps built using Fiori Elements template) consuming odata? 

    Best regards,
    André

     

  • Hi Sandeep,

    Little question about this topic can we use any language for this or only using javascript?
    If I have an application develop for example in ruby, can I deploy it ? Can we use container that contain the application ?

    Thanks for your help

    • Hi Emmanuel,

      Thank you so much for the question.

      No, you are not limited to Javascript. You can use Java, Python or other languages supported by the Cloud Foundry Community Buildpack.

      Irrespective of your development technologies, you must ensure that your application defines the required callbacks (See Step 2 of this Blog).

      You must architect your application in a way which allows you to define the callbacks and bind SaaS Provisioning Service.I hope this answers your query.

  • Hi Sandeep

     

    I have a new cloud platform (enterprise version) and this is the first thing I have done in it. I have not installed a HANA database as yet. I have picked up the cloud foundry endpoint from the Cloud Foundry subaccount in the box on the right hand side detailing the organisation, spaces, members and API endpoint (Sydney data centre: api.cf.ap10.hana.ondemand.com).

    The app builds and deploys successfully, but when I try to launch it, I get redirected to a SAP HANA XS Advanced logon page. If I use my cloud platform credentials, it does not work.

    Is there something I need to do to my user or do I need to create a role for this to work?

    Regards

    Neil

     

    • Hi Neil,

      Thank you so much for your query.

      I am really glad that you are using SAP CP and were successfully able to deploy the application.

      Coming to your query, this happens because of the Tenant Host Pattern we define in our MTA.yaml file.

      Can you please try to create a new route that complies with the following pattern:

      https://<sub-account sub domain>-<app name>.<cf app url>

      For further details please refer to the guide here

      • Hi Sandeep

        Thanks for your response. Your response appear to apply to creating a route manually after the app has been subscribed too.

        Unfortunately, the XSA login screen appears for me after completion of step 4. Does this mean I have the tenant url in Step 3 incorrect?

        Regards

        Neil

        • Hi Neil,

          I apologize for the delay in my response.

          When we define a Tenant Host Pattern in our MTA.yaml file, as we have done in this application, our application routes and URL must conform to this pattern.

          Your current application URL, for the provider sub-account, should look something like this:

          https://<org-name>-<sub-accountName>-<space>-<appName&gt;.<cf-app url>

          This route doesn’t comply with the tenant-host pattern defined by us in the MTA.yaml file.

          Thus, to access the provider’s application, you must create a route which matches the host pattern defined by us.

          For further understanding, you can remove the Tenant-Host Pattern and make other required changes (change UAA service to dedicated in xs-security.json) and deploy the application. When you do this, you will be able to access the application using the default URL constructed by the platform.

  • Hi Sandeep,

    While I am trying to delete the SaaS-registry instance, it throws the following error:

    Service instance pci-registry: Service broker error: SaaS application has active subscriptions for tenants: 50681641-b011-4073-9004-3e0267387329

    I am even not able to deploy my MTA application. It throws the following error:

    Error creating services: Error updating service “pci-registry” from offering “saas-registry” and plan “application”: Service broker operation failed: 502 Bad Gateway: Service broker error: Service broker parameters are invalid: appName can’t be changed.

    I have attached the screenshot of the same.

    Kindly help provide a solution to the same.

    Thanks and Regards

    Debojit

    • Hi Debojit,

      Thank you so much for your query.

      To delete a SaaS Provisioning Service the provider must ensure that there are no active subscriptions on the service.

      The flow to delete a SaaS Provisioning is as follows:

      1. Ask all tenants to un-subscribe your application.
      2. Verify that no active subscriptions are present on your service.
      3. Delete the SaaS provisioning service.

      For the other issue that you have encountered, I need more information. Can you please reach out to me internally?

      Thank you so much for your cooperation.

      I hope this response helps you.

      Warm Regards

      Sandeep T D S

       

  • Hi SANDEEP TDS ,

    I am trying to subscribe a tenant to my multitenant application written in java. I am on canary.

    From the tenant account, when i click on subscribe, the status shows as processing for sometime and then comes back to unsubscribed.

    when trying to subscribe through the REST API, I am able to get the access token,

    but when i hit the tenant onboarding url, i am, getting access denied error.

    I think I am missing something here.

    can you please help me with this.

    Maybe we can connect internally.

    • Hi Nandan,

      Thank you so much for your query.

      From what you’ve described in your comment, I believe the error could be in your application – either where you are defining the callbacks or where you configure the authentication.

      Can you please refer to this sample application, written in JAVA, and try to identify if there’s any deviation in your implementation?

      If you do not find any parity, I will be happy to assist you further.

      Warm Regards
      Sandeep T D S

  • Hi SANDEEP TDS,

    I’m trying to create a multi-tenant application based on HANA.

    Is it possible that we can grant some HANA db roles to tenant user when they subscribe the application?

     

    Thanks in advance,

    Regards,

    Sandy