Swift-cfenv 包提供了结构体和方法来解析 Cloud Foundry 提供的配置变量,例如端口号、IP 地址和应用程序的 URL。 它还提供了在本地运行应用程序时的默认值。
该库根据是否设置了 VCAP_APPLICATION 配置变量来确定您是否在“本地”或云端(即作为 Cloud Foundry 应用程序)运行应用程序。 如果未设置,则假定您在“本地”模式而不是“云模式”下运行。
对于此 Swift 包的实现,我们借鉴了为 Node.js 应用程序开发的类似模块 node-cfenv。
最新版本的 Swift-cfenv 适用于 Swift 4.0 或更高版本。 您可以通过以下链接下载此版本的 Swift 二进制文件。
最新版本的 Swift-cfenv 依赖于 Configuration 包来从多个源加载和合并配置数据,例如环境变量或 JSON 文件。 在以前版本的 Swift-cfenv 中,该库负责直接访问环境变量。 未来,新版本的 Swift-cfenv 将继续依赖于加载到 ConfigurationManager 实例中的配置数据。 有关 Configuration 包的更多详细信息,请参见其 README 文件。
要在您的 Swift 应用程序中利用 Swift-cfenv 包,您应该在您的 Package.swift 文件中为其指定依赖项。
import PackageDescription
let package = Package(
name: "MyAwesomeSwiftProject",
...
dependencies: [
.package(url: "https://github.com/Kitura/Swift-cfenv.git", .upToNextMajor(from: "5.0.0")),
...
]
...
相应地更新您的应用程序的 Package.swift 文件后,您可以在您的代码中导入 CloudFoundryEnv 和 Configuration 模块。
import Configuration
import CloudFoundryEnv
...
let configFileURL: URL = ...
...
let configManager = ConfigurationManager()
// To load configuration data from a file or environment variables:
//configManager.load(url: configFileURL)
// .load(.environmentVariables)
// Use the given port and binding host values to create a socket for our server...
let ip: String = configManager.bind
let port: Int = configManager.port
...
// Once the server starts, print the url value
print("Server is starting on \(configManager.url).")
上面的代码片段通过 ConfigurationManager 对象获取绑定主机和端口值,您的 Swift 应用程序根据其需要(例如,JSON 文件、环境变量等)创建并填充该对象。 Swift-cfenv 查询 ConfigurationManager 实例以获取与 Cloud Foundry 相关的那些配置属性。 这些值然后用于绑定服务器。 此外,应用程序的 URL 值(也从配置属性中获取)可以用于日志记录目的,如上所示。
该库的主要目的是简化访问 Cloud Foundry 提供的配置值。
当您的应用程序在 Cloud Foundry 中作为环境变量运行时,将设置以下配置属性
VCAP_APPLICATIONVCAP_SERVICESPORT在 Cloud Foundry 中运行时,Swift-cfenv 希望这些属性加载到您的应用程序实例化的 ConfigurationManager 实例中。
如果在查询 ConfigurationManager 时未找到 VCAP_APPLICATION,则假定您的应用程序正在本地运行。 对于这种情况,ConfigurationManager 实例返回的值仍然对于启动您的应用程序有用。 因此,此 Swift 包可以在 Cloud Foundry 中运行时使用,也可以在本地运行时使用。
ConfigurationManager 是 Configuration Swift 包提供的类。 Swift-cfenv 只是向该类添加了扩展点,这使您可以直接访问 Cloud Foundry 配置数据。 在您的 Swift 应用程序中,您可能首先从本地 JSON 文件加载配置数据(这使您可以在本地运行),然后再从环境变量加载配置数据。
如果您想创建一个 JSON 文件,您的应用程序可以利用它来进行本地开发,我们建议创建一个遵循以下格式的文件
name - 应用程序名称的字符串值。 如果未在 JSON 文件中指定此属性,则使用 VCAP_APPLICATION 环境变量的 name 属性。protocol - 在生成的 URL 中使用的协议。 它覆盖了在为 ConfigurationManager 对象生成 URL 时使用的默认协议。vcap - JSON 对象,当在本地运行时,为 VCAP_APPLICATION 和 VCAP_SERVICES 环境变量提供值。 此 JSON 对象可以具有 application 字段和/或 services 字段,其值与 VCAP_APPLICATION 和 VCAP_SERVICES 变量中序列化的值相同。 请注意,当在本地运行时,ConfigurationManager 实例的 url 和 urls 扩展属性不是基于 vcap 应用程序对象(在这些情况下,它默认为 localhost)。 另外,请注意,如果不在本地运行,则忽略 vcap 属性。ConfigurationManager 类的实例具有以下扩展属性
isLocal:如果设置了 VCAP_APPLICATION 环境变量,则布尔属性设置为 true。app:VCAP_APPLICATION 环境变量的 JSON 对象版本。services:VCAP_SERVICES 环境变量的 JSON 对象版本。name:包含应用程序名称的字符串。port:包含 HTTP 端口号的整数。bind:用于绑定服务器的 IP 地址的字符串。urls:包含用于访问服务器的 URL 的字符串数组。url:urls 数组中的第一个字符串。如果无法确定 port 属性的值,则为其分配默认端口 8080。 请注意,8080 是在 Diego 上运行的应用程序使用的默认端口值。
如果在本地运行,则用于 URL 的协议将为 http,否则将为 https。 您可以使用 options 参数上的 protocol 属性指定特定协议来覆盖此逻辑。
如果在云端(即在 Cloud Foundry 中)运行时无法确定实际的主机名,则 url 和 urls 值将以 localhost 作为其主机名值。
以下是 ConfigurationManager 对象的实例方法扩展
getApp():返回一个 App 对象,该对象封装了 VCAP_APPLICATION 环境变量的属性。
getServices():在字典中返回绑定到应用程序的所有服务。 字典中的键是服务的名称,而值是 Service 对象。 请注意,此返回值与从 ConfigurationManager 实例返回的 services 属性不同。
getServices(type: String):返回与服务 type 参数的值匹配的 Service 对象数组。 type 参数应该是服务的标签(或用于按标签查找服务的正则表达式)。
getService(spec: String):返回指定 Cloud Foundry 服务的 Service 对象。 spec 参数应该是服务的名称或用于查找服务的正则表达式。 如果没有与 spec 参数匹配的服务,则此方法返回 nil。
getServiceURL(spec: String, replacements: [String:Any]?):返回从指定服务的 VCAP_SERVICES 环境变量生成的服务 URL,如果找不到服务,则返回 nil。 spec 参数应该是服务的名称或用于查找服务的正则表达式。 replacements 参数是一个字典,其中包含在 Foundation 的 URLComponents 类中找到的属性(例如,user、password、port 等)。 要生成服务 URL,首先使用服务凭据中的 url 属性创建一个 URLComponents 对象的实例。 然后,可以通过可选的 replacements 字典参数中指定的属性来覆盖 URLComponents 实例中的初始属性集。 如果服务凭据中没有 url 属性,则此方法返回 nil。 说了这么多,请注意,您有能力使用 url 的 replacements 属性和指定服务凭据中包含基本 URL 的属性名称的值来覆盖服务凭据中的 url 属性。 例如,在服务凭据中没有 url 属性的情况下,您可能会发现这很有用。
getServiceCreds(spec: String):返回一个字典,其中包含指定服务的凭据。 spec 参数应该是服务的名称或用于查找服务的正则表达式。 如果没有与 spec 参数匹配的服务,则此方法返回 nil。 如果指定服务没有凭据属性,则返回一个空字典。
App 是一个结构体,其中包含以下 VCAP_APPLICATION 环境变量属性
id:标识应用程序的 GUID 字符串。name:包含分配给应用程序的名称的字符串。uris:包含分配给应用程序的 URI 的字符串数组。version:标识应用程序版本的 GUID 字符串。instanceId:标识应用程序实例的 GUID 字符串。instanceIndex:表示实例索引号的整数。limits:一个 App.Limits 对象,其中包含应用程序实例的内存、磁盘和文件数(请参见下文)。port:包含应用程序实例的端口号的整数。spaceId:标识应用程序空间的 GUID 字符串。startedAtTs:一个 NSTimeInterval 实例,其中包含应用程序实例启动时间的 Unix 纪元时间戳。startedAt:一个 NSDate 对象,其中包含应用程序实例启动的时间。App.Limits 结构体包含应用程序实例的内存、磁盘和文件数
memory:表示应用程序内存的整数(此值通常在清单文件中指定)。disk:表示应用程序磁盘空间的整数(此值通常在清单文件中指定)。fds:表示文件数的整数。Service 是一个类,其中包含 Cloud Foundry service 的以下属性
name:包含分配给服务实例的名称的字符串。label:包含服务产品名称的字符串。plan:一个字符串,说明创建服务实例时选择的服务计划。 如果服务没有计划,则将字符串“N/A”分配给此字段。tags:包含用于标识服务实例的值的字符串数组。credentials:一个可选字典,其中包含访问服务实例所需的Service 凭据。 请注意,访问服务的凭据属性可能彼此完全不同。 例如,服务的凭据字典可能只包含一个 uri 属性,而另一个服务的凭据字典可能包含 hostname、username 和 password 属性。要在 IBM Cloud 上测试此 Swift 库,您可以按照本节中描述的步骤进行操作,这些步骤使用 IBM Cloud 命令行。
创建一个名为 cf-dummy-service 的虚拟服务
bx service user-provided-create cf-dummy-service -p "url, username, password, database"
IBM Cloud 命令行将会提示您输入以下信息(请输入一些合理的值)
url> http://swift-cfenv-service.test.com
username> username00
password> password00
database> CloudantDB
创建虚拟服务后,您可以使用以下命令克隆 IBM Cloud 的 swift-helloworld 应用程序
git clone https://github.com/IBM-Bluemix/swift-helloworld.git
然后使用以下命令推送 swift-helloworld 应用程序
bx app push
成功推送应用程序后,您需要将之前创建的服务绑定到新应用程序,然后重新暂存应用程序
bx service bind swift-helloworld cf-dummy-service
bx app restage swift-helloworld
重新暂存应用程序后,您可以访问分配给应用程序的路由(即 URL),您应该看到各种 Swift-cfenv 调用的输出。
此 Swift 包在 Apache 2.0 许可下获得许可。完整的许可文本可在 LICENSE 中找到。