Hyperledger Composer REST API 集成现有系统(四)

1.生成REST API

安装REST服务器

Hyperledger Composer REST服务器可以使用npm或Docker进行安装。

要使用npm进行安装,请运行以下命令:

Copy 复制
npm install -g composer-rest-server

要使用Docker安装REST服务器,请参阅部署REST服务器

运行REST服务器

Hyperledger Composer包含独立的Node.js流程,将业务网络公开为REST API。LoopBack框架用于生成由Swagger文档描述的Open API。

要启动REST服务器,只需输入:

Copy 复制
composer-rest-server

然后您将被要求输入关于您的商业网络的一些简单细节。下面显示了使用部署的业务网络的一个示例。

Copy 复制
? Enter the name of the business network card to use: admin@basic-sample-network
? Specify if you want namespaces in the generated REST API: always use namespaces
? Specify if you want to enable authentication for the REST API using Passport: No
? Specify if you want to enable event publication over WebSockets: Yes
? Specify if you want to enable TLS security for the REST API: No

To restart the REST server using the same options, issue the following command:
   composer-rest-server -c admin@basic-sample-network -n always -w true

Discovering types from business network definition ...
Discovered types from business network definition
Generating schemas for all types in business network definition ...
Generated schemas for all types in business network definition
Adding schemas for all types to Loopback ...
Added schemas for all types to Loopback
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer

composer-rest-server命令

composer-rest-server命令有许多选项用于定义安全性和身份验证:

Copy 复制
Options:
  -c, --card            The name of the business network card to use  [string]
  -n, --namespaces      Use namespaces if conflicting types exist  [string] [choices: "always", "required", "never"] [default: "always"]
  -p, --port            The port to serve the REST API on  [number]
  -y, --apikey          The API key to get access to the REST API [string] [default:undefined]
  -a, --authentication  Enable authentication for the REST API using Passport  [boolean] [default: false]
  -m, --multiuser       Enable multiple user and identity management using wallets (implies -a)  [boolean] [default: false]
  -w, --websockets      Enable event publication over WebSockets  [boolean] [default: true]
  -t, --tls             Enable TLS security for the REST API  [boolean] [default: false]
  -e, --tlscert         File containing the TLS certificate  [string] [default: "/usr/local/lib/node_modules/composer-rest-server/cert.pem"]
  -k, --tlskey          File containing the TLS private key  [string] [default: "/usr/local/lib/node_modules/composer-rest-server/key.pem"]
  -h, --help            Show help  [boolean]
  -v, --version         Show version number  [boolean]

查看生成的API

