Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
jan_zwickel
Product and Topic Expert
Product and Topic Expert
One benefit of using the HANA Deployment Infrastructure (HDI) is that a clear interface exists that lists the dependencies to objects outside of the respective HDI container. With this it becomes pretty simple to adapt a project that should run in a different environment, such as when moving a project that has been developed in an on premise XSA environment with SAP Web IDE for SAP HANA to SAP HANA Cloud.

Below several concepts are illustrated that help to adapt existing projects that refer to objects that are not contained in the project.

The main challenge you will face when moving your project to a different environment is that you cannot rely on resources that are not included in your project. For example, resources might only exist under a different name or schema. The new development concepts of SAP HANA, in particular the deployment with the SAP HANA Deployment Infrastructure (HDI), prepares you for this task by abstracting away dependencies to resources outside of your project. Dependencies in HDI come into your project via mainly two routes:

  1. Authorizations for objects outside of the project can create dependencies. One way to abstract away the actual database users that grant the privileges is by using services that execute the granting. If you have a service in your target system that can execute the grants, you don't have to take care of issuing grants on individual database user level. The service takes care instead to use the right database users based on its definition in the target system.

  2. Objects in your project such as views can have dependencies on objects that are not managed by your project, e.g., tables in other HDI containers or other schemas. You refer to such outside objects via synonyms. With synonyms, there is a clear interface that abstracts away the target object. If you move your project to a different environment, you only need to adapt the synonyms to point to the objects in the new environment. Using synonyms helps taking care of potentially multiple references to the same table: only one synonym needs to be changed independently of the number of references to it.


Step 01 - Ensure that features available in the target environment are made available in your project


Your first step is to make sure that your project can take advantage of potential new features. This becomes particularly relevant if you move to SAP HANA Cloud in which features typically become available first. You can do this by changing the .hdiconfig file, which determines which features can be used.

To ensure you have the newest feature set of your target system enabled, you can create a dummy project using the offered template and copy the respective .hdiconfig file from this template.

Step 02 – Prepare roles to grant privileges for target objects


In the target system objects with the same structure as in the source system are required if they are used by the moved project. These objects might have been imported, migrated, replicated, or federated by using virtual tables. Independent of the exact means by which these objects become available in the target system, you need to ensure that your project has the required authorizations to access them.

One option to administrate these privileges is to create dedicated SQL roles that contain the required privileges. If you want to develop calculation views, SELECT WITH GRANT OPTION on the used external objects needs to be granted to the object owner of the project in which you want to create the calculation view. Similarly, SELECT on the objects should be granted to the application users.

The following statements would create a SQL role that grants SELECT privileges on schema VT_SCHEMA with GRANT OPTION and a second SQL role without this GRANT OPTION. These roles could be used in the .hdbgrants file to authorize the object owner and application users (see next section):
CREATE ROLE "GrantSELECTOnVT_SCHEMAWithGRANT";
GRANT SELECT ON SCHEMA VT_SCHEMA to "GrantSELECTOnVT_SCHEMAWithGRANT" with GRANT OPTION;

CREATE ROLE "GrantSELECTOnVT_SCHEMA";
GRANT SELECT ON SCHEMA VT_SCHEMA to "GrantSELECTOnVT_SCHEMA";

Step 03 – Grant roles for external objects to object owner and application user


There are several options how to grant a role to the object owner and the application users of your project.

A.     Using SQL Statements


The easiest option might be to use a user with system privilege ROLE ADMIN, or the user who created the role. With these users you can grant the role to a default role that is assigned to every object owner of projects in Web IDE or Business Application Studio:
GRANT "GrantSELECTOnVT_SCHEMAWithGRANT" TO _SYS_DI#BROKER_CG"."_SYS_DI_OO_DEFAULTS";

Similarly, you can assign a role to every application user of projects created in Web IDE or Business Application Studio:
GRANT "GrantSELECTOnVT_SCHEMA" TO "BROKER_USER"."RT_DEFAULTS";

B.     Using a user-provided service


