C++ (server-side) SDK reference

7 minute readReference

The following information is for the latest SDK version (6.x). The CloudBees platform requires that your installed SDK version be at least 6.x. Please install the latest SDK by following the instructions in the platform UI or in the SDK installation documentation.

Any updates to version 6.x are noted in the platform changelog.

ROX C++ header

Use as follows:

#import <roxx/server.h>

Rox Namespace

The Rox namespace provides an interface for the CloudBees platform to manage feature flags that control the behavior of your application. This namespace handles communications with the server to obtain the latest flag values, implement flag settings, and set up flag configurations. The values in the namespace are marked as feature flags and display in the platform UI once the application is run.

These classes and interfaces also allow you to manage custom properties. These can be static settings of type string, Boolean, integer, or double, or you can use a generator class to provide a custom property that is dependent upon code state. These generated properties must derive from CustomPropertyGeneratorInterface.

You can also use an Options object to configure some aspects of feature flag management. For example, you can set the custom platform, impression handler, dynamic properties rule, and configuration fetched handler.

Setup

Configures the Rox object to work with the provided application.

StateCode Setup(const char *api_key, Options *options = nullptr)
Parameter Modifier and type Description

apiKey

const char *

The environment-specific SDK key provided in the UI.

options

Options*

An Options instance with the desired configuration for this application.

typedef enum RoxStateCode { RoxUninitialized = 0, RoxSettingUp = 1, RoxInitialized = 2, RoxShuttingDown = 3, RoxErrorEmptyApiKey = -1, RoxErrorInvalidApiKey = -2, RoxErrorGenericSetupFailure = -1000 } RoxStateCode;

In case of a successful call, Setup returns RoxInitialized code. Otherwise, the application logs must be analyzed for errors and warnings. If Setup returns failure code, it may be called again after fixing the errors from the logs.

Shutdown

Frees all Rox internal objects. This must be used on exiting the application.

void Shutdown()
Setup may be called again after Shutdown.

Use as in the following example:

// application start Rox::Setup(DEFAULT_API_KEY) // application end Rox::Shutdown();

SetContext

Sets a global context. This context is available to all flag evaluations, in addition to the specific call context.

void SetContext(Context *context)

Fetch

Creates a network request for the latest configuration.

void Fetch()

Custom properties

The role of a custom property is to segment the audience and apply a set of flags for target groups defined by these properties.

Custom properties are any of the following types:

  • bool

  • int

  • double

  • semver

  • string

There are simple (direct) custom properties and calculated ones, using RoxContext to be more dynamic.

Simple (direct) custom properties

Use as in the following examples.

SetCustomProperty

Sets a custom property representing a T value.

template<typename T> void SetCustomProperty(const char *name, T value)
Parameter Modifier and type Description

name

const char *

The name of the property to create.

value

T

The value of the custom property depends on the type.

SetCustomSemverProperty

Sets a custom property representing a semver value.

voidSetCustomSemverProperty(const char *name, const char *value)
Parameter Modifier and type Description

name

const char *

The name of the property to create.

value

const char *

The semver value for the custom property.

Computed custom properties (using RoxContext)

Use as in the following examples.

SetCustomComputedProperty

Sets a computed T custom property on the Rox client. This is a computable T, with an object that generates the value for the property. The generator must be a delegate of type CustomPropertyGeneratorInterface.

template<typename T> void SetCustomComputedProperty(const char *name, CustomPropertyGeneratorInterface *generator)
Parameter Modifier and type Description

name

const char *

The name of the property to create.

generator

CustomPropertyGeneratorInterface *

A CustomPropertyGeneratorInterface class.

SetCustomComputedSemverProperty

Sets a computed semver custom property on the Rox client. This is a computable semver, with an object that generates the value for the property. The generator must be a delegate of type CustomPropertyGeneratorInterface.

void SetCustomComputedSemverProperty(const char *name, CustomPropertyGeneratorInterface *generator)
Parameter Modifier and type Description

name

string

The name of the property to create.

generator

CustomPropertyGeneratorInterface *

A CustomPropertyGeneratorInterface class.

Class Options

RoxOptions covers configuration options for the Rox client. For example, you can set the impression handler and fetch handler.

