diff --git a/unleash-client-java/pom.xml b/unleash-client-java/pom.xml index 07b19f0fa8..b7bd23e3a1 100644 --- a/unleash-client-java/pom.xml +++ b/unleash-client-java/pom.xml @@ -36,12 +36,6 @@ ${version.log4j2} - - org.apache.httpcomponents - httpclient - 4.3.1 - - junit @@ -57,6 +51,12 @@ test + + org.apache.logging.log4j + log4j-core + ${version.log4j2} + test + diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/FeatureToggleBackupFileHandler.java b/unleash-client-java/src/main/java/no/finn/unleash/BackupFileHandler.java similarity index 54% rename from unleash-client-java/src/main/java/no/finn/unleash/repository/FeatureToggleBackupFileHandler.java rename to unleash-client-java/src/main/java/no/finn/unleash/BackupFileHandler.java index a64bc5884f..76a9aa65da 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/FeatureToggleBackupFileHandler.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/BackupFileHandler.java @@ -1,35 +1,32 @@ -package no.finn.unleash.repository; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Collections; +package no.finn.unleash; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -class FeatureToggleBackupFileHandler { +import java.io.*; +import java.util.Collections; + +class BackupFileHandler { private static final Logger LOG = LogManager.getLogger(); private static final String BACKUP_FILE = System.getProperty("java.io.tmpdir") + File.separatorChar + "unleash-repo.json"; - ToggleCollection readBackupFile() { + ToggleCollection read() { LOG.info("Unleash will try to load feature toggle states from temporary backup"); - try(FileReader reader = new FileReader(BACKUP_FILE)) { + try (FileReader reader = new FileReader(BACKUP_FILE)) { BufferedReader br = new BufferedReader(reader); - return JsonToggleParser.collectionFormJson(br); + return JsonToggleParser.fromJson(br); + } catch (FileNotFoundException e) { + LOG.warn("Unable to locate backup file:'{}'", BACKUP_FILE, e); } catch (IOException e) { - //TODO: error if file corrupt, warning if file not found. - LOG.warn("Unleash was unable to feature toggle states from temporary backup", e); - return new ToggleCollection(Collections.emptyList()); + LOG.error("Failed to read backup file:'{}'", BACKUP_FILE, e); } + return new ToggleCollection(Collections.emptyList()); } void write(ToggleCollection toggleCollection) { - try(FileWriter writer = new FileWriter(BACKUP_FILE)) { + try (FileWriter writer = new FileWriter(BACKUP_FILE)) { writer.write(JsonToggleParser.toJsonString(toggleCollection)); } catch (IOException e) { LOG.warn("Unleash was unable to backup feature toggles to file: {}", BACKUP_FILE, e); diff --git a/unleash-client-java/src/main/java/no/finn/unleash/strategy/DefaultStrategy.java b/unleash-client-java/src/main/java/no/finn/unleash/DefaultStrategy.java similarity index 73% rename from unleash-client-java/src/main/java/no/finn/unleash/strategy/DefaultStrategy.java rename to unleash-client-java/src/main/java/no/finn/unleash/DefaultStrategy.java index f0db305f5b..39fcc37c85 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/strategy/DefaultStrategy.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/DefaultStrategy.java @@ -1,8 +1,8 @@ -package no.finn.unleash.strategy; +package no.finn.unleash; import java.util.Map; -public final class DefaultStrategy implements Strategy { +final class DefaultStrategy implements Strategy { public static final String NAME = "default"; @Override diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/FeatureToggleRepository.java b/unleash-client-java/src/main/java/no/finn/unleash/FeatureToggleRepository.java similarity index 57% rename from unleash-client-java/src/main/java/no/finn/unleash/repository/FeatureToggleRepository.java rename to unleash-client-java/src/main/java/no/finn/unleash/FeatureToggleRepository.java index 7416cbc7bd..e63e05f06e 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/FeatureToggleRepository.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/FeatureToggleRepository.java @@ -1,18 +1,11 @@ -package no.finn.unleash.repository; +package no.finn.unleash; -import java.net.URI; -import java.util.Collection; -import java.util.concurrent.Executors; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -import no.finn.unleash.Toggle; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.net.URI; +import java.util.concurrent.*; + public final class FeatureToggleRepository implements ToggleRepository { private static final Logger LOG = LogManager.getLogger(); @@ -32,16 +25,16 @@ public final class FeatureToggleRepository implements ToggleRepository { TIMER.setRemoveOnCancelPolicy(true); } - private final FeatureToggleBackupFileHandler featureToggleBackupFileHandler; + private final BackupFileHandler featureToggleBackupFileHandler; private final ToggleFetcher toggleFetcher; private ToggleCollection toggleCollection; public FeatureToggleRepository(URI featuresUri, long pollIntervalSeconds) { - featureToggleBackupFileHandler = new FeatureToggleBackupFileHandler(); + featureToggleBackupFileHandler = new BackupFileHandler(); toggleFetcher = new HttpToggleFetcher(featuresUri); - toggleCollection = featureToggleBackupFileHandler.readBackupFile(); + toggleCollection = featureToggleBackupFileHandler.read(); startBackgroundPolling(pollIntervalSeconds); } @@ -50,26 +43,25 @@ public final class FeatureToggleRepository implements ToggleRepository { return TIMER.scheduleAtFixedRate(new Runnable() { @Override public void run() { - ToggleResponse response = toggleFetcher.fetchToggles(); - if(response.getStatus() == ToggleResponse.Status.CHANGED) { - featureToggleBackupFileHandler.write(toggleCollection); - toggleCollection = response.getToggleCollection(); + try { + Response response = toggleFetcher.fetchToggles(); + if (response.getStatus() == Response.Status.CHANGED) { + featureToggleBackupFileHandler.write(toggleCollection); + toggleCollection = response.getToggleCollection(); + } + } catch (UnleashException e) { + LOG.warn("Could not refresh feature toggles", e); } } }, pollIntervalSeconds, pollIntervalSeconds, TimeUnit.SECONDS); } catch (RejectedExecutionException ex) { - LOG.error("Unleash background task crashed"); + LOG.error("Unleash background task crashed", ex); return null; } } @Override - public Toggle getToggle(String name) throws ToggleException { + public Toggle getToggle(String name) { return toggleCollection.getToggle(name); } - - @Override - public Collection getToggles() throws ToggleException { - return null; - } } diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/HttpToggleFetcher.java b/unleash-client-java/src/main/java/no/finn/unleash/HttpToggleFetcher.java similarity index 69% rename from unleash-client-java/src/main/java/no/finn/unleash/repository/HttpToggleFetcher.java rename to unleash-client-java/src/main/java/no/finn/unleash/HttpToggleFetcher.java index 3f297a5611..b905fb4975 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/HttpToggleFetcher.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/HttpToggleFetcher.java @@ -1,4 +1,4 @@ -package no.finn.unleash.repository; +package no.finn.unleash; import java.io.BufferedReader; import java.io.IOException; @@ -10,7 +10,7 @@ import java.net.URI; import java.net.URL; import java.nio.charset.StandardCharsets; -public final class HttpToggleFetcher implements ToggleFetcher { +final class HttpToggleFetcher implements ToggleFetcher { public static final int CONNECT_TIMEOUT = 10000; private String etag = null; @@ -20,12 +20,12 @@ public final class HttpToggleFetcher implements ToggleFetcher { try { toggleUrl = repo.toURL(); } catch (MalformedURLException ex) { - throw new IllegalArgumentException("Invalid repo uri", ex); + throw new UnleashException("Invalid repo uri", ex); } } @Override - public ToggleResponse fetchToggles() throws ToggleException { + public Response fetchToggles() throws UnleashException { HttpURLConnection connection = null; try { connection = (HttpURLConnection) toggleUrl.openConnection(); @@ -38,10 +38,10 @@ public final class HttpToggleFetcher implements ToggleFetcher { if(responseCode < 300) { return getToggleResponse(connection); } else { - return new ToggleResponse(ToggleResponse.Status.NOT_CHANGED); + return new Response(Response.Status.NOT_CHANGED); } } catch (IOException e) { - throw new ToggleException("Could not fetch toggles", e); + throw new UnleashException("Could not fetch toggles", e); } finally { if(connection != null) { connection.disconnect(); @@ -49,14 +49,14 @@ public final class HttpToggleFetcher implements ToggleFetcher { } } - private ToggleResponse getToggleResponse(HttpURLConnection request) throws IOException { + private Response getToggleResponse(HttpURLConnection request) throws IOException { etag = request.getHeaderField("ETag"); try(BufferedReader reader = new BufferedReader( new InputStreamReader((InputStream) request.getContent(), StandardCharsets.UTF_8))) { - ToggleCollection toggles = JsonToggleParser.collectionFormJson(reader); - return new ToggleResponse(ToggleResponse.Status.CHANGED, toggles); + ToggleCollection toggles = JsonToggleParser.fromJson(reader); + return new Response(Response.Status.CHANGED, toggles); } } } diff --git a/unleash-client-java/src/main/java/no/finn/unleash/JsonToggleParser.java b/unleash-client-java/src/main/java/no/finn/unleash/JsonToggleParser.java new file mode 100644 index 0000000000..3e441b4639 --- /dev/null +++ b/unleash-client-java/src/main/java/no/finn/unleash/JsonToggleParser.java @@ -0,0 +1,29 @@ +package no.finn.unleash; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.Reader; +import java.util.Collection; + +final class JsonToggleParser { + + private JsonToggleParser() { + } + + public static String toJsonString(ToggleCollection toggleCollection) { + Gson gson = new GsonBuilder().create(); + return gson.toJson(toggleCollection); + } + + public static Collection fromJson(String jsonString) { + Gson gson = new GsonBuilder().create(); + return gson.fromJson(jsonString, ToggleCollection.class).getFeatures(); + } + + public static ToggleCollection fromJson(Reader reader) { + Gson gson = new GsonBuilder().create(); + ToggleCollection gsonCollection = gson.fromJson(reader, ToggleCollection.class); + return new ToggleCollection(gsonCollection.getFeatures()); + } +} diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleResponse.java b/unleash-client-java/src/main/java/no/finn/unleash/Response.java similarity index 72% rename from unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleResponse.java rename to unleash-client-java/src/main/java/no/finn/unleash/Response.java index 9ed24ac1b4..9e02e9dc5c 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleResponse.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/Response.java @@ -1,19 +1,19 @@ -package no.finn.unleash.repository; +package no.finn.unleash; import java.util.Collections; -public final class ToggleResponse { +final class Response { enum Status {NOT_CHANGED, CHANGED} private final Status status; private final ToggleCollection toggleCollection; - public ToggleResponse(Status status, ToggleCollection toggleCollection) { + public Response(Status status, ToggleCollection toggleCollection) { this.status = status; this.toggleCollection = toggleCollection; } - public ToggleResponse(Status status) { + public Response(Status status) { this.status = status; this.toggleCollection = new ToggleCollection(Collections.emptyList()); } diff --git a/unleash-client-java/src/main/java/no/finn/unleash/strategy/Strategy.java b/unleash-client-java/src/main/java/no/finn/unleash/Strategy.java similarity index 79% rename from unleash-client-java/src/main/java/no/finn/unleash/strategy/Strategy.java rename to unleash-client-java/src/main/java/no/finn/unleash/Strategy.java index 81bc2136f8..30bf1f2a90 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/strategy/Strategy.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/Strategy.java @@ -1,4 +1,4 @@ -package no.finn.unleash.strategy; +package no.finn.unleash; import java.util.Map; diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleCollection.java b/unleash-client-java/src/main/java/no/finn/unleash/ToggleCollection.java similarity index 89% rename from unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleCollection.java rename to unleash-client-java/src/main/java/no/finn/unleash/ToggleCollection.java index 4019b3c9b9..d80f62c5b0 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleCollection.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/ToggleCollection.java @@ -1,12 +1,10 @@ -package no.finn.unleash.repository; +package no.finn.unleash; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import no.finn.unleash.Toggle; - final class ToggleCollection { private Collection features = Collections.emptyList(); private Map cache; diff --git a/unleash-client-java/src/main/java/no/finn/unleash/ToggleFetcher.java b/unleash-client-java/src/main/java/no/finn/unleash/ToggleFetcher.java new file mode 100644 index 0000000000..3c02837f56 --- /dev/null +++ b/unleash-client-java/src/main/java/no/finn/unleash/ToggleFetcher.java @@ -0,0 +1,5 @@ +package no.finn.unleash; + +public interface ToggleFetcher { + Response fetchToggles() throws UnleashException; +} diff --git a/unleash-client-java/src/main/java/no/finn/unleash/ToggleRepository.java b/unleash-client-java/src/main/java/no/finn/unleash/ToggleRepository.java new file mode 100644 index 0000000000..f25c87c7e7 --- /dev/null +++ b/unleash-client-java/src/main/java/no/finn/unleash/ToggleRepository.java @@ -0,0 +1,5 @@ +package no.finn.unleash; + +public interface ToggleRepository { + Toggle getToggle(String name); +} diff --git a/unleash-client-java/src/main/java/no/finn/unleash/strategy/UnknownStrategy.java b/unleash-client-java/src/main/java/no/finn/unleash/UnknownStrategy.java similarity index 73% rename from unleash-client-java/src/main/java/no/finn/unleash/strategy/UnknownStrategy.java rename to unleash-client-java/src/main/java/no/finn/unleash/UnknownStrategy.java index 4fb166a470..65299977a0 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/strategy/UnknownStrategy.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/UnknownStrategy.java @@ -1,8 +1,8 @@ -package no.finn.unleash.strategy; +package no.finn.unleash; import java.util.Map; -public final class UnknownStrategy implements Strategy { +final class UnknownStrategy implements Strategy { public static final String NAME = "unknown"; @Override diff --git a/unleash-client-java/src/main/java/no/finn/unleash/Unleash.java b/unleash-client-java/src/main/java/no/finn/unleash/Unleash.java index f43e43c240..989c027684 100644 --- a/unleash-client-java/src/main/java/no/finn/unleash/Unleash.java +++ b/unleash-client-java/src/main/java/no/finn/unleash/Unleash.java @@ -3,18 +3,12 @@ package no.finn.unleash; import java.util.HashMap; import java.util.Map; -import no.finn.unleash.repository.ToggleException; -import no.finn.unleash.repository.ToggleRepository; -import no.finn.unleash.strategy.DefaultStrategy; -import no.finn.unleash.strategy.Strategy; -import no.finn.unleash.strategy.UnknownStrategy; - public final class Unleash { + private static final DefaultStrategy DEFAULT_STRATEGY = new DefaultStrategy(); + private static final UnknownStrategy UNKNOWN_STRATEGY = new UnknownStrategy(); + private final ToggleRepository toggleRepository; private final Map strategyMap; - private final UnknownStrategy unknownStrategy = new UnknownStrategy(); - private final DefaultStrategy defaultStrategy = new DefaultStrategy(); - public Unleash(ToggleRepository toggleRepository, Strategy... strategies) { this.toggleRepository = toggleRepository; @@ -26,28 +20,23 @@ public final class Unleash { } public boolean isEnabled(final String toggleName, final boolean defaultSetting) { - try { - Toggle toggle = toggleRepository.getToggle(toggleName); + Toggle toggle = toggleRepository.getToggle(toggleName); - if(toggle == null) { - return defaultSetting; - } - - Strategy strategy = getStrategy(toggle.getStrategy()); - return toggle.isEnabled() && strategy.isEnabled(toggle.getParameters()); - - } catch (ToggleException rx) { + if (toggle == null) { return defaultSetting; } + + Strategy strategy = getStrategy(toggle.getStrategy()); + return toggle.isEnabled() && strategy.isEnabled(toggle.getParameters()); } private Map buildStrategyMap(Strategy[] strategies) { Map map = new HashMap<>(); - map.put(defaultStrategy.getName(), defaultStrategy); + map.put(DEFAULT_STRATEGY.getName(), DEFAULT_STRATEGY); - if(strategies != null) { - for(Strategy strategy : strategies) { + if (strategies != null) { + for (Strategy strategy : strategies) { map.put(strategy.getName(), strategy); } } @@ -56,12 +45,11 @@ public final class Unleash { } - private Strategy getStrategy(String strategy) { - if(strategyMap.containsKey(strategy)) { + if (strategyMap.containsKey(strategy)) { return strategyMap.get(strategy); } else { - return unknownStrategy; + return UNKNOWN_STRATEGY; } } } diff --git a/unleash-client-java/src/main/java/no/finn/unleash/UnleashException.java b/unleash-client-java/src/main/java/no/finn/unleash/UnleashException.java new file mode 100644 index 0000000000..c245db7ad6 --- /dev/null +++ b/unleash-client-java/src/main/java/no/finn/unleash/UnleashException.java @@ -0,0 +1,8 @@ +package no.finn.unleash; + +public class UnleashException extends RuntimeException { + + public UnleashException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/HTTPToggleRepository.java b/unleash-client-java/src/main/java/no/finn/unleash/repository/HTTPToggleRepository.java deleted file mode 100644 index 1e0d87bb42..0000000000 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/HTTPToggleRepository.java +++ /dev/null @@ -1,58 +0,0 @@ -package no.finn.unleash.repository; - -import java.io.IOException; -import java.util.Collection; - -import no.finn.unleash.Toggle; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; - -//TODO: take advantage of Etag and 304 responses. -public class HTTPToggleRepository implements ToggleRepository { - private static final Log LOG = LogFactory.getLog(HTTPToggleRepository.class); - - private final HttpClient httpClient; - private final String serverEndpoint; - - public HTTPToggleRepository(final String serverEndpoint) { - this.serverEndpoint = serverEndpoint; - this.httpClient = HttpClients.createDefault(); - } - - @Override - public final Toggle getToggle(final String name) throws ToggleException { - try { - for (Toggle toggle : fetchToggles()) { - if (name.equals(toggle.getName())) { - return toggle; - } - } - } catch (IOException e) { - LOG.warn("Could not fetch toggles via HTTP", e); - throw new ToggleException("Could not fetch toggles via HTTP"); - } - - throw new ToggleException("unknown toggle: " + name); - } - - @Override - public final Collection getToggles() { - try { - return fetchToggles(); - } catch (IOException e) { - LOG.warn("Could not fetch toggles via HTTP"); - throw new ToggleException("Could not fetch toggles via HTTP"); - } - } - - private Collection fetchToggles() throws IOException { - HttpResponse httpResponse = httpClient.execute(new HttpGet(serverEndpoint)); - final String jsonString = EntityUtils.toString(httpResponse.getEntity()); - return JsonToggleParser.fromJson(jsonString); - } -} diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/JsonToggleParser.java b/unleash-client-java/src/main/java/no/finn/unleash/repository/JsonToggleParser.java deleted file mode 100644 index a6537096a4..0000000000 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/JsonToggleParser.java +++ /dev/null @@ -1,51 +0,0 @@ -package no.finn.unleash.repository; - -import java.io.Reader; -import java.util.Collection; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import no.finn.unleash.Toggle; - -public final class JsonToggleParser { - - private JsonToggleParser() { - } - - public static Toggle toToggle(String jsonString) { - Gson gson = new GsonBuilder().create(); - return gson.fromJson(jsonString, Toggle.class); - } - - public static String toJsonString(Collection toggles) { - Gson gson = new GsonBuilder().create(); - return gson.toJson(new ToggleCollection(toggles)); - } - - public static String toJsonString(ToggleCollection toggleCollection) { - Gson gson = new GsonBuilder().create(); - return gson.toJson(toggleCollection); - } - - - public static Collection fromJson(String jsonString) { - Gson gson = new GsonBuilder().create(); - return gson.fromJson(jsonString,ToggleCollection.class).getFeatures(); - } - - public static ToggleCollection collectionFormJson(String jsonString) { - Gson gson = new GsonBuilder().create(); - return gson.fromJson(jsonString, ToggleCollection.class); - } - - public static Collection fromJson(Reader reader) { - Gson gson = new GsonBuilder().create(); - return gson.fromJson(reader,ToggleCollection.class).getFeatures(); - } - - public static ToggleCollection collectionFormJson(Reader reader) { - Gson gson = new GsonBuilder().create(); - ToggleCollection gsonCollection = gson.fromJson(reader, ToggleCollection.class); - return new ToggleCollection(gsonCollection.getFeatures()); - } -} diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/PollingToggleRepository.java b/unleash-client-java/src/main/java/no/finn/unleash/repository/PollingToggleRepository.java deleted file mode 100644 index 491d279841..0000000000 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/PollingToggleRepository.java +++ /dev/null @@ -1,137 +0,0 @@ -package no.finn.unleash.repository; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -import no.finn.unleash.Toggle; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class PollingToggleRepository implements ToggleRepository { - private static final Log LOG = LogFactory.getLog(PollingToggleRepository.class); - private static final ScheduledThreadPoolExecutor TIMER = new ScheduledThreadPoolExecutor( - 1, - new ThreadFactory() { - @Override - public Thread newThread(final Runnable r) { - Thread thread = Executors.defaultThreadFactory().newThread(r); - thread.setName("unleash-toggle-repository"); - thread.setDaemon(true); - return thread; - } - } - ); - - static { - TIMER.setRemoveOnCancelPolicy(true); - } - - private final ToggleRepository toggleRepository; - private final int pollIntervalSeconds; - private Map togglesCache; - - - public PollingToggleRepository(final ToggleRepository toggleRepository, final int pollIntervalSeconds) { - this.toggleRepository = toggleRepository; - this.pollIntervalSeconds = pollIntervalSeconds; - - this.togglesCache = new HashMap<>(); - updateTogglesCache(); - startBackgroundPolling(); - } - - @Override - public final Toggle getToggle(final String name) { - return togglesCache.get(name); - } - - @Override - public final Collection getToggles() { - return Collections.unmodifiableCollection(togglesCache.values()); - } - - private void updateTogglesCache() { - try { - Map freshToggleMap = new HashMap<>(); - - for (Toggle toggle : fetchToggles()) { - freshToggleMap.put(toggle.getName(), toggle); - } - - this.togglesCache = Collections.unmodifiableMap(freshToggleMap); - - } catch (ToggleException e) { - //Do nothing - } - } - - private ScheduledFuture startBackgroundPolling() { - try { - return TIMER.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - updateTogglesCache(); - } - }, pollIntervalSeconds, pollIntervalSeconds, TimeUnit.SECONDS); - } catch (RejectedExecutionException ex) { - LOG.error("Unleash background task crashed"); - return null; - } - } - - - private Collection fetchToggles() throws ToggleException { - try { - Collection toggles = toggleRepository.getToggles(); - storeRepoAsTempFile(JsonToggleParser.toJsonString(toggles)); - return toggles; - } catch (ToggleException ex) { - if (togglesCache.isEmpty()) { - return loadFromTempFile(); - } - throw ex; - } - } - - - private Collection loadFromTempFile() throws ToggleException { - LOG.info("Unleash will try to load feature toggle states from temporary backup"); - try (FileReader reader = new FileReader(pathToTmpBackupFile())) { - BufferedReader br = new BufferedReader(reader); - StringBuilder builder = new StringBuilder(); - String line; - while ((line = br.readLine()) != null) { - builder.append(line); - } - return JsonToggleParser.fromJson(builder.toString()); - } catch (IOException e) { - LOG.error("Unleash was unable to feature toggle repo from temporary backup: " + pathToTmpBackupFile()); - throw new ToggleException("Unleash was unable to feature toggle states from temporary backup"); - } - } - - private void storeRepoAsTempFile(final String serverResponse) { - try (FileWriter writer = new FileWriter(pathToTmpBackupFile())) { - writer.write(serverResponse); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private static String pathToTmpBackupFile() { - return System.getProperty("java.io.tmpdir") + File.separatorChar + "unleash-repo.json"; - } -} \ No newline at end of file diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleException.java b/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleException.java deleted file mode 100644 index 95cb07aa99..0000000000 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleException.java +++ /dev/null @@ -1,11 +0,0 @@ -package no.finn.unleash.repository; - -public class ToggleException extends RuntimeException { - public ToggleException(String message) { - super(message); - } - - public ToggleException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleFetcher.java b/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleFetcher.java deleted file mode 100644 index bec57b7bae..0000000000 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleFetcher.java +++ /dev/null @@ -1,5 +0,0 @@ -package no.finn.unleash.repository; - -public interface ToggleFetcher { - ToggleResponse fetchToggles() throws ToggleException; -} diff --git a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleRepository.java b/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleRepository.java deleted file mode 100644 index 883c6d5f86..0000000000 --- a/unleash-client-java/src/main/java/no/finn/unleash/repository/ToggleRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package no.finn.unleash.repository; - -import java.util.Collection; - -import no.finn.unleash.Toggle; - -public interface ToggleRepository { - Toggle getToggle(String name) throws ToggleException; - - Collection getToggles() throws ToggleException; -} diff --git a/unleash-client-java/src/test/java/no/finn/unleash/repository/JsonToggleParserTest.java b/unleash-client-java/src/test/java/no/finn/unleash/JsonToggleParserTest.java similarity index 94% rename from unleash-client-java/src/test/java/no/finn/unleash/repository/JsonToggleParserTest.java rename to unleash-client-java/src/test/java/no/finn/unleash/JsonToggleParserTest.java index 9918ee9e65..9c13cd27f9 100644 --- a/unleash-client-java/src/test/java/no/finn/unleash/repository/JsonToggleParserTest.java +++ b/unleash-client-java/src/test/java/no/finn/unleash/JsonToggleParserTest.java @@ -1,4 +1,6 @@ -package no.finn.unleash.repository; +package no.finn.unleash; + +import org.junit.Test; import java.io.BufferedReader; import java.io.IOException; @@ -7,9 +9,6 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; -import no.finn.unleash.Toggle; -import org.junit.Test; - import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; diff --git a/unleash-client-java/src/test/java/no/finn/unleash/ManualTesting.java b/unleash-client-java/src/test/java/no/finn/unleash/ManualTesting.java index bb9746b1b8..f5a04bab1e 100644 --- a/unleash-client-java/src/test/java/no/finn/unleash/ManualTesting.java +++ b/unleash-client-java/src/test/java/no/finn/unleash/ManualTesting.java @@ -3,9 +3,6 @@ package no.finn.unleash; import java.net.URI; import java.util.Random; -import no.finn.unleash.repository.FeatureToggleRepository; -import no.finn.unleash.repository.ToggleRepository; - public class ManualTesting { public static void main(String[] args) throws Exception { ToggleRepository repository = new FeatureToggleRepository(URI.create("http://localhost:4242/features"), 1); diff --git a/unleash-client-java/src/test/java/no/finn/unleash/UnleashTest.java b/unleash-client-java/src/test/java/no/finn/unleash/UnleashTest.java index 1e1be7df20..ba7bb3e612 100644 --- a/unleash-client-java/src/test/java/no/finn/unleash/UnleashTest.java +++ b/unleash-client-java/src/test/java/no/finn/unleash/UnleashTest.java @@ -1,18 +1,11 @@ package no.finn.unleash; -import no.finn.unleash.repository.ToggleException; -import no.finn.unleash.repository.ToggleRepository; -import no.finn.unleash.strategy.Strategy; import org.junit.Before; import org.junit.Test; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.anyMap; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class UnleashTest { @@ -39,13 +32,6 @@ public class UnleashTest { assertThat(unleash.isEnabled("test"), is(false)); } - @Test - public void failing_repository_should_obey_default() { - when(toggleRepository.getToggle("test")).thenThrow(new ToggleException("service down")); - - assertThat(unleash.isEnabled("test", true), is(true)); - } - @Test public void unknown_feature_should_be_considered_inactive() { when(toggleRepository.getToggle("test")).thenReturn(null); diff --git a/unleash-client-java/src/test/java/no/finn/unleash/example/CustomStrategy.java b/unleash-client-java/src/test/java/no/finn/unleash/example/CustomStrategy.java new file mode 100644 index 0000000000..371a5811b1 --- /dev/null +++ b/unleash-client-java/src/test/java/no/finn/unleash/example/CustomStrategy.java @@ -0,0 +1,17 @@ +package no.finn.unleash.example; + +import no.finn.unleash.Strategy; + +import java.util.Map; + +final class CustomStrategy implements Strategy { + @Override + public String getName() { + return "custom"; + } + + @Override + public boolean isEnabled(Map parameters) { + return false; + } +} diff --git a/unleash-client-java/src/test/java/no/finn/unleash/example/UnleashUsageTest.java b/unleash-client-java/src/test/java/no/finn/unleash/example/UnleashUsageTest.java new file mode 100644 index 0000000000..aabab5864e --- /dev/null +++ b/unleash-client-java/src/test/java/no/finn/unleash/example/UnleashUsageTest.java @@ -0,0 +1,22 @@ +package no.finn.unleash.example; + +import no.finn.unleash.FeatureToggleRepository; +import no.finn.unleash.ToggleRepository; +import no.finn.unleash.Unleash; +import org.junit.Test; + +import java.net.URI; + +import static org.junit.Assert.assertFalse; + +public class UnleashUsageTest { + + @Test + public void wire() { + ToggleRepository repository = new FeatureToggleRepository(URI.create("http://localhost:4242/features"), 1); + + Unleash unleash = new Unleash(repository, new CustomStrategy()); + + assertFalse(unleash.isEnabled("myFeature")); + } +} diff --git a/unleash-client-java/src/test/java/no/finn/unleash/repository/HttpToggleFetcherTest.java b/unleash-client-java/src/test/java/no/finn/unleash/repository/HttpToggleFetcherTest.java deleted file mode 100644 index 033c198931..0000000000 --- a/unleash-client-java/src/test/java/no/finn/unleash/repository/HttpToggleFetcherTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package no.finn.unleash.repository; - -import java.net.URI; - -import org.junit.Ignore; -import org.junit.Test; - -public class HttpToggleFetcherTest { - - - @Test - @Ignore - public void explore() { - HttpToggleFetcher httpToggleFetcher = new HttpToggleFetcher(URI.create("http://localhost:4242/features")); - - ToggleResponse toggleResponse = httpToggleFetcher.fetchToggles(); - toggleResponse = httpToggleFetcher.fetchToggles(); - System.out.println("toggleResponse = " + toggleResponse); - - } - -} \ No newline at end of file