App Configuration 服务器 SDK for Go
App Configuration 服务提供 SDK 以与 Golang Web 和移动应用程序,微服务以及分布式环境集成。
先决条件
以下是使用 App Configuration 服务 SDK for Go 的先决条件:
- Go V 1.16 或更高版本
集成服务器 SDK for Go
已收回 App Configuration Go SDK 的 v1.x.x 版本。
App Configuration 服务提供 SDK 以与 Golang Web 和移动应用程序,微服务以及分布式环境集成。 您可以通过集成 App Configuration SDK 来评估属性和功能标志的值。
-
使用
git
存储库中的以下代码来安装 SDK。go get -u github.com/IBM/appconfiguration-go-sdk@latest
-
在 Golang 微服务或应用程序中,包含 SDK 模块,包括:
import ( AppConfiguration "github.com/IBM/appconfiguration-go-sdk/lib" )
运行
go mod tidy
以下载并安装新的依赖关系,并更新 Go 应用程序的go.mod
文件。 -
初始化 SDK 以与 App Configuration 服务实例连接。
collectionId := "airlines-webapp" environmentId := "dev" appConfigClient := AppConfiguration.GetInstance() appConfigClient.Init("region", "guid", "apikey") appConfigClient.SetContext(collectionId, environmentId)
其中,
region
:创建 App Configuration 服务实例的区域名称。 点击此处 查看支持的地点列表。 例如:-us-south
,au-syd
等。guid
: App Configuration 服务的实例标识。 从 App Configuration 服务仪表板的服务凭证部分获取此信息。apiKey
: App Configuration 服务的 ApiKey。 从 App Configuration 服务仪表板的服务凭证部分获取此信息。collectionId
: 在 App Configuration 服务实例中创建的集合的标识。environmentId
: 在“环境”部分下的 App Configuration 服务实例中创建的环境的标识。
init()
和setContext()
是初始化方法,需要 仅一次 使用appConfigClient
启动。 初始化后,可以使用AppConfiguration.GetInstance()
跨模块获取appConfigClient
。
使用专用端点
通过使用仅可通过 IBM Cloud 专用网络访问的专用端点,设置 SDK 以连接到 App Configuration 服务。
appConfigClient.UsePrivateEndpoint(true)
必须先完成此操作,然后才能在 SDK 上调用 Init
函数。
用于将持久高速缓存用于配置的选项
要使应用程序和 SDK 继续操作,即使在 App Configuration 服务停机的不太可能的场景中,在应用程序重新启动期间,您也可以将 SDK 配置为使用持久高速缓存来工作。 SDK 使用持久高速缓存来存储在应用程序重新启动期间可用的 App Configuration 数据。
// 1. default (without persistent cache)
appConfiguration.SetContext(collectionId, environmentId)
// 2. with persistent cache
appConfiguration.SetContext(collectionId, environmentId, AppConfiguration.ContextOptions{
PersistentCacheDirectory: "/var/lib/docker/volumes/",
})
其中 persistentCacheDirectory
: 具有用户读写许可权的目录的绝对路径。 SDK 在指定目录中创建文件 AppConfiguration.json
,并将其用作持久高速缓存以存储 App Configuration 服务信息。
启用持久高速缓存时,SDK 会在持久高速缓存中保留最后已知的良好配置。 如果无法访问 App Configuration 服务器,那么会将持久高速缓存中的最新配置装入到应用程序以继续工作。
确保在任何情况下都不会丢失或删除高速缓存文件。 例如,请考虑重新启动 Kubernetes pod 并且高速缓存文件 (appconfiguration.json
) 存储在 pod 的临时卷中的情况。 当 pod 重新启动时,kubernetes 会破坏 pod 中的 ephermal 卷,从而删除高速缓存文件。 因此,通过提供持久目录的正确绝对路径,确保 SDK 创建的高速缓存文件始终存储在持久卷中。
脱机选项
SDK 还设计为提供配置,并在不连接到 App Configuration 服务的情况下执行功能标志和属性评估。
appConfiguration.SetContext(collectionId, environmentId, AppConfiguration.ContextOptions{
BootstrapFile: "saflights/flights.json",
LiveConfigUpdateEnabled: false,
})
其中,
-
BootstrapFile
: JSON 文件的绝对路径,其中包含配置详细信息。 请确保提供正确的 JSON 文件。 您可以使用 IBM Cloud App Configuration CLI 的ibmcloud ac export
命令来生成此文件。 -
LiveConfigUpdateEnabled
: 从服务器进行实时配置更新。 如果不能从服务器访存新配置值,请将此值设置为false
。 缺省情况下,此值处于启用状态。
使用与属性和功能相关的 API 的示例
请参阅列出的使用属性和功能相关 API 的示例。
获取单一功能
feature, err := appConfigClient.GetFeature("online-check-in")
if err == nil {
fmt.Println("Feature Name", feature.GetFeatureName())
fmt.Println("Feature Id", feature.GetFeatureID())
fmt.Println("Feature Type", feature.GetFeatureDataType())
if (feature.IsEnabled()) {
// feature flag is enabled
} else {
// feature flag is disabled
}
}
获取所有功能
features, err := appConfigClient.GetFeatures()
if err == nil {
feature := features["online-check-in"]
fmt.Println("Feature Name", feature.GetFeatureName())
fmt.Println("Feature Id", feature.GetFeatureID())
fmt.Println("Feature Type", feature.GetFeatureDataType())
fmt.Println("Is feature enabled?", feature.IsEnabled())
}
功能评估
您可以使用 feature.GetCurrentValue(entityId, entityAttributes)
方法来评估功能标志的值。GetCurrentValue
根据评估返回“已启用”,“已禁用”或“已覆盖”值之一。
entityId := "john_doe"
entityAttributes := make(map[string]interface{})
entityAttributes["city"] = "Bangalore"
entityAttributes["country"] = "India"
featureVal := feature.GetCurrentValue(entityId, entityAttributes)
-
entityId
:entityId
是与将对功能部件进行求值的实体相关的字符串标识。 例如,实体可能是在移动设备上运行的应用程序实例,在云上运行的微服务或运行该微服务的基础结构组件。 对于要与 App Configuration进行交互的任何实体,它必须提供唯一的实体标识。 -
entityAttributes
:entityAttributes
是类型为map[string]interface{}
的映射,由属性名称及其定义指定实体的值组成。 如果未使用任何目标定义配置功能标志,那么这是可选参数。 如果配置了目标,那么必须为规则评估提供entityAttributes
。 属性是用于定义段的参数。 SDK 使用属性值来确定指定的实体是否满足目标规则,并返回相应的功能标志值。
获取单个属性
property, err := appConfigClient.GetProperty("check-in-charges")
if err == nil {
fmt.Println("Property Name", property.GetPropertyName())
fmt.Println("Property Id", property.GetPropertyID())
fmt.Println("Property Type", property.GetPropertyDataType())
}
获取所有属性
properties, err := appConfigClient.GetProperties()
if err == nil {
property := properties["check-in-charges"]
fmt.Println("Property Name", property.GetPropertyName())
fmt.Println("Property Id", property.GetPropertyID())
fmt.Println("Property Type", property.GetPropertyDataType())
}
属性评估
您可以使用 property.GetCurrentValue(entityId, entityAttributes)
方法来评估属性的值。GetCurrentValue
根据求值返回缺省属性值或其覆盖值。
entityId := "john_doe"
entityAttributes := make(map[string]interface{})
entityAttributes["city"] = "Bangalore"
entityAttributes["country"] = "India"
propertyVal := property.GetCurrentValue(entityId, entityAttributes)
-
entityId
:entityId
是与将针对其对属性进行求值的实体相关的字符串标识。 例如,实体可能是在移动设备上运行的应用程序实例,在云上运行的微服务或运行该微服务的基础结构组件。 对于要与 App Configuration进行交互的任何实体,它必须提供唯一的实体标识。 -
entityAttributes
:entityAttributes
是类型为map[string]interface{}
的映射,由属性名称及其定义指定实体的值组成。 如果属性未配置任何目标定义,那么这是可选参数。 如果配置了目标,那么必须为规则评估提供entityAttributes
。 属性是用于定义段的参数。 SDK 使用属性值来确定指定的实体是否满足目标规则,并返回相应的属性值。
获取私钥属性
secretPropertyObject, err := appConfiguration.GetSecret(propertyID, secretsManagerObject)
-
propertyID
:propertyID
是唯一字符串标识,使用此标识,您将能够访存提供了访存私钥所必需的数据的属性。 -
secretsManagerObject
:secretsManagerObject
是 Secrets Manager 变量或对象,将用于在私钥属性求值期间获取私钥。 有关如何创建 Secrets Manager 对象的更多信息,请参阅 此处。
评估私钥属性
使用 secretPropertyObject.GetCurrentValue(entityId, entityAttributes)
方法来评估私钥属性的值。GetCurrentValue
返回基于求值的私钥值。
entityId := "john_doe"
entityAttributes := make(map[string]interface{})
entityAttributes["city"] = "Bangalore"
entityAttributes["country"] = "India"
getSecretRes, detailedResponse, err := secretPropertyObject.GetCurrentValue(entityId, entityAttributes)
-
entityId
:entityId
是与将针对其对属性进行求值的实体相关的字符串标识。 例如,实体可能是在移动设备上运行的应用程序实例,在云上运行的微服务或运行该微服务的基础结构组件。 对于要与 App Configuration进行交互的任何实体,它必须提供唯一的实体标识。 -
entityAttributes
:entityAttributes
是类型为map[string]interface{}
的映射,由属性名称及其定义指定实体的值组成。 如果属性未配置任何目标定义,那么这是可选参数。 如果配置了目标,那么必须为规则评估提供entityAttributes
。 属性是用于定义段的参数。 SDK 使用属性值来确定指定的实体是否满足目标规则,并返回相应的属性值。
如何从响应访问有效内容私钥数据
//make sure this import statement is added
import (sm "github.com/IBM/secrets-manager-go-sdk/secretsmanagerv1")
secret := getSecretRes.Resources[0].(*sm.SecretResource)
secretData := secret.SecretData.(map[string]interface{})
payload := secretData["payload"]
GetCurrentValue
将作为响应的一部分发送三个对象。
getSecretRes
: 这将提供元数据和有效内容。detailedResponse
: 这将提供包含 HTTP 响应头数据,元数据和有效内容的完整数据。err
: 如果请求无效或由于某种原因失败,那么这将给出错误响应。
secretData["payload"]
将返回 interface{}
,以便根据您执行类型强制类型转换所需的数据。
跨其他模块访存 appConfigClient
一旦SDK初始化,appConfigClient
就可以通过其他模块获取,如下所示:
// **other modules**
import (
AppConfiguration "github.com/IBM/appconfiguration-go-sdk/lib"
)
appConfigClient := AppConfiguration.GetInstance()
feature, err := appConfigClient.GetFeature("online-check-in")
if (err == nil) {
enabled := feature.IsEnabled()
featureValue := feature.GetCurrentValue(entityId, entityAttributes)
}
支持的数据类型
您可以使用 App Configuration配置功能部件标志和属性,支持以下数据类型 :Boolean,Numeric,String 和 SecretRef。 字符串数据类型可以是文本字符串,JSON 或 YAML。 SDK 将处理表中显示的每种格式。
功能部件或属性值 | 数据类型 | 数据格式 | GetCurrentValue() 返回的数据类型 |
示例输出 |
---|---|---|---|---|
true |
BOOLEAN | 不适用 | bool |
true |
25 |
NUMERIC | 不适用 | float64 |
25 |
{ "secret_type": "kv", "id": "secret_id_data_here", "sm_instance_crn": "crn_data_added-here" } |
SECRETREF (this type is applicable only for Property) | not applicable | map[string]interface{} |
{ "metadata": { "collection_type":"application/vnd.ibm.secrets-manager.secret+json", "collection_total": 1 }, "resources": [{"created_by": "iam-ServiceId-e4a2f0a4-3c76-4bef-b1f2-fbeae11c0f21", "creation_date": "2020-10-05T21:33:11Z", "crn": "crn:v1:bluemix:public:secrets-manager:us-south:a/a5ebf2570dcaedf18d7ed78e216c263a:f1bc94a6-64aa-4c55-b00f-f6cd70e4b2ce:secret:cb7a2502-8ede-47d6-b5b6-1b7af6b6f563", "description": "Extended description for this secret.", "expiration_date": "2021-01-01T00:00:00Z", "id": "cb7a2502-8ede-47d6-b5b6-1b7af6b6f563", "labels": ["dev","us-south"], "last_update_date": "2020-10-05T21:33:11Z", "name": "example-arbitrary-secret", "secret_data": {"payload": "secret-data"}, "secret_type": "arbitrary", "state": 1, "state_description": "Active", "versions_total": 1, "versions": [{"created_by": "iam-ServiceId-222b47ab-b08e-4619-b68f-8014a2c3acb8","creation_date": "2020-11-23T20:15:01Z","id": "50277266-d706-4b3e-badb-f07257f8f581","payload_available": true,"downloaded": true}],"locks_total": 2}] } Note: Along with the above data you will also provide the detailedResponse and error data. |
"a string text" | STRING | TEXT | string |
a string text |
{"firefox": { "name": "Firefox", "pref_url": "about:config" }} |
字符串 | JSON | map[string]interface{} |
map[browsers:map[firefox:map[name:Firefox pref_url:about:config]]] |
men: - John Smith - Bill Jones women: - Mary Smith - Susan Williams |
STRING | YAML | map[string]interface{} |
map[men:[John Smith Bill Jones] women:[Mary Smith Susan Williams]] |
功能标志
feature, err := appConfigClient.GetFeature("json-feature")
if err == nil {
feature.GetFeatureDataType() // STRING
feature.GetFeatureDataFormat() // JSON
// Example (traversing the returned map)
result := feature.GetCurrentValue(entityID, entityAttributes) // JSON value is returned as a Map
result.(map[string]interface{})["key"] // returns the value of the key
}
feature, err := appConfigClient.GetFeature("yaml-feature")
if err == nil {
feature.GetFeatureDataType() // STRING
feature.GetFeatureDataFormat() // YAML
// Example (traversing the returned map)
result := feature.GetCurrentValue(entityID, entityAttributes) // YAML value is returned as a Map
result.(map[string]interface{})["key"] // returns the value of the key
}
属性
property, err := appConfigClient.GetProperty("json-property")
if err == nil {
property.GetPropertyDataType() // STRING
property.GetPropertyDataFormat() // JSON
// Example (traversing the returned map)
result := property.GetCurrentValue(entityID, entityAttributes) // JSON value is returned as a Map
result.(map[string]interface{})["key"] // returns the value of the key
}
property, err := appConfigClient.GetProperty("yaml-property")
if err == nil {
property.GetPropertyDataType() // STRING
property.GetPropertyDataFormat() // YAML
// Example (traversing the returned map)
result := property.GetCurrentValue(entityID, entityAttributes) // YAML value is returned as a Map
result.(map[string]interface{})["key"] // returns the value of the key
}
侦听属性和功能部件更改
要侦听数据更改,请在应用程序中添加以下代码:
appConfigClient.RegisterConfigurationUpdateListener(func () {
// **add your code**
// To find the effect of any configuration changes, you can call the feature or property related methods
// feature, err := appConfigClient.GetFeature("json-feature")
// newValue := feature.GetCurrentValue(entityID, entityAttributes)
})
访存最新数据
appConfigClient.FetchConfigurations()