Instances of this class must be created using OptionsBuilder.

Set up a new Options object as in the following example. This options object sets the version, provides an impression handler, and calls the fetch handler.

class ImpressionHandler : public Rox::ImpressionHandlerInterface { public: explicit ImpressionHandler() {} public: void HandleImpression( RoxReportingValue *value, RoxExperiment *experiment, RoxContext *context) { // TODO: do something on impression } }; class ConfigurationFetchedHandler : public Rox::ConfigurationFetchedHandlerInterface { public: explicit ConfigurationFetchedHandler() { } public: void ConfigurationFetched(Rox::ConfigurationFetchedArgs *args) override { // TODO: do something on configuration fetched } }; class DynamicRulerHandler : public Rox::DynamicPropertiesRuleInterface { public: explicit DynamicRulerHandler() {} public: DynamicValue *Invoke(const char *propName, Context *context) { // TODO: return a DynanmicValue } }; int main(int argc, char **argv) { ImpressionHandler imp = ImpressionHandler(); ConfigurationFetchedHandler conf = ConfigurationFetchedHandler(); DynamicRulerHandler dynamicRule = DynamicRulerHandler(); Rox::Options *options = Rox::OptionsBuilder() .SetConfigurationFetchedHandler(&conf) .SetDevModeKey("your_dev_mode_secret") .SetDynamicPropertiesRule(&dynamicRule) .SetImpressionHandler(&imp) .SetRoxyUrl("http://localhost:4444") .SetVersion("2.1.0") .SetFetchInterval(100) .Build(); Rox::Setup("ROLLOUT_KEY", options); // do something... Rox::Shutdown(); }

Class OptionsBuilder

Use this Builder class to create a new Options instance.

SetVersion

Sets the version of the service running the CloudBees platform SDK. Use in the UI for targeting filtering.

OptionsBuilder &SetVersion(const char *version);

SetFetchInterval

Sets the polling interval for fetching configurations from the CloudBees platform storage service.

OptionsBuilder &SetFetchInterval(int intervalInSeconds)

SetConfigurationFetchedHandler

Sets the configuration event handler to actions after configurations are fetched.

OptionsBuilder &SetConfigurationFetchedHandler(ConfigurationFetchedHandlerInterface *handler)

SetImpressionHandler

Sets the impression event handler to add actions after an impression.

OptionsBuilder &SetImpressionHandler(ImpressionHandlerInterface *handler)

SetDynamicPropertiesRule

The dynamic custom property generator is called when an explicit custom property definition does not exist on the client side.

If you do not set the SetDynamicPropertiesRule, it activates the default function, which attempts to extract the value from the context by its name.

OptionsBuilder &SetDynamicPropertiesRule(DynamicPropertiesRuleInterface *rule)
if (context != NULL) { return rox_context_get(context, prop_name); } return NULL;

Class DynamicPropertiesRuleInterface

Creates a custom dynamic property rule by overriding this class.

Invoke

Use as follows:

virtual DynamicValue *Invoke(const char *propName, Context *context) = 0

SetRoxyUrl

A roxy URL.

OptionsBuilder &SetRoxyUrl(const char *roxy_url)

SetDevModeKey

Sets the dev mode secret.

OptionsBuilder &SetDevModeKey(const char *devModeKey)

Build

Creates the options object with all set properties.

Options *Build()

Class Flag

Use as in the following examples.

GetName

Returns the flag name.

const char *GetName()

Create

Creates a flag with a default value.

static Flag *Create(const char *name, bool defaultValue = false)

IsEnabled

Returns the current value of the feature flag, or the default if no value is set.

bool IsEnabled(Context *context = nullptr)

Class String

String is a feature flag containing string values.

GetName

Returns the flag name.

const char *GetName()

GetValue

Returns the current value of the feature flag, or the default if no value is set.

char *GetValue(Context *context = nullptr)

Create

Creates a String with a default value and options.

static Flag *Create(const char *name, bool defaultValue = false) static String *Create(const char *name, const char *defaultValue, const std::vector<std::string> &options);

Class Int

Int is a feature flag containing integer values.

GetName

Returns the flag name.

const char *GetName()

GetValue

Returns the current value of the feature flag, or the default if no value is set.

int GetValue(Context *context = nullptr)

Create

Creates a Int with a default value and options.

static Int *Create(const char *name, int defaultValue) static Int *Create(const char *name, int defaultValue, const std::vector<int> &options);

Class Double

Double is a feature flag containing double precision values.

GetName

Returns the flag name.

const char *GetName()

GetValue

Returns the current value of the feature flag, or the default if no value is set.

double GetValue(Context *context = nullptr)

Create

Create a Double with default value and options.

static Double *Create(const char *name, double defaultValue) static Double *Create(const char *name, double defaultValue, const std::vector<double> &options);

Class Context

Use the context class to pass data to the feature flag evaluation. This object is used by the registered CustomProperties to evaluate the experiment expression and return the value. Create a context using the ContextBuilder.

Class ContextBuilder

The following are simple constructors.

ContextBuilder()

AddBoolValue

Adds a bool value to the name key in the context.

ContextBuilder &AddBoolValue(const char *name, bool value)

AddIntValue

Adds an int value to the name key in the context.

ContextBuilder &AddIntValue(const char *name, int value)

AddDoubleValue

Adds a double value to the name key in the context.

ContextBuilder &AddDoubleValue(const char *name, double value)

AddStringValue

Adds a string value to the name key in the context.

ContextBuilder &AddStringValue(const char *name, const char *value)

AddUndefined

Adds an undefined value to the name key in the context.

ContextBuilder &AddUndefined(const char *name)

AddNull

Adds a NULL value to the name key in the context.

ContextBuilder &AddNull(const char *name)

Build

Builds the Context to use in the evaluation of Flag and Variant.

Context *Build()

Using ConfigurationFetchedHandler

Use SetConfigurationFetchedHandler`to write a handler for after a new configurations request. To do so, implement `ConfigurationFetchedHandlerInterface.

Use as follows:

virtual void ConfigurationFetched(ConfigurationFetchedArgs *args) = 0

For ConfigurationFetchedArgs, refer to RoxConfigurationFetchedArgs in the C SDK reference.

Using ImpressionHandler

To use ImpressionHandler, implement the class ImpressionHandlerInterface.

virtual void HandleImpression(ReportingValue *value, Experiment *experiment, Context *context) = 0

DynamicApi

An alternative way to evaluate flags and variants by name without having a static container. The dynamic API creates flags as if they were registered, including sending them to the UI.

Create

Creates a dynamicApi, the proxy to all dynamic flag and variant evaluations.

static DynamicApi *Create()

IsEnabled

Evaluates a feature flag by its name and context. If no experiment is set via the UI, the default_value is returned.

bool IsEnabled(const char *name, bool default_value = false, Context *context = nullptr)

GetString/GetInt/GetDouble - obtain flag value

Evaluates a feature flag by its name and context. Options are sent to the dashboard to allow an easy pick in the experiment. If no experiment is set via the UI, the default_value is returned.

char *GetString(const char *name, char *default_value = nullptr, Context *context = nullptr); char *GetString(const char *name, char *default_value, const std::vector<std::string> &options, Context *context); int GetInt(const char *name, int default_value, Context *context = nullptr) int GetInt(const char *name, int default_value, const std::vector<int> &options Context *context) double GetDouble(const char *name, double default_value, Context *context = nullptr); double GetDouble(const char *name, double default_value, const std::vector<double> &options, Context *context);

Logging

Logging assists you in debugging in case a flag behaves unexpectedly.

If no logging is set, default is used, which prints to stdout errors level logs.

There are two methods to control logging:

SetLogLevel

To use the default logging, with a different log level.

static void SetLogLevel(LogLevel logLevel)

SetLogMessageHandler

To use a customized logger, provide a class that implements LogMessageHandlerInterface.

static void SetLogMessageHandler(LogMessageHandlerInterface *handler)

Class LogMessageHandlerInterface

Use as follows:

HandleLogMessage

The customized logging handler.

virtual void HandleLogMessage(LogMessage *message) = 0

C++ is a C wrapper.

Please refer to the C SDK reference, as some structs have a matching struct without the Rox prefix, for example, RoxDynamicValue ⇒ C++'s DynamicValue.