diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..63b48e2c --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,101 @@ +name: Publish to Maven Central + +on: + push: + branches: [ "main" ] + +jobs: + publish: + runs-on: ubuntu-latest + if: github.repository == 'ReforgeHQ/sdk-java' + + steps: + - name: "Checkout" + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'temurin' + cache: maven + + - name: Extract version from pom.xml + id: extract_version + run: | + VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Current version: $VERSION" + + - name: Check if version exists in Maven Central + id: version_check + run: | + VERSION=${{ steps.extract_version.outputs.version }} + echo "Checking if version $VERSION exists in Maven Central..." + + # Check if version exists (non-snapshot versions only) + if [[ "$VERSION" != *-SNAPSHOT ]]; then + HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://repo1.maven.org/maven2/com/reforge/sdk-parent/$VERSION/sdk-parent-$VERSION.pom") + if [ "$HTTP_STATUS" = "200" ]; then + echo "Version $VERSION already exists in Maven Central" + echo "should_publish=false" >> $GITHUB_OUTPUT + else + echo "Version $VERSION does not exist in Maven Central" + echo "should_publish=true" >> $GITHUB_OUTPUT + fi + else + echo "Snapshot version detected, skipping publication" + echo "should_publish=false" >> $GITHUB_OUTPUT + fi + + - name: Import GPG key + if: steps.version_check.outputs.should_publish == 'true' + uses: crazy-max/ghaction-import-gpg@v5 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + + - name: Configure Maven settings + if: steps.version_check.outputs.should_publish == 'true' + uses: whelk-io/maven-settings-xml-action@v20 + with: + repositories: | + [ + { + "id": "ossrh", + "url": "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + } + ] + servers: | + [ + { + "id": "ossrh", + "username": "${{ secrets.OSSRH_USERNAME }}", + "password": "${{ secrets.OSSRH_TOKEN }}" + } + ] + + - name: Publish to Maven Central + if: steps.version_check.outputs.should_publish == 'true' + run: | + echo "Publishing version ${{ steps.extract_version.outputs.version }} to Maven Central..." + mvn clean deploy -P release --no-transfer-progress + env: + REFORGE_INTEGRATION_TEST_SDK_KEY: ${{ secrets.REFORGE_INTEGRATION_TEST_SDK_KEY }} + REFORGE_SDK_KEY: 1-fake-apikey + REFORGE_INTEGRATION_TEST_ENCRYPTION_KEY: "c87ba22d8662282abe8a0e4651327b579cb64a454ab0f4c170b45b15f049a221" + PREFAB_INTEGRATION_TEST_ENCRYPTION_KEY: "c87ba22d8662282abe8a0e4651327b579cb64a454ab0f4c170b45b15f049a221" + NOT_A_NUMBER: "not a number" + IS_A_NUMBER: 1234 + + - name: Create GitHub Release + if: steps.version_check.outputs.should_publish == 'true' + uses: ncipollo/create-release@v1 + with: + tag: "v${{ steps.extract_version.outputs.version }}" + name: "Release v${{ steps.extract_version.outputs.version }}" + generateReleaseNotes: true + draft: false + prerelease: ${{ contains(steps.extract_version.outputs.version, 'RC') || contains(steps.extract_version.outputs.version, 'beta') || contains(steps.extract_version.outputs.version, 'alpha') }} \ No newline at end of file diff --git a/sdk/src/main/java/com/reforge/sdk/Options.java b/sdk/src/main/java/com/reforge/sdk/Options.java index d04d8275..bde4d8e2 100644 --- a/sdk/src/main/java/com/reforge/sdk/Options.java +++ b/sdk/src/main/java/com/reforge/sdk/Options.java @@ -2,7 +2,6 @@ import com.google.common.collect.ImmutableSet; import com.reforge.sdk.config.ConfigChangeListener; -import com.reforge.sdk.config.logging.LogLevelChangeListener; import com.reforge.sdk.context.ContextSetReadable; import com.reforge.sdk.context.ContextStore; import com.reforge.sdk.internal.Internal; @@ -47,11 +46,8 @@ public enum CollectContextMode { PERIODIC_EXAMPLE, } - private static final String DEFAULT_ENV = "default"; - private String apikey; private String configOverrideDir; - private List prefabEnvs = new ArrayList<>(); private Datasources datasources = Datasources.ALL; private int initializationTimeoutSec = 10; private OnInitializationFailure onInitializationFailure = OnInitializationFailure.RAISE; @@ -61,8 +57,6 @@ public enum CollectContextMode { private final Set changeListenerSet = new HashSet<>(); - private final Set logLevelChangeListeners = new HashSet<>(); - private boolean evaluatedConfigKeyUploadEnabled = true; private boolean collectEvaluationSummaries = true; @@ -170,23 +164,6 @@ public Options setStreamHosts(List streamHosts) { return this; } - public List getPrefabEnvs() { - return prefabEnvs; - } - - /** - * Set the prefab environment names in order of increasing precedence - * Files named with the pattern `.prefab.%s.config.yaml` are loaded first with `default` then the supplied envs, in order - * This means a key in an env named later in the list will override the same key earlier in the list - * Files are loaded from the classpath first, then from the configured override directory - * @param prefabEnvs - * @return this - */ - public Options setPrefabEnvs(List prefabEnvs) { - this.prefabEnvs = prefabEnvs; - return this; - } - public Datasources getPrefabDatasource() { return datasources; } @@ -283,13 +260,6 @@ public Options setCollectEvaluationSummaries(boolean collectEvaluationSummaries) return this; } - public List getAllPrefabEnvs() { - final List envs = new ArrayList<>(); - envs.add(DEFAULT_ENV); - envs.addAll(prefabEnvs); - return envs; - } - public String getApiKeyId() { return getApikey().split("\\-")[0]; } @@ -312,15 +282,6 @@ public Set getChangeListeners() { return ImmutableSet.copyOf(changeListenerSet); } - public Options addLogLevelChangeListener(LogLevelChangeListener configChangeListener) { - logLevelChangeListeners.add(configChangeListener); - return this; - } - - public Set getLogLevelChangeListeners() { - return ImmutableSet.copyOf(logLevelChangeListeners); - } - @Internal public Options setTelemetryListener(@Nullable TelemetryListener telemetryListener) { this.telemetryListener = telemetryListener; diff --git a/sdk/src/main/java/com/reforge/sdk/config/logging/AbstractLoggingListener.java b/sdk/src/main/java/com/reforge/sdk/config/logging/AbstractLoggingListener.java deleted file mode 100644 index 46a7f3f2..00000000 --- a/sdk/src/main/java/com/reforge/sdk/config/logging/AbstractLoggingListener.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.reforge.sdk.config.logging; - -import cloud.prefab.domain.Prefab.ConfigValue; -import cloud.prefab.domain.Prefab.ConfigValue.TypeCase; -import cloud.prefab.domain.Prefab.LogLevel; -import com.reforge.sdk.config.ConfigChangeEvent; -import com.reforge.sdk.config.ConfigChangeListener; -import java.util.Map; -import java.util.Optional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractLoggingListener - implements LogLevelChangeListener { - - public static final String LOG_LEVEL_PREFIX = "log-level"; - - protected final Logger LOG = LoggerFactory.getLogger(getClass()); - - protected abstract Map getValidLevels(); - - protected abstract void setDefaultLevel(Optional level); - - protected abstract void setLevel(String loggerName, Optional level); - - public static boolean keyIsLogLevel(String key) { - return key.startsWith(LOG_LEVEL_PREFIX); - } - - @Override - public final void onChange(LogLevelChangeEvent changeEvent) { - Optional level = changeEvent - .getNewLevel() - .map(newValue -> getValidLevels().get(newValue)); - String key = changeEvent.getLoggerName(); - if (key.equals(LOG_LEVEL_PREFIX)) { - setDefaultLevel(level); - LOG.info("Set default log level to '{}'", level.orElse(null)); - } else if (keyIsLogLevel(key)) { - String loggerName = key.substring(LOG_LEVEL_PREFIX.length() + 1); - setLevel(loggerName, level); - LOG.info("Set log level for '{}' to '{}'", loggerName, level.orElse(null)); - } else { - LOG.warn( - "Expected log level override to start with '{}', but was '{}'", - LOG_LEVEL_PREFIX, - key - ); - } - } -} diff --git a/sdk/src/main/java/com/reforge/sdk/config/logging/JavaUtilLoggingConfigListener.java b/sdk/src/main/java/com/reforge/sdk/config/logging/JavaUtilLoggingConfigListener.java deleted file mode 100644 index f2c9d266..00000000 --- a/sdk/src/main/java/com/reforge/sdk/config/logging/JavaUtilLoggingConfigListener.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.reforge.sdk.config.logging; - -import cloud.prefab.domain.Prefab.LogLevel; -import com.google.common.collect.ImmutableMap; -import com.reforge.sdk.config.ConfigChangeListener; -import java.util.Map; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Log levels require some translation: - * - FATAL -> SEVERE - * - ERROR -> SEVERE - * - WARN -> WARNING - * - DEBUG -> FINE - * - TRACE -> FINER - *

- * OFF, CONFIG, FINEST, and ALL are unsupported - */ -public class JavaUtilLoggingConfigListener extends AbstractLoggingListener { - - private static final LogLevelChangeListener INSTANCE = new JavaUtilLoggingConfigListener(); - - private static final String ROOT_LOGGER = ""; - - private static final Map LEVEL_MAP = ImmutableMap - .builder() - .put(LogLevel.FATAL, Level.SEVERE) - .put(LogLevel.ERROR, Level.SEVERE) - .put(LogLevel.WARN, Level.WARNING) - .put(LogLevel.INFO, Level.INFO) - .put(LogLevel.DEBUG, Level.FINE) - .put(LogLevel.TRACE, Level.FINER) - .build(); - - public static LogLevelChangeListener getInstance() { - return INSTANCE; - } - - private JavaUtilLoggingConfigListener() {} - - @Override - protected Map getValidLevels() { - return LEVEL_MAP; - } - - @Override - protected void setDefaultLevel(Optional level) { - setLevel(ROOT_LOGGER, level); - } - - @Override - protected void setLevel(String loggerName, Optional level) { - Logger logger = Logger.getLogger(loggerName); - logger.setLevel(level.orElse(null)); - } -} diff --git a/sdk/src/main/java/com/reforge/sdk/config/logging/LogLevelChangeEvent.java b/sdk/src/main/java/com/reforge/sdk/config/logging/LogLevelChangeEvent.java deleted file mode 100644 index 78b0cd48..00000000 --- a/sdk/src/main/java/com/reforge/sdk/config/logging/LogLevelChangeEvent.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.reforge.sdk.config.logging; - -import cloud.prefab.domain.Prefab; -import java.util.Optional; - -public class LogLevelChangeEvent { - - private final String loggerName; - - private final Optional previousLevel; - - private final Optional newLevel; - - public LogLevelChangeEvent( - String loggerName, - Optional previousLevel, - Optional newLevel - ) { - this.loggerName = loggerName; - this.previousLevel = previousLevel; - this.newLevel = newLevel; - } - - public String getLoggerName() { - return loggerName; - } - - public Optional getPreviousLevel() { - return previousLevel; - } - - public Optional getNewLevel() { - return newLevel; - } -} diff --git a/sdk/src/main/java/com/reforge/sdk/config/logging/LogLevelChangeListener.java b/sdk/src/main/java/com/reforge/sdk/config/logging/LogLevelChangeListener.java deleted file mode 100644 index e71304b7..00000000 --- a/sdk/src/main/java/com/reforge/sdk/config/logging/LogLevelChangeListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.reforge.sdk.config.logging; - -public interface LogLevelChangeListener { - void onChange(LogLevelChangeEvent changeEvent); -} diff --git a/sdk/src/main/java/com/reforge/sdk/internal/ConfigClientImpl.java b/sdk/src/main/java/com/reforge/sdk/internal/ConfigClientImpl.java index 0e8e8fba..af54a05c 100644 --- a/sdk/src/main/java/com/reforge/sdk/internal/ConfigClientImpl.java +++ b/sdk/src/main/java/com/reforge/sdk/internal/ConfigClientImpl.java @@ -13,9 +13,6 @@ import com.reforge.sdk.config.ConfigChangeEvent; import com.reforge.sdk.config.ConfigChangeListener; import com.reforge.sdk.config.Match; -import com.reforge.sdk.config.logging.AbstractLoggingListener; -import com.reforge.sdk.config.logging.LogLevelChangeEvent; -import com.reforge.sdk.config.logging.LogLevelChangeListener; import com.reforge.sdk.context.Context; import com.reforge.sdk.context.ContextSetReadable; import com.reforge.sdk.context.ContextStore; @@ -56,8 +53,7 @@ public class ConfigClientImpl implements ConfigClient { private static final Logger LOG = LoggerFactory.getLogger(ConfigClientImpl.class); - private static final String LOG_LEVEL_PREFIX_WITH_DOT = - AbstractLoggingListener.LOG_LEVEL_PREFIX + "."; + private static final String LOG_LEVEL_PREFIX_WITH_DOT = "log-level."; private final Options options; @@ -66,8 +62,6 @@ public class ConfigClientImpl implements ConfigClient { private final CountDownLatch initializedLatch = new CountDownLatch(1); private final Set configChangeListeners = Sets.newConcurrentHashSet(); - private final Set logLevelChangeListeners = Sets.newConcurrentHashSet(); - private final String uniqueClientId; private final ConcurrentHashMap loggerNameLookup = new ConcurrentHashMap<>(); @@ -104,7 +98,6 @@ public ConfigClientImpl(Sdk baseClient, ConfigChangeListener... listeners) { ); configChangeListeners.addAll(baseClient.getOptions().getChangeListeners()); configChangeListeners.addAll(Arrays.asList(listeners)); - logLevelChangeListeners.addAll(baseClient.getOptions().getLogLevelChangeListeners()); contextStore = options.getContextStore(); typedConfigImpl = new TypedConfigClientImpl(this); if (options.isLocalOnly()) { @@ -416,7 +409,6 @@ private void startStreaming(long highWaterMark) { private void finishInit(Source source) { final UpdatingConfigResolver.ChangeLists changes = updatingConfigResolver.update(); broadcastChanges(changes.getConfigChangeEvents()); - broadcastLogLevelChanges(changes.getLogLevelChangeEvents()); if (initializedLatch.getCount() > 0) { initializedLatch.countDown(); try { @@ -459,19 +451,6 @@ private void broadcastChanges(List changeEvents) { } } - private void broadcastLogLevelChanges(List changeEvents) { - for (LogLevelChangeListener listener : logLevelChangeListeners) { - for (LogLevelChangeEvent changeEvent : changeEvents) { - LOG.debug("Broadcasting loglevel change {} to {}", changeEvent, listener); - try { - listener.onChange(changeEvent); - } catch (Exception e) { - LOG.debug("Exception in loglevel change listener", e); - } - } - } - } - private void waitForInitialization() { try { if ( diff --git a/sdk/src/main/java/com/reforge/sdk/internal/ConfigLoader.java b/sdk/src/main/java/com/reforge/sdk/internal/ConfigLoader.java index efab20df..42593f77 100644 --- a/sdk/src/main/java/com/reforge/sdk/internal/ConfigLoader.java +++ b/sdk/src/main/java/com/reforge/sdk/internal/ConfigLoader.java @@ -11,7 +11,6 @@ import com.reforge.sdk.Options; import com.reforge.sdk.config.ConfigElement; import com.reforge.sdk.config.Provenance; -import com.reforge.sdk.config.logging.AbstractLoggingListener; import com.reforge.sdk.context.ContextSet; import com.reforge.sdk.context.ContextSetReadable; import java.io.BufferedReader; @@ -166,27 +165,7 @@ private void recomputeHighWaterMark() { } private ImmutableMap loadClasspathConfig() { - ImmutableMap.Builder builder = ImmutableMap.builder(); - if (!options.isLocalDatafileMode()) { - for (String env : options.getAllPrefabEnvs()) { - final String file = String.format(".prefab.%s.config.yaml", env); - - try ( - InputStream resourceAsStream = this.getClass() - .getClassLoader() - .getResourceAsStream(file) - ) { - if (resourceAsStream == null) { - LOG.warn("No default config file found {}", file); - } else { - loadFileTo(resourceAsStream, builder, ConfigClient.Source.CLASSPATH, file); - } - } catch (IOException e) { - throw new RuntimeException("Error loading config from file: " + file, e); - } - } - } - return builder.buildKeepingLast(); + return ImmutableMap.of(); } public static Prefab.ConfigValue configValueFromObj(String key, Object obj) { @@ -202,7 +181,7 @@ public static Prefab.ConfigValue configValueFromObj(String key, Object obj) { } else if (obj instanceof Double) { valueBuilder.setDouble((Double) obj); } else if (obj instanceof String) { - if (AbstractLoggingListener.keyIsLogLevel(key)) { + if (key.startsWith("log-level")) { valueBuilder.setLogLevel(LogLevel.valueOf(((String) obj).toUpperCase())); } else { valueBuilder.setString((String) obj); @@ -327,28 +306,7 @@ private ConfigElement toValue( } private ImmutableMap loadOverrideConfig() { - ImmutableMap.Builder builder = ImmutableMap.builder(); - if (!options.isLocalDatafileMode()) { - File dir = new File(options.getConfigOverrideDir()); - for (String env : options.getAllPrefabEnvs()) { - final String fileName = String.format(".prefab.%s.config.yaml", env); - File file = new File(dir, fileName); - - if (file.exists()) { - try (InputStream inputStream = new FileInputStream(file)) { - loadFileTo( - inputStream, - builder, - ConfigClient.Source.LOCAL_OVERRIDE, - file.getAbsolutePath() - ); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - } - return builder.buildKeepingLast(); + return ImmutableMap.of(); } private void loadFileTo( diff --git a/sdk/src/main/java/com/reforge/sdk/internal/ConfigRuleEvaluator.java b/sdk/src/main/java/com/reforge/sdk/internal/ConfigRuleEvaluator.java index d36bbfd9..57c0071f 100644 --- a/sdk/src/main/java/com/reforge/sdk/internal/ConfigRuleEvaluator.java +++ b/sdk/src/main/java/com/reforge/sdk/internal/ConfigRuleEvaluator.java @@ -9,7 +9,6 @@ import com.reforge.sdk.config.ConfigValueUtils; import com.reforge.sdk.config.EvaluatedCriterion; import com.reforge.sdk.config.Match; -import com.reforge.sdk.config.logging.AbstractLoggingListener; import java.time.Instant; import java.util.ArrayList; import java.util.Collection; @@ -49,7 +48,7 @@ public Optional getMatch(String key, LookupContext lookupContext) { final ConfigElement configElement = configStore.getElement(key); if (configElement == null) { // logging lookups generate a lot of misses so skip those - if (!key.startsWith(AbstractLoggingListener.LOG_LEVEL_PREFIX)) { + if (!key.startsWith("log-level")) { LOG.trace("No config value found for key {}", key); } return Optional.empty(); @@ -79,7 +78,7 @@ private Optional getMatch( ) { if (!configStore.containsKey(key)) { // logging lookups generate a lot of misses so skip those - if (!key.startsWith(AbstractLoggingListener.LOG_LEVEL_PREFIX)) { + if (!key.startsWith("log-level")) { LOG.trace("No config value found for key {}", key); } return Optional.empty(); diff --git a/sdk/src/main/java/com/reforge/sdk/internal/UpdatingConfigResolver.java b/sdk/src/main/java/com/reforge/sdk/internal/UpdatingConfigResolver.java index 34a1caa1..bf5846f1 100644 --- a/sdk/src/main/java/com/reforge/sdk/internal/UpdatingConfigResolver.java +++ b/sdk/src/main/java/com/reforge/sdk/internal/UpdatingConfigResolver.java @@ -1,14 +1,11 @@ package com.reforge.sdk.internal; -import static com.reforge.sdk.config.logging.AbstractLoggingListener.LOG_LEVEL_PREFIX; - import cloud.prefab.domain.Prefab; import com.google.common.collect.Maps; import com.reforge.sdk.ConfigClient; import com.reforge.sdk.config.ConfigChangeEvent; import com.reforge.sdk.config.Match; import com.reforge.sdk.config.Provenance; -import com.reforge.sdk.config.logging.LogLevelChangeEvent; import com.reforge.sdk.context.ContextSetReadable; import com.reforge.sdk.exceptions.ConfigValueException; import java.util.Collection; @@ -28,7 +25,6 @@ public class UpdatingConfigResolver { private final ConfigStoreImpl configStore; private final ConfigResolver configResolver; - private final AbstractConfigStoreDeltaCalculator logLevelValueDeltaCalculator; public UpdatingConfigResolver( ConfigLoader configLoader, @@ -37,17 +33,6 @@ public UpdatingConfigResolver( ) { this.configLoader = configLoader; this.configStoreConfigValueDeltaCalculator = configStoreConfigValueDeltaCalculator; - this.logLevelValueDeltaCalculator = - new AbstractConfigStoreDeltaCalculator<>() { - @Override - LogLevelChangeEvent createEvent( - String name, - Optional oldValue, - Optional newValue - ) { - return new LogLevelChangeEvent(name, oldValue, newValue); - } - }; this.configStore = new ConfigStoreImpl(); ConfigRuleEvaluator configRuleEvaluator = new ConfigRuleEvaluator( configStore, @@ -65,64 +50,30 @@ public static class ChangeLists { final List configChangeEvents; - final List logLevelChangeEvents; - - public ChangeLists( - List configChangeEvents, - List logLevelChangeEvents - ) { + public ChangeLists(List configChangeEvents) { this.configChangeEvents = configChangeEvents; - this.logLevelChangeEvents = logLevelChangeEvents; } public List getConfigChangeEvents() { return configChangeEvents; } - - public List getLogLevelChangeEvents() { - return logLevelChangeEvents; - } } public ChangeLists update() { // catch exceptions resolving, treat as absent // store the old map Map before = buildConfigByNameMap(); - Map logLevelsBefore = buildLogLevelValueMap(); - // load the new map makeLocal(); // build the new map Map after = buildConfigByNameMap(); - Map logLevelsAfter = buildLogLevelValueMap(); return new ChangeLists( - configStoreConfigValueDeltaCalculator.computeChangeEvents(before, after), - logLevelValueDeltaCalculator.computeChangeEvents(logLevelsBefore, logLevelsAfter) + configStoreConfigValueDeltaCalculator.computeChangeEvents(before, after) ); } - private Map buildLogLevelValueMap() { - return configStore - .entrySet() - .stream() - .filter(stringConfigElementEntry -> - stringConfigElementEntry.getValue().getConfig().getConfigType() == - Prefab.ConfigType.LOG_LEVEL || - stringConfigElementEntry.getKey().startsWith(LOG_LEVEL_PREFIX) - ) - .map(entry -> - safeResolve(entry.getKey()) - .map(cv -> Maps.immutableEntry(entry.getKey(), cv)) - .filter(resolvedEntry -> resolvedEntry.getValue().hasLogLevel()) - ) - .flatMap(Optional::stream) - .collect( - Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().getLogLevel()) - ); - } - private Map buildConfigByNameMap() { return configStore .entrySet() diff --git a/sdk/src/test/java/com/reforge/sdk/OptionsTest.java b/sdk/src/test/java/com/reforge/sdk/OptionsTest.java index f8fce025..782f60e8 100644 --- a/sdk/src/test/java/com/reforge/sdk/OptionsTest.java +++ b/sdk/src/test/java/com/reforge/sdk/OptionsTest.java @@ -34,18 +34,6 @@ public void testStreamDomain() { .isEqualTo(List.of("https://stream.staging-prefab.cloud")); } - @Test - public void testPrefabEnvs() { - Options options = new Options(); - - assertThat(options.getAllPrefabEnvs()).isEqualTo(List.of("default")); - - options = new Options().setPrefabEnvs(List.of("development", "jeff")); - - assertThat(options.getAllPrefabEnvs()) - .isEqualTo(List.of("default", "development", "jeff")); - } - @Test public void apiKeyIsTrimmed() { Options options = new Options(); diff --git a/sdk/src/test/java/com/reforge/sdk/config/TestData.java b/sdk/src/test/java/com/reforge/sdk/config/TestData.java index 5eda6f45..cff79571 100644 --- a/sdk/src/test/java/com/reforge/sdk/config/TestData.java +++ b/sdk/src/test/java/com/reforge/sdk/config/TestData.java @@ -24,8 +24,7 @@ public String getEnvironmentName() { public static Options getDefaultOptionsWithEnvName(String envName) { return new Options() .setPrefabDatasource(Options.Datasources.LOCAL_ONLY) - .setConfigOverrideDir("src/test/resources/override_directory") - .setPrefabEnvs(List.of(envName)); + .setConfigOverrideDir("src/test/resources/override_directory"); } /* diff --git a/sdk/src/test/java/com/reforge/sdk/config/logging/AbstractLoggingListenerTest.java b/sdk/src/test/java/com/reforge/sdk/config/logging/AbstractLoggingListenerTest.java deleted file mode 100644 index 756e91cf..00000000 --- a/sdk/src/test/java/com/reforge/sdk/config/logging/AbstractLoggingListenerTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.reforge.sdk.config.logging; - -import cloud.prefab.domain.Prefab; -import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; - -public abstract class AbstractLoggingListenerTest { - - protected abstract void reset(); - - protected String specificLoggerName() { - return "test.logger"; - } - - protected String otherLoggerName() { - return "other.logger"; - } - - protected LogLevelChangeEvent getDefaultLogLevelEvent(Prefab.LogLevel level) { - return buildLogLevelEvent( - AbstractLoggingListener.LOG_LEVEL_PREFIX, - Optional.of(level) - ); - } - - protected LogLevelChangeEvent getDefaultLogLevelEvent(Optional level) { - return buildLogLevelEvent(AbstractLoggingListener.LOG_LEVEL_PREFIX, level); - } - - protected LogLevelChangeEvent getSpecificLogLevelEvent( - String loggerName, - Prefab.LogLevel level - ) { - return getSpecificLogLevelEvent(loggerName, Optional.of(level)); - } - - protected LogLevelChangeEvent getSpecificLogLevelEvent( - String loggerName, - Optional level - ) { - return buildLogLevelEvent( - AbstractLoggingListener.LOG_LEVEL_PREFIX + "." + loggerName, - level - ); - } - - private LogLevelChangeEvent buildLogLevelEvent( - String key, - Optional levelMaybe - ) { - return new LogLevelChangeEvent(key, Optional.empty(), levelMaybe); - } - - @BeforeEach - public void doReset() { - reset(); - } -} diff --git a/sdk/src/test/java/com/reforge/sdk/config/logging/JavaUtilLoggingConfigListenerTest.java b/sdk/src/test/java/com/reforge/sdk/config/logging/JavaUtilLoggingConfigListenerTest.java deleted file mode 100644 index ab53c27c..00000000 --- a/sdk/src/test/java/com/reforge/sdk/config/logging/JavaUtilLoggingConfigListenerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.reforge.sdk.config.logging; - -import static org.assertj.core.api.Assertions.assertThat; - -import cloud.prefab.domain.Prefab; -import com.reforge.sdk.config.ConfigChangeEvent; -import com.reforge.sdk.internal.ConfigClientImpl; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import org.junit.jupiter.api.Test; - -public class JavaUtilLoggingConfigListenerTest extends AbstractLoggingListenerTest { - - @Override - protected void reset() { - LogManager.getLogManager().reset(); - } - - @Test - public void itSetsSpecificLogLevel() { - assertThat(Logger.getLogger(specificLoggerName()).isLoggable(Level.WARNING)).isTrue(); - assertThat(Logger.getLogger(specificLoggerName()).isLoggable(Level.INFO)).isTrue(); - assertThat(Logger.getLogger(otherLoggerName()).isLoggable(Level.WARNING)).isTrue(); - assertThat(Logger.getLogger(otherLoggerName()).isLoggable(Level.INFO)).isTrue(); - - JavaUtilLoggingConfigListener - .getInstance() - .onChange(getSpecificLogLevelEvent(specificLoggerName(), Prefab.LogLevel.WARN)); - - assertThat(Logger.getLogger(specificLoggerName()).isLoggable(Level.WARNING)).isTrue(); - assertThat(Logger.getLogger(specificLoggerName()).isLoggable(Level.INFO)).isFalse(); - assertThat(Logger.getLogger(otherLoggerName()).isLoggable(Level.WARNING)).isTrue(); - assertThat(Logger.getLogger(otherLoggerName()).isLoggable(Level.INFO)).isTrue(); - } - - @Test - public void itSetsDefaultLogLevel() { - assertThat(Logger.getLogger(specificLoggerName()).isLoggable(Level.WARNING)).isTrue(); - assertThat(Logger.getLogger(specificLoggerName()).isLoggable(Level.INFO)).isTrue(); - assertThat(Logger.getLogger(otherLoggerName()).isLoggable(Level.WARNING)).isTrue(); - assertThat(Logger.getLogger(otherLoggerName()).isLoggable(Level.INFO)).isTrue(); - - JavaUtilLoggingConfigListener - .getInstance() - .onChange(getDefaultLogLevelEvent(Prefab.LogLevel.WARN)); - - assertThat(Logger.getLogger(specificLoggerName()).isLoggable(Level.WARNING)).isTrue(); - assertThat(Logger.getLogger(specificLoggerName()).isLoggable(Level.INFO)).isFalse(); - - assertThat(Logger.getLogger(otherLoggerName()).isLoggable(Level.WARNING)).isTrue(); - assertThat(Logger.getLogger(otherLoggerName()).isLoggable(Level.INFO)).isFalse(); - } -} diff --git a/sdk/src/test/java/com/reforge/sdk/config/logging/LogLevelEventsTest.java b/sdk/src/test/java/com/reforge/sdk/config/logging/LogLevelEventsTest.java deleted file mode 100644 index cfee629d..00000000 --- a/sdk/src/test/java/com/reforge/sdk/config/logging/LogLevelEventsTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.reforge.sdk.config.logging; - -import static org.mockito.Mockito.verify; - -import cloud.prefab.domain.Prefab; -import com.google.common.collect.ImmutableMap; -import com.reforge.sdk.Sdk; -import com.reforge.sdk.config.TestData; -import java.util.Map; -import java.util.Optional; -import java.util.logging.Level; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -public class LogLevelEventsTest { - - // This tests that a given prefab on-disk configuration results in expected calls to the setDefaultLevel and setLevel methods - - @Spy - TestListener testListener; - - @Test - void itGetsSpecificLevelMessage() { - try ( - Sdk sdk = new Sdk( - TestData - .getDefaultOptionsWithEnvName( - TestData.TestDataConfigSet.SPECIFIC_LOGGING.getEnvironmentName() - ) - .addLogLevelChangeListener(testListener) - ) - ) { - sdk.configClient(); - verify(testListener).setLevel("test.logger", Optional.of(Level.WARNING)); - } - } - - @Test - void itGetsDefaultLevelMessage() { - try ( - Sdk sdk = new Sdk( - TestData - .getDefaultOptionsWithEnvName( - TestData.TestDataConfigSet.DEFAULT_LOGGING.getEnvironmentName() - ) - .addLogLevelChangeListener(testListener) - ) - ) { - sdk.configClient(); - verify(testListener).setDefaultLevel(Optional.of(Level.WARNING)); - } - } - - private static class TestListener extends AbstractLoggingListener { - - @Override - protected Map getValidLevels() { - return LEVEL_MAP; - } - - @Override - protected void setDefaultLevel(Optional level) {} - - @Override - protected void setLevel(String loggerName, Optional level) {} - - private static final Map LEVEL_MAP = ImmutableMap - .builder() - .put(Prefab.LogLevel.FATAL, Level.SEVERE) - .put(Prefab.LogLevel.ERROR, Level.SEVERE) - .put(Prefab.LogLevel.WARN, Level.WARNING) - .put(Prefab.LogLevel.INFO, Level.INFO) - .put(Prefab.LogLevel.DEBUG, Level.FINE) - .put(Prefab.LogLevel.TRACE, Level.FINER) - .build(); - } -} diff --git a/sdk/src/test/java/com/reforge/sdk/internal/ConfigClientImplTest.java b/sdk/src/test/java/com/reforge/sdk/internal/ConfigClientImplTest.java index 9d3c1827..28ac2ddd 100644 --- a/sdk/src/test/java/com/reforge/sdk/internal/ConfigClientImplTest.java +++ b/sdk/src/test/java/com/reforge/sdk/internal/ConfigClientImplTest.java @@ -71,70 +71,6 @@ void initializationUnlock() { assertThat(configClient.get("key")).isNotPresent(); } - @Test - void broadcast() { - final Sdk baseClient = new Sdk( - new Options() - .setApikey("0-P1-E1-SDK-1234-123-23") - .setConfigOverrideDir("none") - .setInitializationTimeoutSec(1) - .setOnInitializationFailure(Options.OnInitializationFailure.UNLOCK) - ); - - ConfigClient configClient = new ConfigClientImpl(baseClient); - - List receivedEvents = new ArrayList<>(); - ConfigChangeListener listener = receivedEvents::add; - - configClient.addConfigChangeListener(listener); - - assertThat(configClient.get("key")).isNotPresent(); - - assertThat(receivedEvents) - .containsExactlyInAnyOrder( - new ConfigChangeEvent( - "sample_bool", - Optional.empty(), - Optional.of( - Prefab.Config - .newBuilder() - .addRows( - Prefab.ConfigRow - .newBuilder() - .addValues( - Prefab.ConditionalValue - .newBuilder() - .setValue(ConfigValueUtils.from(true)) - .build() - ) - .build() - ) - .build() - ) - ), - new ConfigChangeEvent( - "sample", - Optional.empty(), - Optional.of( - Prefab.Config - .newBuilder() - .addRows( - Prefab.ConfigRow - .newBuilder() - .addValues( - Prefab.ConditionalValue - .newBuilder() - .setValue(ConfigValueUtils.from("default sample value")) - .build() - ) - .build() - ) - .build() - ) - ) - ); - } - @Test void localDataFileMode() { final Sdk baseClient = new Sdk( @@ -166,12 +102,7 @@ void beforeEach() { Options options = new Options().setPrefabDatasource(Options.Datasources.LOCAL_ONLY); when(sdk.getOptions()).thenReturn(options); when(updatingConfigResolver.update()) - .thenReturn( - new UpdatingConfigResolver.ChangeLists( - Collections.emptyList(), - Collections.emptyList() - ) - ); + .thenReturn(new UpdatingConfigResolver.ChangeLists(Collections.emptyList())); this.configClient = new ConfigClientImpl(sdk, updatingConfigResolver); this.contextHelper = new ContextHelper(configClient); diff --git a/sdk/src/test/java/com/reforge/sdk/internal/ConfigLoaderTest.java b/sdk/src/test/java/com/reforge/sdk/internal/ConfigLoaderTest.java index 28e70184..14a62c6d 100644 --- a/sdk/src/test/java/com/reforge/sdk/internal/ConfigLoaderTest.java +++ b/sdk/src/test/java/com/reforge/sdk/internal/ConfigLoaderTest.java @@ -31,7 +31,6 @@ void beforeEach() { buildLoaderWithOptions( new Options() .setConfigOverrideDir("src/test/resources/override_directory") - .setPrefabEnvs(List.of("default")) .setLocalDatafile("src/test/resources/prefab.Development.5.config.json") ); } @@ -58,145 +57,7 @@ class UnitTestEnvTests { @BeforeEach void beforeEach() { - buildLoaderWithOptions( - new Options() - .setConfigOverrideDir("src/test/resources/override_directory") - .setPrefabEnvs(List.of("unit_tests")) - ); - } - - @Test - public void testLoad() { - assertValueOfConfigIs("test sample value", "sample"); - assertThat(getValue("sample_int")).map(Prefab.ConfigValue::getInt).contains(123L); - assertThat(getValue("sample_double")) - .map(Prefab.ConfigValue::getDouble) - .contains(12.12); - assertThat(getValue("sample_bool")).map(Prefab.ConfigValue::getBool).contains(true); - assertValueOfConfigIs("value from override in default", "sample_to_override"); - } - - @Test - public void testLoggersCapitalization() { - assertValueOfConfigIsLogLevel(Prefab.LogLevel.INFO, "log-level.tests.capitalized"); - assertValueOfConfigIsLogLevel( - Prefab.LogLevel.INFO, - "log-level.tests.uncapitalized" - ); - assertValueOfConfigIsLogLevel(Prefab.LogLevel.DEBUG, "log-level.tests"); - } - - @Test - void testSimpleFeatureFlagLoad() { - assertThat(getConfig("flag_with_a_value")).isPresent(); - - Prefab.Config ffWithValue = getConfig("flag_with_a_value").get(); - assertThat(ffWithValue.getConfigType()).isEqualTo(Prefab.ConfigType.FEATURE_FLAG); - assertThat(ffWithValue.getRowsList().get(0).getValues(0).getValue().getString()) - .isEqualTo("all-features"); - } - - @Test - void testFeatureFlagLoadWithCriteria() { - assertThat(getConfig("in_lookup_key")).isPresent(); - - Prefab.Config ffWithValue = getConfig("in_lookup_key").get(); - assertThat(ffWithValue.getConfigType()).isEqualTo(Prefab.ConfigType.FEATURE_FLAG); - Prefab.ConditionalValue conditionalValue = ffWithValue - .getRowsList() - .get(0) - .getValues(0); - assertThat(conditionalValue.getValue().getBool()).isTrue(); - assertThat(conditionalValue.getCriteriaCount()).isEqualTo(1); - Prefab.Criterion criteria = conditionalValue.getCriteria(0); - assertThat(criteria) - .isEqualTo( - Prefab.Criterion - .newBuilder() - .setOperator(Prefab.Criterion.CriterionOperator.LOOKUP_KEY_IN) - .setValueToMatch( - Prefab.ConfigValue - .newBuilder() - .setStringList( - Prefab.StringList - .newBuilder() - .addValues("abc123") - .addValues("xyz987") - .build() - ) - .build() - ) - .build() - ); - } - - @Test - void testFeatureFlagLoadWithCriteriaAndProperty() { - assertThat(getConfig("just_my_domain")).isPresent(); - - Prefab.Config ffWithValue = getConfig("just_my_domain").get(); - assertThat(ffWithValue.getConfigType()).isEqualTo(Prefab.ConfigType.FEATURE_FLAG); - Prefab.ConditionalValue conditionalValue = ffWithValue - .getRowsList() - .get(0) - .getValues(0); - assertThat(conditionalValue.getValue().getString()).isEqualTo("new-version"); - assertThat(conditionalValue.getCriteriaCount()).isEqualTo(1); - Prefab.Criterion criteria = conditionalValue.getCriteria(0); - assertThat(criteria) - .isEqualTo( - Prefab.Criterion - .newBuilder() - .setOperator(Prefab.Criterion.CriterionOperator.PROP_IS_ONE_OF) - .setPropertyName("domain") - .setValueToMatch( - Prefab.ConfigValue - .newBuilder() - .setStringList( - Prefab.StringList - .newBuilder() - .addValues("prefab.cloud") - .addValues("example.com") - .build() - ) - .build() - ) - .build() - ); - } - - @Test - public void testNested() { - assertValueOfConfigIsEmpty("nested"); - assertValueOfConfigIs("nested value", "nested.values.string"); - assertValueOfConfigIs("top level", "nested.values"); - assertValueOfConfigIs("", "log-level"); - assertValueOfConfigIsLogLevel(Prefab.LogLevel.WARN, "log-level"); - assertValueOfConfigIsLogLevel(Prefab.LogLevel.WARN, "log-level.tests.nested"); - assertValueOfConfigIsLogLevel( - Prefab.LogLevel.ERROR, - "log-level.tests.nested.deeply" - ); - } - - @Test - void nestedVsDottedFormatsAreIdentical() { - assertValueOfConfigIsEmpty("example"); - assertValueOfConfigIsEmpty("example2"); - assertValueOfConfigIsEmpty("example.nested"); - assertValueOfConfigIsEmpty("example2.nested"); - assertValueOfConfigIs("hello", "example.nested.path"); - assertValueOfConfigIs("hello2", "example2.nested.path"); - } - - @Test - public void testUnderscoreNestingForLogger() { - assertValueOfConfigIsLogLevel(Prefab.LogLevel.WARN, "log-level"); - } - - @Test - public void testUnderscoreNestingForConfig() { - assertValueOfConfigIs("the value", "nested2"); + buildLoaderWithOptions(new Options()); } @Test @@ -231,23 +92,6 @@ public void testKeepsMostRecent() { assertThat(getValue("sample_int")).map(Prefab.ConfigValue::getInt).contains(4L); } - @Test - public void testAPIPrecedence() { - configLoader.calcConfig(); - - assertThat(getValue("sample_int")) - .map(Prefab.ConfigValue::getInt) - .isPresent() - .get() - .isEqualTo(123L); - configLoader.set(cd(2, "sample_int", 456)); - assertThat(getValue("sample_int")) - .map(Prefab.ConfigValue::getInt) - .isPresent() - .get() - .isEqualTo(456L); - } - @Test public void testLoadingTombstonesRemoves() { assertThat(configLoader.calcConfig().getConfigs().get("val_from_api")).isNull(); @@ -278,9 +122,7 @@ class ContextLoadingTests { @BeforeEach void beforeEach() { - buildLoaderWithOptions( - new Options().setGlobalContext(globalContext).setPrefabEnvs(List.of("default")) - ); + buildLoaderWithOptions(new Options().setGlobalContext(globalContext)); } @Test