简介
这篇博客的目的是展示不同的CAP项目中的几种表共享模式。我已经使用CAP大约一年了,但我还是HANA数据库的新手,所以希望大家能提出意见和建议。
场景
我想出了以下方案。
每个淡蓝色的盒子代表一个CAP项目,最左边的盒子里的 "Customers "是要被重用的实体。
* 请记住,这些方案纯粹是为了学习。在有些情况下,消费OData服务比直接访问数据库更合适。

- 一个与被重用的实体共享相同的HDI容器和命名空间的项目
- 一个项目共享相同的HDI容器,但使用与重用实体不同的命名空间
- 一个使用与被重用实体不同的HDI容器的项目
- 一个与被重用的实体在不同空间的项目
总结
下面的矩阵显示了每种情况下所需的工件的概况。

在下面的章节中,我将展示每个项目的设置。这些项目是使用HANA云计算试验开发的。整个代码可在下面的GitHub存储库中找到。
完成设置后,你可以从OData服务中访问重用的实体,可以使用/Customers 或/<mainenity>?$expand=customer 端点。

情景1
当你的项目与重用实体共享同一个HDI容器和命名空间时,你需要。
- 用
@cds.persistence.exists注释重复使用的实体。
namespace master.partners;
entity Vendors {
key ID: Integer;
name: String;
customer: Association to Customers
}
@cds.persistence.exists
entity Customers {
key ID: Integer;
name: String
}
- 使用与被重用实体相同的HDI容器服务实例。在mta.yaml中,指定资源类型为org.cloudfoundry.existing-service。
resources:
- name: master-db
type: org.cloudfoundry.existing-service
parameters:
service-name: master-db
情景 2
当你的项目共享同一个HDI容器,但使用与重用实体不同的命名空间时,你需要。
- 用
@cds.persistence.exists注释重复使用的实体。
namespace master.orgs;
entity Plants {
key ID: Integer;
name: String;
customer: Association to Customers
}
@cds.persistence.exists
entity Customers {
key ID: Integer;
name: String
}
- 创建**.hdbsynonym**文件,以便将重用实体的名称与你的命名空间相匹配。

{
"MASTER_ORGS_CUSTOMERS": {
"target": {
"object": "MASTER_PARTNERS_CUSTOMERS"
}
}
}
- 使用与重用实体相同的HDI容器服务实例(与场景1相同)。
情景3
当你的项目使用与重用实体不同的HDI容器时,你需要。
- 首先在被重用的项目中,创建角色以允许来自外部容器的访问。


*文件名可以是任何名字,只有扩展名重要。
MASTER_PARTNERS_EXTERNAL_ACCESS.hdbrole
{
"role": {
"name": "MASTER_PARTNERS_EXTERNAL_ACCESS",
"object_privileges": [
{
"name":"MASTER_PARTNERS_CUSTOMERS",
"type":"TABLE",
"privileges":[ "SELECT" ],
"privileges_with_grant_option":[]
}
]
}
}
MASTER_PARTNERS_EXTERNAL_ACCESS_G.hdbrole
{
"role": {
"name": "MASTER_PARTNERS_EXTERNAL_ACCESS_G#",
"object_privileges": [
{
"name":"MASTER_PARTNERS_CUSTOMERS",
"type":"TABLE",
"privileges":[],
"privileges_with_grant_option":["SELECT"]
}
]
}
}
这些文件看起来很相似,唯一的区别是第一个文件有 "SELECT "的 "特权",而第二个文件有 "SELECT "的 "privileges_with_grant_option"。之后,第一个角色将被分配给新创建的HDI容器的应用程序用户,第二个角色将被分配给同一容器的对象所有者。一旦您做出上述更改,请将项目部署到 Cloud Foundry。
接下来的步骤将在 "销售 "项目中执行。

- 用
@cds.persistence.exists对重复使用的实体进行注释。
namespace sales;
entity Orders {
key ID: Integer;
amount: Integer;
customer: Association to Customers;
}
@cds.persistence.exists
entity Customers {
key ID: Integer;
name: String;
}
- 创建**.hdbsynonym**文件,使重用实体的名称符合你的命名空间。
{
"SALES_CUSTOMERS": {
"target": {
"object": "MASTER_PARTNERS_CUSTOMERS",
"schema": "_PLACEHOLDER_"
}
}
}
在这种情况下,你需要指定模式,因为目标对象驻留在一个不同的模式中。但是"_PLACEHOLDER_"是从哪里来的?
为了提供模式名称,我们还需要一个文件:.hdbsynonymconfig。这个文件需要放在db/cfg下,如下图。db/cfg中的工件在部署时首先被处理。

