Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Instead of using SwitcherContext, which is used to automatically load from the s

```java
MyAppFeatures.configure(ContextBuilder.builder()
.contextLocation("com.switcherapi.playground.Features")
.context(Features.class.getName())
.apiKey("API_KEY")
.url("https://switcher-api.com")
.domain("Playground")
Expand Down Expand Up @@ -130,8 +130,15 @@ class MySwitcherClientConfig extends SwitcherContextBase {

### Defining your features

Create a class that extends SwitcherContext if you are loading the configuration from the switcherapi.properties file.
Or use SwitcherContextBase to define the configuration using the ContextBuilder or SwitcherConfig.
Create a class that extends `SwitcherContext` if you are loading the configuration from the switcherapi.properties file.<br>
Or use `SwitcherContextBase` to define the configuration using the ContextBuilder or SwitcherConfig.

Switcher Keys are defined using the @SwitcherKey annotation and must be public static final String.<br>
- Public because you will need to access it from other places of your code.
- Static because you will access it without instantiating the class.
- Final because the value must not be changed during runtime.

The attribute name can be defined as you want (e.g. FEATURE01, FEATURE_01, myFeatureOne, etc), but the value must be the exact Switcher Key defined in Switcher Management or snapshot files.

```java
public class MyAppFeatures extends SwitcherContext {
Expand Down
23 changes: 19 additions & 4 deletions src/main/java/com/switcherapi/client/SwitcherContextBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
* // Initialize the Switcher Client using ContextBuilder
* public void configureClient() {
* Features.configure(ContextBuilder.builder()
* .context("com.business.config.Features")
* .context(Features.class.getName())
* .apiKey("API_KEY")
* .domain("Playground")
* .component("switcher-playground")
Expand Down Expand Up @@ -243,12 +243,22 @@ private static void registerSwitcherKeys() {
* @param fields to be registered
*/
private static void registerSwitcherKey(Field[] fields) {
switcherKeys = Optional.ofNullable(switcherKeys).orElse(new HashSet<>());
Set<String> switcherKeys = new HashSet<>();

for (Field field : fields) {
if (field.isAnnotationPresent(SwitcherKey.class)) {
switcherKeys.add(field.getName());
try {
switcherKeys.add(field.get(null).toString());
} catch (Exception e) {
throw new SwitcherContextException(
String.format("Error retrieving Switcher Key value from field %s", field.getName()));
}
}
}

if (!switcherKeys.isEmpty()) {
setSwitcherKeys(switcherKeys);
}
}

/**
Expand Down Expand Up @@ -538,8 +548,13 @@ private static synchronized void setContextBase(SwitcherContextBase contextBase)
SwitcherContextBase.contextBase = contextBase;
}

private static synchronized void setSwitcherKeys(Set<String> switcherKeys) {
private static synchronized void setSwitcherKeys(Set<String> switcherKeys)
throws SwitcherContextException {
SwitcherContextBase.switcherKeys = switcherKeys;

if (switcherKeys.stream().anyMatch(StringUtils::isBlank)) {
throw new SwitcherContextException("One or more Switcher Keys are empty");
}
}

}
4 changes: 4 additions & 0 deletions src/test/java/com/switcherapi/Switchers.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,8 @@ public class Switchers extends SwitcherContext {

@SwitcherKey
public static final String NOT_FOUND_KEY = "NOT_FOUND_KEY";

@SwitcherKey
public static final String friendlyFeatureName = "USECASE1";

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class SwitcherContextBuilderTest {
void shouldReturnSuccess() {
//given
configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.url("http://localhost:3000")
.apiKey("API_KEY")
.domain("switcher-domain")
Expand All @@ -41,7 +41,7 @@ void shouldReturnSuccess() {
void shouldReturnError_snapshotNotLoaded() {
//given
configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.url("http://localhost:3000")
.apiKey("API_KEY")
.domain("switcher-domain")
Expand All @@ -59,7 +59,7 @@ void shouldReturnError_snapshotNotLoaded() {
void shouldThrowError_wrongContextKeyTypeUsage() {
//given
configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.domain("switcher-domain")
.snapshotLocation(SNAPSHOTS_LOCAL)
.local(true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void shouldConfigureRemotePoolSize() {

//given
SwitchersBase.configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.apiKey("API_KEY")
.domain("switcher-domain")
Expand Down Expand Up @@ -67,7 +67,7 @@ void shouldConfigureRemoteTimeout() {

//given
SwitchersBase.configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.apiKey("API_KEY")
.domain("switcher-domain")
Expand Down
54 changes: 54 additions & 0 deletions src/test/java/com/switcherapi/client/SwitcherFail3Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.switcherapi.client;

import com.switcherapi.client.exception.SwitcherContextException;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;

import java.nio.file.Paths;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class SwitcherFail3Test {

private static final String SNAPSHOTS_LOCAL = Paths.get(StringUtils.EMPTY).toAbsolutePath() + "/src/test/resources";

@Test
void shouldNotRegisterSwitcher_nullKey() {
//given
TestCaseNull.configure(ContextBuilder.builder()
.context(TestCaseNull.class.getName())
.snapshotLocation(SNAPSHOTS_LOCAL)
.local(true));

//test
Exception exception = assertThrows(SwitcherContextException.class, TestCaseNull::initializeClient);
assertEquals("Something went wrong: Context has errors - Error retrieving Switcher Key value from field NULL_KEY",
exception.getMessage());
}

@Test
void shouldNotRegisterSwitcher_emptyKey() {
//given
TestCaseEmpty.configure(ContextBuilder.builder()
.context(TestCaseEmpty.class.getName())
.snapshotLocation(SNAPSHOTS_LOCAL)
.local(true));

//test
Exception exception = assertThrows(SwitcherContextException.class, TestCaseEmpty::initializeClient);
assertEquals("Something went wrong: Context has errors - One or more Switcher Keys are empty",
exception.getMessage());
}

static class TestCaseNull extends SwitcherContextBase {
@SwitcherKey
public static final String NULL_KEY = null;
}

static class TestCaseEmpty extends SwitcherContextBase {
@SwitcherKey
public static final String EMPTY_KEY = "";
}

}
11 changes: 11 additions & 0 deletions src/test/java/com/switcherapi/client/SwitcherLocal1Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ void localShouldReturnTrue() {
// check result history
assertTrue(switcher.getLastExecutionResult().isItOn());
}

@Test
void localShouldReturnTrueUsingFriendlyConstantName() {
SwitcherRequest switcher = Switchers.getSwitcher(Switchers.friendlyFeatureName, true);

assertNull(switcher.getLastExecutionResult());
assertTrue(switcher.isItOn());

// check result history
assertTrue(switcher.getLastExecutionResult().isItOn());
}

@Test
void localShouldReturnFalse() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void shouldUpdateSnapshot_local() {

//that
Switchers.configure(ContextBuilder.builder(true)
.context(Switchers.class.getCanonicalName())
.context(Switchers.class.getName())
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.apiKey("[API_KEY]")
.snapshotLocation(SNAPSHOTS_LOCAL)
Expand All @@ -110,7 +110,7 @@ void shouldUpdateSnapshot_remote() {

//that
Switchers.configure(ContextBuilder.builder(true)
.context(Switchers.class.getCanonicalName())
.context(Switchers.class.getName())
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.apiKey("[API_KEY]")
.domain("Test")
Expand All @@ -137,7 +137,7 @@ void shouldNotUpdateSnapshot_whenNoUpdateAvailable() {

//that
Switchers.configure(ContextBuilder.builder(true)
.context(Switchers.class.getCanonicalName())
.context(Switchers.class.getName())
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.apiKey("[API_KEY]")
.snapshotLocation(SNAPSHOTS_LOCAL)
Expand Down Expand Up @@ -165,7 +165,7 @@ void shouldUpdateSnapshot_remote_inMemory() {

//that
Switchers.configure(ContextBuilder.builder(true)
.context(Switchers.class.getCanonicalName())
.context(Switchers.class.getName())
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.apiKey("[API_KEY]")
.environment("generated_mock_default_5")
Expand All @@ -192,7 +192,7 @@ void shouldNotKillThread_whenAPI_wentLocal() {

//that
Switchers.configure(ContextBuilder.builder(true)
.context(Switchers.class.getCanonicalName())
.context(Switchers.class.getName())
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.apiKey("[API_KEY]")
.environment("generated_mock_default_6")
Expand Down Expand Up @@ -227,7 +227,7 @@ void shouldRestartSnapshotAutoUpdate_whenAlreadySetup() {

//that
Switchers.configure(ContextBuilder.builder(true)
.context(Switchers.class.getCanonicalName())
.context(Switchers.class.getName())
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.apiKey("[API_KEY]")
.environment("generated_mock_default_6")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class SwitcherLocalServiceTest {
static void init() {
executorService = Executors.newSingleThreadExecutor();
SwitchersBase.configure(ContextBuilder.builder()
.context("com.switcherapi.SwitchersBase")
.context(SwitchersBase.class.getName())
.snapshotLocation(SNAPSHOTS_LOCAL)
.environment("default")
.local(true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static void setupContext() throws IOException {
generateFixture();

SwitchersBase.configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.environment("generated_watcher_default")
.snapshotLocation(SNAPSHOTS_LOCAL)
.snapshotWatcher(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class SnapshotWatcherErrorTest {
void shouldNotWatchSnapshotWhenRemote() {
//given
SwitchersBase.configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.url("https://api.switcherapi.com")
.apiKey("[API_KEY]")
.domain("Test")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static void setupContext() throws IOException {
generateFixture();

SwitchersBase.configure(ContextBuilder.builder()
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.environment("generated_watcher_default")
.snapshotLocation(SNAPSHOTS_LOCAL)
.local(true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class SnapshotWatcherWorkerTest extends SnapshotTest {
@BeforeAll
static void setupContext() {
SwitchersBase.configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getCanonicalName())
.context(SwitchersBase.class.getName())
.snapshotLocation(SNAPSHOTS_LOCAL)
.environment("default")
.local(true));
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/com/switcherapi/playground/Features.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class Features extends SwitcherContextBase {
@Override
protected void configureClient() {
configure(ContextBuilder.builder()
.context(Features.class.getCanonicalName())
.context(Features.class.getName())
.url("https://api.switcherapi.com")
.apiKey(System.getenv("switcher.api.key"))
.component(System.getenv("switcher.component"))
Expand Down
8 changes: 8 additions & 0 deletions src/test/resources/snapshot/fixture1.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
"description": "Simple test",
"activated": true,
"config": [
{
"key": "USECASE1",
"description": "Simple test - Config enabled",
"activated": true,
"components": [
"switcher-client"
]
},
{
"key": "USECASE11",
"description": "Simple test - Config enabled",
Expand Down