Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/main/java/io/github/protocol/bookkeeper/AutoRecovery.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
package io.github.protocol.bookkeeper;

public interface AutoRecovery {

AutoRecoveryStatus autoRecoveryStatus() throws BookkeeperAdminException;

void recoveryBookie(RecoveryBookieReqData reqData) throws BookkeeperAdminException;

UnderReplicatedLedger listUnderReplicatedLedger(ListUnderReplicatedLedgerReqData reqData)
throws BookkeeperAdminException;

Auditor whoIsAuditor() throws BookkeeperAdminException;

void triggerAudit() throws BookkeeperAdminException;

void lostBookieRecoveryDelay() throws BookkeeperAdminException;

void lostBookieRecoveryDelay(int delaySeconds) throws BookkeeperAdminException;

void decommission(String bookieId) throws BookkeeperAdminException;

}
124 changes: 124 additions & 0 deletions src/main/java/io/github/protocol/bookkeeper/AutoRecoveryImpl.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,133 @@
package io.github.protocol.bookkeeper;

import com.fasterxml.jackson.core.type.TypeReference;

import java.io.IOException;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;

public class AutoRecoveryImpl implements AutoRecovery {
private final InnerHttpClient innerHttpClient;

public AutoRecoveryImpl(InnerHttpClient innerHttpClient) {
this.innerHttpClient = innerHttpClient;
}

@Override
public AutoRecoveryStatus autoRecoveryStatus() throws BookkeeperAdminException {
try {
HttpResponse<String> resp = innerHttpClient.get(UrlConst.AUTO_RECOVERY_STATUS);
return JacksonService.toRefer(resp.body(), new TypeReference<AutoRecoveryStatus>() {
});
} catch (Exception e) {
throw new BookkeeperAdminException(e);
}
}

@Override
public void recoveryBookie(RecoveryBookieReqData reqData) throws BookkeeperAdminException {
try {
innerHttpClient.put(UrlConst.AUTO_RECOVERY, reqData);
} catch (IOException | InterruptedException e) {
throw new BookkeeperAdminException(e);
}
}

@Override
public UnderReplicatedLedger listUnderReplicatedLedger(ListUnderReplicatedLedgerReqData reqData)
throws BookkeeperAdminException {
try {
String url = UrlConst.AUTO_RECOVERY_LIST_UNDER_REPLICATED_LEDGER;
if (reqData.isPrintMissingReplica()) {
url += "?&printmissingreplica=true";
} else {
url += "?&printmissingreplica=false";
}
if (reqData.getExcludingBookieId() != null && !"".equals(reqData.getExcludingBookieId())) {
url = url + "&excludingmissingreplica=" + reqData.getExcludingBookieId();
}
if (reqData.getIncludingBookieId() != null && !"".equals(reqData.getIncludingBookieId())) {
url = url + "&missingreplica=" + reqData.getIncludingBookieId();
}
HttpResponse<String> resp = innerHttpClient.get(url);
if ((resp.statusCode() < 200 || resp.statusCode() >= 300) && resp.body() != null) {
throw new BookkeeperAdminException(resp.body());
}
return JacksonService.toRefer(resp.body(), new TypeReference<UnderReplicatedLedger>() {
});
} catch (Exception e) {
throw new BookkeeperAdminException(e);
}
}

@Override
public Auditor whoIsAuditor() throws BookkeeperAdminException {
try {
HttpResponse<String> resp = innerHttpClient.get(UrlConst.AUTO_RECOVERY_WHO_IS_AUDITOR);

if ((resp.statusCode() < 200 || resp.statusCode() >= 300) && resp.body() != null) {
throw new BookkeeperAdminException(resp.body());
}
return JacksonService.toRefer(resp.body(), new TypeReference<Auditor>() {
});
} catch (Exception e) {
throw new BookkeeperAdminException(e);
}
}

@Override
public void triggerAudit() throws BookkeeperAdminException {
try {
HttpResponse<String> resp = innerHttpClient.put(UrlConst.AUTO_RECOVERY_TRIGGER_AUDIT);
if ((resp.statusCode() < 200 || resp.statusCode() >= 300) && resp.body() != null) {
throw new BookkeeperAdminException(resp.body());
}
} catch (IOException | InterruptedException e) {
throw new BookkeeperAdminException(e);
}
}

@Override
public void lostBookieRecoveryDelay() throws BookkeeperAdminException {
try {
HttpResponse<String> resp = innerHttpClient.put(UrlConst.AUTO_RECOVERY_LOST_BOOKIE_RECOVERY_DELAY);
if ((resp.statusCode() < 200 || resp.statusCode() >= 300) && resp.body() != null) {
throw new BookkeeperAdminException(resp.body());
}
} catch (IOException | InterruptedException e) {
throw new BookkeeperAdminException(e);
}
}

@Override
public void lostBookieRecoveryDelay(int delaySeconds) throws BookkeeperAdminException {
Map<String, Integer> reqDate = new HashMap<>();
reqDate.put("delay_seconds", delaySeconds);
try {
HttpResponse<String> resp = innerHttpClient.put(UrlConst.AUTO_RECOVERY_LOST_BOOKIE_RECOVERY_DELAY, reqDate);
if ((resp.statusCode() < 200 || resp.statusCode() >= 300) && resp.body() != null) {
throw new BookkeeperAdminException(resp.body());
}
} catch (IOException | InterruptedException e) {
throw new BookkeeperAdminException(e);
}
}

@Override
public void decommission(String bookieId) throws BookkeeperAdminException {
if (bookieId == null || "".equals(bookieId)) {
throw new BookkeeperAdminException("bookie is empty");
}
Map<String, String> reqDate = new HashMap<>();
reqDate.put("bookie_src", bookieId);
try {
HttpResponse<String> resp = innerHttpClient.put(UrlConst.AUTO_RECOVERY_DECOMMISSION, reqDate);
if ((resp.statusCode() < 200 || resp.statusCode() >= 300) && resp.body() != null) {
throw new BookkeeperAdminException(resp.body());
}
} catch (IOException | InterruptedException e) {
throw new BookkeeperAdminException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import io.github.embedded.bookkeeper.core.EmbeddedBookkeeperServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.util.Collections;

public class AutoRecoveryImplTest {

Expand All @@ -23,4 +27,51 @@ public static void setup() throws Exception {
public static void teardown() throws Exception {
SERVER.close();
}

@Test
public void testAutoRecoveryStatus() throws BookkeeperAdminException {
AutoRecoveryStatus status = autoRecovery.autoRecoveryStatus();
Assertions.assertNotNull(status);
Assertions.assertTrue(status.isEnabled());
}

@Test
public void testRecoveryBookie() throws BookkeeperAdminException {
RecoveryBookieReqData reqData = new RecoveryBookieReqData();
reqData.setBookieSrc(Collections.singletonList("localhost:3181"));
reqData.setDeleteCookie(false);
autoRecovery.recoveryBookie(reqData);
}

@Test
public void testListUnderReplicatedLedger() {
ListUnderReplicatedLedgerReqData reqData = new ListUnderReplicatedLedgerReqData();
reqData.setPrintMissingReplica(true);
Assertions.assertThrows(BookkeeperAdminException.class, () -> autoRecovery.listUnderReplicatedLedger(reqData));
}

@Test
public void testWhoIsAuditor() {
Assertions.assertThrows(BookkeeperAdminException.class, () -> autoRecovery.whoIsAuditor());
}

@Test
public void testTriggerAudit() {
Assertions.assertThrows(BookkeeperAdminException.class, () -> autoRecovery.triggerAudit());
}

@Test
public void testLostBookieRecoveryDelayByDefault() {
Assertions.assertThrows(BookkeeperAdminException.class, () -> autoRecovery.lostBookieRecoveryDelay());
}

@Test
public void testLostBookieRecoveryDelay() throws BookkeeperAdminException {
autoRecovery.lostBookieRecoveryDelay(5);
}

@Test
public void testDecommission() throws BookkeeperAdminException {
autoRecovery.decommission("localhost:3181");
}
}