- 创建.hdbsynonymconfig文件以提供模式名称。
{
"SALES_CUSTOMERS": {
"target": {
"object": "MASTER_PARTNERS_CUSTOMERS",
"schema.configure": "master-db/schema"
}
}
}
模式名称将取自 "master-db"服务实例的 "schema "属性。
- 创建**.hdbgrants**文件,为HDI容器用户分配角色。
{
"master-db": {
"object_owner": {
"container_roles": [
"MASTER_PARTNERS_EXTERNAL_ACCESS_G#"
]
},
"application_user": {
"container_roles": [
"MASTER_PARTNERS_EXTERNAL_ACCESS"
]
}
}
}
顶部的 "master-db"是重复使用的HDI容器服务实例,它是这些权限的授予者。
- 将重复使用的实体**(master-db**)的HDI容器服务实例添加到mta.yaml中。
# --------------------- SERVER MODULE ------------------------
- name: sales-srv
# ------------------------------------------------------------
type: nodejs
path: gen/srv
parameters:
buildpack: nodejs_buildpack
requires:
# Resources extracted from CAP configuration
- name: sales-db
- name: master-db
provides:
- name: srv-api # required by consumers of CAP services (e.g. approuter)
properties:
srv-url: ${default-url}
# -------------------- SIDECAR MODULE ------------------------
- name: sales-db-deployer
# ------------------------------------------------------------
type: hdb
path: gen/db
parameters:
buildpack: nodejs_buildpack
properties:
TARGET_CONTAINER: sales-db
requires:
# 'hana' and 'xsuaa' resources extracted from CAP configuration
- name: sales-db
- name: master-db
resources:
# services extracted from CAP configuration
# 'service-plan' can be configured via 'cds.requires.<name>.vcap.plan'
# ------------------------------------------------------------
- name: sales-db
# ------------------------------------------------------------
type: com.sap.xs.hdi-container
parameters:
service: hana # or 'hanatrial' on trial landscapes
service-plan: hdi-shared
properties:
hdi-service-name: ${service-name}
- name: master-db
type: org.cloudfoundry.existing-service
parameters:
service-name: master-db
这里,两个HDI容器分别被srv模块和db部署器模块使用。为了让部署者知道哪个容器要部署项目自己的工件,属性TARGET_CONTAINER被指定。
情景四
当你的项目在与重用实体的HDI容器不同的空间时,你需要创建一个用户提供的服务,其中包含一个数据库用户,他有权限授予重用实体的访问。下面的图片显示了所需的用户和角色分配给用户。

- 用DBADMIN用户进入数据库资源管理器,打开SQL控制台。

- 检查角色名称和相应的模式名称。要做到这一点,请执行下面的语句。'MASTER_PARTNERS%'是我们在方案3中创建的角色名称的一部分。
select * from roles where role_name like 'MASTER_PARTNERS%';
因此,你会得到角色名称和它们的模式名称。

