-
Notifications
You must be signed in to change notification settings - Fork 394
用ResourceVO定义一个资源
ZStack中一个资源(例如Zone、Cluster、VM)都由UUID唯一标识,大都有一个字段name
表示资源的名称。ZStack用一些表维护资源之间的关系,例如AccountResourceRefVO维护各个资源与账号的关系,SystemVO表中有resourceUuid
字段维护资源和系统标签之间的关系。AccountResourceRefVO的部分定义如下:
CREATE TABLE `zstack`.`AccountResourceRefVO` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
`accountUuid` varchar(32) NOT NULL, # 资源所属账户
`resourceUuid` varchar(32) NOT NULL, # 资源UUID
`resourceType` varchar(255) NOT NULL, # 资源类型
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这里resourceUuid
字段表示资源UUID,reesourceType
表示资源类型,根据resourceType
的不同,UUID代表不同资源。这种表设计方法称为Ploymorphic Associations,在数据库设计中是典型的anti-pattern。但为了让Java编程更加容易和OO,我们仍然采用这种设计。该设计带来的主要问题是无法使用数据库的foreign key
维护数据一致性,因为同一foreign key无法指向多个parent表(部分数据允许,但要求每张表里都有相同的内容)。所以AccountResourceRefVO
表的resourceUuid
字段无法使用foreign key同时指向VmInstanceVO和ImageVO表。这样带来的结果是,我们需要在application层面维护AccountResourceRefVO
表的一致性,例如删除了一个VM后,要清理AccountResourceRefVO
对应的条目。
为了在应用层面方便的维护AccountResourceRefVO
等使用Ploymorphic Associations设计的表的一致性,我们引入ResourceVO
表作为所有资源的父表,该表设计如下:
CREATE TABLE `ResourceVO` (
`uuid` varchar(32) NOT NULL UNIQUE, # 资源UUID
`resourceName` varchar(255) DEFAULT NULL, # 资源名称
`resourceType` varchar(255) DEFAULT NULL, # 资源类型
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
resourceName和resourceType两个字段程序员无需关心,写入数据库时程序自动生成。
在Java程序中,对应的资源需要继承ResourceVO类,例如EipVO:
@Entity
@Table
public class EipVO extends ResourceVO {
EipVO表不再定义uuid字段,该字段由ResourceVO
提供,name
字段由各个资源类自定义。
资源应该尽可能使用单词
name
作为名字字段,如果使用了非name
单词,需要通过@ResourceAttributes指定名字字段,例如:java @Entity @Table @ResourceAttributes(nameField = "jobName") public class SchedulerVO extends ResourceVO {
由于所有资源类继承了ResourceVO类,JPA在删除一个子资源的时候,会将ResourceVO对应的row同时删除。这样AccountResourceRefVO
等表只要将resourceUuid
设置一个ON DELETE CASCADE
foreign key到ResourceVO表即可维护数据的一致性。
ResourceVO表的另一个功能是实现资源UUID到资源name的翻译功能。例如知道一个UUID 1f89148d5fb74604a64403d83f67db12
,不知道该UUID代表的是什么资源,又需要知道它的名字时,可以使用如下API:
curl -H "Content-Type: application/json" -H "Authorization: OAuth aa21b8a1fe9749fea2e96ebba7a11518" -X GET http://localhost:8080/v1/resources/names?uuids=1f89148d5fb74604a64403d83f67db12&uuids=8918fcec918d4b19a0485be700ed98f1
``