Add an endpoint for getting the current state of feature flags.

This commit is contained in:
Jon Chambers 2020-08-27 12:25:25 -04:00 committed by Jon Chambers
parent acf52ad8a3
commit 32b18c9509
3 changed files with 52 additions and 1 deletions

View File

@ -6,15 +6,19 @@ import org.whispersystems.textsecuregcm.storage.FeatureFlagsManager;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Path("/v1/featureflag")
@ -28,6 +32,17 @@ public class FeatureFlagsController {
this.authorizedTokens = authorizedTokens.stream().map(token -> token.getBytes(StandardCharsets.UTF_8)).collect(Collectors.toList());
}
@Timed
@GET
@Produces(MediaType.APPLICATION_JSON)
public Map<String, Boolean> get(@HeaderParam("Token") final String token) {
if (!isAuthorized(token)) {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
return featureFlagsManager.getAllFlags();
}
@Timed
@PUT
@Path("/{featureFlag}")

View File

@ -67,11 +67,15 @@ public class FeatureFlagsManager implements Managed {
refreshFeatureFlags();
}
public Map<String, Boolean> getAllFlags() {
return featureFlags.get();
}
@VisibleForTesting
void refreshFeatureFlags() {
final Map<String, Boolean> refreshedFeatureFlags = featureFlagDatabase.getFeatureFlags();
featureFlags.set(refreshedFeatureFlags);
featureFlags.set(Collections.unmodifiableMap(refreshedFeatureFlags));
for (final Map.Entry<String, Boolean> entry : refreshedFeatureFlags.entrySet()) {
final String featureFlag = entry.getKey();

View File

@ -20,12 +20,15 @@ import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@RunWith(JUnitParamsRunner.class)
public class FeatureFlagsControllerTest {
@ -83,6 +86,35 @@ public class FeatureFlagsControllerTest {
}
}
@SuppressWarnings("rawtypes")
@Test
public void testGet() {
final Map<String, Boolean> managedFlags = Map.of("activeFlag", true, "inactiveFlag", false);
when(FEATURE_FLAG_MANAGER.getAllFlags()).thenReturn(managedFlags);
{
final Map returnedFlags = resources.getJerseyTest()
.target("/v1/featureflag")
.request()
.header("Token", "first")
.get(Map.class);
verify(FEATURE_FLAG_MANAGER).getAllFlags();
assertEquals(managedFlags, returnedFlags);
}
{
final Response response = resources.getJerseyTest()
.target("/v1/featureflag")
.request()
.header("Token", "bogus-token")
.get();
assertEquals(401, response.getStatus());
verifyNoMoreInteractions(FEATURE_FLAG_MANAGER);
}
}
@Test
public void testDelete() {
{