本文档为CAP for Nodejs入门练习 | SAP Blogs 的后续,本练习会将前一练习的结果部署到SAP BTP的Cloud Foundry容器运行时中去,其中涉及到云端环境准备,本地代码修改
着重需要强调的一个概念就是MTA,是多目标应用的缩写称呼,是一个部署框架,CAP编程框架一般结合MTA框架下的MBT部署工具来完成对前后端数据库的整体打包,最后基于CF脚手架进行一站式部署
文档最后还涉及了approuter,是一个SAP官方推荐的作为前端单一入口的服务器应用,这个应用没有UI界面,但是可以将其他各种语言开发的前端界面囊括在一起,作为一整个服务部署上云,从用户的角度看到的一个前端服务背后其实可能是由多个微服务组成
Cloud Foundry是一款开源PaaS平台,提供了应用全生命周期管理的功能,BTP底层采用了Cloud Foundry作为容器运行时,也提供给客户用来部署自己的应用,对该平台感兴趣的可以查阅Cloud Foundry开源PaaS平台概况介绍 | SAP Blogs
在部署应用之前,首先我们需要打开BTP中控台中的CF服务:子账户–概览-Cloud Foundry环境-启用Cloud Foundry
在弹窗中修改实例名称,点击创建,即可打开服务
接下来子账户左侧的 服务 下就会出现 Cloud Foundry菜单,点击其下的 空间 ,在左上角点击 创建空间,填写空间名和给自己的权限后就会看到这个空间了
最后,CF可以在BTP中控台进行操作,但是更多时候依赖命令行的CF CLI来完成操作,所以我们需要安装 CF的CLI脚手架:https://developers.sap.com/tutorials/btp-app-_install-the-cloud-foundry-command-line-interface.html
安装好之后就可以在命令行登录到CF环境了:
打开BTP中控台-进入子账户-记录Org Name,API Endpoint和Org ID,接下来需要这几个属性来登录CF到子账户中
打开命令行:
cf api <API Endpoint of your landscape>(这里输入先前从子账户Overview获取的API Endpoint)
cf login
接下来按照提示输入用户名,密码,选择org Name和space,即可完成登录
在cpapp目录下执行
cds add hana –for production
这一步会在根目录的package.json内cds-require下添加一个”[production]”结构,内容为”db”:”hana”,意思即为在生产部署时使用hana的数据库引擎。
我们需要一个HANA Cloud实例用以部署我们的数据库内容,
如果你已经有其他现存的HANA Cloud实例,请将该HANA 实例和此次新创建的space相连:
进入已有HANA Cloud实例的子账户 – 左侧Cloud Foundry菜单 – space – 选择存在HANA 实例的space – 左侧SAP HANA Cloud 菜单 此处即会显示现有的实例,
再在右上角点击 管理HANA Cloud – 进入HANA Cloud Central后默认会将搜索条件设置在当前子账户/org和space,点击实例名 – 点击右上角的Create Mapping – 填入本次练习的目标space参数即可
如果当前任一space都没有创建过HANA Cloud实例:首先要将HANA Cloud权利分配给当前子账户:请参阅SAP Business Technology Platform (BTP) 中控台概览及基本操作练习 | SAP Blogs 中的3,4,5,6
然后创建HANA Cloud实例:请参阅Provision an Instance of SAP HANA Cloud, SAP HANA Database | SAP Tutorials,
开发环境和生产环境比较大的区别除了数据库之外就是各种外部服务了,其中身份服务是最基础的一项,这里先为本地代码配置上身份服务(XSUAA即XS User Authentication and Authorization service):
cds add xsuaa –for production
此时检查cpapp/package.json即可看到cds – require – [production]
同时在cpapp目录下会生成一个xs-security.json文件,生成时会根据package.json定义过的用户自动生成身份配置:
{
//scope即最细的权限颗粒,不能直接赋予用户,需要赋予role-template来间接赋予用户
"scopes": [
{
"name": "$XSAPPNAME.RiskViewer",
"description": "RiskViewer"
},
{
"name": "$XSAPPNAME.RiskManager",
"description": "RiskManager"
}
],
"attributes": [],
//这里定义的两个role各自只包含一个scope
"role-templates": [
{
"name": "RiskViewer",
"description": "generated",
"scope-references": [
"$XSAPPNAME.RiskViewer"
],
"attribute-references": []
},
{
"name": "RiskManager",
"description": "generated",
"scope-references": [
"$XSAPPNAME.RiskManager"
],
"attribute-references": []
}
]
}
现在的代码已经包含了生产环境下对数据库和身份服务的引用,这里我们安装mbt工具来部署这份代码:
npm install –global mbt
如果你使用的是windows系统,还需要安装make工具,这个工具在linux系操作系统是预装好的
进入网站下载安装包Make for Windows (sourceforge.net) , 点击 Download下Complete package, except sources 右侧的setup按钮进行下载
下载完成后,打开exe安装包,安装在默认路径C:\Program Files (x86)\GnuWin32,安装完成后将该路径+bin(C:\Program Files (x86)\GnuWin32\bin)添加到环境变量下即可
执行Cf plugins,可以看到当前本地电脑安装过的插件列表
如果没有安装过multiapps这个插件,执行cf install-plugin multiapps,命令行安装失败时请参阅GitHub – cloudfoundry/multiapps-cli-plugin: A CLI plugin for Multi-Target Application (MTA) operations in Cloud Foundry
我这里将手动下载的安装包放在了CAP-tutorial文件夹内,
执行cf install-plugin *path/CAP-tutorial/multiapps-plugin.win64.exe -f 就完成了安装
本地启动项目时使用的是本地安装的nodejs,部署到CF后会使用容器运行时提供的nodejs,所以最好可以在配置文件中声明要使用的nodejs版本,本练习需要使用nodejs16及以上,在package.json内添加一个和devDependencies同级的配置:”engines”,内容为”node”:”^16”
“engines”: {
“node”: “^16”
},
(我这里使用的node版本为18.19.0,故将^16替换为了^18, 要查看CF支持的Node版本请查阅Releases · cloudfoundry/nodejs-buildpack (github.com))
首先利用cds工具生成mbt工具需要的配置文件cds add mta
这会在cpapp下生成一个mta.yaml文件,用于设定部署时的参数
在部署前,还需要注意的是,每次部署时如果项目的db/data文件夹内携带了用来初始化的csv数据文件,那么部署时会清除数据库中现有的数据并用初始化数据填充,所以需要修改部署文件以防止这个现象:
在mta.yaml第一级添加:(如果已经存在build-parameter这个第一层参数,则将其修改至与下方一致即可)
build-parameters:
before-all:
- builder: custom
commands:
- npm install --production
- npx -p @sap/cds-dk cds build --production
- npx rimraf gen/db/src/gen/data
再修改mta.yaml内的内容:
modules – requires 下的 cpapp-auth 修改为 cpapp-uaa
resources 下第二个属性的name从cpapp-auth修改为cpapp-uaa,其下的parameters – config添加一个属性:
role-collections:
- name: 'RiskManager-${space}'
description: Manage Risks
role-template-references:
- $XSAPPNAME.RiskManager
- name: 'RiskViewer-${space}'
description: View Risks
role-template-references:
- $XSAPPNAME.RiskViewer
在项目根目录下执行mbt build -t ./
这会持续一段时间,最后会生成一个mtar文件
最后在根目录执行cf deploy cpapp_1.0.0.mtar (第一次编译时应该会是这个文件名)即可完成部署
一切顺利的话,命令行执行cf services即可看到当前自动创建好的服务:
再检查app是否正常运行:
cf apps
在浏览器打开cpapp-srv的routes属性内的URL即可看到自动生成的启动页面,但是现在当前用户还没有对应的身份,所以点开服务也无法访问到数据
最后形成的代码可以在GitHub – SAP-samples/cloud-cap-risk-management at cap-mta-deployment 内找到
现在本地启动的服务是包含了权限控制的,我们先关闭掉权限控制:
首先将srv/risk-service.cds的内容替换为templates/create-cap-application/srv/risk-service.cds的内容
这样后端服务就没有权限控制了
然后在app文件夹下新建文件夹approuter
新建文件package.json,内容如下:
{
"name": "myapprouter",
"scripts": {
"start": "node node_modules/@sap/approuter/approuter.js"
},
"dependencies": {
"@sap/approuter": "^6.0.1"
}
}
实质上approuter就是一个server,可以为其他前端app提供统一的身份验证,路由转发,反向代理等功能
再新建文件xs-app.json,内容如下:
{
"welcomeFile": "/app/",
"authenticationMethod": "none",
"routes": [
{
"source": "^/svc/(.*)",
"target": "/$1",
"destination": "srv-api"
},
{
"source": "^/app/(.*)",
"target": "/$1",
"localDir": "../mitigations/webapp"
}
]
}
这里主要是为approuter定义路由,例如本地访问approuter的 URL localhost:5000时,请求会在路径上附加welcomeFile的值,令目标URL变成localhost:5000/app/
而这个请求被下方定义的路由规则所抓取,就会将请求转发至mitigations文件夹内的index.html
这里引用了destination,所以在approuter文件夹下创建一个模拟destination服务的文件default-env.json,内容如下
{
"destinations" : [
{
"name": "srv-api",
"url": "http://localhost:4004",
"forwardAuthToken": true
}
]
}
这里主要是将访问srv_api的请求转发至4004,也就是我们的后端服务URL
准备好文件内容后,进入approuter文件夹,执行npm install, 再执行npm start,即可在本地启动前端服务
如果此时后端CDS服务保持打开状态,则可以在浏览器内打开localhost:5000,
由于5000端口由前端的approuter监听,它会将浏览器访问请求根据xs-app内的welcomeFile来将请求重定向至localhost:5000/app/,
而xs-app检测到localhost:5000/app/的请求后会根据”source”: “^/app/(.*)” 的规则将请求转发至本地文件夹”../mitigations/webapp”,也就是mitigation的前端UI路径
然后UI根据dataSource的路径去/svc/odata/v4/service/risk/获取数据,请求通过route被转发到后端服务处取得数据
关于本文内容有任何问题或见解,欢迎在评论区留下你的想法,如果需要帮助,也可以直接联系到我 [email protected],感谢你的时间