启动浏览器并转到给定的URL(http://0.0.0.0:3000/explorer)。你会看到类似这样的屏幕。

Hyperledger Composer REST API 集成现有系统(四)_第1张图片

更新REST服务器

在更新业务网络定义之后,可以更新REST服务器以生成反映业务网络定义更新的新API。

要更新REST服务器,首先必须停止使用REST服务器ctrl-C然后可以使用重新启动REST服务器composer-rest-server

使用API​​KEY生成REST API

API密钥可用于提供第一层安全性以在开发环境中访问REST API。

Copy 复制
composer-rest-server -y YOUR_API_KEY

这将只接受x-api-key带有值设置为Header的请求YOUR_API_KEY

概要

在Hyperledger Composer运行时之上使用Loopback框架使我们能够基于已部署的业务网络模型生成特定于业务领域的REST API!


2. 从REST服务器发布事件

REST服务器可以配置为订阅从部署的业务网络发出的事件,并发布这些业务事件以供客户端应用程序使用。目前,REST服务器支持通过WebSockets向客户端应用程序发布事件。

客户端应用程序可以使用WebSocket客户端订阅REST服务器发布的业务事件。WebSocket客户端可用于所有主要编程语言和应用程序类型,例如客户端Web用户界面,后端服务器进程,移动应用程序和集成工具。

启用WebSockets

您可以-w在命令行上使用参数启用WebSockets

Copy 复制
composer-rest-server -c alice1@my-network -w

或者,您可以使用COMPOSER_WEBSOCKETS环境变量启用WebSockets

Copy 复制
export COMPOSER_WEBSOCKETS=true
composer-rest-server -c alice1@my-network

当您成功启用WebSocket时,您将能够将WebSocket客户端连接到REST服务器输出中显示的基本URL:

Copy 复制
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer

在此示例中,要使用的基本URL是http://localhost:3000你必须从改变协议转换为WebSocket的URL这个httpws在这个例子中,使用的WebSocket URL是ws://localhost:3000

测试WebSocket已启用

您可以通过使用WebSocket客户端来订阅事件来测试已启用WebSocket。开源命令行应用程序wscat可用于此目的。

要安装wscat,您可以使用npm如果您没有正确的权限来全局安装npm模块,则可能需要使用sudo或root身份运行此命令

Copy 复制
npm install -g wscat

然后,您可以使用wscat它连接并订阅REST服务器发布的业务事件。收到的任何商业活动都将打印到控制台:

Copy 复制
$ wscat -c ws://localhost:3000
connected (press CTRL+C to quit)
< {"$class":"org.example.basic.SampleEvent","asset":"resource:org.example.basic.SampleAsset#assetId:1","oldValue":"","newValue":"hello world","eventId":"a80d220b-09db-4812-b04b-d5d03b663671#0","timestamp":"2017-08-23T12:47:17.685Z"}
>


3. 为REST服务器启用身份验证

REST服务器可以配置为对客户端进行身份验证。当启用此选项时,客户端必须在允许调用REST API之前向REST服务器进行身份验证。

选择一种认证策略

REST服务器使用开源Passport身份验证中间件。REST服务器的管理员必须选择Passport策略来认证客户端。可以选择多个Passport策略,允许REST服务器的客户端选择首选的身份验证机制。Passport包含多种策略(撰写时为300+),其中包括社交媒体(Google,Facebook,Twitter)和企业(SAML,LDAP)策略的组合。

本文的其余部分将演示如何使用该passport-github策略来使用他们的GitHub ID对用户进行身份验证。passport-github通过执行以下命令来安装策略:

Copy 复制
npm install -g passport-github

配置REST服务器以使用身份验证策略

REST服务器必须配置有一系列Passport策略才能在启用REST API认证之前使用。该配置包括要使用的策略的名称和每个策略的单独配置。

为了配置passport-github策略,我们需要在GitHub上注册OAuth应用程序,并检索客户端ID和客户端密钥。按照以下步骤在GitHub上注册OAuth应用程序:

  1. 导航到GitHub并使用您的用户ID和密码登录。
  2. 点击右上角的个人资料图片,然后点击下拉菜单中的设置
  3. 点击左侧栏上开发人员设置下的OAuth应用程序
  4. 点击注册一个新的应用程序
  5. 指定以下设置:
    • 应用程序名称:Composer
    • 主页:http:// localhost:3000 /
    • 应用程序描述:Composer的OAuth应用程序
    • 授权回调URL:http:// localhost:3000 / auth / github / callback
  6. 点击注册申请
  7. 记下客户端ID客户端密钥的值

应该使用环境变量来指定REST服务器的配置COMPOSER_PROVIDERS通过替换的值设置为REST服务器的配置REPLACE_WITH_CLIENT_IDREPLACE_WITH_CLIENT_SECRET与来自步骤7检索的值,并执行下面的命令:

Copy 复制
export COMPOSER_PROVIDERS='{
  "github": {
    "provider": "github",
    "module": "passport-github",
    "clientID": "REPLACE_WITH_CLIENT_ID",
    "clientSecret": "REPLACE_WITH_CLIENT_SECRET",
    "authPath": "/auth/github",
    "callbackURL": "/auth/github/callback",
    "successRedirect": "/",
    "failureRedirect": "/"
  }
}'

启用REST API身份验证启动REST服务器

一旦设置了环境变量COMPOSER_PROVIDERS,就可以使用该-a true参数启用启用了身份验证的REST服务器。启用身份验证后,客户端必须先进行身份验证,然后才能向业务网络发出任何请求。

例如,以下是作为开发者教程一部分部署的业务网络的命令,但您可能需要修改您的业务网络的命令:

Copy 复制
composer-rest-server -c admin@my-network -a true

现在,导航到位于http:// localhost:3000 / explorer /的REST API资源管理器如果已成功启用身份验证,则任何尝试使用REST API浏览器调用其中一个业务网络REST API操作的尝试都应该被拒绝并显示一条HTTP 401 Authorization Required消息。

使用Web浏览器对REST服务器进行身份验证

此步骤取决于REST服务器使用的Passport策略的配置和行为。

  1. 通过导航到authPath环境变量中指定属性的值,对REST服务器进行身份验证COMPOSER_PROVIDERS在上面的例子中,这是http:// localhost:3000 / auth / github
  2. REST服务器会将您重定向到GitHub以执行OAuth Web服务器身份验证流程。GitHub会询问您是否要授权Composer应用程序访问您的帐户。点击授权按钮。
  3. 如果成功,GitHub会将您重定向回REST服务器。

现在,导航到位于http:// localhost:3000 / explorer /的REST API资源管理器试图再次使用REST API浏览器调用其中一个业务网络REST API操作。这一次,电话会成功。

使用HTTP或REST客户端向REST服务器进行身份验证

当用户向REST服务器进行身份验证时,会生成唯一的访问令牌并将其分配给经过身份验证的用户。当用户使用Web浏览器进行认证时,访问令牌存储在用户Web浏览器的本地存储中的cookie中。当经过身份验证的用户发起后续请求时,将从cookie中检索访问令牌,并且验证访问令牌而不是重新对用户进行身份验证。

访问令牌可用于认证任何希望调用REST服务器的HTTP或REST客户端。当HTTP或REST客户端无法执行配置的Passport策略所需的认证流程时,这是必需的。例如,所有OAuth2 Web认证流程都需要使用Web浏览器导航到认证提供商网站。

