-
Notifications
You must be signed in to change notification settings - Fork 210
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Oleg Kovalov
committed
May 28, 2019
1 parent
5d91f39
commit 324b9b2
Showing
9 changed files
with
234 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
hermes-api/src/main/java/pl/allegro/tech/hermes/api/endpoints/ModeEndpoint.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package pl.allegro.tech.hermes.api.endpoints; | ||
|
||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON; | ||
import pl.allegro.tech.hermes.api.BlacklistStatus; | ||
|
||
import javax.ws.rs.Consumes; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.HttpMethod; | ||
import javax.ws.rs.POST; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.PathParam; | ||
import javax.ws.rs.Produces; | ||
import javax.ws.rs.core.Context; | ||
import javax.ws.rs.core.Response; | ||
import javax.ws.rs.core.SecurityContext; | ||
|
||
@Path("mode") | ||
public interface ModeEndpoint { | ||
|
||
@GET | ||
@Produces(APPLICATION_JSON) | ||
String getMode(); | ||
|
||
@POST | ||
@Produces(APPLICATION_JSON) | ||
Response setMode(String mode); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
hermes-management/src/main/java/pl/allegro/tech/hermes/management/api/ReadOnlyFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package pl.allegro.tech.hermes.management.api; | ||
|
||
import static javax.servlet.http.HttpServletResponse.*; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.web.filter.GenericFilterBean; | ||
import pl.allegro.tech.hermes.management.domain.mode.ModeService; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.ServletRequest; | ||
import javax.servlet.ServletResponse; | ||
import javax.servlet.annotation.WebFilter; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
@WebFilter(urlPatterns = "/*") | ||
public class ReadOnlyFilter extends GenericFilterBean { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(ReadOnlyFilter.class); | ||
private static final String READ_ONLY_ERROR_MESSAGE = "Action forbidden due to read-only mode"; | ||
private static final Set<String> whitelist = new HashSet<>(); | ||
|
||
private final ModeService modeService; | ||
|
||
public ReadOnlyFilter(ModeService modeService) { | ||
this.modeService = modeService; | ||
|
||
initWhitelist(); | ||
} | ||
|
||
@Override | ||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { | ||
HttpServletRequest req = (HttpServletRequest) request; | ||
|
||
if (modeService.isReadOnlyEnabled()) { | ||
if (!req.getMethod().equals("GET") && !isWhitelisted(req.getRequestURI())) { | ||
HttpServletResponse resp = ((HttpServletResponse) response); | ||
resp.sendError(SC_SERVICE_UNAVAILABLE, READ_ONLY_ERROR_MESSAGE); | ||
return; | ||
} | ||
} | ||
chain.doFilter(request, response); | ||
} | ||
|
||
private boolean isWhitelisted(String requestURI) { | ||
if (requestURI.startsWith("/query")) { | ||
return true; | ||
} | ||
if (requestURI.startsWith("/mode")) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
private void initWhitelist() { | ||
whitelist.add("/topics/query"); | ||
whitelist.add("topics/{topicName}/subscriptions/query"); | ||
whitelist.add("query/groups"); | ||
whitelist.add("query/topics"); | ||
whitelist.add("query/topics"); | ||
whitelist.add("query/subscriptions"); | ||
whitelist.add("query/topics/metrics"); | ||
whitelist.add("query/subscriptions/metrics"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
.../src/integration/java/pl/allegro/tech/hermes/integration/management/ReadOnlyModeTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package pl.allegro.tech.hermes.integration.management; | ||
|
||
import org.testng.annotations.BeforeMethod; | ||
import org.testng.annotations.Test; | ||
import pl.allegro.tech.hermes.api.Group; | ||
import pl.allegro.tech.hermes.integration.IntegrationTest; | ||
import static pl.allegro.tech.hermes.integration.test.HermesAssertions.assertThat; | ||
import static pl.allegro.tech.hermes.management.domain.mode.ModeService.ManagementMode.READ_ONLY; | ||
import static pl.allegro.tech.hermes.management.domain.mode.ModeService.ManagementMode.READ_WRITE; | ||
import static pl.allegro.tech.hermes.test.helper.builder.GroupBuilder.group; | ||
|
||
import javax.ws.rs.core.Response; | ||
|
||
public class ReadOnlyModeTest extends IntegrationTest { | ||
|
||
@BeforeMethod | ||
public void initialize() { | ||
management.modeEndpoint().setMode(READ_WRITE.getText()); | ||
} | ||
|
||
@Test | ||
public void shouldAllowNonModifyingOperations() { | ||
// given | ||
management.modeEndpoint().setMode(READ_WRITE.getText()); | ||
String groupName = "kek"; | ||
|
||
// when | ||
Response response = createGroup(groupName); | ||
|
||
// then | ||
assertThat(response).hasStatus(Response.Status.CREATED); | ||
} | ||
|
||
@Test | ||
public void shouldRestrictModifyingOperations() { | ||
// given | ||
management.modeEndpoint().setMode(READ_ONLY.getText()); | ||
String groupName = "lol"; | ||
|
||
// when | ||
Response response = createGroup(groupName); | ||
|
||
// then | ||
assertThat(response).hasStatus(Response.Status.SERVICE_UNAVAILABLE); | ||
} | ||
|
||
@Test | ||
public void shouldSwitchModeBack() { | ||
// given | ||
management.modeEndpoint().setMode(READ_ONLY.getText()); | ||
String groupName = "mda"; | ||
|
||
// when | ||
Response response = createGroup(groupName); | ||
|
||
// then | ||
assertThat(response).hasStatus(Response.Status.SERVICE_UNAVAILABLE); | ||
|
||
// and | ||
management.modeEndpoint().setMode(READ_WRITE.getText()); | ||
|
||
// when | ||
response = createGroup(groupName); | ||
|
||
// then | ||
assertThat(response).hasStatus(Response.Status.CREATED); | ||
} | ||
|
||
public Response createGroup(String groupName) { | ||
Group group = group(groupName).build(); | ||
return management.group().create(group); | ||
} | ||
} |