After you have deployed the sample application the following components will be available in your provider account:
- Application Router for handling multitenancy authentication
- UI Component providing the user interface of the app
- Business Application Service for onboarding and providing OData services
- API Service for external data integration
- API Broker for creating an API Service Broker
- Tenant database containers for tenant-specific data
- Shared database container for data shared among all tenants
- Resiliency components to make the app more resilient
- Further information
This part of the mission will provide deeper insights into the different components and let you build up some expert knowledge about topics like Service Brokers or Multitenancy. The screenshot below shows the architecture of the Basic Scope which can be done using Free (Tier) service plans of your own Pay-as-you-Go (PAYG) or CPEA account.
Hint - The Basic Scope can also be done in Trial accounts, although we recommend to use one of the account types mentioned above.
Important - Find more details in the Multitenancy Readme Reamde document!
The application router is the single point of entry for most applications running in SAP BTP. An application router can be used to serve static content, authenticate users, rewrite URLs, and forward or proxy requests to other microservices while propagating user and tenant information.
Each multitenant application has to deploy its own application router, and the application router handles requests of all tenants to the application. The application router is able to determine the tenant identifier out of the URL and then forwards the authentication request to the tenant User Account and Authentication (UAA) service and the related identity zone.
The user interface of this sample application has been developed using SAP Fiori Elements. SAP Fiori Elements applications benefit from a template and metadata-driven approach. SAP Fiori Elements provides designs for UI patterns and predefined floorplans for common application use cases. App developers can use SAP Fiori Elements to create SAP Fiori applications based on OData services and annotations that don't need JavaScript UI coding.
The resulting Fiori Elements components use predefined views and controllers that are provided centrally. This means no application-specific view instances are required. SAPUI5 interprets metadata and annotations of the underlying OData service and uses the corresponding views for the SAP Fiori app at startup. Still, SAP Fiori Elements applications can be extended with minimal coding effort.
To learn more about SAP Fiori Elements please check out the excellent SAP Fiori elements for OData V4 Feature Showcase and the links provided in the Further Information section.
Important - Find more details in the Helper Classes Reamde document!
The service layer of the sample application has been developed using the SAP CAP framework. It provides OData services for the UI component and has built-in support for multitenancy with an SAP HANA Cloud database. Furthermore, it provides the (un-)subscription callbacks required for tenant onboarding. While the OData service definition and the custom handlers are straightforward, most of the interesting code snippets can be found in the helper functions and classes used for the automation of subscription requirements. The Business Application Service also contains the annotations required by SAP Fiori Elements for automatically rendering a proper UI.
Important - Find more information on how to use the SaaS API in the following part of this mission (click here)!
For consumers that want to push data to their database container instances, an API endpoint has been developed using CAP. Tenants can use this API to push data to their own SAP HANA HDI containers for calculation and analysis purposes. The API is accessible using client credentials provided to consumer tenants using a service instance of the SaaS API Service Broker. Check out the next chapter to find out how to push data to this API as a SaaS consumer.
Below you can see the available entities of the SaaS API like Product details and Sales Orders.
Besides the default CRUD methods for entity maintenance, also sample actions are provided allowing bulk upload (DELETE & INSERT) for the main application entities. Finally, you can find samples for OData actions allowing you to bulk-update products using CAP CQL UPDATE feature and to bulk-upsert Sales Orders using an SAP HANA Stored procedure.
Important - Find more details in the Service Broker Reamde document!
Service brokers manage instances of services used by applications running in the SAP BTP environment.
A service broker is responsible for managing service instances of a certain service implementation. Such service instances can then be bound to applications that require the features provided by such a service implementation. For this purpose, a service broker can also be used to create and manage bindings between service instances and applications that want to make use of the service features.
In this application scenario, we created an API for SaaS subscribers as a backing service. Therefore, the service broker is responsible for creating SaaS API service instances in the tenant subaccounts. Using these service instances, subscribers can then create so-called service bindings, providing them with client credentials to interact with the SaaS API. Both, creating a service instance and corresponding service bindings, are handled by the API Service Broker.
The application provides a sample data model, which supports a flexible usage of SAP Fiori Elements for OData v4 including features like Draft support. This data model is deployed upon subscription of a consumer tenant into a new SAP HANA HDI database container. You don't have to take care of this process as it is automatically handled by the Service Manager Instance (container plan). Check the Further Information section to learn more about the HDI Containers managed by the Service Manager. Using the HANA Deployment Infrastructure (HDI) and associated containers, allows secure isolation of all tenant-related data.
As CAP is a great backing service for the usage of SAP Fiori Elements providing the required OData services and annotations, also the data model structure has to be compliant with an easy-to-consume user interface usage.
Furthermore, the requirement for a tenant-based SaaS API is fulfilled by dedicated tables which each consumer can maintain using the SaaS API. By decoupling these tables from draft-enabled application tables, consumers can decide to prefill content into their assessments but are also flexible in setting up their own scenarios using the manual data input.
Below you can see an overview pf the tables deployed into new tenant database containers upon subscription.
Hint - The Roles table is only used for local development scenarios. If running the app in SAP BTP, the roles are automatically fetched from SAP XSUAA and no separate storage is required.
Important - Find more details in the Shared Container Reamde document!
To have the ability to share data among your consumer tenants, a shared database container is set up for the sample scenario. This allows the provider to maintain e.g. master data (Languages, Countries, Currencies) in a central place and update it simultaneously for all consumer tenants. This concept is building on the cross-container access capabilities of database containers.
To make your SaaS application more resilient additional services are used by the solution.
Autoscaler
The Autoscaler is declared in the deployment descriptor and scaling rules can be defined in the respective requires section of the applications using the Autoscaler service instance. Below you can see an up- or downscale based on memory and CPU consumption of the business application service.
# ----------------- AUTOSCALER ------------------------------------
- name: susaas-autoscaler
# ------------------------------------------------------------------
type: org.cloudfoundry.managed-service
parameters:
service: autoscaler
service-plan: standard
# --------------------- SERVER MODULE ------------------------
- name: susaas-srv
# ------------------------------------------------------------
type: nodejs
path: gen/srv
...
requires:
- name: susaas-autoscaler
parameters:
config:
instance_min_count: 1
instance_max_count: 2
scaling_rules:
- {"metric_type": "memoryutil","threshold": 80,"operator": ">=","adjustment": "+1"}
- {"metric_type": "memoryutil","threshold": 60,"operator": "<","adjustment": "-1"}
- {"metric_type": "cpu","threshold": 80,"operator": ">=","adjustment": "+1"}
- {"metric_type": "cpu","threshold": 30,"operator": "<","adjustment": "-1"}
Alert Notification
The Alert Notification service instance is declared in the deployment descriptor (mta.yaml) and further detailed configurations can be found in an additional config file (configs/alert-notif.json).
# ----------------- ALERT NOTIFICATION ----------------------------
- name: susaas-alert-notification
# ------------------------------------------------------------------
type: org.cloudfoundry.managed-service
parameters:
service: alert-notification
service-plan: standard
service-name: susaas-alert-notification
path: ./configs/alert-notif.json
As already explained, please make sure to update the recipient's e-mail address in the config file before deploying the solution. After deployment, check your inbox to confirm that Alert Notification may sent e-mails to you.
{
"actions": [
{
"type": "EMAIL",
"name": "send-email",
"state": "ENABLED",
"properties": {
"destination": "[email protected]",
"useHtml": "false"
}
}
]
}
Besides default lifecycle events being monitored by Alert Notification like Stop or Crash of your application, also a generic alert is defined in the config file. This event type can e.g., be used from within your application coding.
{
"name": "Audit-App-Process-Crash",
"propertyKey": "eventType",
"propertyValue": "audit.app.process.crash"
},
{
"name": "Alert-App-Generic",
"propertyKey": "eventType",
"propertyValue": "alert.app.generic"
}
A sample of how to manually trigger an Alert Notification event can be found in the error handler of the subscription UPDATE implementation (srv/provisioning.js). The respective helper class can be found in the srv/utils folder (srv/utils/alertNotification.js).
try {
let automator = new Automator();
await automator.deployTenantArtifacts(tenant, tenantSubdomain, user);
} catch (error) {
console.log("Automation skipped!");
await alertNotification.sendEvent({
type : 'GENERIC',
data : {
body : JSON.stringify(error),
subject : 'Error during automation of tenant onboarding!',
eventType : 'alert.app.generic',
severity : 'FATAL',
category : 'ALERT'
}
});
}
The result of such a custom event looks similar to the following screenshot.
Please use the following links to find further information on the topics above:
- SAP Help - Application Router
- SAP Help - Multitenancy
- npmjs - @sap/approuter
- Fiori Design Guidelines - SAP Fiori Elements
- SAPUI5 - Developing Apps with SAP Fiori Elements
- GitHub - SAP Fiori Elements for OData V4 Feature Showcase
- CAP documentation - Serving Fiori UIs
- CAP documentation - Welcome to CAP
- SAP Blog - The hidden life of ServiceManager handled containers
- Youtube - In 1 Take HiddenLife
- Youtube - Multitenant Business Applications with CAP
- SAP Help - Application Autoscaler
- SAP Help - SAP Alert Notification service for SAP BTP