diff --git a/hermes-management/src/main/java/pl/allegro/tech/hermes/management/api/ModeEndpoint.java b/hermes-management/src/main/java/pl/allegro/tech/hermes/management/api/ModeEndpoint.java index a02976afb5..c07ae31509 100644 --- a/hermes-management/src/main/java/pl/allegro/tech/hermes/management/api/ModeEndpoint.java +++ b/hermes-management/src/main/java/pl/allegro/tech/hermes/management/api/ModeEndpoint.java @@ -17,8 +17,8 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.MediaType.TEXT_PLAIN; -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.management.domain.mode.ModeService.ManagementMode.READ_ONLY_ADMIN; @Component @Path("/mode") @@ -48,10 +48,11 @@ public Response setMode(@QueryParam("mode") String mode) { } switch (mode) { case ModeService.READ_WRITE: - modeService.setMode(READ_WRITE); + modeService.setModeByAdmin(READ_WRITE); break; case ModeService.READ_ONLY: - modeService.setMode(READ_ONLY); + case ModeService.READ_ONLY_ADMIN: + modeService.setModeByAdmin(READ_ONLY_ADMIN); break; default: return Response.status(Response.Status.BAD_REQUEST).build(); diff --git a/hermes-management/src/main/java/pl/allegro/tech/hermes/management/domain/mode/ModeService.java b/hermes-management/src/main/java/pl/allegro/tech/hermes/management/domain/mode/ModeService.java index df1e2d92f0..6b8583d0a5 100644 --- a/hermes-management/src/main/java/pl/allegro/tech/hermes/management/domain/mode/ModeService.java +++ b/hermes-management/src/main/java/pl/allegro/tech/hermes/management/domain/mode/ModeService.java @@ -7,10 +7,12 @@ public class ModeService { public static final String READ_WRITE = "readWrite"; public static final String READ_ONLY = "readOnly"; + public static final String READ_ONLY_ADMIN = "readOnlyAdmin"; public enum ManagementMode { READ_WRITE(ModeService.READ_WRITE), - READ_ONLY(ModeService.READ_ONLY); + READ_ONLY(ModeService.READ_ONLY), + READ_ONLY_ADMIN(ModeService.READ_ONLY_ADMIN); private final String text; @@ -30,11 +32,18 @@ public ManagementMode getMode() { return mode; } - public void setMode(ManagementMode mode) { + public synchronized void setModeByAdmin(ManagementMode mode) { this.mode = mode; } public boolean isReadOnlyEnabled() { - return mode == ManagementMode.READ_ONLY; + return mode == ManagementMode.READ_ONLY || mode == ManagementMode.READ_ONLY_ADMIN; + } + + public synchronized void setMode(ManagementMode newMode) { + /* READ_ONLY_ADMIN is a flag that can be changed only by admin */ + if (!mode.equals(ManagementMode.READ_ONLY_ADMIN)) { + this.mode = newMode; + } } } diff --git a/hermes-management/src/test/groovy/pl/allegro/tech/hermes/management/domain/health/HealthCheckTaskTest.groovy b/hermes-management/src/test/groovy/pl/allegro/tech/hermes/management/domain/health/HealthCheckTaskTest.groovy index aed11162b0..bdff69be31 100644 --- a/hermes-management/src/test/groovy/pl/allegro/tech/hermes/management/domain/health/HealthCheckTaskTest.groovy +++ b/hermes-management/src/test/groovy/pl/allegro/tech/hermes/management/domain/health/HealthCheckTaskTest.groovy @@ -90,6 +90,37 @@ class HealthCheckTaskTest extends MultiZookeeperIntegrationTest { successfulCounter.count() == 3 } + def "should not change status to READ_WRITE if READ_ONLY is set by admin"() { + given: + modeService.setModeByAdmin(ModeService.ManagementMode.READ_ONLY_ADMIN) + + when: + healthCheckTask.run() + + then: + modeService.readOnlyEnabled + + and: + successfulCounter.count() == 2 + } + + def "should change status from READ_ONLY_ADMIN to READ_WRITE only by admin"() { + given: + modeService.setModeByAdmin(ModeService.ManagementMode.READ_ONLY_ADMIN) + + when: + healthCheckTask.run() + + then: + modeService.readOnlyEnabled + + when: + modeService.setModeByAdmin(ModeService.ManagementMode.READ_WRITE) + + then: + !modeService.readOnlyEnabled + } + static setupZookeeperPath(ZookeeperClient zookeeperClient, String path) { def healthCheckPathExists = zookeeperClient.curatorFramework .checkExists()