目录结构
├── json
│ ├── intf
│ │ └── mdb
│ │ └── bmc
│ └── path
│ └── mdb
│ └── bmc
├── messages
│ ├── base.json
│ └── custom.json
└── proto说明
- 资源协作接口与MDS一样,采用json格式描述,当前已经有部分使用proto格式描述,因此新增同级目录json用于存放json格式描述的资源协作接口,待全部完成转换后删除proto目录,并把json目录下面的子目录提升为一级目录
- 按照DBus的设计,Interface可以看作是抽象的表示和行为,ObjectPath可以看作是实例的类型,实例类型里面组合一个或多个Interface,因此把资源协作接口的设计分为两部分,一部分是接口(Interface,在json/path目录中),一部分是路径(ObjectPath,在json/path目录中)
- 在intf目录下面,按照Interface名称创建子目录层级,如接口名称
bmc.kepler.x.y.z,则在bmc/kepler下面创建子目录x/y,创建接口描述文件z.json - 在path目录下面,按照ObjectPath名称创建子目录层级,如path名称是
/bmc/kepler/x/y/z或/bmc/kepler/x/${SystemId}/y/z/${Id},则在bmc/kepler目录下面创建子目录x/y/z/,然后创建path描述文件,文件名不做约束,例如path名称是/bmc/kepler/Systems/${SystemId}/ThresholdSensors/${Id},其对应的文件路径为/bmc/kepler/Systems/ThresholdSensors/,具体的path描述文件可以是ThresholdSensor.json或ThresholdSensors.json,即path目录下存在如下两个文件: (1)/bmc/kepler/Systems/ThresholdSensors/ThresholdSensor.json在MDS数据模型中。类名是ThresholdSensor,其path是/bmc/kepler/Systems/${SystemId}/ThresholdSensors/${Id}(2)/bmc/kepler/Systems/ThresholdSensors/ThresholdSensors.json在MDS数据模型中。类名是ThresholdSensors,其path是/bmc/kepler/Systems/${SystemId}/ThresholdSensors - 消息(message)是组件(APP)的资源协作接口在被访问时向访问者传递的一种数据,主要用于北向接口访问后台资源时,通过消息向外传递系统的状态或错误等,参考redfish的message定义,总体分为base(redfish标准定义)和custom(iBMC自定义)两部分
配置示例
Interface配置示例
示例一
{
"bmc.demo.IDemo": {
"virtual": true,
"properties": {
"Property1": {
"baseType": "U8",
"default": 0,
"maximum": 127,
"minimum": 1,
"description": "abc"
}
},
"methods": {
"Method1": {
"req": {
"ReqArg1": {
"baseType": "U8"
},
"ReqArg2": {
"baseType": "Array",
"items": {
"$ref": "#/defs/StructAbc"
}
}
},
"rsp": {
"RspArg1":{
"baseType": "U16"
}
}
}
},
"description": "this is an example"
},
"defs": {
"StructAbc": {
"MemVar1": {
"baseType": "Boolean"
},
"MemVar2": {
"baseType": "Enum",
"$ref": "#/defs/EnumAbc"
},
"MemVar3": {
"baseType": "Struct",
"$ref": "#/defs/StructXyz"
}
},
"StructXyz": {
"MemVar4": {
"baseType": "S64[]"
},
"MemVar5": {
"baseType": "String",
"maxLength": 256,
"minLength": 1
}
},
"EnumAbc": {
"EnumVar1": 1,
"EnumVar2": 2
}
}
}说明
bmc.demo.IDemo表示接口名称virtual表示接口是否能重载(主要指方法),可选字段,不写时表示virtual为falseproperties表示接口中的属性,属性名用大驼峰风格,baseType表示属性的基本类型,default表示属性的默认值(如果baseType是Enum时,default则用枚举变量名称,比如这里的EnumVar1)methods表示接口中的方法,方法名称用大驼峰风格,req/rsp分别表示方法的请求和响应,参数名称用大驼峰风格- 如果
req/rsp中存在复杂数据类型: (1)如果是结构体(参考MemVar3),则baseType设置为Struct,通过$ref指定具体的结构体定义,结构体成员变量使用大驼峰风格 (2)如果是结构体数组(参考ReqArg2),则baseType设置为Array,items中通过$ref指定具体的结构体定义,结构体成员变量使用大驼峰风格 (3)如果是枚举(参考MemVar2),则baseType设置为Enum,通过$ref指定具体的枚举定义,枚举变量使用大驼峰风格 该规则描述同样适用于接口中的属性以及信号中的参数 defs表示本文件的属性或方法、信号参数的复杂类型定义,支持嵌套描述(如StructAbc的MemVar3仍然是结构体,其定义为StructXyz)description是注释说明,可选字段
示例二
{
"bmc.demo.IDemo": {
"properties": {
"property1": {
"baseType": "U8",
"options": {
"volatile": true
}
},
"property2": {
"baseType": "U32",
"options": {
"deprecated": true
}
},
"property1": {
"baseType": "U8",
"options": {
"explicit": true
}
},
"property1": {
"baseType": "I32",
"options": {
"emitsChangedSignal": "true"
}
}
}
}
}说明
options表示资源协作接口中属性的能力选项,当前支持的能力包括:
volatile: 表示属性是否易变,如果取值为true,则表示该属性的值不稳定,组件可以选择不监听该属性的变化信号,默认为falsedeprecated: 表示属性是否弃用,如果取值为true,则表示属性被弃用,默认为falseexplicit: 表示属性值在属性名明确时才可见,如果取值为true,则表示属性在introspect(list操作,不指定属性名)时不显示,只能在单独Get(需要明确属性名)时才显示,默认为falseemitsChangedSignal: 表示是否发送属性变化信号,默认为"true"。注意此选项的值不是Boolean类型而是String类型 (1)如果取值为 "false",表示属性变化时不发送信号 (2)如果取值为 "const",表示属性永不变化,不需要发送信号 (3)如果取值为 "true",表示属性变化时发送信号,信号携带属性值 (4)如果取值为 "invalidates",表示属性变化时发送信号,但信号不携带属性值
ObjectPath配置示例
以Demo.json为例
{
"Demo": {
"path": "/bmc/kepler/Demo",
"interfaces": [
"bmc.demo.IDemo",
"bmc.demo.IDemoUnit.Default"
]
}
}说明
- 一个文件只描述一个资源树对象路径
Demo表示对象路径的名称,采用大驼峰风格,与model.json里面的类名没有关联path表示在资源树上的对象路径interfaces表示此路径下组合了哪些接口,必须时intf目录下已经定义的接口- 接口的默认实现(bmc.demo.IDemoUnit.Default)只能被单例的路径组合,即对象路径不能带有实例化对象名作为参数(SystemId/ManagerId除外)
消息配置示例
{
"Description": "This registry defines the oem messages of openUBMC",
"RegistryPrefix": "openUBMC",
"RegistryVersion": "1.0.0",
"Messages": {
"PropertyValueLengthOutOfRange": {
"Description": "Indicates that the length of property value is out of range.",
"Message": "The length of value %1 for the property %2 is out of range. The range of length of value is %3 to %4.",
"Severity": "Warning",
"NumberOfArgs": 4,
"ParamTypes": [
"string",
"string",
"string",
"string"
],
"Resolution": "Retry using a valid value.",
"HttpStatusCode": 400,
"IpmiCompletionCode": "0xC7",
"SnmpStatusCode": 10,
"TraceDepth": 0
},
}
}说明
Description表示本消息注册表的说明,可选字段RegistryPrefix表示本消息注册表的前缀,必选字段RegistryVersion表示本消息注册表的版本,必选字段Messages表示消息的集合,必选字段PropertyValueLengthOutOfRange表示消息名称,必选字段Severity表示消息严重级别,级别有OK、Warning、Critical,必选字段TraceDepth表示消息管理引擎的追踪深度,取值0-5,0表示不追踪,可选字段,默认值为0HttpStatusCode表示消息对应的HTTP响应码(遵循HTTP协议定义的状态码),可选字段,默认值为400IpmiCompletionCode表示消息对应的IPMI响应码(遵循IPMI规范定义的完成码),可选字段,默认值为0xFFSnmpStatusCode表示消息对应的SNMP错误码,可选字段,默认值为5Message表示消息的描述,必选字段,支持动态参数,参数用%1、%2...表示NumberOfArgs和ParamTypes分别表示描述中动态参数个数和每个动态参数的类型,类型包括string、integer、numberResolution表示消息的处理建议,可选字段
关键字使用范围
属性关键字
除default关键字允许组件模型定义覆盖资源树接口定义,以下属性关键字仅资源树接口可定义
| 属性关键字 | 属性关键字说明 |
|---|---|
| baseType | 表示属性的基本类型 |
| items | 表示结构体数组类型的元素定义,通过$ref指向元素定义 |
| decription | 表示属性的描述信息 |
| default | 表示属性的默认值 |
| minimum maximum | 表示数值类型属性的取值范围 |
| maxLength minLength | 表示字符串类型属性的长度范围 |
| pattern | 表示字符串类型属性的格式要求,正则式匹配 |
| enum | 表示属性的枚举值范围 |
| readOnly | 表示属性是否只读 |
| deprecated | 表示属性废弃 |
| constrait | 表示属性使用约束,包括属性互斥、依赖关系、唯一性要求、兼容性要求等 |
| example | 表示属性样例,用于描述属性格式等信息 |
| options/emitsChangedSignal | 表示是否发送属性变化信号,默认为"true" i) 如果取值为false,表示属性变化时不发送信号; ii)如果取值为const,表示属性永不变化,不需要发送信号; iii)如果取值为true,表示属性变化时发送信号,信号携带属性值; iv)如果取值为invalidates,表示属性变化时发送信号,但信号不携带属性值; |
方法关键字
以下方法关键字仅资源树接口可定义
| 方法关键字 | 方法关键字说明 |
|---|---|
| decription | 表示方法或参数的描述信息 |
| baseType | 表示参数的基本类型 |
| items | 表示结构体数组类型的元素定义,通过$ref指向元素定义 |
| minimum maximum | 表示数值类型参数的取值范围 |
| maxLength minLength | 表示字符串类型参数的长度范围 |
| pattern | 表示字符串类型参数的格式要求,正则式匹配 |
| enum | 表示参数的枚举值范围 |
信号关键字
以下信号关键字仅资源树接口可定义
| 信号关键字 | 信号关键字说明 |
|---|---|
| decription | 表示信号或参数的描述信息 |
| baseType | 表示参数的基本类型 |
| items | 表示结构体数组类型的元素定义,通过$ref指向元素定义 |
| minimum maximum | 表示数值类型参数的取值范围 |
| maxLength minLength | 表示字符串类型参数的长度范围 |
| pattern | 表示字符串类型参数的格式要求,正则式匹配 |
| enum | 表示参数的枚举值范围 |
资源协作接口开发规范
资源树命名要求
1. 服务Service采用 “域名表示法”,命名统一unix_like风格,与APP名称对应
- 服务Service采用 “域名表示法”:bmc.kepler.<app_name>,其中 <app_name> 采用unix_like风格,并且与APP名称保持一致
- 此服务表示在总线上提供IPC API的进程,如:bmc.kepler.fructrl,表示组件fructrl提供的API接口
- 示例: bmc.kepler.fructrl bmc.kepler.key_mgmt bmc.kepler.bios
2. 对象Object采用 “文件系统目录法”,除根节点外,资源各级节点的命名遵循 “大驼峰命名语法”
- 对象Object采用 “文件系统目录法”,比如 “/bmc/kepler/[资源分类]/:Id/[资源子分类]/[资源子子分类],其中 “资源分类及其子分类” 统一采用大驼峰命名风格。
- Object类似C指针,引用C对象,采用文件系统路径方式以便于理解,开发人员按照目录划分资源树
- 对象Object按照资源分类命名,与APP名称无关
3. 接口Interface采用 “域名表示法”,除根节点外,资源各级节点的命名遵循 “大驼峰命名语法”
- 接口Interface是信号、方法、属性的集合,表示某一类资源操作的集合体,也就是 “类” 的定义,开发人员负责接口的实现,如bmc.kepler.Systems.Power,表示系统电源接口集合
- 接口Interface按照资源分类命名,与APP名称无关
4. 方法Method的方法名、参数遵循 “大驼峰命名语法”
- 方法Method的方法名、参数遵循 “大驼峰命名语法”,接口可以包含方法(函数)
5. 信号Signal的命名遵循 “大驼峰命名语法”
- 信号Signal:类似方法,使用场景:用于对等体的一般通知,总线广播。一般情况下,方法是“双工,一对一通信”,信号是“单工,一对多通信”
6. 属性Property的命名遵循 “大驼峰命名语法”
- 属性Property:对象公开的变量,可以由客户端读取或修改
7. 签名Signature统一采用DBus简写
- 签名Signature:“方法、信号、属性” 接受或返回的一组参数
8. 集合资源的下一级路径Id命名要求
- 资源路径中/bmc/kepler/Chassis/:ChassisId、/bmc/kepler/Systems/:SystemId、/bmc/kepler/Managers/:ManagerId,变量名称固定使用ChassisId、SystemId、ManagerId,作为资源树和自发现的接口
- 只要是组件内使用的Id,简化为 "Id"
- 示例: /bmc/kepler/Chassis/:ChassisId /bmc/kepler/Systems/:SystemId/Bios /bmc/kepler/Managers/:ManagerId/SOL /bmc/kepler/TaskService/Tasks/:Id
资源树属性(Property)及方法(Method)定义
1. 属性变化默认会发送 signal,属性定义时,按需配置是否广播( emitsChangedSignal 配置为 false/const 都不会发送广播)
2. 属性取值范围要明确、可校验,并上库 mdb_interface 代码仓统一管理
- mdb_interface代码仓对属性的取值范围要明确。非bool类的整数属性、参数要用枚举类型定义,尤其是enum、array类型使用$ref定义取值
3. 通用方法定义,需要考虑“签名”稳定性、扩展性,推荐用 a{ss}
4. 敏感信息需要以方法查询,不能直接暴露在资源数属性上
- 敏感信息(例如加密后的明文数据)需要做成method查询,不能以property直接暴露