IBM Cloud Docs
App Configuration 服务器 SDK for Java

App Configuration 服务器 SDK for Java

App Configuration 服务提供 SDK 以与应用程序,微服务和分布式环境集成。

集成服务器 SDK for Java

App Configuration 服务提供 SDK 以与 Java 应用程序集成。 您可以通过集成 App Configuration SDK 来评估功能部件标志的值。

  1. 以下列方式之一安装 SDK。

    使用 Maven

    <dependency>
       <groupId>com.ibm.cloud</groupId>
       <artifactId>appconfiguration-java-sdk</artifactId>
       <version>0.3.3</version>
    </dependency>
    

    通过添加以下内容,通过 Gradle 获取软件包:

    implementation group: 'com.ibm.cloud', name: 'appconfiguration-java-sdk', version: '0.3.3'
    
  2. 在 Java 微服务或应用程序中,包含具有以下内容的 SDK:

    import com.ibm.cloud.appconfiguration.sdk.AppConfiguration;
    
  3. 初始化 SDK 以与 App Configuration 服务实例连接。

    String region = AppConfiguration.REGION_US_SOUTH;
    String guid = "guid";
    String apikey = "apikey";
    
    String collectionId = "airlines-webapp";
    String environmentId = "dev";
    
    AppConfiguration appConfigClient = AppConfiguration.getInstance();
    appConfigClient.init(region, guid, apikey);
    appConfigClient.setContext(collectionId, environmentId);
    

    其中,

    • region:创建 App Configuration 服务实例的区域名称。 点击此处 查看支持的地点列表。 例如:- us-south, au-syd 等。
    • guid: App Configuration 服务的 GUID。 从 App Configuration 服务仪表板的服务凭证部分获取此信息。
    • apiKey: App Configuration 服务的 ApiKey。 从 App Configuration 服务仪表板的服务凭证部分获取此信息。
    • collectionId: 在“集合”部分下的 App Configuration 服务实例中创建的集合的标识。
    • environmentId: 在“环境”部分下的 App Configuration 服务实例中创建的环境的标识。

init()setContext() 是初始化类,必须使用 appConfigClient 仅调用一次。 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)
    appConfigClient.setContext(collectionId, environmentId);

// 2. optional (with persistent cache)
    ConfigurationOptions configOptions = new ConfigurationOptions();
    configOptions.setPersistentCacheDirectory("/var/lib/docker/volumes/");
    appConfigClient.setContext(collectionId, environmentId, configOptions);

其中:

  • persistentCacheDirectory: 用户具有读写许可权的目录的绝对路径。 SDK 在指定目录中创建文件 appconfiguration.json,并将其用作持久高速缓存以存储 App Configuration 服务信息。

启用持久高速缓存时,SDK 会在持久高速缓存中保留最后已知的良好配置。 如果无法访问 App Configuration 服务器,那么会将持久高速缓存中的最新配置装入到应用程序以继续工作。

确保在任何情况下都不会丢失或删除高速缓存文件。 例如,请考虑重新启动 Kubernetes pod 并且高速缓存文件 (appconfiguration.json) 存储在 pod 的临时卷中的情况。 当 pod 重新启动时,kubernetes 会破坏 pod 中的 ephermal 卷,从而删除高速缓存文件。 因此,通过提供持久目录的正确绝对路径,确保 SDK 创建的高速缓存文件始终存储在持久卷中。

脱机选项

SDK 还设计为提供配置,并在不连接到 App Configuration 服务的情况下执行功能标志和属性评估。

ConfigurationOptions configOptions = new ConfigurationOptions();
configOptions.setBootstrapFile("saflights/flights.json");
configOptions.setLiveConfigUpdateEnabled(false);
appConfigClient.setContext(collectionId, environmentId, configOptions);

其中:

  • bootstrapFile: JSON 文件的绝对路径,其中包含配置详细信息。 请确保提供正确的 JSON 文件。 您可以使用 IBM Cloud App Configuration CLI 的 ibmcloud ac export 命令来生成此文件。
  • liveConfigUpdateEnabled: 从服务器进行实时配置更新。 如果不能从服务器访存新配置值,请将此值设置为 false。 默认情况下,该值设置为 true

使用与功能部件和属性相关的 API 的示例

请参阅以下示例以使用与功能部件和属性相关的 API。

获取单一功能

Feature feature = appConfigClient.getFeature("online-check-in");

if (feature != null) {
    System.out.println("Feature Name : " + feature.getFeatureName());
    System.out.println("Feature Id : " + feature.getFeatureId());
    System.out.println("Feature Type : " + feature.getFeatureDataType());
    System.out.println("Is feature enabled? : " + feature.isEnabled());
}

获取所有功能

HashMap<String, Feature> features = appConfigClient.getFeatures();

功能评估

您可以使用 feature.getCurrentValue(entityId, entityAttributes) 方法来评估功能标志的值。 必须传递唯一的 entityId 作为功能部件标志求值的参数。 如果使用 App Configuration 服务中的段配置了功能标志,那么可以将属性值设置为 JSONObject。

String entityId = "john_doe";
JSONObject entityAttributes = new JSONObject();
entityAttributes.put("city", "Bangalore");
entityAttributes.put("country", "India");

String value = (String) feature.getCurrentValue(entityId, entityAttributes);
  • entityId: 实体的标识。 这是与对功能进行求值的实体相关的字符串标识。 例如,实体可能是在移动设备上运行的应用程序实例,在云上运行的微服务或运行该微服务的基础结构组件。 对于要与 App Configuration进行交互的任何实体,它必须提供唯一的实体标识。

  • entityAttributes: 由属性名称及其定义指定实体的值组成的 JSON 对象。 如果未使用任何目标定义配置功能标志,那么这是可选参数。 如果配置了目标,那么应该为规则评估提供 entityAttributes。 属性是用于定义段的参数。 SDK 使用属性值来确定指定的实体是否满足目标规则,并返回相应的功能标志值。