为了使用访问令牌,必须首先使用Web浏览器检索访问令牌。当您向REST服务器进行身份验证时,http:// localhost:3000 / explorer /上的REST API浏览器将在页面顶部显示访问令牌。默认情况下,访问令牌是隐藏的,但可以通过单击Show按钮来显示访问令牌是一个长的字母数字字符串,例如:e9M3CLDEEj8SDq0Bx1tkYAZucOTWbgdiWQGLnOxCe7K9GhTruqlet1h5jsw10YjJ

一旦检索到访问令牌,就可以将访问令牌传递到任何HTTP或REST请求中,以对HTTP或REST客户端进行身份验证。传递访问令牌有两种选择 - 使用查询字符串参数或HTTP标头。对于以下两个示例,请将该字符串替换xxxxx为访问令牌的值。

查询字符串 - 将access_token查询字符串参数添加到所有HTTP或REST请求:

Copy 复制
curl -v http://localhost:3000/api/system/ping?access_token=xxxxx

HTTP标头 - 将X-Access-Token头添加到所有HTTP或REST请求中:

Copy 复制
curl -v -H 'X-Access-Token: xxxxx' http://localhost:3000/api/system/ping



4.为REST服务器启用多用户模式

默认情况下,Hyperledger Composer REST服务器通过使用在启动时在命令行上指定的区块链标识服务所有请求。例如,使用以下命令时,对REST服务器发出的所有请求都将使用区块链身份alice1对所有事务进行数字签名:

Copy 复制
composer-rest-server -c alice1@my-network

这意味着业务网络无法区分REST服务器的不同客户端。在某些使用情况下,这可能是可以接受的,例如,如果区块链身份只具有只读访问权限,而REST服务器使用API​​管理网关进行安全保护。

REST服务器可以配置为多用户模式。多用户模式允许REST服务器的客户端为数字签名事务提供自己的区块链身份。这使业务网络能够区分REST服务器的不同客户端。

多用户模式要求启用REST API身份验证,并且如果未明确指定,它将自动启用REST API身份验证。您必须选择并配置用于验证用户的Passport策略。REST API身份验证是必需的,这样才能识别客户端。

一旦客户端向REST API进行了身份验证,该客户端就可以将区块链身份添加到钱包。该钱包对该客户是私人的,并且不能被其他客户访问。当客户端向REST服务器发出请求时,客户端钱包中的区块链标识用于对该客户端所做的所有事务进行数字签名。

请注意,此功能要求客户端信任REST服务器。此信任是必需的,因为此功能要求REST服务器存储客户端区块链身份,包括私钥。因此,强烈建议客户端仅使用由受信任方(例如其组织内的管理员)管理的REST服务器。

启用多用户模式的REST服务器

COMPOSER_PROVIDERS在继续之前,您必须配置环境变量有关如何执行此任务的说明,请在继续之前阅读以下主题:启用REST服务器的身份验证

您可以使用-m true参数在启用多用户模式的情况下启动REST服务器。一旦启用多用户模式,客户端在向业务网络发出任何请求之前必须进行身份验证。

例如,以下是作为开发者教程一部分部署的业务网络的命令,但您可能需要修改您的业务网络的命令:

Copy 复制
composer-rest-server -c admin@my-network -m true

-m true参数自动启用REST API认证。-a true -m true如果你希望明确,你可以选择提供两个参数在继续之前,您必须使用配置的身份验证机制对REST API进行身份验证。环境变量COMPOSER_MULTIUSER可以被设置为true或者false就地使用-m在命令行上。

现在,导航到位于http:// localhost:3000 / explorer /的REST API资源管理器如果多个用户模式已成功启用,则任何尝试使用REST API浏览器调用其中一个业务网络REST API操作的尝试都应该被拒绝并显示A business network card has not been specified错误消息。

如果您看到HTTP 401 Authorization Required错误消息,则说明您没有正确验证REST API。

将商业网卡添加到钱包

首先,您必须向商业网络中的参与者颁发区块链身份。此示例将假定您已向alice1参与者发布了区块链身份org.example.mynetwork.Trader#[email protected],并且您已为此文件中存储的此区块链身份创建了一张企业网卡[email protected]

按照以下步骤将商业网卡添加到钱包中:

  1. 导航到http:// localhost:3000 / explorer /上的REST API资源管理器,然后通过展开电子钱包类别导航到钱包API

  2. 通过调用GET /wallet操作检查钱包是否包含任何业务网卡操作的回应应该是:

    Copy 复制
    []
    
  3. 通过调用POST /wallet/import操作将业务网卡导入钱包您必须[email protected]通过单击选择文件按钮指定业务网卡文件操作的回应应该是:

    Copy 复制
    no content
    

    商业网卡alice1@my-network现在已经被导入到钱包中。

  4. alice1@my-network通过调用GET /wallet操作检查钱包是否包含业务网卡操作的回应应该是:

    Copy 复制
    [
        {
            "name": "alice1@my-network",
            "default": true
        }
    ]
    

    显示业务网卡alice1@my-networkdefault属性的值true,这意味着此业务网卡将在与业务网络进行交互时默认使用。

