项目说明
目的
通过构建聚合和分发ATOM提要的简单系统,以了解构建客户端/服务器系统所需的条件。
介绍
随着要跟踪的事物数量的增加,信息管理和跟踪变得更加困难。对于大多数用户而言,他们希望跟踪的网页数量非常多,如果他们不得不记住手动检查所有内容,那么当您疲倦或忙碌时,很容易忘记一两个网页。输入联合,该机制使网站可以将摘要发布为供您签名的提要,以便在发生新情况时收到通知,然后,如果您感兴趣,可以去看看。在联合组织领域中,最初的努力包括开发RSS协议系列,但实际上这些协议尚未标准化。ATOM联合协议是一种基于标准的方法,旨在尝试并为联合提供坚实的基础。您可以看到ATOM RFC这里 (链接到外部站点。) 尽管您不会全部实现!
基于XML的格式易于通过Web的超文本传输协议(HTTP)进行传输,并且越来越常见的是使用标准格式在客户端和服务器之间进行交换,而不是针对一种小型协议开发特殊协议。客户端和服务器组。在20年前,我们可能已经在传输的数据中使用字节边界定义的模式进行通信了,而使用基于XML的标准和现有的HTTP机制来绕开事物则更为普遍。这是客户端和服务器之间基于套接字的通信,不需要使用Java RMI机制来支持它-正如您所期望的那样,因为您不必使用RMI客户端来访问网页!在本练习中,您将获取数据并将其转换为ATOM格式,然后将其发送到服务器。服务器将对其进行检查,然后将有限形式的数据分发给每个连接并请求该数据的客户端。当您要更改服务器中的数据时,您将覆盖现有文件,从而进行更新操作幂等(您可以随意进行多次,并获得相同的结果)。系统的真正测试是,您可以接受服务器上其他学生的PUT和GET请求,而客户可以与他们交谈。和往常一样,不要共享代码。
联合服务器
联合服务器是提供符合RSS或ATOM标准的XML文档的Web服务器。收到HTTP GET后,服务器将以如下XML响应进行响应(来自“在PHP中创建ATOM供稿” (链接到外部站点。)):
一旦配置好,服务器就会将该ATOM XML文件提供给通过HTTP请求它的任何客户端。通常,这将是Web客户端的一部分,但是在这种情况下,您将编写聚合服务器,内容服务器和读取客户端。内容服务器将在服务器上放置内容,而读取客户端将从服务器获取内容。
元素
该任务的主要内容是:
• 一个ATOM服务器(或聚合服务器),用于响应对提要的请求,并且还接受来自客户端的提要更新。聚合服务器将永久存储提要信息,仅在提供提要的内容服务器不再联系或提要项不是最新的20之一时才将其删除。
• 客户端向服务器发出HTTP GET请求,然后显示提要数据(已删除其XML信息)的客户端。
• 一个内容服务器,向服务器发出HTTP PUT请求,然后将提要的新版本上载到服务器,以替换旧版本。从内容服务器的本地文件系统上的文件读取此提要信息后,该提要信息将被组合为ATOM XML。
所有代码元素都将使用Java编程语言编写。期望您的客户具有彻底的故障处理机制,使他们在遇到故障时可以预期地表现,保持一致性,不容易出现竞争状况并可靠且可预测地恢复。
此实践摘要
在此分配中,您将构建下面描述的聚合系统,包括一个故障管理系统,用于处理您可能会想到的针对此问题的尽可能多的故障模式。这显然包括客户端,服务器和网络故障,但是现在您必须处理以下附加约束(在阅读下面的描述后,请回到这些约束):
• 多个客户端可能会尝试同时进行GET,并且如果与任何PUT交错,则需要GET对Lamport时钟调整时间正确的聚合提要。因此,如果按此顺序到达一个PUT,一个GET和另一个PUT,则必须应用第一个PUT并建议内容服务器,然后GET将更新的提要返回给客户端,然后应用下一个PUT。在每种情况下,如果参与者使用Lamport时钟,将保证他们维持该顺序。
• 多个内容服务器可能会尝试同时进行PUT。必须将其序列化,并由Lamport时钟时间戳记维护顺序。
• 您的聚合服务器将过期,并从最近12秒钟内未通信的内容服务器中删除任何内容。您可以为此选择机制,但必须考虑效率和规模。
• 您的作业中的所有元素都必须能够实现Lamport时钟,以实现同步和协调目的。
您的聚合服务器
为简单起见,我们假设您的文件系统中有一个文件,其中包含条目列表以及它们来自何处。它不必是ATOM格式,但是当客户端发送GET请求时,它必须能够转换为标准ATOM文件。但是,此文件必须在服务器崩溃并重新启动后仍然可以承受,包括在服务器崩溃时是否正在更新文件时进行恢复!您的服务器应将其还原为重新启动或崩溃之前的状态。因此,您应该将PUT视为处理传递进来的信息(可能转换为中间存储格式)的请求,而不仅仅是覆盖文件。这反映了PUT的微妙本质-不仅仅是文件写入请求!您应该检查从PUT请求提供的提要文件,以确保它是有效的。
系统中的所有实体都必须能够维护Lamport时钟。
首次创建ATOM Feed时,您应该返回状态201-HTTP_CREATED。如果以后可以上传,则应该返回状态200。(这意味着,如果内容服务器首先连接到Aggregtion服务器,则返回201作为成功代码,然后在内容服务器断开连接之前,所有其他成功响应都应使用200)。 。除GET或PUT之外的任何其他请求都应返回状态400(注意:这不是标准操作,只是为了简化您的任务)。不向服务器发送任何内容应导致返回204状态码。最后,如果ATOM XML没有意义,则可能返回状态码500-内部服务器错误。
默认情况下,您的服务器将在端口4567上启动,但将接受一个给出起始端口号的命令行参数。您服务器的main方法将驻留在名为的文件中AggregationServer.java。
您的服务器旨在保持最新状态,并将删除Feed中来自内容服务器的所有项目,这些内容在12秒钟内未与之通信。如何执行此操作取决于您,但请高效!
您的GET客户
您的GET客户端将启动,阅读命令行以查找服务器名称和端口号(以URL格式),并将发送对ATOM提要的GET请求。然后,将剥离该提要的XML,并一次显示一行及其属性及其值。GET客户端的main方法将驻留在名为的文件中GETClient.java。服务器名称和端口号的可能格式包括“ http://servername.domain.domain:portnumber”,“ http:// servername:portnumber”(具有隐式域信息)和“ servername:portnumber”(具有隐式域和协议信息)。
您应该显示输出,以便于阅读,但您无需提供活动的超链接。您还应该使该客户端具有容错功能,并且显然,您必须使客户端能够维护Lamport时钟。
您的内容服务器
您的内容服务器将启动,从命令行读取两个参数,其中第一个是服务器名称和端口号(对于GET),第二个是文件在Content Server本地文件系统中的位置(预计此文件位于您的项目文件夹中)。该文件将包含许多来自ATOM格式的字段,这些字段将被组装成ATOM XML提要,然后上载到服务器。您可以假定所有字段都是文本,并且没有嵌入的HTML或XHMTL。您需要支持的ATOM元素列表是:
• 标题
• 字幕
• 链接
• 更新
• 作者
• 名称
• ID
• 条目
• 摘要
输入文件格式
为了简化解析,您可以假定输入文件将遵循以下格式:
请注意,author字段仅包含名称,您必须将其转换为author元素内的name元素。条目可以由另一个entry关键字终止,也可以由文件末尾终止,这也将终止供稿。您可以拒绝任何没有标题,链接或ID的提要或条目,因为它们是错误的。您可以忽略文本字段中的任何标记,而直接按原样打印。
PUT消息格式
您的PUT消息应采用以下格式:
您的内容服务器将需要确认它已从服务器收到正确的确认,然后检查以确保该信息已按预期包含在Feed中。它还必须支持Lamport时钟。
一些基本建议
以下是解决此问题的好方法:
• 考虑一下您将如何进行测试,以及如何构建每一块。个别步骤是什么?
• 编写服务器和客户端的简单版本,以确保您可以在它们之间进行通信。
• 使用已知可用的ATOM提要来测试系统的各个部分,并仔细阅读所有相关的规范部分!
• 那里有许多默认的Java XML解析器,学习如何使用它们而不是自己编写。这两个选项都是可以接受的,但是我们发现使用现有选项确实可以节省时间(如果没有用,那么这里有很多教程!)
• 我们强烈建议您使用套接字而不是HttpServer来实现此分配
• 尝试模块化代码;例如,在所有地方都需要ATOM Feed解析功能,因此最好将所有这些功能放在一个类中,然后在其他地方重用。
兰波特钟表注意事项
请注意,您将必须在整个系统中实现Lamport时钟和更新机制。这意味着每个实体将保留本地Lamport时钟,并且当该实体与其他实体通信或处理事件时,该时钟将被更新。由您决定实体在Lamport时钟更新中将考虑哪些事件(例如发送,接收或处理)(例如,System.out.println可能不会引起兴趣)。这种粒度将影响实现的性能。每个消息/请求都需要将本地Lamport时钟发送到其他实体(例如在请求标头中)-您负责确保此标记发生,并负责在收到消息/请求后对Lamport时钟进行本地更新。为此,遵循在课堂上和/或在论坛上可访问的Lamport Clocks论文中讨论的算法。作为此要求的一部分,我们知道您在通信中嵌入Lamport时钟信息的方法可能意味着您失去与其他客户端和服务器的互操作性。对于此分配,这是可以接受的结果,但是通常,我们将采用基于标准的方法来确保我们保持互操作性。
评定
此分配的标记分配如下:
• 60%-软件解决方案
• 40%-自动化测试
您的软件解决方案的评估将分配如下:
• 10%-代码质量,遵循附录A中的清单(以下)
• 20%-建筑设计决策
• 30%-支持基本功能,请遵循附录B中的清单(如下)
• 40%-支持全部功能和设计质量,遵循附录B中的清单(如下)
您的测试评估将分配如下:
• 考虑的测试用例范围
而不是关注测试的数量,您是否确定最重要的测试用例并在可能的用例之间很好地分布?
• 测试用例的清晰度
应该足够详细,以确保我们了解您所测试的内容和测试结果
理想情况下,包含在测试文档中的测试体系结构应该成为开发过程中的重要组成部分!
附录A
代码质量清单
做
• 在每个方法的标题上方写注释,描述方法的作用,输入和预期的输出
• 在评论中描述任何特殊情况
• 遵循内聚和耦合原则创建模块化代码
别
• 使用魔术数字
• 使用注释作为结构元素
• 拼写您的评论
• 使用难以理解的变量名
• 方法长于80行
• 允许TODO块
附录B
作业2清单
基本功能是指:
• XML解析工作
• 客户端,Atom服务器和内容服务器进程启动并进行通信
• PUT操作适用于一台内容服务器
• GET操作适用于许多读取客户端
• Atom服务器过期的Feed正常工作(12秒)
• 重试错误(服务器不可用等)有效
完整功能是指:
• Lamport时钟已实现
• 实现所有错误代码:空XML,格式错误的XML
• 内容服务器已复制且具有容错能力