Context Aware Config Client Integration
This provides SDK to interact with context-aware-config
.
- Rust
- Haskell
Rust
The rust client have a client factory that helps you work with multiple clients connected to different tenants
Client Factory Methods Reference
Create Client
Create a client in the factory. You can chose to use the result to check for errors faced by the Client Factory while creating your client, it is not mandatory to consume the Ok
value.
Function definition
pub async fn create_client(
tenant: String,
polling_interval: Duration,
hostname: String,
) -> Result<Arc<Client>, String>
Params
Param | type | description | Example value |
---|---|---|---|
tenant | String | specifies the tenants configs and contexts that will be loaded into the client at polling_interval from hostname | mjos |
polling_interval | Duration | specifies the time cac client waits before checking with the server for updates | Duration::from_secs(5) |
hostname | String | The URL of the superposition server | https://superposition.example.com |
Get Client
Get a client
Function definition
pub async fn get_client(
tenant: String
) -> Result<Arc<Client>, String>
Params
Param | type | description | Example value |
---|---|---|---|
tenant | String | specifies the tenant used during create_client | mjos |
Example Implementation
Below is the rust implementation to instantiate CAC client using the client factory.
use cac_client as cc;
let tenants: Vec<String> = ["dev", "test"];
//You can create a clientFactory
for tenant in tenants {
cc::CLIENT_FACTORY
.create_client(
tenant.to_string(),
update_cac_periodically,//flag for if you want to update cac config periodically
polling_interval,//polling interval in secs, default is 60
cac_hostname.to_string(),// superposition service host
)
.await
.expect(format!("{}: Failed to acquire cac_client", tenant).as_str());
};
//You can extract an individual tenant's client from clientFactory
let tenant = "dev".to_owned();
let cac_client = cc::CLIENT_FACTORY.get_client(tenant.clone()).map_err(|e| {
log::error!("{}: {}", tenant.clone(), e);
ErrorType::IgnoreError(format!("{}: Failed to get cac client", tenant))
})?;
CAC Client Methods Reference
After calling get_client
method of Client Factory, you can do the following with the Client
returned.
Run polling for updates from Superposition Service
the CAC client polls for updates from the superposition service and loads any changes done on the server. This means that configs changed in superposition are reflected on the client in the duration of polling_interval
. run_polling_updates()
should be run in a separate thread, as it does not terminate.
Function definition
pub async fn run_polling_updates()
Get Config
Get the full config definition of your tenants configuration from superposition. Config
has the following information:
pub struct Config {
contexts: Vec<Context>,
overrides: Map<String, Value>,
default_configs: Map<String, Value>,
}
Funtion Definition
pub fn get_full_config_state_with_filter(query_data: Option<Map<String, Value>>) -> Result<Config, String>
Get the last modified Time
CAC client lets you get the last modified time of your configs, in case you want to log it, etc.
Function Definition
pub fn get_last_modified() -> Result<DateTime<Utc>, String>
Evaluate Context to derive configs
Given a context, get overrides for a specific set of keys, if provided. If None is provided for filter_keys
, all configs are returned.
Function Definition
pub fn get_resolved_config(context: Map<String, Value>, filter_keys: Option<Vec<String>>) -> Result<Map<String, Value>, String>
Params
Param | type | description | Example value |
---|---|---|---|
context | Map<String, Value> | The context under which you want to resolve configs | {"os": "android", "merchant": "juspay"} |
filter_keys | Option<Vec<String>> | The keys for which you want the values. If empty, all configuration keys are returned | Some([payment, network, color]) |
Get Default Config
The default config for a specific set of keys, if provided. If None is provided for filter_keys
, all configs are returned.
Function Definition
pub fn get_default_config(filter_keys: Option<Vec<String>>) -> Result<Map<String, Value>, String>
Param
Param | type | description | Example value |
---|---|---|---|
filter_keys | Option<Vec<String>> | The keys for which you want the values. If None, all configuration keys are returned | Some([payment, network, color]) |
Haskell
Adding the clients to your project
Nix
Add the following to your inputs
superposition = {
url = "github:juspay/superposition";
inputs.nixpkgs.follows = "common/nixpkgs";
};
then, add the following to your imports section in outputs:
imports = [
......
inputs.superposition.haskellFlakeProjectModules.output
]
then add the libraries to your project.cabal file:
extra-libraries:
cac_client
experimentation_client
Haskell CAC client functions reference
Create a client
Create a new client in the Client Factory
Function Definition
createCacClient:: Tenant -> Interval -> Hostname -> IO (Either Error ())
Param
Param | type | description | Example value |
---|---|---|---|
Tenant | String | specifies the tenants configs and contexts that will be loaded into the client at Interval from Hostname | mjos |
Interval | Duration | specifies the time cac client waits before checking with the server for updates, in seconds | 10 |
Hostname | String | The URL of the superposition server | https://superposition.example.com |
Get a client
Create a new client in the Client Factory
Function Definition
getCacClient :: Tenant -> IO (Either Error (ForeignPtr CacClient))
Param
Param | type | description | Example value |
---|---|---|---|
Tenant | String | specifies the tenants configs and contexts that will be loaded into the client at Interval from Hostname | mjos |
Run polling for updates from Superposition Service
the CAC client polls for updates from the superposition service and loads any changes done on the server. This means that configs changed in superposition are reflected on the client in the duration of Interval
. cacStartPolling
should be run in a separate thread, as it does not terminate.
Function definition
cacStartPolling :: Tenant -> IO ()
Param
Param | type | description | Example value |
---|---|---|---|
Tenant | String | specifies the tenants configs and contexts that will be loaded into the client at Interval from Hostname | mjos |
Get Config
Get the full config definition of your tenants configuration from superposition. Config
has the following information:
{
contexts: [Context],
overrides: Map String Value,
default_configs: Map String Value,
}
Funtion Definition
getFullConfigStateWithFilter :: ForeignPtr CacClient -> Maybe String -> Maybe [String] -> IO (Either Error Value)
Params
Param | type | description | Example value |
---|---|---|---|
context | Maybe (String) | Specifies the context for which you want the configurations, If empty, all contexts are returned | Just {"os": "android", "merchant": "juspay"} |
prefix | Maybe([String]) | The keys for which you want the values. If empty, all configuration keys are returned | Just ([payment, network, color]) |
Get the last modified Time
CAC client lets you get the last modified time of your configs, in case you want to log it, etc.
Function Definition
getCacLastModified :: ForeignPtr CacClient -> IO (Either Error String)
Evaluate Context to derive configs
Given a context, get overrides for a specific set of keys, if provided. If Nothing is provided for filter_keys
, all configs are returned.
Function Definition
getResolvedConfig :: ForeignPtr CacClient -> String -> Maybe [String] -> IO (Either Error Value)
Params
Param | type | description | Example value |
---|---|---|---|
context | String | The context under which you want to resolve configs | {"os": "android", "merchant": "juspay"} |
filter_keys | Maybe([String]) | The keys for which you want the values. If empty, all configuration keys are returned | Just ([payment, network, color]) |
Get Default Config
The default config for a specific set of keys, if provided. If Nothing is provided for filter_keys
, all configs are returned.
Function Definition
getDefaultConfig :: ForeignPtr CacClient -> Maybe [String] -> IO (Either Error Value)
Param | type | description | Example value |
---|---|---|---|
filter_keys | Maybe([String]) | The keys for which you want the values. If Nothing, all configuration keys are returned | Just ([payment, network, color]) |
Sample Integration
{-# LANGUAGE LambdaCase #-}
module Main (main) where
import Client (getResolvedConfig, createCacClient, getCacClient,
getFullConfigStateWithFilter, getCacLastModified, cacStartPolling, getDefaultConfig)
import Control.Concurrent
import Prelude
main :: IO ()
main = do
createCacClient "dev" 10 "http://localhost:8080" >>= \case
Left err -> putStrLn err
Right _ -> pure ()
threadId <- forkOS (cacStartPolling "dev")
print threadId
getCacClient "dev" >>= \case
Left err -> putStrLn err
Right client -> do
config <- getFullConfigStateWithFilter client Nothing Nothing
lastModified <- getCacLastModified client
overrides <- getResolvedConfig client "{\"country\": \"India\"}" $ Just ["country_image_url", "hyperpay_version"]
defaults <- getDefaultConfig client $ Just ["country_image_url", "hyperpay_version"]
filteredConfig <- getFullConfigStateWithFilter client (Just "{\"os\": \"android\"}") $ Just ["hyperpay"]
print config
print lastModified
print overrides
print defaults
print filteredConfig
threadDelay 1000000000
pure ()