转载

构建一个云存储应用程序

在许多云服务中,云对象存储的成长或许是最快的。云对象存储常被用于存储照片、图像、文档和音视频文件。每一天,人们都会发现其最喜欢的对象存储的新用途。无论您开发的应用程序有何用途,理解云对象存储服务都是构建真实的可扩展解决方案的一个重要步骤。

有了这里学到的知识,您就可以利用 IBM Object Storage 非常快地开发优秀的应用程序。

在本教程中,我们将展示如何使用 Bluemix 的 Object Storage 服务(一个基于 OpenStack Swift 的对象存储服务)开发一个简单应用程序,还将解释如何使用 REST 风格的存储 API。您开发的应用程序允许用户利用 Bluemix 的 Object Storage 服务上传、下载和管理其照片和文档。您还可以下载示例应用程序并查看代码。有了这里学到的知识,您就可以使用 Object Storage 服务快速开发优秀的应用程序。

获取代码

构建本教程中的示例应用程序需要做的准备工作

  1. 一个 Bluemix 帐户
  2. 基本了解 Cloud Foundry 命令行接口
  3. 基本了解 Node.js以下文档可能有所帮助:
    • Node.js 应用程序开发
    • Node.js 快速入门教程
    • Node.js 高级教程
  4. 基本了解 Object Storage 服务应用程序 术语(可选)
  5. 基本了解 OpenStack Swift API (可选)

第 1 步. 创建一个 Node.js 应用程序

  1. 登录到您的 Bluemix 帐户。
  2. 单击 CREATE AN APP
  3. 选择 WEB 应用程序类型。
  4. 选择 SDK for Node.js 并单击 CONTINUE
  5. 输入一个在您选择的 Bluemix 域中惟一的应用程序名称。在此示例中,我们使用 awesome-store 作为应用程序的名称。

第 2 步. 添加 Bluemix Object Storage 服务的一个实例

  1. 创建应用程序后,单击 ADD A SERVICE 按钮。
  2. 向下滚动到 Data Management 节并单击 Object Storage 图标。
  3. Object Storage 服务随带了非常详细的 Object Storage 入门 文档,可以单击 VIEW DOCS 按钮来查阅它。也可以单击 TERMS 按钮来查阅服务许可协议。您可能已经注意到,这个 beta 服务是免费提供的。
  4. 单击 CREATE 按钮并对您的应用程序执行 RESTAGE 。您现在已使用 Bluemix 提供的 Node.js 入门模板项目创建了一个应用程序,创建了一个 Object Storage 服务实例,并将该实例绑定到了新创建的应用程序。
  5. 您的应用程序名称 awesome-store 显示在浏览器顶部,名称下方是一个链接。要查看该应用程序的用途,可单击该链接。这将打开一个类似下图的窗口。请注意,您的浏览器地址区域显示了 awesome-store.mybluemix.net 。这个 URL 是应用程序名称和您选择的域的组合。您可以使用该 URL 从任何浏览器访问您的应用程序。 构建一个云存储应用程序

    点击查看大图

    关闭 [x]

    构建一个云存储应用程序

  6. 在仪表板的左边栏,单击 Environment Variables 链接来检查 VCAP_SERVICES 。这是一部分重要的信息,您的应用程序需要使用它们来调用 Object Storage 服务,比如用于为应用程序用户创建一个帐户,允许用户上传和下载文档。下图提供了一个示例。 usernamepassword 显得杂乱无章,以增加安全性。 构建一个云存储应用程序

    点击查看大图

    关闭 [x]

    构建一个云存储应用程序

    您可以注意到,在 credentials 部分,可以找到 auth_uriusernamepassword 。这 3 个字段用于向服务验证您的应用程序,它们现在开始被称为 auth_uri、usernamepassword 。您一定要知道的是,这个成对出现的 usernamepassword 是您的应用程序用于向服务执行验证的凭据。如果您的应用程序支持多个用户,那么它们与您应用程序的 usernamepassword 不同。