获取单个属性

Property property = appConfigClient.getProperty("check-in-charges");

if (property != null) {
    System.out.println("Property Name : " + property.getPropertyName());
    System.out.println("Property Id : " + property.getPropertyId());
    System.out.println("Property Type : " + property.getPropertyDataType());
}

获取所有属性

HashMap<String, Property> property = appConfigClient.getProperties();

属性评估

您可以使用 property.getCurrentValue(entityId, entityAttributes) 方法来评估属性的值。 此方法根据求值返回缺省属性值或其覆盖值。

String entityId = "john_doe";
JSONObject entityAttributes = new JSONObject();
entityAttributes.put("city", "Bangalore");
entityAttributes.put("country", "India");

String value = (String) property.getCurrentValue(entityId, entityAttributes);
  • entityId: 实体的标识。 这是与针对其对属性求值的实体相关的字符串标识。 例如,实体可能是在移动设备上运行的应用程序实例,在云上运行的微服务或运行该微服务的基础结构组件。 对于要与 App Configuration进行交互的任何实体,它必须提供唯一的实体标识。

  • entityAttributes: 由属性名称及其定义指定实体的值组成的 JSON 对象。 如果属性未配置任何目标定义,那么这是可选参数。 如果配置了目标,那么应该为规则评估提供 entityAttributes。 属性是用于定义段的参数。 SDK 使用属性值来确定指定的实体是否满足目标规则,并返回相应的属性值。

跨其他类访存 appConfigClient

初始化 SDK 时,可以跨其他类获取 appConfigClient,如下所示:

// **other classes**

import com.ibm.cloud.appconfiguration.sdk.AppConfiguration;
AppConfiguration appConfigClient = AppConfiguration.getInstance();

Feature feature = appConfigClient.getFeature("string-feature");
boolean enabled = feature.isEnabled();
String featureValue = (String) feature.getCurrentValue(entityId, entityAttributes);

支持的数据类型

App Configuration 服务允许您配置具有以下数据类型的功能标志和属性 :Boolean,Numeric 和 String。 字符串数据类型的格式可以是 TEXT 字符串,JSON 或 YAML。 SDK 处理每种格式,如表 1 中所示。

输出示例
功能部件或属性值 数据类型 数据格式 GetCurrentValue() 返回的数据类型 示例输出
true BOOLEAN 不适用 bool true
25 NUMERIC 不适用 float64 25
"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 java.lang.String

`"men:

  • John Smith
  • Bill Jones\women:
  • Mary Smith
  • Susan Williams"`

功能标志

Feature feature = appConfigClient.getFeature("json-feature");
if (feature != null) {
   feature.getFeatureDataType();       // STRING
   feature.getFeatureDataFormat();     // JSON
   feature.getCurrentValue(entityId, entityAttributes); // JSONObject or JSONArray is returned
}

// Example Below
// input json :- [{"role": "developer", "description": "do coding"},{"role": "tester", "description": "do testing"}]
// expected output :- "do coding"

JSONArray tar_val = (JSONArray) feature.get_current_value(entityId, entityAttributes);
String expected_output = (String) ((JSONObject) tar_val.get(0)).get('description');

// input json :- {"role": "tester", "description": "do testing"}
// expected output :- "tester"

JSONObject tar_val = (JSONObject) feature.get_current_value(entityId, entityAttributes);
String expected_output = (String) tar_val.get('role');

Feature feature = appConfigClient.getFeature("yaml-feature");
if (feature != null) {
   feature.getFeatureDataType();       // STRING
   feature.getFeatureDataFormat();     // YAML
   feature.getCurrentValue(entityId, entityAttributes); // Yaml String is returned
}

属性

Property property = appConfigClient.getProperty("json-property");
if (property != null) {
   property.getPropertyDataType();     // STRING
   property.getPropertyDataFormat();   // JSON
   property.getCurrentValue(entityId, entityAttributes); // JSONObject or JSONArray is returned
}

// Example Below
// input json :- [{"role": "developer", "description": "do coding"},{"role": "tester", "description": "do testing"}]
// expected output :- "do coding"

JSONArray tar_val = (JSONArray) property.get_current_value(entityId, entityAttributes);
String expected_output = (String) ((JSONObject) tar_val.get(0)).get('description');

// input json :- {"role": "tester", "description": "do testing"}
// expected output :- "tester"

JSONObject tar_val = (JSONObject) property.get_current_value(entityId, entityAttributes);
String expected_output = (String) tar_val.get('role');

Property property = appConfigClient.getProperty("yaml-property");
if (property != null) {
   property.getPropertyDataType();     // STRING
   property.getPropertyDataFormat();   // YAML
   property.getCurrentValue(entityId, entityAttributes); // Yaml String is returned
}

为功能部件或属性更改设置侦听器

SDK 提供了在功能标志或属性的配置发生更改时实时通知您的机制。 您可以使用相同的 appConfigClient 订阅配置更改。

appConfigClient.registerConfigurationUpdateListener(new ConfigurationUpdateListener() {
   @Override
   public void onConfigurationUpdate() {
      System.out.println("Received updated configurations");
      // **add your code**
      // To find the effect of any configuration changes, you can call the feature or property related methods

      // Feature feature = appConfigClient.getFeature("numeric-feature");
      // Integer newValue = (Integer) feature.getCurrentValue(entityId, entityAttributes);
   }
});

访存最新数据

appConfigClient.fetchConfigurations();