Hyperledger Composer REST服务器可以使用npm或Docker进行安装。
要使用npm进行安装,请运行以下命令:
npm install -g composer-rest-server
要使用Docker安装REST服务器,请参阅部署REST服务器。
Hyperledger Composer包含独立的Node.js流程,将业务网络公开为REST API。LoopBack框架用于生成由Swagger文档描述的Open API。
要启动REST服务器,只需输入:
composer-rest-server
然后您将被要求输入关于您的商业网络的一些简单细节。下面显示了使用部署的业务网络的一个示例。
? 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
命令有许多选项用于定义安全性和身份验证:
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]
启动浏览器并转到给定的URL(http://0.0.0.0:3000/explorer)。你会看到类似这样的屏幕。
在更新业务网络定义之后,可以更新REST服务器以生成反映业务网络定义更新的新API。
要更新REST服务器,首先必须停止使用REST服务器ctrl-C
。然后可以使用重新启动REST服务器composer-rest-server
。
API密钥可用于提供第一层安全性以在开发环境中访问REST API。
composer-rest-server -y YOUR_API_KEY
这将只接受x-api-key
带有值设置为Header的请求YOUR_API_KEY
。
在Hyperledger Composer运行时之上使用Loopback框架使我们能够基于已部署的业务网络模型生成特定于业务领域的REST API!
REST服务器可以配置为订阅从部署的业务网络发出的事件,并发布这些业务事件以供客户端应用程序使用。目前,REST服务器支持通过WebSockets向客户端应用程序发布事件。
客户端应用程序可以使用WebSocket客户端订阅REST服务器发布的业务事件。WebSocket客户端可用于所有主要编程语言和应用程序类型,例如客户端Web用户界面,后端服务器进程,移动应用程序和集成工具。
您可以-w
在命令行上使用参数启用WebSockets :
composer-rest-server -c alice1@my-network -w
或者,您可以使用COMPOSER_WEBSOCKETS
环境变量启用WebSockets :
export COMPOSER_WEBSOCKETS=true
composer-rest-server -c alice1@my-network
当您成功启用WebSocket时,您将能够将WebSocket客户端连接到REST服务器输出中显示的基本URL:
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
在此示例中,要使用的基本URL是http://localhost:3000
。你必须从改变协议转换为WebSocket的URL这个http
来ws
。在这个例子中,使用的WebSocket URL是ws://localhost:3000
。
您可以通过使用WebSocket客户端来订阅事件来测试已启用WebSocket。开源命令行应用程序wscat
可用于此目的。
要安装wscat
,您可以使用npm
。如果您没有正确的权限来全局安装npm
模块,则可能需要使用sudo或root身份运行此命令:
npm install -g wscat
然后,您可以使用wscat
它连接并订阅REST服务器发布的业务事件。收到的任何商业活动都将打印到控制台:
$ 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"}
>
REST服务器可以配置为对客户端进行身份验证。当启用此选项时,客户端必须在允许调用REST API之前向REST服务器进行身份验证。
REST服务器使用开源Passport身份验证中间件。REST服务器的管理员必须选择Passport策略来认证客户端。可以选择多个Passport策略,允许REST服务器的客户端选择首选的身份验证机制。Passport包含多种策略(撰写时为300+),其中包括社交媒体(Google,Facebook,Twitter)和企业(SAML,LDAP)策略的组合。
本文的其余部分将演示如何使用该passport-github
策略来使用他们的GitHub ID对用户进行身份验证。passport-github
通过执行以下命令来安装策略:
npm install -g passport-github
REST服务器必须配置有一系列Passport策略才能在启用REST API认证之前使用。该配置包括要使用的策略的名称和每个策略的单独配置。
为了配置passport-github
策略,我们需要在GitHub上注册OAuth应用程序,并检索客户端ID和客户端密钥。按照以下步骤在GitHub上注册OAuth应用程序:
应该使用环境变量来指定REST服务器的配置COMPOSER_PROVIDERS
。通过替换的值设置为REST服务器的配置REPLACE_WITH_CLIENT_ID
和REPLACE_WITH_CLIENT_SECRET
与来自步骤7检索的值,并执行下面的命令:
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": "/"
}
}'
一旦设置了环境变量COMPOSER_PROVIDERS
,就可以使用该-a true
参数启用启用了身份验证的REST服务器。启用身份验证后,客户端必须先进行身份验证,然后才能向业务网络发出任何请求。
例如,以下是作为开发者教程一部分部署的业务网络的命令,但您可能需要修改您的业务网络的命令:
composer-rest-server -c admin@my-network -a true
现在,导航到位于http:// localhost:3000 / explorer /的REST API资源管理器。如果已成功启用身份验证,则任何尝试使用REST API浏览器调用其中一个业务网络REST API操作的尝试都应该被拒绝并显示一条HTTP 401 Authorization Required
消息。
此步骤取决于REST服务器使用的Passport策略的配置和行为。
authPath
环境变量中指定的属性的值,对REST服务器进行身份验证COMPOSER_PROVIDERS
。在上面的例子中,这是http:// localhost:3000 / auth / github。现在,导航到位于http:// localhost:3000 / explorer /的REST API资源管理器。试图再次使用REST API浏览器调用其中一个业务网络REST API操作。这一次,电话会成功。
当用户向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请求:
curl -v http://localhost:3000/api/system/ping?access_token=xxxxx
HTTP标头 - 将X-Access-Token
标头添加到所有HTTP或REST请求中:
curl -v -H 'X-Access-Token: xxxxx' http://localhost:3000/api/system/ping
默认情况下,Hyperledger Composer REST服务器通过使用在启动时在命令行上指定的区块链标识服务所有请求。例如,使用以下命令时,对REST服务器发出的所有请求都将使用区块链身份alice1对所有事务进行数字签名:
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服务器。
COMPOSER_PROVIDERS
在继续之前,您必须配置环境变量。有关如何执行此任务的说明,请在继续之前阅读以下主题:启用REST服务器的身份验证
您可以使用-m true
参数在启用多用户模式的情况下启动REST服务器。一旦启用多用户模式,客户端在向业务网络发出任何请求之前必须进行身份验证。
例如,以下是作为开发者教程一部分部署的业务网络的命令,但您可能需要修改您的业务网络的命令:
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]
。
按照以下步骤将商业网卡添加到钱包中:
导航到http:// localhost:3000 / explorer /上的REST API资源管理器,然后通过展开电子钱包类别导航到钱包API 。
通过调用GET /wallet
操作检查钱包是否包含任何业务网卡。操作的回应应该是:
[]
通过调用POST /wallet/import
操作将业务网卡导入钱包。您必须[email protected]
通过单击选择文件按钮来指定业务网卡文件。操作的回应应该是:
no content
商业网卡alice1@my-network
现在已经被导入到钱包中。
alice1@my-network
通过调用GET /wallet
操作检查钱包是否包含业务网卡。操作的回应应该是:
[
{
"name": "alice1@my-network",
"default": true
}
]
显示业务网卡alice1@my-network
。该default
属性的值是true
,这意味着此业务网卡将在与业务网络进行交互时默认使用。
现在,导航到位于http:// localhost:3000 / explorer /的REST API资源管理器。试图再次使用REST API浏览器调用其中一个业务网络REST API操作。这一次,电话会成功。
您可以通过调用该GET /system/ping
操作来测试Blockchain身份。此操作会返回区块链身份颁发给参与者的完全限定标识符:
{
"version": "0.8.0",
"participant": "org.example.mynetwork.Trader#[email protected]"
}
当REST服务器在启用多用户模式的情况下启动时,客户端所做的所有REST API请求都使用存储在客户端钱包中的区块链标识。启动时在命令行中指定的区块链标识不用于处理任何请求; 它仅用于初始连接到业务网络并下载生成REST API所需的业务网络定义。因此,在命令行上指定的区块链身份只需要最低限度的权限 - 连接能力和下载业务网络定义的能力 - 无需任何资产,参与者或交易的许可。
所有用户信息都通过LoopBack连接器保留在LoopBack数据源中。默认情况下,REST服务器使用LoopBack“内存”连接器来保存用户信息,当REST服务器终止时会丢失这些信息。REST服务器应配置一个LoopBack连接器,用于将数据存储在高可用性数据源(例如数据库)中。有关更多信息,请参阅部署REST服务器。
在生产环境中部署Hyperledger Composer REST服务器时,应将REST服务器配置为使用HTTPS和TLS(传输层安全性)进行保护。一旦使用HTTPS和TLS配置了REST服务器,在REST服务器和所有REST客户端之间传输的所有数据都将被加密。
您必须提供证书和私钥对才能配置REST服务器。REST服务器包含一个示例证书和私钥对,可用于轻松实现,但此配置仅建议在初始开发期间易于使用。不要在生产环境中使用示例证书和私钥对。
您可以使用示例证书和私钥对通过-t
在命令行中使用参数来启用HTTPS和TLS :
composer-rest-server -c alice1@my-network -t
或者,您可以使用COMPOSER_TLS
环境变量使用示例证书和私钥对启用HTTPS和TLS :
export COMPOSER_TLS=true
composer-rest-server -c alice1@my-network
当您成功启用HTTPS和TLS时,您将看到REST服务器的输出指定了一个https://
URL而不是http://
URL:
Web server listening at: https://localhost:3000
Browse your REST API at https://localhost:3000/explorer
建议仅在初始开发期间使用该配置以方便使用。对于测试,QA或生产部署,您应提供自己的证书和私钥以启用HTTPS和TLS。
您可以通过提供自己的证书和私钥对来启用HTTPS和TLS。证书和私钥对必须作为两个单独的文件以PEM格式提供。这些文件必须在运行REST服务器的系统的文件系统上可用,并且REST服务器必须具有这些文件的读取权限。
您可以通过在命令行中使用'-e'(证书文件)和'-k'(私钥文件)参数,将REST服务器配置为使用您的证书和私钥对文件:
composer-rest-server -c alice1@my-network -t -e /tmp/cert.pem -k /tmp/key.pem
或者,可以使用COMPOSER_TLS_CERTIFICATE
和COMPOSER_TLS_KEY
环境变量将“REST”服务器配置为使用您的证书和私钥对文件:
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
在生产环境中部署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映像访问。
有关经过身份验证的用户及其钱包(包含启用多用户模式时的用户业务网卡)的所有信息都通过LoopBack连接器保留在LoopBack数据源中。默认情况下,REST服务器使用LoopBack“内存”连接器来保存用户信息,当REST服务器终止时会丢失这些信息。REST服务器应配置一个LoopBack连接器,用于将数据存储在高可用性数据源(例如数据库)中。
您应该可以使用任何LoopBack连接器,但我们建议您为NoSQL数据库使用LoopBack连接器。例如,MongoDB或Apache CouchDB。
需要安装LoopBack连接器才能让REST服务器找到并使用它。您可以使用以下方法安装其他LoopBack连接器npm
:
npm install -g loopback-connector-mongodb
最后,您需要为REST服务器提供LoopBack连接器所需的连接信息。这个连接信息应该使用COMPOSER_DATASOURCES
环境变量来提供。有关可用于配置REST服务器的环境变量的更多信息,请参阅参考文档:Hyperledger Composer REST服务器
为了将REST服务器部署为具有其他LoopBack连接器和Passport策略的Docker容器,您必须扩展hyperledger/composer-rest-server
Docker镜像。
以下是一个Dockerfile示例,它将MongoDB的LoopBack连接器和GitHub的Passport策略添加到Docker镜像中:
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镜像,例如:
docker build -t myorg/my-composer-rest-server .
您可能需要将此Docker映像发布到Docker映像存储库(例如Docker Hub),以便将其用于基于云的Docker部署服务。
以下示例将演示如何使用Docker部署REST服务器。部署的REST服务器将使用MongoDB保存数据,并使用GitHub身份验证进行保护。
这些示例基于作为开发者教程的一部分部署到Hyperledger Fabric v1.1的业务网络,并且可能需要调整您的配置,例如,如果Docker网络名称不匹配。
通过运行以下composer network ping
命令,确保业务网络的有效业务网卡位于本地业务网卡存储中。此示例在业务网络上为admin
用户使用my-network
业务网卡:
composer network ping -c admin@my-network
请注意,在继续之前,您必须使用该composer network ping
命令来测试与业务网络的连接。如果商业网卡仅包含用户ID和登记密码,则该composer network ping
命令将触发注册过程发生并将证书存储在商业网卡中。这是不建议使用泊坞窗图像的REST服务器时使用商业网络卡只有一个用户ID和注册的秘密。
启动一个名为MongoDB的Docker镜像实例mongo
。这个MongoDB实例将用于持久保存关于REST服务器的认证用户及其钱包(包含启用多用户模式的用户业务网卡)的所有信息。
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实例进行交互。
通过为MongoDB添加LoopBack连接器并为GitHub身份验证添加Passport策略,扩展REST服务器的Docker镜像。在本地文件系统上创建一个新的空目录,并Dockerfile
在新目录中创建一个新文件,其中包含以下内容:
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镜像:
docker build -t myorg/my-composer-rest-server .
如果此命令成功完成,则会调用一个名为Docker的新图像myorg/my-composer-rest-server
并将其存储在系统的本地Docker注册表中。如果您希望在其他系统上使用此Docker镜像,则可能需要将Docker镜像推送到Docker注册中心,例如Docker Hub。
REST服务器的Docker镜像使用环境变量而不是命令行选项进行配置。创建一个名为envvars.txt
存储REST服务器的环境变量的新文件,其中包含以下内容:
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_ID
并REPLACE_WITH_CLIENT_SECRET
使用GitHub中的相应配置才能使此配置成功运行。
我们通过在COMPOSER_DATASOURCES
环境变量中为MongoDB配置LoopBack连接器来配置我们的REST服务器以使用我们的MongoDB实例。请注意,mongo
已在host
名为LoopBack数据源的属性中指定了MongoDB实例的主机名db
。
通过运行以下命令将环境变量加载到当前shell中:
source envvars.txt
如果您打开一个新的shell,例如新的终端窗口或选项卡,则必须source
再次运行相同的命令以将环境变量加载到新的shell中。
有关可用于配置REST服务器的环境变量的更多信息,请参阅参考文档:Hyperledger Composer REST服务器
通过运行以下docker run
命令,为您在步骤3中创建的REST服务器启动扩展Docker镜像的新实例:
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网络上可用rest
。REST服务器端口3000
也使用端口在主机网络上公开3000
。
您可以使用该docker logs
命令检查REST服务器是否已成功启动,例如:
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服务器的生产部署,您需要:
--name
参数更改Docker容器的名称以及使用参数更新或删除后续REST服务器实例的主机端口映射,很容易-p 3000:3000
。完成这三项任务后,您应该能够停止,重新启动或删除任何REST服务器实例(但不是全部!),而不会失去通过REST访问已部署的业务网络。
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-out节点与注入节点结合使用,您可以通过提交这些参与者的JSON定义来创建参与者。
节点红色中流节点,允许您从注册表中创建,检索,更新或删除资产和参与者。例如,将hyperledger-composer-mid与注入节点结合使用,您可以通过提交正确的注册表并将字段标识为JSON对象来检索资产或参与者。
订阅区块链事件的Node-RED输入节点。
在某些情况下,希望能够从事务处理器函数中调用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
全局变量自动提供给所有交易处理器功能。您不需要将文件request
或request-promise
模块添加到package.json
文件中,也不需要使用该require
功能来加载模块。
全局request
方法和所有的便利方法的各种HTTP方法(request.get
,request.post
等)可用于交易处理器功能。这些方法为处理请求主体,响应主体,HTTP标头,身份验证,Cookie,代理和TLS / SSL提供了一整套选项。
有关这些方法和可用选项的详细信息,请查看request
和request-promise
模块的文档。
向HTTP服务器发出HTTP GET请求,该请求以字符串形式返回当前股票价格:
/**
* 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结构返回:
/**
* 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请求正文,并以字符串形式返回当前股票价格:
/**
* 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服务器返回库存资产的序列化实例:
/**
* 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请求可能会导致不同的响应:
为了最大限度地减少从事务处理函数发出HTTP请求时出现一致性失败的风险,建议您使用make HTTP请求:
从Hyperledger Composer Playground部署到Web浏览器连接的业务网络在Web浏览器内部运行。当这些业务网络中的事务处理器功能使用上述API发出HTTP请求时,这些HTTP请求将使用内置于Web浏览器中的HTTP客户端进行处理。
Web浏览器中内置的HTTP客户端要求HTTP服务器符合CORS(跨源资源共享)。如果将业务网络部署到Web浏览器连接,则必须确保HTTP服务器已配置为符合CORS。有关更多信息,请参阅:https://enable-cors.org
部署到Hyperledger Fabric的业务网络在链码代码容器中运行。这意味着业务网络需要由Docker提供的DNS解析和网络服务,而不是由主机提供的服务。另外,chaincode Docker容器有自己的IP地址。
这意味着localhost
解析为链码的Docker容器,而不是主机。任何HTTP请求localhost
,例如http:// localhost:3000 / api / Vehicle,都不会按预期工作。最简单的解决方法是使用可公开解析的REST服务器的DNS名称。