You can also assign the role using a user provided service. To do so:

  1. Create a user-provided service, e.g., by using the graphical user interface in Business Application Studio:

  2. Assign the role to your database user of your user-provided service that you want to use to authorize your project users. Alternatively, see here how to grant privileges using a procedure. Using a procedure can help reducing the number of privileges that are directly assigned to the user behind the user provided service

  3. Use a .hdbgrants file to assign the role to the object owner of the project. To do so, create a .hdbgrants file within the src folder of the project. Here is an example of the contents of a .hdbgrants file that grants the respective roles from above to the object owner (section “object_owner” and the application users (section “application_user”):


{
"<user-provided service>": {

"object_owner": {
"roles": ["GrantSELECTOnVT_SCHEMAWithGRANT"]
},

"application_user": {
"roles": ["GrantSELECTOnVT_SCHEMA"]
}

}
}

Step 04. Adapt the synonyms to point to the new targets


There are several ways of changing to which target object a synonym is pointing. The options depend on the way the synonym is defined. In the examples below we assume that the target schema name has to be changed

  • Option A - Pointing directly to the objects

  • Option B - Using a schema-configure approach

  • Option C - Using a logical schema approach


 

A.     Point directly to the objects


A synonym can point directly to a target object. In this case you will need to change the target schema for each object if you use the project in another database with a different schema name in which the objects reside.

Here is an example, how a file with extension “.hdbsynonym” would define the reference to an object
{
"TLOGF ": {
"target": {
"object": "TLOGF",
"schema": "VT_SCHEMA"
}
}
}

 

B.     Use a schema-configure abstraction


You can also point your synonyms to the target objects using an approach that takes the target schema from a user-provided service. You can achieve this by defining a .hdbsynonymconfig file that overwrites the “template” of the .hdbsynonym files at runtime and refers to the schema of your service there.

This gives you the flexibility to make a change at a single location (the schema defined for the user-provided service) that will affect all these synonyms at once.

Below is an example for table TLOGF:
"TLOGF": {
"target": {
"object": "TLOGF",
"schema.configure": "UPSWithSchema/schema"
}
}

The schema information is provided by the user-provided service in this approach. Therefore, a user-provided service must be added to the project. This also works for multiple schemas if you use different tags for the schemas in the user-provided service see e.g. FAQ.

 

C.     Use a logical schema abstraction


Synonyms can also make use of logical schemas. The advantage of this option is that it allows you to adapt all the target schemas for several objects with one small change, by changing the logical schema file (.hdblogicalschema) under the cfg folder: Redirect your existing synonyms to the new schema by pointing to the schema in a file with ending “.hdblogicalschema” in folder “cfg”.

Here is an example how a source schema could be “translated” into a target schema using a .hdblogicalschema file:
"sourceSchema" : {
"target": {
"schema" : "targetSchema"
}
}

 

The respective .hdbsynonym file could look like:
{
"TLOG_F": {
"target": {
"object": "TLOG_F",
"logical_schema": "sourceSchema"
}
}
}

 

The logical schema abstraction can be combined with the schema-configure abstraction by using a file with the extension .hdblogicalschemaconfig. Details can be found e.g., in the SAP HANA documentation.
6 Comments
Cocquerel
Active Contributor

Thanks, great blog.
I would just add 2 comments related to security:
- SELECT privilege on application users could be replace by SELECT METADATA privilege if your application users do not access directly the external objects but only via your Calculation views. SELECT METADATA privilege is the minimum required for the synonym search help in the calculation view editor to work.
- For the user provided service, for security reason, I would recommend to use grantor procedure as explained here https://blogs.sap.com/2018/04/06/best-practices-and-recommendations-for-developing-hdi-based-roles/

jan_zwickel
Product and Topic Expert
Product and Topic Expert
Thanks Michael for these helpful comments!

You are correct that strictly speaking SELECT METADATA is enough for the modeler. However, it would mean that data previews directly on the tables do not work. I think this is often useful for developers. From a security perspective the developers could wrap a calculation view around the table and see the data this way anyway. Therefore, I see this more as a convenience feature to grant SELECT.

Using a procedure for granting the privileges reduces the "direct power" of the user behind the user provided service and your link is very helpful in this regard which I've added in the post

Best,

Jan

 

 
Cocquerel
Active Contributor
an other comment regarding usage of hdbgrants behavior that was confusing to me initially. When you remove authorization from hdbgrants files and build/deploy your project again, the corresponding authorizations are not removed from application or object owner users. You have to explicitly revoke them in an hdbrevokes file.
jan_zwickel
Product and Topic Expert
Product and Topic Expert
Hi Michael,

yes, if you grant privileges directly in .hdbgrants files you need a hdbrevokes file. Another option would be to grant roles instead. Revoking privileges from roles takes effect immediately. See e.g., section

"WHY ARE PRIVILEGES NOT REVOKEDTHAT HAVE BEEN GRANTED VIA .HDBGRANTS FILES EVEN AFTER THE .HDBGRANTS FILES HAVE BEEN DELETEDAND THE PROJECT HAS BEEN SUCCESSFULLY BUILTIN E.G. BUSINESS APPLICATION STUDIO OR WEB IDE?"

in FAQ linked here.

Best,

Jan
maxnuf
Explorer
On top of hdblogicalschema, you additionally can add an hdblogicalschemaconfig in /cfg.

This way the actual schema can be taken from a service.
"sourceSchema" : {
"target": {
"schema.configure": "UPSWithSchema/schema"
}
}


You will need to include hdblogicalschemaconfig in your .hdiconfig file.
jan_zwickel
Product and Topic Expert
Product and Topic Expert
0 Kudos
Thank you maxnuf for this suggestion. I have added this option to the main text.