第 3 步. 从 Bluemix 获取初始代码

  1. 在 Bluemix 屏幕上查看 awesome-store 应用程序时,可单击左侧边栏上的 Start Coding 链接。 构建一个云存储应用程序

    点击查看大图

    关闭 [x]

    构建一个云存储应用程序

  2. 右侧显示了一些与 Bluemix 应用程序开发流程相关的步骤。如果您尚未在自己最喜欢的环境中设置 Cloud Foundry 命令行接口,现在请按照 Setup 步骤进行设置。
  3. 单击 Download Starter Code 。下载的代码是一个压缩文件。在解压该文件后,就会看到以下文件夹和文件结构: 构建一个云存储应用程序

    因为本教程的目的是演示如何使用 Object Storage 服务,所以我们不会深入详细介绍 Node.js 应用程序编程。相反,我们将重点介绍编写 Object Storage 服务需要注意的 3 个重要方面。

    1. 我们将介绍 Object Storage 服务如何利用 OpenStack Swift 对象存储 API,让应用程序能够操作其对象存储中的各种实体。
    2. 我们知道,要让应用程序能够访问 Swift 对象存储,它首先必须获得一个访问令牌。
    3. 随后,我们展示了应用程序如何在请求中传递此访问令牌,以便操作文件夹和对象。
  4. 尽管有许多方式来完成上面设定的任务,但为了简便起见,我们开发了一些 URL 来完成这个 Node.js 应用程序中的任务。这些 URL 将以请求的形式输入到您的浏览器中,所以您无需使用任何特殊工具来测试代码。以下是这些 URL 的列表以及每个 URL 的简短描述。将带有冒号前缀的变量替换为您选择的字符串。例如,将 /gettoken/:userid 变成 /gettoken/tongli
    • /gettoken/:userid :获取 userid 的一个访问令牌
    • /listfolders/:userid :列出 userid 的所有文件夹。
    • /createfolder/:userid/:foldername :为 userid 创建一个名为 foldername 的文件夹。
    • /delfolder/:userid/:foldername :删除 userid 的一个文件夹。这个文件夹未在应用程序中实现,作为练习,您可以添加该实现。该实现非常类似于 deldoc 操作。
    • /listdocs/:userid/:foldername :列出 userid 的一个文件夹的所有文档。
    • /createdoc/:userid/:foldername/:docname :在 foldername 文件夹下为 userid 创建一个名为 docname 的文档。您可能注意到,GET 请求没有真正发送文档的任何内容。在此应用程序中,只发送了一个硬编码的字符串。
    • /getdoc/:userid/:foldername/:docname :在 userid 下的 foldername 文件夹中获取名为 docname 的文档。
    • /deldoc/:userid/:foldername/:docname :删除一个文档。
  5. 在您的 views 文件夹中,创建一个名为 layout.jade 的 Jade 模板,并复制并粘贴以下代码作为其内容,然后保存该文件。
    doctype html   html     include head     body       table(style="width:100%")         tr           td(style= "width:307px" )             img(src="/images/newapp-icon.png")           td             block content
  6. 在您的 views 文件夹中,创建另一个名为 results.jade 的 Jade 模板,并复制并粘贴以下代码作为其内容,然后保存该文件。
    extends layout   block content     div(id="results")       h2         pre           !=JSON.stringify(body, null, 2)
  7. 打开 app.js 文件,将以下行添加到 var services 行的后面:
    The existing code:      var services = JSON.parse(process.env.VCAP_SERVICES || "{}");      The new code to be added after the above line:      app.get('/gettoken/:userid', function(req, res){    res.render('results', {body: {});   });

    新代码使用 results.jade 作为模板,将一个名为 body 的变量传递给该模板,然后呈现 HTML。

  8. 这些新文件和 app.js 中的更改使我们能实现更多功能。尽管我们目前尚未完成多少更改,但仍可部署此应用程序来查看新代码的运行情况。使用 cf push 命令将应用程序部署在 Bluemix 上,然后在浏览器中打开 http://awesome-store.mybluemix.net/gettoken/tong 来查看结果,结果类似于下图:
    构建一个云存储应用程序

    如果看到错误,请仔细检查这两个文件和 app.js 文件中执行的更改。通常浏览器会显示有帮助的调试信息。

第 4 步. 获取应用程序用户的访问令牌

  1. Object Storage 服务支持对每个服务实例使用多个用户帐户。它使您能够轻松地开发一个支持多个用户的应用程序,因为它为您执行了主要工作。要获取应用程序用户的访问令牌,可以使用基本的身份验证方法向此端点发送请求: auth_uri/<app_userid> 。在此示例中,URL 类似于:

    点击查看代码清单

    关闭 [x]

    https://swift.ng.bluemix.net/auth/e40bf8f2-c3c6-4e51-8cde-476e30574637/fe07a633-61b3-4797-9a4d-c36daee7335b/tong

    请注意,URL 并不是您从 VCAP_SERVICES 变量获取的完全相同的 auth_uri 。它是 auth_uri 与您的应用程序选择的 userid 的串联结果。您的应用程序可以支持多个用户,而且您可以选择任何内容作为 userid,只要这些 userid 在整个应用程序中是惟一的。每个 userid 应惟一地标识您应用程序中的一个用户。基本验证标头应该符合标准的基本验证协议。

  2. 因为您将在应用程序中发送 HTTP 请求,所以需要包含一个 Node.js HTTP 请求库。将下面这行添加到 app.js 文件中。
    The existing code:   var express = require('express');      The new code to be added after the above line:   var request = require('request');
  3. 将以下代码添加到 app.js 文件中,替换掉 3.7 步中添加的行。

    var cache = {};   var auth = null;      var set_app_vars = function() {    var credentials = services['objectstorage'][0]['credentials'];    auth = {"auth_uri": credentials['auth_uri'],      "userid" : credentials['username'],      "password" : credentials['password'],    };    auth["secret"] = "Basic " +     Buffer(auth.userid + ":" + auth.password).toString("base64");   };      app.get('/gettoken/:userid', function(req, res){    if (!auth) { set_app_vars(); }    var res_handler = function(error, response, res_body) {     var body = {};     if (!error && response.statusCode == 200) {      body = {"userid": req.params.userid,        "token": response.headers['x-auth-token'],        "url": response.headers['x-storage-url']};      cache[req.params.userid] = body;     }     else {      body = {"token": error, "url": ""};     };     res.render('results', {"body": body});    };    var req_options = {         url: auth.auth_uri + '/' + req.params.userid,     headers: {'accept': 'application/json',                  'Authorization': auth.secret},     timeout: 100000,     method: 'GET'    };    request(req_options, res_handler);   });

    在上面的代码中,函数 set_app_vars 接受来自变量 VCAP_SERVICES 的值,并查找该服务实例的 objectstorage 设置。该函数还会获取 auth_uri、useridpassword ,然后根据基本验证协议创建一个 base64 字符串,并保存它供以后使用。

    app.get('/gettoken/:userid') 调用将会设置一个请求处理函数,以便通过这个代码块处理所有针对 /gettoken/:userid 的 GET 请求。在这个代码块中,定义一个响应处理函数和请求选项,以获取 IBM Bluemix Object Storage 所提供的端点的访问令牌。在发送该请求后,响应处理函数会检查响应状态代码,然后创建一个 body 变量并传递它,以便依据 results.jade 文件中提供的定义将其呈现为 HTML 页面。

    另请注意,收到的令牌由这个应用程序临时缓存,供以后使用。如果正在使用此服务开发一个真实应用程序,则应缓存该令牌,这样您就无需每次都向此服务发送请求来获取访问令牌。

  4. 使用 cf push 命令重新部署应用程序。
  5. 访问您之前使用的相同 URL。您应看到类似下图的信息:同样出于安全原因遮住了令牌。

    http://awesome-store.mybluemix.net/gettoken/tong

    构建一个云存储应用程序
  6. 响应显示了一个令牌和一个 URL。您的应用程序应保存令牌和 URL 这两部分信息,以便在云对象存储服务中创建文件夹(容器)和文档(对象)。
  7. 首次为某个特定用户发送 GET 请求时,该请求会返回 202 状态代码。这是因为第一次访问对象存储都会导致对象存储为该用户配比一个新帐户,这可能花费 5 到 10 分钟的时间。如果您的请求未获得令牌,您可以等待几分钟,然后再次尝试同样的请求。最终,您会在请求和访问令牌中获得一个 200 状态代码,在响应标头中获得一个 URL。有了这两部分信息,您就可以使用 OpenStack Swift API 来探索 Object Storage 了。如果不熟悉该 API,可以在 http://docs.openstack.org/api/openstack-object-storage/1.0/content/ 上了解有关的更多信息。

第 5 步. 使用 OpenStack Swift API 为用户创建文件夹

  1. 在前面的步骤中,您成功获取了用户 tong 的访问令牌。现在是时候为 tong 创建一个文件夹OpenStack Swift 定义来创建文件夹的 API 是一个 PUT 请求,请求标头包含访问令牌。该端点是存储服务的 URL,您会在获取访问令牌时获得它。因此,要创建一个文件夹,可使用上面收到的访问令牌和存储 URL 来发送 PUT 请求。
    app.get('/createfolder/:userid/:foldername', function(req, res){   var user_info = cache[req.params.userid];   var res_handler = function(error, response, body) {    if (!error && (response.statusCode == 201 ||       response.statusCode == 204)) {     res.render('results', {'body': {result: 'Succeeded!'}});    }    else {     res.render('results', {'body': {result: 'Failed!'}});    }   };   var req_options = {    url: user_info['url'] + "/" + req.params.foldername,    headers: {'accept': 'application/json',          'X-Auth-Token': user_info['token']},    timeout: 100000,    method: 'PUT'   };   request(req_options, res_handler);  });
  2. 上面的代码为一个针对端点 /createfolder/:userid/:foldername 的请求定义了一个处理函数。在您自己的应用程序中,您能够以任何您喜欢的方式定义该 URL,但您应采用某种方式来获取文件夹名称和 userid。例如,您可以对 userid 使用会话跟踪。或者可以使用一个 form post 来获取文件夹名称。有许多选项可供选择。在此应用程序中,在请求路径中使用了一个参数。在收到请求后,它会在缓存中找到用户信息,定义响应处理函数和请求选项,然后发送请求。
  3. 将上述代码添加到 app.js 文件中,并重新部署应用程序。重新部署应用程序时,缓存的用户令牌会丢失,所以您需要使用 /gettoken/:userid 请求再次获取该令牌。以下是两个可以试用的 URL。
    • http://awesome-store.mybluemix.net/gettoken/tong
    • http://awesome-store.mybluemix.net/createfolder/tong/newfolder
  4. 如果一切正常,您会看到类似下图的结果: 构建一个云存储应用程序

第 6 步. 使用 OpenStack Swift API 为一个用户上传一个文档

在前面的步骤中,您成功添加了用来获取访问令牌和创建文件夹的函数。在这一节中,我们将添加另外一些代码,以便将文档上传到已创建的名为 newfolder 的文件夹。OpenStack Swift 上传对象 API 也是端点上的一个 PUT 请求,该请求包含存储 URL 和文件夹名称。访问令牌必须包含在请求标头中。

以下是上传文档的代码:

app.get('/createdoc/:userid/:foldername/:docname', function(req, res){       var user_info = cache[req.params.userid];       var res_handler = function(error, response, body) {    if (!error && response.statusCode == 201) {        res.render('results', {'body': {result: 'Succeeded!'}});    }    else {        res.render('results', {'body': {result: 'Failed!'}});    }       };       var req_options = {    url: user_info['url'] + "/" + req.params.foldername + "/" +     req.params.docname,    headers: {'accept': 'application/json',        'X-Auth-Token': user_info['token']},    timeout: 100000,    body: "Some random data",    method: 'PUT'       };       request(req_options, res_handler);   });

上面的代码采用了与前面的代码块相同的模式。它首先在请求 URL 中获取 userid 的访问令牌,然后定义一个响应处理函数和请求选项,最后发送请求。惟一的区别是,我们添加了一个字符串 "Some random data" 作为已上传对象的内容。

在您的应用程序中,您可以为用户提供各种各样的上传文档的途径。因为这在本教程讨论的范畴内,所以我们为文档内容硬编码了示例数据。这使得代码非常简单,而且便于演示,但是,如果按原样使用该应用程序,每个文档都将包含相同的内容。

结束语

在本教程中,我们演示了如何创建一个简单的 Node.js 应用程序来使用 Bluemix 的 Object Storage 服务。该应用程序展示了如何获取用户的访问令牌,创建文件夹和上传文档。在应用程序代码中,您还可以发现处理一些请求的代码块,比如列出用户的文件夹,列出文件夹中的文档,删除文档和其他请求。利用您在本教程中学到的知识,快速而又轻松地使用 Object Storage 开发优秀的应用程序。

BLUEMIX SERVICE USED IN THIS TUTORIAL: Object Storage 服务 拥有对配置独立对象存储的内置支持,而且它为每个对象存储创建单独的子帐户。

相关主题: Node.js

正文到此结束
Loading...