转自: http://www.ibm.com/developerworks/cn/aix/library/au-aix-systemsdirector/section2.html
如何使用 Java 测试 IBM Systems Director 的 REST API
-
REST 代表 Representational State Transfer。REST 风格的架构由客户端和服务器组成。IBM Systems Director 也提供一个基于 RESTFul webservices 的接口。IBM Systems Director 是一个基于 Web 的工具,并为 REST 提供大量支持。几乎所有通过 CLI 和 GUI 支持的功能也可以通过 REST API 支持。REST 使用 HTTP 协议。它支持以下 HTTP 方法:
- POST:该方法用于创建一个新的资源。
- PUT:该方法用于修改一个现有资源。
- GET:该方法用于检索有关资源的信息。
- DELETE:该方法用于删除资源。
-
REST 操作和返回代码的类型:
有两种类型的 REST 操作:
-
同步操作:
在这种操作类型中,在作业完成之前,REST API 调用一直保持阻塞。作业完成后,该操作类型将返回 HTTP 返回代码和响应(如适用)。这种操作类型的返回代码示例如下:
- 200: 请求成功。所有 GET 操作都返回 200。
- 204: 无内容
- 304: 无变更
-
异步操作:
在这种操作类型中,REST API 调用将启动一个作业,并提供返回代码和位置,使用户能够确定作业的状态。用户可以查询位置,或者使用基于 JMS 的侦听程序,直到操作完成。这种操作类型的返回代码示例如下:
- 201 CREATED: 资源已创建。所有 POST 操作都会返回 201。
- 202 ACCEPTED: 请求已接受,等待处理。部分 PUT 和 DELETE 操作会返回此代码。
-
同步操作:
-
3. 一些 HTTP 错误代码:
- 400:请求无效。请求可能不正确,或者请求中的数据格式不正确。
- 401:请求需要用户身份验证。
- 404:IBM Systems Director Server 没有找到任何结果可以匹配请求 URI 中的指定资源。
- 500:IBM Systems Director 遇到了一个意外情况,阻止它处理请求。
- 手动(使用工具):使用一些外部 REST 客户端,如 Firefox Poster、http4e 等,并手动调用 REST API。我们在本教程中使用了 Poster。您可以使用自己喜欢的 REST 客户端。
- 自动:使用编程语言或脚本自动调用 REST API。本教程将介绍使用 Java 进行自动测试。您可以使用自己喜欢的任何其他语言或脚本。
这两个方法的说明如下:
-
手动(使用 Poster):
在本节中,我们将讨论使用 Poster 手动测试一些 IBM Systems Director 的基本功能:
- 获得资源列表(GET 操作)
- 发现新资源 (POST 操作)
- 修改已发现的资源(PUT 操作)
- 删除资源(DELETE 操作)
-
获得资源列表(GET 操作):
如图 1 所示,您使用 GET 操作可以列出资源。GET 检索有关该资源的信息。检索资源的请求如图 1 所示:
图 1. 使用 Poster 的 GET 操作
在图 1 中,您作为用户可以看到以下信息:
- URL: 检索有关服务器信息的 URI。
- Actions: 选定的操作是 GET。
- Header 部分:用户需要在这部分中输入以下内容:
- ISDAPIVersion: IBM Systems Director 的版本。
- Authorization: 这是一个 base64 转换的用户 ID 和密码,用于 IBM Systems Director。
- Accept: 可接受的内容类型
-
发现资源(POST 操作)
发现是 IBM Systems Director 的一个非常基本的操作,用于发现资源。您需要使用 POST 方法进行发现,因此,您需要提供 HTTP 正文 (JSON) 与 HTTP 头。发现的 HTTP 正文如下:
清单 1. 输入 POST 发现操作的 JSON{ "IPAddress": ["9.1.2.3"], "ResourceTypes": ["Server", "OperatingSystem"] }
您需要提供资源的 IP 地址和资源类型。使用 POST 操作可以发现新源,如图 3 所示。
图 3. POST 操作发现资源
响应如图 4 所示:
图 4. 发现的 POST 操作的响应
在图 4 的 HTTP 响应中要注意一些重要事项:
- 返回代码:对于 POST 请求是 201
- Location: POST 操作是异步操作,它包括返回的位置。位置是一个 URL,它可以用于检查使用 GET 操作的作业状态,如图 1 所示。
使用 Location URI 的 GET 操作的响应如图 5 所示。
图 5. 使用 Location URI 的 GET 操作的响应
在 HttpResponse 中,如图 5 所示,您可以看见以下值:
- URI: 它是之前 POST 操作的 "Location"。
- Percent Complete: 它以百分比显示任务的完成状态。在图 5 中它是 100%,意味着任务已经完成。
- DiscoveryStatus: 该字段显示作业的状态,即,它是否成功。在图 5 中,它的值是 "Ok",这意味着作业已成功完成。
-
修改资源(PUT 操作):
要修改一个现有资源,您需要使用 PUT 操作。对于 PUT 操作,您需要传递 HTTP 正文和 HTTP 头。用于修改资源的 HTTP 正文如下:
清单 2. 清单 2. 输入 PUT 修改资源操作的 JSON{ "Properties": {"DisplayName" : "NewName"} }
您可以使用 PUT 操作来修改资源,如图 6 所示。
图 6. PUT 操作来修改资源
对 PUT 请求的响应如图 7 所示:
图 7. 对 PUT 请求的响应
如图 7 所示,IBM Systems Director 返回了 204 作为返回代码,这意味着,它没有内容要返回,并且请求已成功提交。
-
删除资源(DELETE 操作):
当您需要删除资源时,应使用 DELETE 方法。您需要将想删除的资源 OID 追加到 URI 本身。使用 DELETE 操作可删除资源,如图 8 所示。
图 8. DELETE 操作删除资源。
DELETE 操作的响应如图 9 所示。
图 9. DELETE 操作的响应
如图 9 所示,IBM Systems Director 返回了 204 作为返回代码,这意味着它没有内容要返回,并且 DELETE 请求已成功提交。
我们已介绍了使用 Poster 的四种基本 ISD REST API 操作。同样地,您也可以利用该工具或其他一些您喜欢的工具,手动地测试或使用其他 IBM Systems Director 功能。您也可以通过使用编程方式访问这些 REST API,自动化整个过程。本教程的下一节讨论使用 Java 程序执行所有上述 IBM Systems Director REST API 功能所需的步骤。
响应如图 2 所示:
图 2. GET 操作的响应
在图 2 中,您可以看到 IBM Systems Director 对 GET 请求的响应。响应包括一个返回代码和响应正文。图 2 中的返加代码是 200 (OK),而响应正文是 IBM Systems Director 所返回的所有资源的列表。
在这里,我们也将看到在上面已经讨论过的四个相同功能。我们已经使用 Apache 的 HttpClient 和 HttpResponse 类调用 REST API,并读取响应。我们使用这些类来简化更新请求头以及将 HTTP 正文作为参数传递的过程。您甚至可以使用 Java 的 HttpURLConnection 类,或者您所喜欢的任何其他实用工具来进行调用。您能够以编程方式来调用 ISD REST API,如下:
-
列出资源 (GET 操作):
GET 操作列出有关该资源的信息。为了运行 IBM Systems Director 的 GET 请求,我们需要针对 IBM Systems Director 相关的条目修改 HttpClient 的 sendGetRequest 方法,如清单 3 所示:
清单 3. 在 HttpClient.java 中的 sendGetRequest 方法. . . sendGetRequest(String uri){ GetMethod method = new GetMethod(uri); method.addRequestHeader(new Header("Accept","application/json")); method.addRequestHeader(new Header("Accept-Language", "en_us")); method.addRequestHeader(new Header("ISDAPIVersion","6.2.1.0")); method.addRequestHeader(new Header ("Authorization", "Basic cm9vdDpnbzRic==")); int statusCode = client.executeMethod(method); return statusCode; }
在清单 3 的代码片段中,您可以看到以下信息:
- 初始化 GetMethod 类的一个对象,并将 URI 传递给它。
- 使用 addRequestHeader () 方法将 Request 头添加给 GetMethod 对象。以下 IBM Systems
Director 特定条目需要被添加到请求头:
- Accept: 拥有 "application/json" 值的 Accept 头。
- Accept-Language: 值可以是任意支持的语言。我们使用了 en_us。
- ISDAPIVersion: IBM Systems Director 版本 "6.2.1.0"。
- Authorization: base64 转换的用户名和密码。
- 调用 HttpClient 的执行方法并将 GetMethod 的对象传递给它。
在更新 HttpClient 之后,您需要编写自己的客户端,以调用 HttpClient 类的 sendGetRequest 方法,以 URI 作为一个参数。我们使用了基于 JUnit 的测试来调用 sendGetRequest 方法并检查返回代码。
清单 4. 清单 4. 测试 GET 的 JUnit 测试用例private DWHttpClient httpClient = null; String hostURI = null; @Test public void testListRes() { httpClient = new DWHttpClient(); properties = new Properties(); try { hostURI = "https://1.2.3.4:8422/ibm/director/rest/resources/System"; statusCode = httpClient.sendGetRequest(hostURI); assertEquals(HttpStatus.SC_OK, statusCode); } catch (Exception e) { fail("unexpected exception has happened "+e.getMessage()); e.printStackTrace(); } }
在清单 4 的代码中,我们首先初始化 HttpClient 类的对象,我们在清单 3 中已修改过该对象。接着,我们初始化 hostURI,它用于从 IBM Systems Director 检索资源信息,最后,调用 sendGetRequest() 方法以运行 GET 请求。
我们使用 JUnit 的 assertEquals() 方法检查了状态代码,验证它是否 HttpStatus.SC_OK,这实际上表示返回代码 200。
-
发现资源(POST 操作):
该 POSToperation 发现了在 IBM Systems Director 中的资源。为了运行 IBM Systems Director 的 POST 请求,我们需要针对 IBM Systems Director 相关的条目修改 HttpClient 的 sendPostRequest 方法,并编写我们自己的客户端来调用请求和检查结果。sendPostRequest 和客户端的代码片段如清单 5 所示:
清单 5. HttpClient.java 中的 sendPostRequest 方法. . . sendPostRequest(String hostURI, String requestData){ PostMethod method = new PostMethod(uri); method.addRequestHeader(new Header("Content-Type","application/json")); method.setRequestEntity (new StringRequestEntity (requestData, "application/json", "UTF-8")); method.addRequestHeader (new Header ("Authorization", "Basic cm9vdDpnbzRicm9rZQ==")); method.addRequestHeader(new Header("ISDAPIVersion", "6.2.1.0")); int statusCode = client.executeMethod(method); return statusCode; }
在清单 5 的代码片段中,您可以看到以下信息:
- 初始化一个 PostMethod 的对象并将 URI 传递给它。
- 将 Request 头添加到 PostMethod 对象,其中包括 Content-Type、Authorization 和 ISDAPIVersion。
- 设置一个 Request Entity 以传递请求数据。
- 最后通过传递 PostMethod 对象来运行方法。
基于 JUnit 的客户端调用 POST 请求如清单 6 所示:
清单 6. 测试 POST 的 JUnit 测试用例private DWHttpClient httpClient = null; String hostURI = null; @Test public void testDiscovery() { httpClient = new DWHttpClient(); try { hostURI = "https://1.2.3.4:8422/ibm/director/rest/discover"; String requestData = "{\"IPAddress\": [\"5.6.7.8\"], \"ResourceTypes\": [\"Server\", \"OperatingSystem\"]}"; statusCode = httpClient.sendPostRequest(hostURI, requestData); assertEquals(HttpStatus.SC_CREATED, statusCode); } catch (Exception e) { fail("unexpected exception has happened "+e.getMessage()); e.printStackTrace(); } }
在清单 6 的代码中,我们首先初始化了 HttpClient 类的对象,我们已在清单 5 的代码中修改过该对象。然后我们初始化 hostURI,它用于发现在请求数据中所提及的资源。
在下一步中,我们调用了 HttpClient 的 sendPosttRequest() 方法,使用 hostURI 和 requestData 作为参数,然后我们使用 assertEquals() 方法检查返回代码。在请求成功执行后,它返回一个代码 201,这表示 "CREATED"(已创建)。
由于 POST 是一个异步操作,您需要跟踪作业的进度,出于这个原因,它始终将位置作为头的一部分返回。您需要从请求返回的响应对象中检索响应头。您可以使用位置头的值来检查进度。请参考下载小节中的样例类,获得完整代码。
-
修改资源(PUT 操作):
当您需要修改资源时,要使用 PUT 请求。为了运行 IBM Systems Director 的 PUT 请求,我们需要针对 IBM Systems Director 相关的条目修改 HttpClient 的 sendPutRequest 方法,并编写我们自己的客户端来调用请求和检查结果。sendPutRequest 和客户端的代码片段如清单 7 所示。
清单 7. HttpClient.java 中的 sendPutRequest 方法. . . sendPutRequest(String uri, String requestData){ PutMethod method = new PutMethod(uri); method.addRequestHeader(new Header ("Content-Type","application/json")); method.addRequestHeader(new Header("ISDAPIVersion", "6.2.1.0")); method.setRequestEntity(new StringRequestEntity (requestData, "application/json", "UTF-8")); method.addRequestHeader(new Header ("Authorization", "Basic cm9vdDpnbzRicm9rZQ==")); int statusCode = client.executeMethod(method); return statusCode; }
基于 JUnit 的客户端调用 PUT 请求,如代码清单 8 所示:
清单 8. 测试 PUT 的 JUnit 测试用例private DWHttpClient httpClient = null; String hostURI = null; @Test public void testModifyResource() throws IOException { httpClient = new DWHttpClient(); hostURI = "https:1.2.3.4:8422/ibm/director/rest/resources/Server/12345"; String requestData = " {\"Properties\": {\"DisplayName\" : \"NewResName\"}}"; statusCode = httpClient.sendPutRequest(hostURI, requestData); assertEquals(HttpStatus.SC_NO_CONTENT,statusCode); }
在请求成功执行后,IBM Systems Director 返回代码 204,如代码清单 8 所示
-
删除资源(DELETE 操作):
当您需要删除资源时,应使用 DELETE 方法。您需要将想删除的资源 OID 追加到 URI 本身。为了运行 IBM Systems Director 的 DELETE 请求,我们需要针对 IBM Systems Director 相关的条目修改 HttpClient 的 sendDeleteRequest 方法,并编写我们自己的客户端来调用请求和检查结果。sendDeleteRequest 和客户端的代码片段如下所示:
清单 9. HttpClient.java 中的 sendDeleteRequest 方法. . . sendDeleteRequest(String uri){ DeleteMethod method = new DeleteMethod(uri); method.addRequestHeader(new Header ("Authorization", "Basic cm9vdDpnbzRicm9rZQ==")); method.addRequestHeader(new Header("ISDAPIVersion", "6.2.1.0")); int statusCode = client.executeMethod(method); return statusCode; }
基于 JUnit 的客户端调用 DELETE 请求,如下所示:
清单 10. 测试 DELETE 的 JUnit 测试用例private DWHttpClient httpClient = null; String hostURI = null; @Test public void testDiscovery() throws IOException { httpClient = new DWHttpClient(); hostURI = "https://1.2.3.4:8422/ibm/director/rest/resources/Server/12345"; statusCode = httpClient.sendDeleteRequest(hostURI); assertEquals(HttpStatus.SC_NO_CONTENT, statusCode); }
在请求成功执行后,IBM Systems Director 会返回代码 204,如代码清单 10 所示
使用 HTTP 客户端自动化 REST API 测试的样例代码
我们已对本教程中所提及的所有场景以及一些其他 POST 操作场景编写了样例代码。该代码可以从本教程的下载小节处下载。该代码包括以下部分:
- 列出资源(GET 操作)
- 发现新资源(POST 操作)
- 请求访问已发现的资源(POST 操作)
- 收集清单(POST 操作)
- 修改资源(PUT 操作)
- 删除资源(DELETE 操作)
如果有需要,可以重用样例代码。该代码也包括一些实用工具类和属性文件,如下所示:
- HttpClient:该类定义所有 HTTP 操作,如 GET、POST、PUT 和 DELETE。该类还包含了 Director 服务器的证书验证代码。
- HttpResponse:该类用于格式化 HTTP 响应。
- Read Properties file:该类用于从属性文件读取属性。
- Util:该类包含一些实用工具方法,用于检索资源的 OID 等。
- config.properties:该文件中的属性针对不同系统而有所不同。
为了使代码更灵活并可以实现重用,我们引入了一个属性文件,您可以在该文件中输入 IBM Systems Director 和所有端点的信息。测试用例会在运行时读取该属性文件,以检索这些信息。只需更新该属性文件,即可在任何系统上运行此代码。
您可以运行各个类,以执行任何特定操作。我们还引入了一个 TestSuite 文件,一次运行所有脚本。
我们已经创建了一个 ISDSuite 文件,并推出了套装文件,从 Eclipse 运行所有测试。图 10 显示了执行的结果。
您还可以使用以下命令,从命令提示符运行所有测试:
java org.junit.runner.JUnitCore ISDSuite |
要注意几个重点:
- 为了运行 REST API,您要将用户名和密码的组合转换成 base 64 编码。
- 对于 Linux?:您需要使用以下格式: usrename:password
将上述字符串转换成 base 64 编码,并在字符串前面追加 "Basic",然后把它放在 Authorization 头。例如,Basic "Base64 converted string"
- 对于 Microsoft? Windows?:用户需要使用以下格式:domain\\usrename:password
将上述字符串转换成 base 64 编码,并在字符串前面追加 "Basic",然后把它放在 Authorization 头。例如,Basic "Base64 converted string"
- 对于 Linux?:您需要使用以下格式: usrename:password
- IBM Systems Director 证书:DWHttpClient 类负责创建远程系统的证书,以执行安全的调用。