现在,导航到位于http:// localhost:3000 / explorer /的REST API资源管理器试图再次使用REST API浏览器调用其中一个业务网络REST API操作。这一次,电话会成功。

您可以通过调用该GET /system/ping操作来测试Blockchain身份此操作会返回区块链身份颁发给参与者的完全限定标识符:

Copy 复制
{
  "version": "0.8.0",
  "participant": "org.example.mynetwork.Trader#[email protected]"
}

最后的笔记

当REST服务器在启用多用户模式的情况下启动时,客户端所做的所有REST API请求都使用存储在客户端钱包中的区块链标识。启动时在命令行中指定的区块链标识不用于处理任何请求; 它仅用于初始连接到业务网络并下载生成REST API所需的业务网络定义。因此,在命令行上指定的区块链身份只需要最低限度的权限 - 连接能力和下载业务网络定义的能力 - 无需任何资产,参与者或交易的许可。

所有用户信息都通过LoopBack连接器保留在LoopBack数据源中。默认情况下,REST服务器使用LoopBack“内存”连接器来保存用户信息,当REST服务器终止时会丢失这些信息。REST服务器应配置一个LoopBack连接器,用于将数据存储在高可用性数据源(例如数据库)中。有关更多信息,请参阅部署REST服务器



5. 使用HTTPS和TLS来保护REST服务器

在生产环境中部署Hyperledger Composer REST服务器时,应将REST服务器配置为使用HTTPS和TLS(传输层安全性)进行保护。一旦使用HTTPS和TLS配置了REST服务器,在REST服务器和所有REST客户端之间传输的所有数据都将被加密。

您必须提供证书和私钥对才能配置REST服务器。REST服务器包含一个示例证书和私钥对,可用于轻松实现,但此配置仅建议在初始开发期间易于使用。不要在生产环境中使用示例证书和私钥对。

通过使用示例证书和私钥对启用HTTPS和TLS

您可以使用示例证书和私钥对通过-t在命令行中使用参数来启用HTTPS和TLS

Copy 复制
composer-rest-server -c alice1@my-network -t

或者,您可以使用COMPOSER_TLS环境变量使用示例证书和私钥对启用HTTPS和TLS

Copy 复制
export COMPOSER_TLS=true
composer-rest-server -c alice1@my-network

当您成功启用HTTPS和TLS时,您将看到REST服务器的输出指定了一个https://URL而不是http://URL:

Copy 复制
Web server listening at: https://localhost:3000
Browse your REST API at https://localhost:3000/explorer

建议仅在初始开发期间使用该配置以方便使用。对于测试,QA或生产部署,您应提供自己的证书和私钥以启用HTTPS和TLS。

通过提供证书和私钥对来启用HTTPS和TLS

您可以通过提供自己的证书和私钥对来启用HTTPS和TLS。证书和私钥对必须作为两个单独的文件以PEM格式提供。这些文件必须在运行REST服务器的系统的文件系统上可用,并且REST服务器必须具有这些文件的读取权限。

您可以通过在命令行中使用'-e'(证书文件)和'-k'(私钥文件)参数,将REST服务器配置为使用您的证书和私钥对文件:

Copy 复制
composer-rest-server -c alice1@my-network -t -e /tmp/cert.pem -k /tmp/key.pem

或者,可以使用COMPOSER_TLS_CERTIFICATECOMPOSER_TLS_KEY环境变量将“REST”服务器配置为使用您的证书和私钥对文件

Copy 复制
export COMPOSER_TLS=true
export COMPOSER_TLS_CERTIFICATE=/tmp/cert.pem
export COMPOSER_TLS_KEY=/tmp/key.pem
composer-rest-server -c alice1@my-network


6. 为业务网络部署REST服务器

在生产环境中部署Hyperledger Composer REST服务器时,例如使用Docker Swarm或Kubernetes,应将REST服务器配置为高度可用。这意味着您必须部署REST服务器的多个实例,并且应配置这些实例以共享数据。例如,应共享诸如业务网卡,区块链身份和REST API身份验证设置等数据,以便REST API客户端可以向任何实例发出请求,而无需重新进行身份验证。

商务网卡和商务网卡商店

REST服务器使用在启动期间指定的业务网卡来连接并发现部署的业务网络中的资产,参与者和交易。这些信息是为了生成REST API所必需的。该业务网卡被称为发现业务网卡。默认情况下,发现业务网卡也用于处理对REST API的所有请求。但是,REST服务器也可以配置为多用户模式,允许经过身份验证的用户提供自己的业务网卡以处理对REST API的请求。

