mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-20 00:08:02 +01:00
Client: Experiementing with native http-connection
to replace httpclient.
This commit is contained in:
parent
d2a09d89b9
commit
8d41825f82
@ -0,0 +1,37 @@
|
||||
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;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
class FeatureToggleBackupFileHandler {
|
||||
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() {
|
||||
LOG.info("Unleash will try to load feature toggle states from temporary backup");
|
||||
try(FileReader reader = new FileReader(BACKUP_FILE)) {
|
||||
BufferedReader br = new BufferedReader(reader);
|
||||
return JsonToggleParser.collectionFormJson(br);
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
|
||||
void write(ToggleCollection toggleCollection) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package no.finn.unleash.repository;
|
||||
|
||||
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;
|
||||
|
||||
public final class FeatureToggleRepository implements ToggleRepository {
|
||||
private static final Logger LOG = LogManager.getLogger();
|
||||
|
||||
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 FeatureToggleBackupFileHandler featureToggleBackupFileHandler;
|
||||
private final ToggleFetcher toggleFetcher;
|
||||
|
||||
private ToggleCollection toggleCollection;
|
||||
|
||||
public FeatureToggleRepository(URI featuresUri, long pollIntervalSeconds) {
|
||||
featureToggleBackupFileHandler = new FeatureToggleBackupFileHandler();
|
||||
toggleFetcher = new HttpToggleFetcher(featuresUri);
|
||||
|
||||
toggleCollection = featureToggleBackupFileHandler.readBackupFile();
|
||||
startBackgroundPolling(pollIntervalSeconds);
|
||||
}
|
||||
|
||||
private ScheduledFuture startBackgroundPolling(long pollIntervalSeconds) {
|
||||
try {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}, pollIntervalSeconds, pollIntervalSeconds, TimeUnit.SECONDS);
|
||||
} catch (RejectedExecutionException ex) {
|
||||
LOG.error("Unleash background task crashed");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toggle getToggle(String name) throws ToggleException {
|
||||
return toggleCollection.getToggle(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Toggle> getToggles() throws ToggleException {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -9,8 +9,6 @@ import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import no.finn.unleash.Toggle;
|
||||
|
||||
public final class HttpToggleFetcher implements ToggleFetcher {
|
||||
public static final int CONNECT_TIMEOUT = 10000;
|
||||
@ -57,7 +55,7 @@ public final class HttpToggleFetcher implements ToggleFetcher {
|
||||
try(BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader((InputStream) request.getContent(), StandardCharsets.UTF_8))) {
|
||||
|
||||
Collection<Toggle> toggles = JsonToggleParser.fromJson(reader);
|
||||
ToggleCollection toggles = JsonToggleParser.collectionFormJson(reader);
|
||||
return new ToggleResponse(ToggleResponse.Status.CHANGED, toggles);
|
||||
}
|
||||
}
|
||||
|
@ -18,14 +18,30 @@ public final class JsonToggleParser {
|
||||
return gson.toJson(new ToggleCollection(toggles));
|
||||
}
|
||||
|
||||
public static String toJsonString(ToggleCollection toggleCollection) {
|
||||
Gson gson = new GsonBuilder().create();
|
||||
return gson.toJson(toggleCollection);
|
||||
}
|
||||
|
||||
|
||||
public static Collection<Toggle> 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<Toggle> 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());
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,26 @@
|
||||
package no.finn.unleash.repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import no.finn.unleash.Toggle;
|
||||
|
||||
public final class ToggleCollection {
|
||||
private final Collection<Toggle> features;
|
||||
final class ToggleCollection {
|
||||
private Collection<Toggle> features = Collections.emptyList();
|
||||
private Map<String, Toggle> cache;
|
||||
|
||||
public ToggleCollection(final Collection<Toggle> features) {
|
||||
ToggleCollection(final Collection<Toggle> features) {
|
||||
this.features = features;
|
||||
cache = new HashMap<>();
|
||||
features.forEach(toggle -> cache.put(toggle.getName(), toggle));
|
||||
}
|
||||
|
||||
public Collection<Toggle> getFeatures() {
|
||||
Collection<Toggle> getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
Toggle getToggle(final String name) {
|
||||
return cache.get(name);
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,28 @@
|
||||
package no.finn.unleash.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import no.finn.unleash.Toggle;
|
||||
|
||||
public final class ToggleResponse {
|
||||
enum Status {NOT_CHANGED, CHANGED}
|
||||
|
||||
private final Status status;
|
||||
private final Collection<Toggle> getToggles;
|
||||
private final ToggleCollection toggleCollection;
|
||||
|
||||
public ToggleResponse(Status status, Collection<Toggle> getToggles) {
|
||||
public ToggleResponse(Status status, ToggleCollection toggleCollection) {
|
||||
this.status = status;
|
||||
this.getToggles = getToggles;
|
||||
this.toggleCollection = toggleCollection;
|
||||
}
|
||||
|
||||
public ToggleResponse(Status status) {
|
||||
this.status = status;
|
||||
this.getToggles = Collections.emptyList();
|
||||
this.toggleCollection = new ToggleCollection(Collections.emptyList());
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Collection<Toggle> getGetToggles() {
|
||||
return getToggles;
|
||||
public ToggleCollection getToggleCollection() {
|
||||
return toggleCollection;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
package no.finn.unleash;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Random;
|
||||
import no.finn.unleash.repository.FeatureToggleRepository;
|
||||
import no.finn.unleash.repository.HTTPToggleRepository;
|
||||
import no.finn.unleash.repository.PollingToggleRepository;
|
||||
import no.finn.unleash.repository.ToggleRepository;
|
||||
|
||||
public class ManualTesting {
|
||||
public static void main(String[] args) throws Exception {
|
||||
HTTPToggleRepository httpRepo = new HTTPToggleRepository("http://localhost:4242/features");
|
||||
ToggleRepository repository = new PollingToggleRepository(httpRepo, 1);
|
||||
ToggleRepository repository = new FeatureToggleRepository(URI.create("http://localhost:4242/features"), 1);
|
||||
|
||||
|
||||
Unleash unleash = new Unleash(repository);
|
||||
|
Loading…
Reference in New Issue
Block a user