diff --git a/core-api/src/main/java/com/optimizely/ab/Optimizely.java b/core-api/src/main/java/com/optimizely/ab/Optimizely.java index 12b9f33d1..5f41bcd6e 100644 --- a/core-api/src/main/java/com/optimizely/ab/Optimizely.java +++ b/core-api/src/main/java/com/optimizely/ab/Optimizely.java @@ -27,6 +27,7 @@ import com.optimizely.ab.event.*; import com.optimizely.ab.event.internal.*; import com.optimizely.ab.event.internal.payload.EventBatch; +import com.optimizely.ab.internal.NotificationRegistry; import com.optimizely.ab.notification.*; import com.optimizely.ab.odp.*; import com.optimizely.ab.optimizelyconfig.OptimizelyConfig; @@ -124,10 +125,15 @@ private Optimizely(@Nonnull EventHandler eventHandler, if (odpManager != null) { odpManager.getEventManager().start(); - if (getProjectConfig() != null) { + if (projectConfigManager.getCachedConfig() != null) { updateODPSettings(); } - addUpdateConfigNotificationHandler(configNotification -> { updateODPSettings(); }); + if (projectConfigManager.getSDKKey() != null) { + NotificationRegistry.getInternalNotificationCenter(projectConfigManager.getSDKKey()). + addNotificationHandler(UpdateConfigNotification.class, + configNotification -> { updateODPSettings(); }); + } + } } @@ -153,6 +159,8 @@ public void close() { tryClose(eventProcessor); tryClose(eventHandler); tryClose(projectConfigManager); + notificationCenter.clearAllNotificationListeners(); + NotificationRegistry.clearNotificationCenterRegistry(projectConfigManager.getSDKKey()); if (odpManager != null) { tryClose(odpManager); } @@ -1477,8 +1485,8 @@ public void identifyUser(@Nonnull String userId) { } private void updateODPSettings() { - if (odpManager != null && getProjectConfig() != null) { - ProjectConfig projectConfig = getProjectConfig(); + ProjectConfig projectConfig = projectConfigManager.getCachedConfig(); + if (odpManager != null && projectConfig != null) { odpManager.updateSettings(projectConfig.getHostForODP(), projectConfig.getPublicKeyForODP(), projectConfig.getAllSegments()); } } diff --git a/core-api/src/main/java/com/optimizely/ab/config/AtomicProjectConfigManager.java b/core-api/src/main/java/com/optimizely/ab/config/AtomicProjectConfigManager.java index fa1f4bd62..336d33c0e 100644 --- a/core-api/src/main/java/com/optimizely/ab/config/AtomicProjectConfigManager.java +++ b/core-api/src/main/java/com/optimizely/ab/config/AtomicProjectConfigManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019, Optimizely and contributors + * Copyright 2019, 2023, Optimizely and contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,21 @@ public ProjectConfig getConfig() { return projectConfigReference.get(); } + /** + * Access to current cached project configuration. + * + * @return {@link ProjectConfig} + */ + @Override + public ProjectConfig getCachedConfig() { + return projectConfigReference.get(); + } + + @Override + public String getSDKKey() { + return null; + } + public void setConfig(ProjectConfig projectConfig) { projectConfigReference.set(projectConfig); } diff --git a/core-api/src/main/java/com/optimizely/ab/config/PollingProjectConfigManager.java b/core-api/src/main/java/com/optimizely/ab/config/PollingProjectConfigManager.java index b03aeabc0..4ad34e7a8 100644 --- a/core-api/src/main/java/com/optimizely/ab/config/PollingProjectConfigManager.java +++ b/core-api/src/main/java/com/optimizely/ab/config/PollingProjectConfigManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019-2020, Optimizely and contributors + * Copyright 2019-2020, 2023, Optimizely and contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ */ package com.optimizely.ab.config; +import com.optimizely.ab.internal.NotificationRegistry; import com.optimizely.ab.notification.NotificationCenter; import com.optimizely.ab.notification.UpdateConfigNotification; import com.optimizely.ab.optimizelyconfig.OptimizelyConfig; @@ -56,6 +57,7 @@ public abstract class PollingProjectConfigManager implements ProjectConfigManage private final CountDownLatch countDownLatch = new CountDownLatch(1); + private volatile String sdkKey; private volatile boolean started; private ScheduledFuture scheduledFuture; @@ -84,6 +86,16 @@ public PollingProjectConfigManager(long period, TimeUnit timeUnit, long blocking protected abstract ProjectConfig poll(); + /** + * Access to current cached project configuration, This is to make sure that config returns without any wait, even if it is null. + * + * @return {@link ProjectConfig} + */ + @Override + public ProjectConfig getCachedConfig() { + return currentProjectConfig.get(); + } + /** * Only allow the ProjectConfig to be set to a non-null value, if and only if the value has not already been set. * @param projectConfig @@ -109,6 +121,13 @@ void setConfig(ProjectConfig projectConfig) { currentProjectConfig.set(projectConfig); currentOptimizelyConfig.set(new OptimizelyConfigService(projectConfig).getConfig()); countDownLatch.countDown(); + + if (sdkKey == null) { + sdkKey = projectConfig.getSdkKey(); + } + if (sdkKey != null) { + NotificationRegistry.getInternalNotificationCenter(sdkKey).send(SIGNAL); + } notificationCenter.send(SIGNAL); } @@ -150,6 +169,11 @@ public OptimizelyConfig getOptimizelyConfig() { return currentOptimizelyConfig.get(); } + @Override + public String getSDKKey() { + return this.sdkKey; + } + public synchronized void start() { if (started) { logger.warn("Manager already started."); @@ -189,6 +213,10 @@ public synchronized void close() { started = false; } + protected void setSdkKey(String sdkKey) { + this.sdkKey = sdkKey; + } + public boolean isRunning() { return started; } diff --git a/core-api/src/main/java/com/optimizely/ab/config/ProjectConfigManager.java b/core-api/src/main/java/com/optimizely/ab/config/ProjectConfigManager.java index 1a1b2f4bc..002acae55 100644 --- a/core-api/src/main/java/com/optimizely/ab/config/ProjectConfigManager.java +++ b/core-api/src/main/java/com/optimizely/ab/config/ProjectConfigManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019, Optimizely and contributors + * Copyright 2019, 2023, Optimizely and contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ */ package com.optimizely.ab.config; +import javax.annotation.Nullable; + public interface ProjectConfigManager { /** * Implementations of this method should block until a datafile is available. @@ -23,5 +25,24 @@ public interface ProjectConfigManager { * @return ProjectConfig */ ProjectConfig getConfig(); + + /** + * Implementations of this method should not block until a datafile is available, instead return current cached project configuration. + * return null if ProjectConfig is not ready at the moment. + * + * NOTE: To use ODP segments, implementation of this function is required to return current project configuration. + * @return ProjectConfig + */ + @Nullable + ProjectConfig getCachedConfig(); + + /** + * Implementations of this method should return SDK key. If there is no SDKKey then it should return null. + * + * NOTE: To update ODP segments configuration via polling, it is required to return sdkKey. + * @return String + */ + @Nullable + String getSDKKey(); } diff --git a/core-api/src/main/java/com/optimizely/ab/internal/NotificationRegistry.java b/core-api/src/main/java/com/optimizely/ab/internal/NotificationRegistry.java new file mode 100644 index 000000000..92d0c6d38 --- /dev/null +++ b/core-api/src/main/java/com/optimizely/ab/internal/NotificationRegistry.java @@ -0,0 +1,52 @@ +/** + * + * Copyright 2023, Optimizely + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.optimizely.ab.internal; + +import com.optimizely.ab.notification.NotificationCenter; + +import javax.annotation.Nonnull; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class NotificationRegistry { + private final static Map _notificationCenters = new ConcurrentHashMap<>(); + + private NotificationRegistry() + { + } + + public static NotificationCenter getInternalNotificationCenter(@Nonnull String sdkKey) + { + NotificationCenter notificationCenter = null; + if (sdkKey != null) { + if (_notificationCenters.containsKey(sdkKey)) { + notificationCenter = _notificationCenters.get(sdkKey); + } else { + notificationCenter = new NotificationCenter(); + _notificationCenters.put(sdkKey, notificationCenter); + } + } + return notificationCenter; + } + + public static void clearNotificationCenterRegistry(@Nonnull String sdkKey) { + if (sdkKey != null) { + _notificationCenters.remove(sdkKey); + } + } + +} diff --git a/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java b/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java index 9fd3dd675..705ce1cb6 100644 --- a/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java +++ b/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2016-2022, Optimizely, Inc. and contributors * + * Copyright 2016-2023, Optimizely, Inc. and contributors * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * @@ -119,6 +119,23 @@ public static Collection data() throws IOException { public OptimizelyRule optimizelyBuilder = new OptimizelyRule(); public EventHandlerRule eventHandler = new EventHandlerRule(); + public ProjectConfigManager projectConfigManagerReturningNull = new ProjectConfigManager() { + @Override + public ProjectConfig getConfig() { + return null; + } + + @Override + public ProjectConfig getCachedConfig() { + return null; + } + + @Override + public String getSDKKey() { + return null; + } + }; + @Rule @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") public RuleChain ruleChain = RuleChain.outerRule(thrown) @@ -4505,13 +4522,13 @@ public void isValidReturnsTrueWhenClientIsValid() throws Exception { @Test public void testGetNotificationCenter() { - Optimizely optimizely = optimizelyBuilder.withConfigManager(() -> null).build(); + Optimizely optimizely = optimizelyBuilder.withConfigManager(projectConfigManagerReturningNull).build(); assertEquals(optimizely.notificationCenter, optimizely.getNotificationCenter()); } @Test public void testAddTrackNotificationHandler() { - Optimizely optimizely = optimizelyBuilder.withConfigManager(() -> null).build(); + Optimizely optimizely = optimizelyBuilder.withConfigManager(projectConfigManagerReturningNull).build(); NotificationManager manager = optimizely.getNotificationCenter() .getNotificationManager(TrackNotification.class); @@ -4521,7 +4538,7 @@ public void testAddTrackNotificationHandler() { @Test public void testAddDecisionNotificationHandler() { - Optimizely optimizely = optimizelyBuilder.withConfigManager(() -> null).build(); + Optimizely optimizely = optimizelyBuilder.withConfigManager(projectConfigManagerReturningNull).build(); NotificationManager manager = optimizely.getNotificationCenter() .getNotificationManager(DecisionNotification.class); @@ -4531,7 +4548,7 @@ public void testAddDecisionNotificationHandler() { @Test public void testAddUpdateConfigNotificationHandler() { - Optimizely optimizely = optimizelyBuilder.withConfigManager(() -> null).build(); + Optimizely optimizely = optimizelyBuilder.withConfigManager(projectConfigManagerReturningNull).build(); NotificationManager manager = optimizely.getNotificationCenter() .getNotificationManager(UpdateConfigNotification.class); @@ -4541,7 +4558,7 @@ public void testAddUpdateConfigNotificationHandler() { @Test public void testAddLogEventNotificationHandler() { - Optimizely optimizely = optimizelyBuilder.withConfigManager(() -> null).build(); + Optimizely optimizely = optimizelyBuilder.withConfigManager(projectConfigManagerReturningNull).build(); NotificationManager manager = optimizely.getNotificationCenter() .getNotificationManager(LogEvent.class); @@ -4713,24 +4730,6 @@ public void initODPManagerWithProjectConfig() throws IOException { verify(mockODPManager, times(1)).updateSettings(any(), any(), any()); } - @Test - public void updateODPManagerWhenConfigUpdates() throws IOException { - ODPEventManager mockODPEventManager = mock(ODPEventManager.class); - ODPManager mockODPManager = mock(ODPManager.class); - NotificationCenter mockNotificationCenter = mock(NotificationCenter.class); - - Mockito.when(mockODPManager.getEventManager()).thenReturn(mockODPEventManager); - Optimizely.builder() - .withDatafile(validConfigJsonV4()) - .withNotificationCenter(mockNotificationCenter) - .withODPManager(mockODPManager) - .build(); - - verify(mockODPManager, times(1)).updateSettings(any(), any(), any()); - - Mockito.verify(mockNotificationCenter, times(1)).addNotificationHandler(any(), any()); - } - @Test public void sendODPEvent() { ProjectConfigManager mockProjectConfigManager = mock(ProjectConfigManager.class); diff --git a/core-api/src/test/java/com/optimizely/ab/config/PollingProjectConfigManagerTest.java b/core-api/src/test/java/com/optimizely/ab/config/PollingProjectConfigManagerTest.java index 390c9b874..130f8844a 100644 --- a/core-api/src/test/java/com/optimizely/ab/config/PollingProjectConfigManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/config/PollingProjectConfigManagerTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019-2021, Optimizely and contributors + * Copyright 2019-2021, 2023, Optimizely and contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ */ package com.optimizely.ab.config; +import com.optimizely.ab.internal.NotificationRegistry; import com.optimizely.ab.notification.NotificationCenter; import com.optimizely.ab.notification.UpdateConfigNotification; import org.junit.After; @@ -95,12 +96,14 @@ public void testBlockingGetConfig() throws Exception { testProjectConfigManager.release(); TimeUnit.MILLISECONDS.sleep(PROJECT_CONFIG_DELAY); assertEquals(projectConfig, testProjectConfigManager.getConfig()); + assertEquals(projectConfig.getSdkKey(), testProjectConfigManager.getSDKKey()); } @Test public void testBlockingGetConfigWithDefault() throws Exception { testProjectConfigManager.setConfig(projectConfig); assertEquals(projectConfig, testProjectConfigManager.getConfig()); + assertEquals(projectConfig.getSdkKey(), testProjectConfigManager.getSDKKey()); } @Test @@ -124,6 +127,7 @@ public void testGetConfigNotStartedDefault() throws Exception { testProjectConfigManager.close(); assertFalse(testProjectConfigManager.isRunning()); assertEquals(projectConfig, testProjectConfigManager.getConfig()); + assertEquals(projectConfig.getSdkKey(), testProjectConfigManager.getSDKKey()); } @Test @@ -210,11 +214,17 @@ public ProjectConfig poll() { @Test public void testUpdateConfigNotificationGetsTriggered() throws InterruptedException { - CountDownLatch countDownLatch = new CountDownLatch(1); + CountDownLatch countDownLatch = new CountDownLatch(2); + NotificationCenter registryDefaultNotificationCenter = NotificationRegistry.getInternalNotificationCenter("ValidProjectConfigV4"); + NotificationCenter userNotificationCenter = testProjectConfigManager.getNotificationCenter(); + assertNotEquals(registryDefaultNotificationCenter, userNotificationCenter); + testProjectConfigManager.getNotificationCenter() .getNotificationManager(UpdateConfigNotification.class) .addHandler(message -> {countDownLatch.countDown();}); - + NotificationRegistry.getInternalNotificationCenter("ValidProjectConfigV4") + .getNotificationManager(UpdateConfigNotification.class) + .addHandler(message -> {countDownLatch.countDown();}); assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS)); } @@ -271,5 +281,13 @@ public int getCount() { public void release() { countDownLatch.countDown(); } + + @Override + public String getSDKKey() { + if (projectConfig == null) { + return null; + } + return projectConfig.getSdkKey(); + } } } diff --git a/core-api/src/test/java/com/optimizely/ab/internal/NotificationRegistryTest.java b/core-api/src/test/java/com/optimizely/ab/internal/NotificationRegistryTest.java new file mode 100644 index 000000000..4f130a848 --- /dev/null +++ b/core-api/src/test/java/com/optimizely/ab/internal/NotificationRegistryTest.java @@ -0,0 +1,84 @@ +/** + * + * Copyright 2023, Optimizely + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.optimizely.ab.internal; + +import com.optimizely.ab.notification.NotificationCenter; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + + +public class NotificationRegistryTest { + + @SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION") + @Test + public void getNullNotificationCenterWhenSDKeyIsNull() { + String sdkKey = null; + NotificationCenter notificationCenter = NotificationRegistry.getInternalNotificationCenter(sdkKey); + assertNull(notificationCenter); + } + + @Test + public void getSameNotificationCenterWhenSDKKeyIsSameButNotNull() { + String sdkKey = "testSDkKey"; + NotificationCenter notificationCenter1 = NotificationRegistry.getInternalNotificationCenter(sdkKey); + NotificationCenter notificationCenter2 = NotificationRegistry.getInternalNotificationCenter(sdkKey); + assertEquals(notificationCenter1, notificationCenter2); + } + + @Test + public void getSameNotificationCenterWhenSDKKeyIsEmpty() { + String sdkKey1 = ""; + String sdkKey2 = ""; + NotificationCenter notificationCenter1 = NotificationRegistry.getInternalNotificationCenter(sdkKey1); + NotificationCenter notificationCenter2 = NotificationRegistry.getInternalNotificationCenter(sdkKey2); + assertEquals(notificationCenter1, notificationCenter2); + } + + @Test + public void getDifferentNotificationCenterWhenSDKKeyIsNotSame() { + String sdkKey1 = "testSDkKey1"; + String sdkKey2 = "testSDkKey2"; + NotificationCenter notificationCenter1 = NotificationRegistry.getInternalNotificationCenter(sdkKey1); + NotificationCenter notificationCenter2 = NotificationRegistry.getInternalNotificationCenter(sdkKey2); + Assert.assertNotEquals(notificationCenter1, notificationCenter2); + } + + @Test + public void clearRegistryNotificationCenterClearsOldNotificationCenter() { + String sdkKey1 = "testSDkKey1"; + NotificationCenter notificationCenter1 = NotificationRegistry.getInternalNotificationCenter(sdkKey1); + NotificationRegistry.clearNotificationCenterRegistry(sdkKey1); + NotificationCenter notificationCenter2 = NotificationRegistry.getInternalNotificationCenter(sdkKey1); + + Assert.assertNotEquals(notificationCenter1, notificationCenter2); + } + + @SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION") + @Test + public void clearRegistryNotificationCenterWillNotCauseExceptionIfPassedNullSDkKey() { + String sdkKey1 = "testSDkKey1"; + NotificationCenter notificationCenter1 = NotificationRegistry.getInternalNotificationCenter(sdkKey1); + NotificationRegistry.clearNotificationCenterRegistry(null); + NotificationCenter notificationCenter2 = NotificationRegistry.getInternalNotificationCenter(sdkKey1); + + Assert.assertEquals(notificationCenter1, notificationCenter2); + } +} diff --git a/core-httpclient-impl/src/main/java/com/optimizely/ab/OptimizelyFactory.java b/core-httpclient-impl/src/main/java/com/optimizely/ab/OptimizelyFactory.java index 37d56da03..1c6ee2820 100644 --- a/core-httpclient-impl/src/main/java/com/optimizely/ab/OptimizelyFactory.java +++ b/core-httpclient-impl/src/main/java/com/optimizely/ab/OptimizelyFactory.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019-2021, Optimizely + * Copyright 2019-2021, 2023, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.optimizely.ab; import com.optimizely.ab.config.HttpProjectConfigManager; +import com.optimizely.ab.config.ProjectConfig; import com.optimizely.ab.config.ProjectConfigManager; import com.optimizely.ab.event.AsyncEventHandler; import com.optimizely.ab.event.BatchEventProcessor; @@ -222,7 +223,22 @@ public static Optimizely newDefaultInstance() { public static Optimizely newDefaultInstance(String sdkKey) { if (sdkKey == null) { logger.error("Must provide an sdkKey, returning non-op Optimizely client"); - return newDefaultInstance(() -> null); + return newDefaultInstance(new ProjectConfigManager() { + @Override + public ProjectConfig getConfig() { + return null; + } + + @Override + public ProjectConfig getCachedConfig() { + return null; + } + + @Override + public String getSDKKey() { + return null; + } + }); } return newDefaultInstance(sdkKey, null); diff --git a/core-httpclient-impl/src/main/java/com/optimizely/ab/config/HttpProjectConfigManager.java b/core-httpclient-impl/src/main/java/com/optimizely/ab/config/HttpProjectConfigManager.java index cef13fdcd..4be1715d2 100644 --- a/core-httpclient-impl/src/main/java/com/optimizely/ab/config/HttpProjectConfigManager.java +++ b/core-httpclient-impl/src/main/java/com/optimizely/ab/config/HttpProjectConfigManager.java @@ -332,11 +332,10 @@ public HttpProjectConfigManager build(boolean defer) { .withEvictIdleConnections(evictConnectionIdleTimePeriod, evictConnectionIdleTimeUnit) .build(); } - + if (sdkKey == null) { + throw new NullPointerException("sdkKey cannot be null"); + } if (url == null) { - if (sdkKey == null) { - throw new NullPointerException("sdkKey cannot be null"); - } if (datafileAccessToken == null) { url = String.format(format, sdkKey); @@ -358,7 +357,7 @@ public HttpProjectConfigManager build(boolean defer) { blockingTimeoutPeriod, blockingTimeoutUnit, notificationCenter); - + httpProjectManager.setSdkKey(sdkKey); if (datafile != null) { try { ProjectConfig projectConfig = HttpProjectConfigManager.parseProjectConfig(datafile); diff --git a/core-httpclient-impl/src/test/java/com/optimizely/ab/OptimizelyFactoryTest.java b/core-httpclient-impl/src/test/java/com/optimizely/ab/OptimizelyFactoryTest.java index 07c2c0634..aaa3a67fa 100644 --- a/core-httpclient-impl/src/test/java/com/optimizely/ab/OptimizelyFactoryTest.java +++ b/core-httpclient-impl/src/test/java/com/optimizely/ab/OptimizelyFactoryTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019-2020, Optimizely + * Copyright 2019-2020, 2023, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,8 @@ import com.google.common.base.Charsets; import com.google.common.io.Resources; import com.optimizely.ab.config.HttpProjectConfigManager; +import com.optimizely.ab.config.ProjectConfig; +import com.optimizely.ab.config.ProjectConfigManager; import com.optimizely.ab.event.AsyncEventHandler; import com.optimizely.ab.event.BatchEventProcessor; import com.optimizely.ab.internal.PropertyUtils; @@ -260,17 +262,33 @@ public void newDefaultInstanceWithDatafileAccessTokenAndCustomHttpClient() throw optimizely = OptimizelyFactory.newDefaultInstance("sdk-key", datafileString, "auth-token", httpClient); assertTrue(optimizely.isValid()); } + public ProjectConfigManager projectConfigManagerReturningNull = new ProjectConfigManager() { + @Override + public ProjectConfig getConfig() { + return null; + } + + @Override + public ProjectConfig getCachedConfig() { + return null; + } + + @Override + public String getSDKKey() { + return null; + } + }; @Test public void newDefaultInstanceWithProjectConfig() throws Exception { - optimizely = OptimizelyFactory.newDefaultInstance(() -> null); + optimizely = OptimizelyFactory.newDefaultInstance(projectConfigManagerReturningNull); assertFalse(optimizely.isValid()); } @Test public void newDefaultInstanceWithProjectConfigAndNotificationCenter() throws Exception { NotificationCenter notificationCenter = new NotificationCenter(); - optimizely = OptimizelyFactory.newDefaultInstance(() -> null, notificationCenter); + optimizely = OptimizelyFactory.newDefaultInstance(projectConfigManagerReturningNull, notificationCenter); assertFalse(optimizely.isValid()); assertEquals(notificationCenter, optimizely.getNotificationCenter()); } @@ -278,7 +296,7 @@ public void newDefaultInstanceWithProjectConfigAndNotificationCenter() throws Ex @Test public void newDefaultInstanceWithProjectConfigAndNotificationCenterAndEventHandler() { NotificationCenter notificationCenter = new NotificationCenter(); - optimizely = OptimizelyFactory.newDefaultInstance(() -> null, notificationCenter, logEvent -> {}); + optimizely = OptimizelyFactory.newDefaultInstance(projectConfigManagerReturningNull, notificationCenter, logEvent -> {}); assertFalse(optimizely.isValid()); assertEquals(notificationCenter, optimizely.getNotificationCenter()); } diff --git a/core-httpclient-impl/src/test/java/com/optimizely/ab/config/HttpProjectConfigManagerTest.java b/core-httpclient-impl/src/test/java/com/optimizely/ab/config/HttpProjectConfigManagerTest.java index c61a1f01a..9cbc0bb01 100644 --- a/core-httpclient-impl/src/test/java/com/optimizely/ab/config/HttpProjectConfigManagerTest.java +++ b/core-httpclient-impl/src/test/java/com/optimizely/ab/config/HttpProjectConfigManagerTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019, Optimizely + * Copyright 2019, 2023, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -129,6 +129,7 @@ public void testHttpGetByCustomUrl() throws Exception { projectConfigManager = builder() .withOptimizelyHttpClient(mockHttpClient) + .withSdkKey("custom-sdkKey") .withUrl(expected) .build(); @@ -207,6 +208,7 @@ public void testBuildDefer() throws Exception { .withOptimizelyHttpClient(mockHttpClient) .withSdkKey("sdk-key") .build(true); + assertEquals("sdk-key", projectConfigManager.getSDKKey()); } @Test