为了使用发现业务网卡,必须先将该业务网卡导入到REST服务器可用的业务网络存储卡中。默认的业务网卡存储是一个带有路径的本地文件系统目录~/.composer(其中~是当前用户主目录)。在为REST服务器使用Docker映像时,必须将卷装入到包含导入的发现业务网卡的默认业务网卡存储区中。在REST服务器的Docker映像中,REST服务器使用的业务网卡存储位于目录中/home/composer/.composer(因为Docker映像中的REST服务器始终在composer用户下运行)。

业务网卡包含一个连接配置文件,该配置文件描述如何连接到正在运行已部署业务网络的Hyperledger Fabric网络。请注意,连接配置文件必须在用于REST服务器的Docker映像中有效,并且主机名必须正确且可由此Docker映像访问。

使用持久数据存储配置REST服务器

有关经过身份验证的用户及其钱包(包含启用多用户模式时的用户业务网卡)的所有信息都通过LoopBack连接器保留在LoopBack数据源中。默认情况下,REST服务器使用LoopBack“内存”连接器来保存用户信息,当REST服务器终止时会丢失这些信息。REST服务器应配置一个LoopBack连接器,用于将数据存储在高可用性数据源(例如数据库)中。

您应该可以使用任何LoopBack连接器,但我们建议您为NoSQL数据库使用LoopBack连接器。例如,MongoDB或Apache CouchDB。

需要安装LoopBack连接器才能让REST服务器找到并使用它。您可以使用以下方法安装其他LoopBack连接器npm

Copy 复制
npm install -g loopback-connector-mongodb

最后,您需要为REST服务器提供LoopBack连接器所需的连接信息。这个连接信息应该使用COMPOSER_DATASOURCES环境变量来提供有关可用于配置REST服务器的环境变量的更多信息,请参阅参考文档:Hyperledger Composer REST服务器

用额外的Node.js模块扩展REST服务器的Docker镜像

为了将REST服务器部署为具有其他LoopBack连接器和Passport策略的Docker容器,您必须扩展hyperledger/composer-rest-serverDocker镜像。

以下是一个Dockerfile示例,它将MongoDB的LoopBack连接器和GitHub的Passport策略添加到Docker镜像中:

Copy 复制
FROM hyperledger/composer-rest-server
RUN npm install --production loopback-connector-mongodb passport-github && \
    npm cache clean --force && \
    ln -s node_modules .node_modules

您可以通过将Dockerfile放置在目录中并使用该docker build命令来构建此Docker镜像,例如:

Copy 复制
docker build -t myorg/my-composer-rest-server .

您可能需要将此Docker映像发布到Docker映像存储库(例如Docker Hub),以便将其用于基于云的Docker部署服务。

使用Docker部署持久且安全的REST服务器

以下示例将演示如何使用Docker部署REST服务器。部署的REST服务器将使用MongoDB保存数据,并使用Gi​​tHub身份验证进行保护。

