Findings of the SAP Mobiliser 5.1 data model: #1 – multi-tenant capable?
I’m currently participating in a bootcamp on SAP Mobiliser 5.1. During this learning phase, I’m stumbled about some questions or topics which need further explanation and/or or expert’s enlightenment. Perhaps these are typical beginner’s understanding problems.
I’ll try to compile these topics in this blog series.
Please see also my other Mobile blogs.
Data Model and Data Access Objects
I’ve read about the Mobiliser data model and performed the first steps in development. The related examples (Hands-On labs) are available here: http://scn.sap.com/docs/DOC-40367
Database tables are accessed using the Java framework Hibernate: typically DAO (Data Access Object) classes will be used to query the database. These classes will provide methods like:
If using a getById query, the given ID is the primary key (a single column). The resulting WHERE statement won’t contain a tenant/org-unit/client related criterion.
#1 – Multi-tenant capabilities
SAP Mobiliser claims to be multi-tenant capable, see for example this excerpt from the document Money_Mobiliser_5.1_Architecture_and_Businesslogic.pdf:
2.1.9 Table MOB_ORGUNITS
Lists the org-units where entities can belong to – provides multi-tenancy to the system.
Usually for each new Mobiliser installation one or multiple org-units are created. The org-unit is the way to
handle multiple tenants in one system. Business rules can be configured based on the org-unit that is assigned
to a customer. Usually, a customer is created in an org-unit and this org-unit is never changed. The org-unit
Definition in Wikipedia
Multi-tenancy vs. client-capability
Is there a difference between multi-tenancy and client-capability?
This is the http://SAPterm definition:
Principle of software architecture in which a single software instance c an run for multiple tenants on a single application server. In a multitenancy AS ABAP, application clients are the tenants.
The related definition of Client is:
Organizational unit in AS ABAP. Each logon to AS ABAP must include a client ID. This ID indicates a logon to a specific client. The various clients in an AS ABAP have separate user master records and separate authorizations. Client-specific data is split by the client column in application tables. Application programs generally run in application clients. Alongside these, a system client and optional administration clients are used to run system-specific or administration tasks. On an AS ABAP that supports multitenancy, tenants are mapped to clients.
As being both Java and ABAP developer, this summarizes my understanding of the traditional SAP Business Suite: each client-specific table has a column “CLIENT” (or MANDT). This matches with above statement:
Client-specific data is split by the client column in application tables.
This CLIENT (or MANDT) column will be the first part of the table’s composed primary key (exception is table T000 – there it’s the only key).
In ABAP, the current client will be used for any database query automatically – unless it’s a non-client specifc table or the CLIENT is specified explicity using ABAP keywords. The later case will be logged in the system protocol and AFAIK could be switched off. So a strict separation of client-specifc records is given by the ABAP runtime framework.
If using Hibernate, a typical primary key query will use a single ID value – there exists no concept of automatically adding the current CLIENT. So it would be possibly (by program error or by malicious code) to read master data of a different tenant (org-unit).
For a simple example of the problem, let’s take the Mobiliser table MOB_ERROR_CODES:
/*==============================================================*/ /* Table: MOB_ERROR_CODES */ /*==============================================================*/ create table MOB_ERROR_CODES ( ID_ERROR_CODE NUMBER(5) not null, ID_ERROR_LEVEL VARCHAR2(80 char) not null, STR_INFORMATION VARCHAR2(200 char) not null, DAT_CREATION TIMESTAMP, ID_CUSTOMER_CREATION NUMBER(18), DAT_LAST_UPDATE TIMESTAMP, ID_CUSTOMER_LAST_UPDATE NUMBER(18), constraint PK_ERROR_CODES primary key (ID_ERROR_CODE) )
As ID_ERROR_CODE is the primary key, this means that two tenants cannot have the same error code (e.g. 10001) with different meaning. The normal workaround would be to separate the tenants by a number range, e.g. tenant 1 error codes are in the range 10000-19999, tenant 2 in the range from 20000-29999 and so on.
This is only a simplistic example, but it shows the problem with the missing CLIENT column. (As a side note: the error text isn’t multi-language capable – no language indicator, not of type Unicode).
There exist several tables which have a column ID_ORGUNIT defined and this is in fact a starting point. And I’ve read about the programming logic where first this column is checked for an exact match and afterwards a test on “null” is performed.
This logic is described for example in the description of column ID_ORGUNIT of table MOB_CUSTOMERS_IDENTIFICATIONS (chapter 2.1.5):
The org-unit this identification belongs to. This field is optional, and we check that the combination of STR_IDENTIFICATION and ID_ORGUNIT is unique. Also, if the org-unit field is filled for identifications, any Mobiliser service calls passing in an identification must also fill the org-unit field in order to match.
In ABAP, the CLIENT column never could be “null” or initial as it’s part of the primary key.
In my opinion, the multi-tenancy concept in SAP Mobiliser can’t be compared to the traditional ABAP data model of client-capability:
- less powerful – no built-in separation of records
- cannot restrict reading (changing?) other tenant’s records
- less performant – no primary key query
I’m interested in your feedback about this topic – especially whether this caused any trouble in real-world projects.
The next blog in this series will be about the grouping of customers.
Thank you for sharing the insight, it's helpful.
A quick clarification, is it only the ERROR_CODES table that doesn't have Org Unit field to support multi-tenancy or is it true for most of the tables.
I am sure as a ABAPer you would also appreciate the concept of Client Dependent and Client Independent tables in SAP. Just noticed that the Error Messages tables in ABAP is also client independent, so wondering if it's the same designing principle in Mobiliser as well. http://help.sap.com/abapdocu_702/en/abenabap_messages_storing.htm
most of the tables do NOT contain the OrgUnit field. In the reference documentation Architecture and Businesslogic the following tables are explicitly listed as having a ID_ORGUNIT column:
Additionally I've performed a database search and found the following tables containing the column ID_ORGUNIT too:
Most probably the prefix MOB stands for the Mobiliser core and MBA for the mBanking component.
Thnaks for pointing out the differentiation between client-dependent and client-independent tables. Of course I know this and the related effect/warnings especially during customizing. The basis for this differentiation is a solid client concept though, which I am missing here.
My main concern for this article was, that one could read data from a different client (OrgUnit) if using a getXyzById() query. There is no automatic mechanism which will prevent reading records from a different client.
I think you're making a good distinction here between multi-tenancy and multi-client capability. I'm not sure if these words are commonly used and most likely they mean different things to different people, but Mobiliser is not intended to run different clients on a single system in total isolation.
Instead, the Architecture and Businesslogic document describes a couple of the configurations that relate to org-units, and what that concept is really used for in Mobiliser installations is rather setting up different tenants, where customers of these tenants can still interact between each others - but configuration of businesslogic might be different.
You might rather think of this setup being a consortium of different companies operating a Mobiliser installation. If we had to support strict multi-client installations, we would rather setup distinct Mobiliser installations, in particular distinct databases.