mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Extended java-client to support the following:
* Unleash - the actual unleash client exposed to the clients. * Toggle - represents a concrete feature toggle. * ToggleRepository - the logic to communicate with the unleash-server. * Strategy - implements the logic associated with strategies. I have also included to common strategies: "Default" and "Unknown". related to issue #17.
This commit is contained in:
		
							parent
							
								
									2ca8291eac
								
							
						
					
					
						commit
						0ed61a1f0f
					
				| @ -19,6 +19,17 @@ | |||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
|  | 
 | ||||||
|  |         <!-- | ||||||
|  |           TODO: we should write our own manual json serialize/deserializer | ||||||
|  |           to avvoid this dependency | ||||||
|  |         --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.google.code.gson</groupId> | ||||||
|  |             <artifactId>gson</artifactId> | ||||||
|  |             <version>2.2.4</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.apache.logging.log4j</groupId> |             <groupId>org.apache.logging.log4j</groupId> | ||||||
|             <artifactId>log4j-api</artifactId> |             <artifactId>log4j-api</artifactId> | ||||||
| @ -31,12 +42,22 @@ | |||||||
|             <version>4.3.1</version> |             <version>4.3.1</version> | ||||||
|         </dependency> |         </dependency> | ||||||
| 
 | 
 | ||||||
|  |         <!-- Test dependencies --> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>junit</groupId> |             <groupId>junit</groupId> | ||||||
|             <artifactId>junit</artifactId> |             <artifactId>junit</artifactId> | ||||||
|             <version>4.11</version> |             <version>4.11</version> | ||||||
|  |             <scope>test</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
| 
 | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.mockito</groupId> | ||||||