这些示例基于作为开发者教程的一部分部署到Hyperledger Fabric v1.1的业务网络,并且可能需要调整您的配置,例如,如果Docker网络名称不匹配。

  1. 通过运行以下composer network ping命令,确保业务网络的有效业务网卡位于本地业务网卡存储中此示例在业务网络上为admin用户使用my-network业务网卡:

    Copy 复制
    composer network ping -c admin@my-network
    

    请注意,在继续之前,您必须使用该composer network ping命令来测试与业务网络的连接。如果商业网卡仅包含用户ID和登记密码,则该composer network ping命令将触发注册过程发生并将证书存储在商业网卡中。这是建议使用泊坞窗图像的REST服务器时使用商业网络卡只有一个用户ID和注册的秘密。

  2. 启动一个名为MongoDB的Docker镜像实例mongo这个MongoDB实例将用于持久保存关于REST服务器的认证用户及其钱包(包含启用多用户模式的用户业务网卡)的所有信息。

    Copy 复制
    docker run -d --name mongo --network composer_default -p 27017:27017 mongo
    

    请注意,MongoDB实例已连接到名为的Docker网络composer_default这意味着MongoDB实例将在composer_default使用主机名命名的Docker网络上可用mongo我们将mongo在后续步骤中使用主机名来配置REST服务器。根据您的Docker网络配置,您可能需要指定不同的Docker网络名称。MongoDB端口27017也使用端口在主机网络上公开27017,所以如果需要,您可以使用其他MongoDB客户端应用程序与此MongoDB实例进行交互。

  3. 通过为MongoDB添加LoopBack连接器并为GitHub身份验证添加Passport策略,扩展REST服务器的Docker镜像。在本地文件系统上创建一个新的空目录,并Dockerfile在新目录中创建一个新文件,其中包含以下内容:

    Copy 复制
    FROM hyperledger/composer-rest-server
    RUN npm install --production loopback-connector-mongodb passport-github && \
        npm cache clean --force && \
        ln -s node_modules .node_modules
    

    docker build在包含Dockerfile刚刚创建的文件的目录中运行以下命令来构建扩展Docker镜像

    Copy 复制
    docker build -t myorg/my-composer-rest-server .
    

    如果此命令成功完成,则会调用一个名为Docker的新图像myorg/my-composer-rest-server并将其存储在系统的本地Docker注册表中。如果您希望在其他系统上使用此Docker镜像,则可能需要将Docker镜像推送到Docker注册中心,例如Docker Hub。

  4. REST服务器的Docker镜像使用环境变量而不是命令行选项进行配置。创建一个名为envvars.txt存储REST服务器的环境变量的新文件,其中包含以下内容:

    Copy 复制
    COMPOSER_CARD=admin@my-network
    COMPOSER_NAMESPACES=never
    COMPOSER_AUTHENTICATION=true
    COMPOSER_MULTIUSER=true
    COMPOSER_PROVIDERS='{
        "github": {
            "provider": "github",
            "module": "passport-github",
            "clientID": "REPLACE_WITH_CLIENT_ID",
            "clientSecret": "REPLACE_WITH_CLIENT_SECRET",
            "authPath": "/auth/github",
            "callbackURL": "/auth/github/callback",
            "successRedirect": "/",
            "failureRedirect": "/"
        }
    }'
    COMPOSER_DATASOURCES='{
        "db": {
            "name": "db",
            "connector": "mongodb",
            "host": "mongo"
        }
    }'
    

    请注意,发现业务网卡的名称admin@my-network已被设置为COMPOSER_CARD环境变量的值我们通过指定环境变量never的值来禁用生成的REST API中的命名空间COMPOSER_NAMESPACES我们通过设置COMPOSER_AUTHENTICATION环境变量来启用对REST API客户端的身份验证true,并且通过将COMPOSER_MULTIUSER环境变量设置为启用多用户模式true

    我们通过在COMPOSER_PROVIDERS环境变量中为GitHub配置Passport策略来配置我们的REST服务器以使用GitHub身份验证请注意,您必须替换两者REPLACE_WITH_CLIENT_IDREPLACE_WITH_CLIENT_SECRET使用GitHub中的相应配置才能使此配置成功运行。

    我们通过在COMPOSER_DATASOURCES环境变量中为MongoDB配置LoopBack连接器来配置我们的REST服务器以使用我们的MongoDB实例请注意,mongo已在host名为LoopBack数据源属性中指定了MongoDB实例的主机名db

    通过运行以下命令将环境变量加载到当前shell中:

    Copy 复制
    source envvars.txt
    

    如果您打开一个新的shell,例如新的终端窗口或选项卡,则必须source再次运行相同的命令以将环境变量加载到新的shell中。

    有关可用于配置REST服务器的环境变量的更多信息,请参阅参考文档:Hyperledger Composer REST服务器

  5. 通过运行以下docker run命令,为您在步骤3中创建的REST服务器启动扩展Docker镜像的新实例

    Copy 复制
    docker run \
        -d \
        -e COMPOSER_CARD=${COMPOSER_CARD} \
        -e COMPOSER_NAMESPACES=${COMPOSER_NAMESPACES} \
        -e COMPOSER_AUTHENTICATION=${COMPOSER_AUTHENTICATION} \
        -e COMPOSER_MULTIUSER=${COMPOSER_MULTIUSER} \
        -e COMPOSER_PROVIDERS="${COMPOSER_PROVIDERS}" \
        -e COMPOSER_DATASOURCES="${COMPOSER_DATASOURCES}" \
        -v ~/.composer:/home/composer/.composer \
        --name rest \
        --network composer_default \
        -p 3000:3000 \
        myorg/my-composer-rest-server
    

    请注意,我们已经通过使用多个-e选项通过了前面步骤中设置的所有环境变量如果您需要添加或删除任何其他环境变量来配置REST服务器,那么您必须添加或删除相应的-e选项。

    通过指定,我们已将本地业务网络存储卡安装到REST服务器Docker容器中-v ~/.composer:/home/composer/.composer这允许REST服务器在尝试加载使用COMPOSER_CARD环境变量指定的发现业务网卡时访问和使用我们的本地业务网卡存储

    我们还指定了Docker网络名称composer_default和Docker容器的名称rest这意味着REST服务器实例将在composer_default使用主机名命名的Docker网络上可用restREST服务器端口3000也使用端口在主机网络上公开3000

    您可以使用该docker logs命令检查REST服务器是否已成功启动,例如:

    Copy 复制
    docker logs -f rest
    

    如果REST服务器已成功启动,则会看到它输出类似于的日志消息Browse your REST API at http://localhost:3000/explorer

现在REST服务器已成功启动,您可以使用以下URL访问在Docker容器内运行的REST服务器:http:// localhost:3000 / explorer /

最后的笔记