- 创建一个新的数据库用户,并将上述角色分配给管理员选项。这样,这个用户就可以把 "MASTER_PARTNERS_EXTERNAL_ACESS_xx "角色授予其他容器用户。
create user UPS_GRANTOR password "UpsGrntr01" no FORCE_FIRST_PASSWORD_CHANGE;
grant "<schema_name>"."MASTER_PARTNERS_EXTERNAL_ACCESS_G#" to UPS_GRANTOR with admin option;
grant "<schema_name>"."MASTER_PARTNERS_EXTERNAL_ACCESS" to UPS_GRANTOR with admin option;
- 现在我们已经有了一个授予者用户,在dev2空间创建一个用户提供的服务。在你的终端执行以下cf命令。
cf create-user-provided-service cross-schema-master-partners -p '{ \"user\": \"UPS_GRANTOR\", \"password\": \"UpsGrntr01\", \"driver\": \"com.sap.db.jdbc.Driver\", \"tags\": [\"hana\"], \"schema\": \"<schema_name>\" }'
* 你提供参数的方式因你的机器而异。要检查它,请执行cf create-user-provided-service -h 。这里我使用的是Windows PowerShell模式。
Linux/Mac:
cf.exe create-user-provided-service my-db-mine -p '{"username":"admin","password":"pa55woRD"}'
Windows Command Line:
cf.exe create-user-provided-service my-db-mine -p "{\"username\":\"admin\",\"password\":\"pa55woRD\"}"
Windows PowerShell:
cf.exe create-user-provided-service my-db-mine -p '{\"username\":\"admin\",\"password\":\"pa55woRD\"}'
剩下的步骤与方案3相似。
- 用以下内容来注释重用的实体
@cds.persistence.exists
namespace accounting;
entity Invoices {
key ID: Integer;
amount: Integer;
customer: Association to Customers
}
@cds.persistence.exists
entity Customers {
key ID: Integer;
name: String;
}
- 创建**.hdbsynonym**文件,使重用实体的名称符合你的命名空间。
{
"ACCOUNTING_CUSTOMERS": {
"target": {
"object": "MASTER_PARTNERS_CUSTOMERS",
"schema": "_PLACEHOLDER_"
}
}
}
- 创建**.hdbsynonymconfig**文件以提供模式名称。这个文件应该放在db/cfg下。
{
"ACCOUNTING_CUSTOMERS": {
"target": {
"object": "MASTER_PARTNERS_CUSTOMERS",
"schema.configure": "cross-schema-master-partners/schema"
}
}
}
模式名称将取自 "cross-schema-master-partners"服务实例的 "schema "属性,它是我们在上一步创建的用户提供的服务。
- 创建**.hdbgrants**文件,将角色分配给HDI容器用户。
{
"cross-schema-master-partners": {
"object_owner": {
"container_roles": [
"MASTER_PARTNERS_EXTERNAL_ACCESS_G#"
]
},
"application_user": {
"container_roles": [
"MASTER_PARTNERS_EXTERNAL_ACCESS"
]
}
}
}
- 将用户提供的服务实例**(cross-container-master-partners**)添加到mta.yaml。
# --------------------- SERVER MODULE ------------------------
- name: accounting-srv
# ------------------------------------------------------------
type: nodejs
path: gen/srv
parameters:
buildpack: nodejs_buildpack
requires:
# Resources extracted from CAP configuration
- name: accounting-db
- name: cross-schema-master-partners #add
provides:
- name: srv-api # required by consumers of CAP services (e.g. approuter)
properties:
srv-url: ${default-url}
# -------------------- SIDECAR MODULE ------------------------
- name: accounting-db-deployer
# ------------------------------------------------------------
type: hdb
path: gen/db
parameters:
buildpack: nodejs_buildpack
requires:
# 'hana' and 'xsuaa' resources extracted from CAP configuration
- name: accounting-db
- name: cross-schema-master-partners #add
resources:
# services extracted from CAP configuration
# 'service-plan' can be configured via 'cds.requires.<name>.vcap.plan'
# ------------------------------------------------------------
- name: accounting-db
# ------------------------------------------------------------
type: com.sap.xs.hdi-container
parameters:
service: hana # or 'hanatrial' on trial landscapes
service-plan: hdi-shared
properties:
hdi-service-name: ${service-name}
- name: cross-schema-master-partners
type: org.cloudfoundry.existing-service
parameters:
service-name: cross-schema-master-partners
总结
在这篇博客中,我解释了在不同CAP项目中共享表的四种模式。
-
与重用实体共享同一HDI容器和命名空间的项目
- 不需要特殊的设置。只要使用相同的HDI容器服务实例作为重复使用的实体。
-
一个共享相同的HDI容器的项目,但使用与重用实体不同的命名空间
- 需要.hdbsynonym来使重用实体的名字空间与你的名字空间相适应。
-
一个使用与被重用实体不同的HDI容器的项目
- .hdbsynonym是必需的,以使重用的实体的名字空间与你的名字空间相适应。
- 需要.hdbsynonymconfig来为同义词提供模式名称。
- .hdbgrants是必需的,以授予HDI容器用户访问重用实体的权限。
-
在与被重用实体不同的空间中的一个项目
- 需要一个用户提供的服务 来实现跨空间的访问。
- .hdbsynonym是必需的,以使重用实体的命名空间与你的命名空间相适应。
- 需要.hdbsynonymconfig来为同义词提供模式名称。
- .hdbgrants是用来给HDI容器用户分配访问重用实体的权限的。