洛约拉的仓储研究¶
Loyola的文件系统研究¶
教授们。Thiruvathukal、Laufer和我几年来一直致力于文件系统和文件系统框架。
我们的第一个项目是OLFS。OLFS是一个FUSE文件系统,类似于Union FS,但用Java编写。这对我们来说是一次极好的学习经历。
基于我们使用OLFS的经验,我们开发了两个框架:NOFS和RestFS。我们相信,这两个框架都有助于将文件系统开发引入高级语言,并极大地简化了问题空间。
NOFS¶
在大多数面向对象的图形应用程序中,有几个常见组件:
域模型
视图/表示层
在域模型和表示层之间进行转换的控制层
持久层。这可以是文件系统或数据库。
NOFS(裸体对象)没有任何部分背后的原则是,如果其他层可以自动生成,那么行为上完整的域模型就是应用程序所需的全部。
对于许多应用程序,裸露对象体系结构减少了开发工作量和复杂性,同时生成了一个像样的应用程序
NOFS¶
NOFS背后的原则是,文件系统的基本结构或域对象应该是需要实现的全部,并且应该以自动方式提供到任何VFS层或任何持久性机制(硬盘、数据库、文件系统)的接口。
使用NOFS,可以用一个Java类构建一个完整的文件系统,该类包含不超过50-60行代码,并且几乎不了解文件系统约定(如截断、读取、写入、查找等操作...)或底层存储体系结构(硬盘、文件等)
3张幻灯片中的NOFS文件系统示例¶
@RootFolderObject
@DomainObject
@FolderObject(CanAdd=false, CanRemove=false)
public class Book {
private IDomainObjectContainer<Book> _bookContainer;
private IDomainObjectContainerManager _containerManager;
@NeedsContainer
public void setContainer(IDomainObjectContainer<Book> container) {
_bookContainer = container;
}
@NeedsContainerManager
public void setContainerManager(IDomainObjectContainerManager manager) {
_containerManager = manager;
}
private IDomainObjectContainerManager GetContainerManager() throws Exception {
if(_containerManager -- null) {
throw new Exception("container manager is null");
}
return _containerManager;
}
public List<Contact> getContacts() throws Exception {
IDomainObjectContainer<Contact> contactContainer =
GetContainerManager().GetContainer(Contact.class);
if(contactContainer -- null) {
throw new Exception("Container for Contact is null");
}
return new LinkedList<Contact>(contactContainer.GetAllInstances());
}
3张幻灯片中的NOFS文件系统示例¶
@Executable
public void AddAContact(String name, String phone) throws Exception {
IDomainObjectContainer<Contact> contactContainer =
GetContainerManager().GetContainer(Contact.class);
Contact contact = contactContainer.NewPersistentInstance();
contact.setName(name);
contact.setPhoneNumber(phone);
_bookContainer.ObjectChanged(this);
}
@Executable
public void RemoveAContact(Contact contact) throws Exception {
IDomainObjectContainer<Contact> contactContainer =
GetContainerManager().GetContainer(Contact.class);
contactContainer.Remove(contact);
_bookContainer.ObjectChanged(this);
}
@Executable
public void RenameAContact(Contact contact, String newName) throws Exception {
IDomainObjectContainer<Contact> contactContainer =
GetContainerManager().GetContainer(Contact.class);
String oldName = contact.getName();
contact.setName(newName);
contactContainer.ObjectRenamed(contact, oldName, newName);
contactContainer.ObjectChanged(contact);
}
}
3张幻灯片中的NOFS文件系统示例¶
@DomainObject
public class Contact {
private String _name;
private String _phoneNumber;
private IDomainObjectContainer<Contact> _container;
@ProvidesName
public String getName() {
return _name;
}
@ProvidesName
public void setName(String name) throws Exception {
_name = name;
_container.ObjectChanged(this);
}
public String getPhoneNumber() { return _phoneNumber; }
public void setPhoneNumber(String value) throws Exception {
_phoneNumber = value;
_container.ObjectChanged(this);
}
@NeedsContainer
public void setContainer(IDomainObjectContainer<Contact> container) {
_container = container;
}
}
NOFS-运行示例¶
![]()
图像¶
NOFS¶
有了NOFS,开发人员可以填写他们所关心的所有细节。
如果开发人员想要实现有关权限、随机文件访问、持久性、缓存等的详细信息。这是可选的。任何遗漏的细节都由NOFS框架使用合理的缺省值填充。
对于面向应用程序的文件系统-更多地面向行为而不是存储的文件系统-开发人员不需要关心文件系统合同的任何细节。
对于面向存储的文件系统,开发人员需要管理更多细节。权限、访问/修改时间、用户和组所有权等内容变得更加相关。
NOFS-架构-与FUSE和操作系统的关系¶
![]()
图像¶
NOFS-架构-域模型到文件的转换¶
![]()
图像¶
NOFS-架构-方法执行¶
![]()
图像¶
RestFS¶
在开发NOFS时,我们意识到有两种常见的面向应用程序的文件系统
第一种类型是本地或本地/远程混合行为文件系统。类似于我们前面演示的通讯录示例。
我们发现的第二种类型是连接到Web服务的文件系统。我们构建的一个示例是一个NOFS文件系统,它用大约400-500行代码将Flickr相册挂载为图片文件夹。
了解RESTful服务在体系结构上与文件系统非常相似,以及NOFS在面向应用程序的文件系统方面做得很好。我们问自己,我们是否可以让访问Web服务变得更容易。
RestFS-服务组合¶
![]()
图像¶
RestFS¶
在使用NOFS为Web服务开发应用程序文件系统时,我们发现域模型修改大致是将一个或两个FUSE操作映射到一个HTTP谓词。
因此,我们对RestFS的第一次尝试是提供文件和配置文件对,以将特定的FS系统调用映射到特定的Web方法。
这让我们可以做一些事情,比如配置一个文件,这样当它被‘触摸’时,就可以用存储到文件中的结果执行Google搜索。
RestFS-通信¶
![]()
图像¶
RestFS-谷歌搜索¶
#!/bin/bash
URL_ARGS=`echo $@ | sed 's/ /%20/g'`
FILE_NAME=`echo $@ | sed 's/ /_/g'`
RESOURCE="ajax/services/search/web?v=1.0&q=$URL_ARGS"
RESOURCE=`echo $RESOURCE | \
sed -e 's~&~\&~g' \
-e 's~<~\<~g' \
-e 's~>~\>~g'`
touch $FILE_NAME
./configureResource .$FILE_NAME \
fs:utime web:get \
host:ajax.googleapis.com \
resource:$RESOURCE
touch $FILE_NAME
cat $FILE_NAME
RestFS-身份验证¶
许多REST服务的共同关注点是身份验证。
许多REST服务的一种流行的身份验证方法是OAuth。
由于RestFS构建在NOFS之上,因此我们能够将现有的OAuth库映射到文件系统
在RestFS中,有一个特殊的OAuth文件夹,名为‘/auth’
RestFS-身份验证¶
![]()
图像¶
RestFS-身份验证¶
![]()
图像¶
RestFS¶
通过RestFS,我们已经能够展示如何将主要处理文件(CAT、grep)的本地软件与Web服务一起使用
我们还演示了如何使用RestFS在本地增强远程Web服务,然后将其重新公开为新的REST Web服务。
RestFS--未来发展方向¶
我们目前正在重新设计RestFS,使其更多地基于规则,以便每个文件可以映射多个FS系统调用。
我们还在研究如何使用文件夹和符号链接来进一步增强RestFS。
2011年秋天,在陈少辉的帮助下,我们已经能够将NOF从Java迁移到.NET框架
这种移植工作将允许我们同时支持Windows和Linux,并为我们提供一个更好的语言框架。