99import com .launchdarkly .sdk .LDValue ;
1010import com .launchdarkly .sdk .LDValueType ;
1111import com .launchdarkly .sdk .internal .http .HttpHelpers ;
12+ import com .launchdarkly .sdk .server .integrations .EnvironmentMetadata ;
13+ import com .launchdarkly .sdk .server .integrations .Hook ;
14+ import com .launchdarkly .sdk .server .integrations .Plugin ;
15+ import com .launchdarkly .sdk .server .integrations .SdkMetadata ;
1216import com .launchdarkly .sdk .server .interfaces .BigSegmentStoreStatusProvider ;
1317import com .launchdarkly .sdk .server .interfaces .BigSegmentsConfiguration ;
1418import com .launchdarkly .sdk .server .interfaces .DataSourceStatusProvider ;
3034import java .io .UnsupportedEncodingException ;
3135import java .security .InvalidKeyException ;
3236import java .security .NoSuchAlgorithmException ;
37+ import java .util .ArrayList ;
38+ import java .util .Collections ;
39+ import java .util .List ;
3340import java .util .concurrent .Executors ;
3441import java .util .concurrent .Future ;
3542import java .util .concurrent .ScheduledExecutorService ;
@@ -206,13 +213,33 @@ public LDClient(String sdkKey, LDConfig config) {
206213
207214 EvaluatorInterface evaluator = new InputValidatingEvaluator (dataStore , bigSegmentStoreWrapper , eventProcessor , evaluationLogger );
208215
216+ // build environment metadata for plugins
217+ SdkMetadata sdkMetadata ;
218+ if (config .wrapperInfo == null ) {
219+ sdkMetadata = new SdkMetadata ("JavaClient" , Version .SDK_VERSION );
220+ } else {
221+ sdkMetadata = new SdkMetadata ("JavaClient" , Version .SDK_VERSION , config .wrapperInfo .getWrapperName (), config .wrapperInfo .getWrapperVersion ());
222+ }
223+ EnvironmentMetadata environmentMetadata = new EnvironmentMetadata (config .applicationInfo , sdkMetadata , sdkKey );
224+
225+ // add plugin hooks
226+ List <Hook > allHooks = new ArrayList <>(config .hooks .getHooks ());
227+ for (Plugin plugin : config .plugins .getPlugins ()) {
228+ try {
229+ allHooks .addAll (plugin .getHooks (environmentMetadata ));
230+ } catch (Exception e ) {
231+ baseLogger .error ("Exception thrown getting hooks for plugin " + plugin .getMetadata ().getName () + ". Unable to get hooks, plugin will not be registered." );
232+ }
233+ }
234+ allHooks = Collections .unmodifiableList (allHooks );
235+
209236 // decorate evaluator with hooks if hooks were provided
210- if (config . hooks . getHooks () .isEmpty ()) {
237+ if (allHooks .isEmpty ()) {
211238 this .evaluator = evaluator ;
212239 this .migrationEvaluator = new MigrationStageEnforcingEvaluator (evaluator , evaluationLogger );
213240 } else {
214- this .evaluator = new EvaluatorWithHooks (evaluator , config . hooks . getHooks () , this .baseLogger .subLogger (Loggers .HOOKS_LOGGER_NAME ));
215- this .migrationEvaluator = new EvaluatorWithHooks (new MigrationStageEnforcingEvaluator (evaluator , evaluationLogger ), config . hooks . getHooks () , this .baseLogger .subLogger (Loggers .HOOKS_LOGGER_NAME ));
241+ this .evaluator = new EvaluatorWithHooks (evaluator , allHooks , this .baseLogger .subLogger (Loggers .HOOKS_LOGGER_NAME ));
242+ this .migrationEvaluator = new EvaluatorWithHooks (new MigrationStageEnforcingEvaluator (evaluator , evaluationLogger ), allHooks , this .baseLogger .subLogger (Loggers .HOOKS_LOGGER_NAME ));
216243 }
217244
218245 this .flagChangeBroadcaster = EventBroadcasterImpl .forFlagChangeEvents (sharedExecutor , baseLogger );
@@ -236,6 +263,15 @@ public LDClient(String sdkKey, LDConfig config) {
236263 this .dataSource = config .dataSource .build (context .withDataSourceUpdateSink (dataSourceUpdates ));
237264 this .dataSourceStatusProvider = new DataSourceStatusProviderImpl (dataSourceStatusNotifier , dataSourceUpdates );
238265
266+ // register plugins as soon as possible after client is valid
267+ for (Plugin plugin : config .plugins .getPlugins ()) {
268+ try {
269+ plugin .register (this , environmentMetadata );
270+ } catch (Exception e ) {
271+ baseLogger .error ("Exception thrown registering plugin " + plugin .getMetadata ().getName () + ". Plugin will not be registered." );
272+ }
273+ }
274+
239275 Future <Void > startFuture = dataSource .start ();
240276 if (!config .startWait .isZero () && !config .startWait .isNegative ()) {
241277 if (!(dataSource instanceof ComponentsImpl .NullDataSource )) {
0 commit comments