|  |             <artifactId>mockito-all</artifactId> | ||||||
|  |             <version>1.9.5</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <build> |     <build> | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								unleash-client-java/src/main/no/finn/unleash/Toggle.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								unleash-client-java/src/main/no/finn/unleash/Toggle.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | package no.finn.unleash; | ||||||
|  | 
 | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | public final class Toggle { | ||||||
|  |     private final String name; | ||||||
|  |     private final boolean enabled; | ||||||
|  |     private final String strategy; | ||||||
|  |     private final Map<String, String> parameters; | ||||||
|  | 
 | ||||||
|  |     public Toggle(String name, boolean enabled, String strategy, Map<String, String> parameters) { | ||||||
|  |         this.name = name; | ||||||
|  |         this.enabled = enabled; | ||||||
|  |         this.strategy = strategy; | ||||||
|  |         this.parameters = parameters; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isEnabled() { | ||||||
|  |         return enabled; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getStrategy() { | ||||||
|  |         return strategy; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Map<String, String> getParameters() { | ||||||
|  |         return parameters; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,4 +1,66 @@ | |||||||
| package no.finn.unleash; | 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 { | public final class Unleash { | ||||||
|  |     private final ToggleRepository toggleRepository; | ||||||
|  |     private final Map<String, Strategy> strategyMap; | ||||||
|  |     private final UnknownStrategy unknownStrategy = new UnknownStrategy(); | ||||||
|  |     private final DefaultStrategy defaultStrategy = new DefaultStrategy(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public Unleash(ToggleRepository toggleRepository, Strategy... strategies) { | ||||||
|  |         this.toggleRepository = toggleRepository; | ||||||
|  |         this.strategyMap = buildStrategyMap(strategies); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isEnabled(final String toggleName) { | ||||||
|  |         return isEnabled(toggleName, false); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isEnabled(final String toggleName, final boolean defaultSetting) { | ||||||
|  |         try { | ||||||
|  |             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) { | ||||||
|  |             return defaultSetting; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Map<String, Strategy> buildStrategyMap(Strategy[] strategies) { | ||||||
|  |         Map<String, Strategy> map = new HashMap<>(); | ||||||
|  | 
 | ||||||
|  |         map.put(defaultStrategy.getName(), defaultStrategy); | ||||||
|  | 
 | ||||||
|  |         if(strategies != null) { | ||||||
|  |             for(Strategy strategy : strategies) { | ||||||
|  |                 map.put(strategy.getName(), strategy); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return map; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private Strategy getStrategy(String strategy) { | ||||||
|  |         if(strategyMap.containsKey(strategy)) { | ||||||
|  |             return strategyMap.get(strategy); | ||||||
|  |         } else { | ||||||
|  |             return unknownStrategy; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,57 @@ | |||||||
|  | package no.finn.unleash.repository; | ||||||
|  | 
 | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.List; | ||||||
|  | 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; | ||||||
|  | 
 | ||||||
|  | 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 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 Collection<Toggle> 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 List<Toggle> fetchToggles() throws IOException { | ||||||
|  |         HttpResponse httpResponse = httpClient.execute(new HttpGet(serverEndpoint)); | ||||||
|  |         final String jsonString = EntityUtils.toString(httpResponse.getEntity()); | ||||||
|  |         return JsonParser.toListOfToggles(jsonString); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | package no.finn.unleash.repository; | ||||||
|  | 
 | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.List; | ||||||
|  | import com.google.gson.Gson; | ||||||
|  | import com.google.gson.GsonBuilder; | ||||||
|  | import com.google.gson.reflect.TypeToken; | ||||||
|  | import no.finn.unleash.Toggle; | ||||||
|  | 
 | ||||||
|  | public final class JsonParser { | ||||||
|  | 
 | ||||||
|  |     public static Toggle toToggle(String jsonString) { | ||||||
|  |         Gson gson = new GsonBuilder().create(); | ||||||
|  |         return gson.fromJson(jsonString, Toggle.class); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static String toJsonString(Collection<Toggle> toggles) { | ||||||
|  |         Gson gson = new GsonBuilder().create(); | ||||||
|  |         return gson.toJson(toggles); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public static List<Toggle> toListOfToggles(String jsonString) { | ||||||
|  |         Gson gson = new GsonBuilder().create(); | ||||||
|  |         return gson.fromJson(jsonString, new TypeToken<List<Toggle>>(){}.getType()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,136 @@ | |||||||
|  | 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.List; | ||||||
|  | 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<String, Toggle> togglesCache; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public PollingToggleRepository(final ToggleRepository toggleRepository, final int pollIntervalSeconds){ | ||||||
|  |         this.toggleRepository = toggleRepository; | ||||||
|  |         this.pollIntervalSeconds = pollIntervalSeconds; | ||||||
|  | 
 | ||||||
|  |         this.togglesCache = new HashMap<>(); | ||||||
|  |         updateTogglesCache(); | ||||||
|  |         startBackgroundPolling(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Toggle getToggle(final String name){ | ||||||
|  |         return togglesCache.get(name); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Collection<Toggle> getToggles() { | ||||||
|  |         return Collections.unmodifiableCollection(togglesCache.values()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void updateTogglesCache() { | ||||||
|  |         try { | ||||||
|  |             Map<String, Toggle> 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<Toggle> fetchToggles() throws ToggleException { | ||||||
|  |         try { | ||||||
|  |             Collection<Toggle> toggles = toggleRepository.getToggles(); | ||||||
|  |             storeRepoAsTempFile(JsonParser.toJsonString(toggles)); | ||||||
|  |             return toggles; | ||||||
|  |         } catch (ToggleException ex) { | ||||||
|  |             if(togglesCache.isEmpty()) { | ||||||
|  |                 return loadFromTempFile(); | ||||||
|  |             } | ||||||
|  |             throw ex; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private List<Toggle> 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 JsonParser.toListOfToggles(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"; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | package no.finn.unleash.repository; | ||||||
|  | 
 | ||||||
|  | public class ToggleException extends RuntimeException { | ||||||
|  |     public ToggleException(String message) { | ||||||
|  |         super(message); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | package no.finn.unleash.repository; | ||||||
|  | 
 | ||||||
|  | import java.util.Collection; | ||||||
|  | import no.finn.unleash.Toggle; | ||||||
|  | 
 | ||||||
|  | public interface ToggleRepository { | ||||||
|  |     Toggle getToggle(String name) throws ToggleException; | ||||||
|  | 
 | ||||||
|  |     Collection<Toggle> getToggles() throws ToggleException; | ||||||
|  | } | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | package no.finn.unleash.strategy; | ||||||
|  | 
 | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | public final class DefaultStrategy implements Strategy { | ||||||
|  |     public static final String NAME = "default"; | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String getName() { | ||||||
|  |         return NAME; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean isEnabled(Map<String, String> parameters) { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | package no.finn.unleash.strategy; | ||||||
|  | 
 | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | public interface Strategy { | ||||||
|  |     String getName(); | ||||||
|  | 
 | ||||||
|  |     boolean isEnabled(Map<String, String> parameters); | ||||||
|  | } | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | package no.finn.unleash.strategy; | ||||||
|  | 
 | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | public final class UnknownStrategy implements Strategy { | ||||||
|  |     public static final String NAME = "unknown"; | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String getName() { | ||||||
|  |         return NAME; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean isEnabled(Map<String, String> parameters) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,13 +1,67 @@ | |||||||
| package no.finn.unleash; | 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 org.junit.Test; | ||||||
| 
 | 
 | ||||||
| import static org.junit.Assert.assertTrue; | import static org.hamcrest.CoreMatchers.is; | ||||||
|  | import static org.hamcrest.CoreMatchers.nullValue; | ||||||
|  | import static org.junit.Assert.assertThat; | ||||||
|  | import static org.mockito.Mockito.*; | ||||||
| 
 | 
 | ||||||
| public class UnleashTest { | public class UnleashTest { | ||||||
| 
 | 
 | ||||||
|  |     private ToggleRepository toggleRepository; | ||||||
|  |     private Unleash unleash; | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void setup() { | ||||||
|  |         toggleRepository = mock(ToggleRepository.class); | ||||||
|  |         unleash = new Unleash(toggleRepository); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void helloWorld() { |     public void known_toogle_and_strategy_should_be_active() { | ||||||
|         assertTrue(true); |         when(toggleRepository.getToggle("test")).thenReturn(new Toggle("test", true, "default", null)); | ||||||
|  | 
 | ||||||
|  |         assertThat(unleash.isEnabled("test"), is(true)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void unknown_strategy_should_be_considered_inactive() { | ||||||
|  |         when(toggleRepository.getToggle("test")).thenReturn(new Toggle("test", true, "whoot_strat", null)); | ||||||
|  | 
 | ||||||
|  |         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); | ||||||
|  | 
 | ||||||
|  |         assertThat(unleash.isEnabled("test"), is(false)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void should_register_custom_strategies() { | ||||||
|  |         //custom strategy | ||||||
|  |         Strategy customStrategy = mock(Strategy.class); | ||||||
|  |         when(customStrategy.getName()).thenReturn("custom"); | ||||||
|  | 
 | ||||||
|  |         //register custom strategy | ||||||
|  |         unleash = new Unleash(toggleRepository, customStrategy); | ||||||
|  |         when(toggleRepository.getToggle("test")).thenReturn(new Toggle("test", true, "custom", null)); | ||||||
|  | 
 | ||||||
|  |         unleash.isEnabled("test"); | ||||||
|  | 
 | ||||||
|  |         verify(customStrategy, times(1)).isEnabled(anyMap()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user