在本指南中,您已经看到了如何使用Docker启动REST服务器的单个实例,其中将单个实例配置为将MongoDB用作持久数据存储。要获得真正高度可用的REST服务器的生产部署,您需要:

  • 配置持久数据存储的高可用实例,例如MongoDB副本集。
  • 运行REST服务器Docker镜像的多个实例。通过使用--name参数更改Docker容器的名称以及使用参数更新或删除后续REST服务器实例的主机端口映射,很容易-p 3000:3000
  • 部署负载均衡器(例如Nginx),以便跨REST服务器的所有实例分发来自客户端的REST请求。

完成这三项任务后,您应该能够停止,重新启动或删除任何REST服务器实例(但不是全部!),而不会失去通过REST访问已部署的业务网络。



7. 与Node-RED集成

Node-RED是一种轻量级的开源集成技术,用JavaScript编写。它使用图形流来集成不同的节点,其中节点可以接收数据,转换数据和输出数据。

Node-RED通常用于快速建立物联网样式应用的原型,或将现有的互联网服务连接在一起。

您可以使用Hyperledger Composer Node-RED贡献来:

  • 提交交易
  • 阅读和更新资产和参与者
  • 订阅活动
  • 删除资产和参与者

Hyperledger Composer Node-RED节点作为一个独立的npm包分发,发布在这里: - https://www.npmjs.com/package/node-red-contrib-composer

Hyperledger Composer节点 - 红色节点

Hyperledger作曲家出

节点红色输出节点,允许您创建,更新或删除资产或参与者并提交交易。例如,将hyperledger-composer-out节点与注入节点结合使用,您可以通过提交这些参与者的JSON定义来创建参与者。

Hyperledger作曲家 - 中

节点红色中流节点,允许您从注册表中创建,检索,更新或删除资产和参与者。例如,将hyperledger-composer-mid注入节点结合使用,您可以通过提交正确的注册表并将字段标识为JSON对象来检索资产或参与者。

Hyperledger作曲家,在

订阅区块链事件的Node-RED输入节点。


8. 从事务处理函数调用HTTP或REST API

在某些情况下,希望能够从事务处理器函数中调用HTTP或REST API。这使您可以将复杂或昂贵的计算从区块链转移到中央或同级托管服务。

或者,交易处理器功能可能希望调用提供外部数据的第三方HTTP或REST API。例如,第三方API可以提供关于股票的当前价格或当前天气和温度的数据,其可以用于确定合同条件是否已经满足。

Hyperledger Composer允许事务处理函数开发人员在事务处理函数内调用HTTP或REST API。

请注意,使用此功能可能会导致由共识失败引起的错误,因此只能谨慎使用。有关更多信息,请参阅下面的共识注意事项

使用请求模块

