目录结构

├── json
│   ├── intf
│   │   └── mdb
│   │       └── bmc
│   └── path
│       └── mdb
│           └── bmc
├── messages
│   ├── base.json
│   └── custom.json
└── proto

说明

  1. 资源协作接口与MDS一样,采用json格式描述,当前已经有部分使用proto格式描述,因此新增同级目录json用于存放json格式描述的资源协作接口,待全部完成转换后删除proto目录,并把json目录下面的子目录提升为一级目录
  2. 按照DBus的设计,Interface可以看作是抽象的表示和行为,ObjectPath可以看作是实例的类型,实例类型里面组合一个或多个Interface,因此把资源协作接口的设计分为两部分,一部分是接口(Interface,在json/path目录中),一部分是路径(ObjectPath,在json/path目录中)
  3. 在intf目录下面,按照Interface名称创建子目录层级,如接口名称bmc.kepler.x.y.z,则在bmc/kepler下面创建子目录x/y,创建接口描述文件z.json
  4. 在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.jsonThresholdSensors.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
  5. 消息(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
        }
    }
}

说明

  1. bmc.demo.IDemo表示接口名称
  2. virtual表示接口是否能重载(主要指方法),可选字段,不写时表示virtualfalse
  3. properties表示接口中的属性,属性名用大驼峰风格baseType表示属性的基本类型,default表示属性的默认值(如果baseTypeEnum时,default则用枚举变量名称,比如这里的EnumVar1
  4. methods表示接口中的方法,方法名称用大驼峰风格,req/rsp分别表示方法的请求和响应,参数名称用大驼峰风格
  5. 如果req/rsp中存在复杂数据类型: (1)如果是结构体(参考MemVar3),则baseType设置为Struct,通过$ref指定具体的结构体定义,结构体成员变量使用大驼峰风格 (2)如果是结构体数组(参考ReqArg2),则baseType设置为Arrayitems中通过$ref指定具体的结构体定义,结构体成员变量使用大驼峰风格 (3)如果是枚举(参考MemVar2),则baseType设置为Enum,通过$ref指定具体的枚举定义,枚举变量使用大驼峰风格 该规则描述同样适用于接口中的属性以及信号中的参数
  6. defs表示本文件的属性或方法、信号参数的复杂类型定义,支持嵌套描述(如StructAbcMemVar3仍然是结构体,其定义为StructXyz
  7. 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表示资源协作接口中属性的能力选项,当前支持的能力包括:

  1. volatile: 表示属性是否易变,如果取值为true,则表示该属性的值不稳定,组件可以选择不监听该属性的变化信号,默认为false
  2. deprecated: 表示属性是否弃用,如果取值为true,则表示属性被弃用,默认为false
  3. explicit: 表示属性值在属性名明确时才可见,如果取值为true,则表示属性在introspect(list操作,不指定属性名)时不显示,只能在单独Get(需要明确属性名)时才显示,默认为false
  4. emitsChangedSignal: 表示是否发送属性变化信号,默认为"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"
        ]
    }
}

说明

  1. 一个文件只描述一个资源树对象路径
  2. Demo表示对象路径的名称,采用大驼峰风格,与model.json里面的类名没有关联
  3. path表示在资源树上的对象路径
  4. interfaces表示此路径下组合了哪些接口,必须时intf目录下已经定义的接口
  5. 接口的默认实现(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
        },
    }
}

说明

  1. Description表示本消息注册表的说明,可选字段
  2. RegistryPrefix表示本消息注册表的前缀,必选字段
  3. RegistryVersion表示本消息注册表的版本,必选字段
  4. Messages表示消息的集合,必选字段
  5. PropertyValueLengthOutOfRange表示消息名称,必选字段
  6. Severity表示消息严重级别,级别有OK、Warning、Critical,必选字段
  7. TraceDepth表示消息管理引擎的追踪深度,取值0-5,0表示不追踪,可选字段,默认值为0
  8. HttpStatusCode表示消息对应的HTTP响应码(遵循HTTP协议定义的状态码),可选字段,默认值为400
  9. IpmiCompletionCode表示消息对应的IPMI响应码(遵循IPMI规范定义的完成码),可选字段,默认值为0xFF
  10. SnmpStatusCode表示消息对应的SNMP错误码,可选字段,默认值为5
  11. Message表示消息的描述,必选字段,支持动态参数,参数用%1、%2...表示
  12. NumberOfArgsParamTypes分别表示描述中动态参数个数和每个动态参数的类型,类型包括string、integer、number
  13. Resolution表示消息的处理建议,可选字段

关键字使用范围

属性关键字

除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直接暴露

5. 资源树属性及方法需要配置对应的访问权限

资源树信息范围

1. 资源树接口定义,需要保证接口的清晰、稳定、兼容

2. 只将对外暴露的数据定义在资源树上,内部逻辑处理的中间数据本地程序管理

组件依赖关系

1. 组件统一依赖接口,资源树定义接口

2. 在 mds 中列出组件所依赖的所有接口 Interface

3. 资源树为偏序依赖,上层服务能访问本层及较下层的资源数据,不能反过来依赖