request模块(https://github.com/request/request)是许多Node.js应用程序使用的流行HTTP客户端。Hyperledger Composer嵌入request模块,以便事务处理函数可以使用它来调用HTTP或REST API。

标准request模块使用面向回调的API。但是,事务处理函数是基于promise的,面向回调的API会导致大量不必要的代码将回调包装在promise中。为了让交易处理器功能开发者更容易体验,我们已经公开了基于承诺的request-promise模块(https://github.com/request/request-promise)。

request-promise模块通过request全局变量自动提供给所有交易处理器功能您不需要将文件requestrequest-promise模块添加package.json文件中,也不需要使用该require功能来加载模块。

全局request方法和所有的便利方法的各种HTTP方法(request.getrequest.post等)可用于交易处理器功能。这些方法为处理请求主体,响应主体,HTTP标头,身份验证,Cookie,代理和TLS / SSL提供了一整套选项。

有关这些方法和可用选项的详细信息,请查看requestrequest-promise模块的文档

例子

向HTTP服务器发出HTTP GET请求,该请求以字符串形式返回当前股票价格:

Copy 复制
/**
 * Buy a given amount of CONGA stocks.
 * @param {org.example.BuyStocks} transaction The transaction.
 * @transaction
 */
async function buyStocks(transaction) {

    // Look up the current price of the CONGA stock, and parse it into a float.
    const priceAsStr = await request.get('http://stocks.org/CONGA');
    const price = parseFloat(priceAsStr);

    // Get the current participant, and update their stock and balance.
    const participant = getCurrentParticipant();
    const units = transaction.units;
    participant.stockUnits += units;
    participant.balance -= price * units;

    // Update the current participant in the participant registry.
    const participantRegistry = await getParticipantRegistry('org.example.Trader');
    await participantRegistry.update(participant);

}

向HTTP服务器发出HTTP GET请求,该服务器将当前股票价格作为JSON结构返回:

Copy 复制
/**
 * Buy a given amount of CONGA stocks.
 * @param {org.example.BuyStocks} transaction The transaction.
 * @transaction
 */
async function buyStocks(transaction) {

    // Look up the current price of the CONGA stock, and extract the price.
    // The option "json: true" automatically parses JSON from the HTTP response.
    const stock = await request.get({ uri: 'http://stocks.org/CONGA', json: true });
    const price = stock.price;

    // Get the current participant, and update their stock and balance.
    const participant = getCurrentParticipant();
    const units = transaction.units;
    participant.stockUnits += units;
    participant.balance -= price * units;

    // Update the current participant in the participant registry.
    const participantRegistry = await getParticipantRegistry('org.example.Trader');
    await participantRegistry.update(participant);

}

向包含当前参与者的HTTP服务器发出HTTP POST请求作为HTTP请求正文,并以字符串形式返回当前股票价格:

Copy 复制
/**
 * Buy a given amount of CONGA stocks.
 * @param {org.example.BuyStocks} transaction The transaction.
 * @transaction
 */
async function buyStocks(transaction) {

    // Get the current participant.
    const participant = getCurrentParticipant();

    // Look up the current price of the CONGA stock, and extract the price.
    // The option "json" sends the participant as the HTTP request body,
    // and automatically parses JSON from the HTTP response.
    const stock = await request.post({ uri: 'http://stocks.org/CONGA', json: participant });
    const price = stock.price;

    // Get the current participant, and update their stock and balance.
    const units = transaction.units;
    participant.stockUnits += units;
    participant.balance -= price * units;

    // Update the current participant in the participant registry.
    const participantRegistry = await getParticipantRegistry('org.example.Trader');
    await participantRegistry.update(participant);

}

向HTTP服务器发送HTTP POST请求,该HTTP服务器返回库存资产的序列化实例:

Copy 复制
/**
 * Buy a given amount of CONGA stocks.
 * @param {org.example.BuyStocks} transaction The transaction.
 * @transaction
 */
async function buyStocks(transaction) {

    // Look up the current price of the CONGA stock, and extract the price.
    // The option "json: true" automatically parses JSON from the HTTP response.
    const json = await request.get({ uri: 'http://stocks.org/CONGA', json: true });

    // Parse the JavaScript object into the stock asset.
    const serializer = getSerializer();
    const stock = serializer.fromJSON(json);
    const price = stock.price;

    // Get the current participant, and update their stock and balance.
    const participant = getCurrentParticipant();
    const units = transaction.units;
    participant.stockUnits += units;
    participant.balance -= price * units;

    // Update the current participant in the participant registry.
    const participantRegistry = await getParticipantRegistry('org.example.Trader');
    await participantRegistry.update(participant);

}

共识考虑

在Hyperledger Fabric中,业务网络中的共识是通过让多个组织中的对等节点支持事务来实现的。通过执行链接代码并签署执行结果来签署事务。为了使交易由区块链网络承担,所有支持交易的对等节点必须从执行链接代码产生相同的结果。

当业务网络使用上述API发出HTTP请求时,这些HTTP请求将在支持该事务的所有对等节点上执行。这将导致n个 HTTP请求,其中n是支持该事务的对等节点的数量。

为了在业务网络发出HTTP请求时达成共识,您必须小心确保事务处理器功能在所有对等节点上发出相同的HTTP请求,然后对所有对等节点上的HTTP响应执行相同的处理。

例如,考虑使用HTTP请求从外部符号查找股票价格的业务网络。业务网络然后使用股票价格来调整参与者账户的余额。如果不同的对等节点收到不同的股票价格,他们将尝试对参与者账户的余额进行不同的调整。这将导致共识失败,并且交易被拒绝。

由于多种原因,HTTP请求可能会导致不同的响应:

  • 不同组织中的对等节点可以运行在不同的数据中心,不同的国家,不同的时区。
  • 根据公共Internet访问和防火墙限制,不同组织中的对等节点可能无法访问HTTP服务器。
  • 不同组织中的对等节点可能会以不同的用户身份向HTTP服务器进行身份验证,从而导致不同的HTTP响应。

为了最大限度地减少从事务处理函数发出HTTP请求时出现一致性失败的风险,建议您使用make HTTP请求:

  • 安全,因为HTTP请求不会修改HTTP服务器上的任何状态。
  • 幂等性的,因为相同的HTTP请求可以被做很多次而没有不同的结果。

CORS(跨源资源共享)

从Hyperledger Composer Playground部署到Web浏览器连接的业务网络在Web浏览器内部运行。当这些业务网络中的事务处理器功能使用上述API发出HTTP请求时,这些HTTP请求将使用内置于Web浏览器中的HTTP客户端进行处理。

Web浏览器中内置的HTTP客户端要求HTTP服务器符合CORS(跨源资源共享)。如果将业务网络部署到Web浏览器连接,则必须确保HTTP服务器已配置为符合CORS。有关更多信息,请参阅:https//enable-cors.org

Docker网络解决方案

部署到Hyperledger Fabric的业务网络在链码代码容器中运行。这意味着业务网络需要由Docker提供的DNS解析和网络服务,而不是由主机提供的服务。另外,chaincode Docker容器有自己的IP地址。

这意味着localhost解析为链码的Docker容器,而不是主机。任何HTTP请求localhost,例如http:// localhost:3000 / api / Vehicle,都不会按预期工作。最简单的解决方法是使用可公开解析的REST服务器的DNS名称。


你可能感兴趣的:(区块链)