use of org.apache.hadoop.hbase.errorhandling.ForeignException in project hbase by apache.
the class MasterRpcServices method isSnapshotDone.
/**
* Checks if the specified snapshot is done.
* @return true if the snapshot is in file system ready to use,
* false if the snapshot is in the process of completing
* @throws ServiceException wrapping UnknownSnapshotException if invalid snapshot, or
* a wrapped HBaseSnapshotException with progress failure reason.
*/
@Override
public IsSnapshotDoneResponse isSnapshotDone(RpcController controller, IsSnapshotDoneRequest request) throws ServiceException {
LOG.debug("Checking to see if snapshot from request:" + ClientSnapshotDescriptionUtils.toString(request.getSnapshot()) + " is done");
try {
server.checkInitialized();
IsSnapshotDoneResponse.Builder builder = IsSnapshotDoneResponse.newBuilder();
boolean done = server.snapshotManager.isSnapshotDone(request.getSnapshot());
builder.setDone(done);
return builder.build();
} catch (ForeignException e) {
throw new ServiceException(e.getCause());
} catch (IOException e) {
throw new ServiceException(e);
}
}
use of org.apache.hadoop.hbase.errorhandling.ForeignException in project hbase by apache.
the class LogRollMasterProcedureManager method execProcedure.
@Override
public void execProcedure(ProcedureDescription desc) throws IOException {
if (!isBackupEnabled()) {
LOG.warn("Backup is not enabled. Check your " + BackupRestoreConstants.BACKUP_ENABLE_KEY + " setting");
return;
}
this.done = false;
// start the process on the RS
ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getInstance());
List<ServerName> serverNames = master.getServerManager().getOnlineServersList();
List<String> servers = new ArrayList<>();
for (ServerName sn : serverNames) {
servers.add(sn.toString());
}
List<NameStringPair> conf = desc.getConfigurationList();
byte[] data = new byte[0];
if (conf.size() > 0) {
// Get backup root path
data = Bytes.toBytes(conf.get(0).getValue());
}
Procedure proc = coordinator.startProcedure(monitor, desc.getInstance(), data, servers);
if (proc == null) {
String msg = "Failed to submit distributed procedure for '" + desc.getInstance() + "'";
LOG.error(msg);
throw new IOException(msg);
}
try {
// wait for the procedure to complete. A timer thread is kicked off that should cancel this
// if it takes too long.
proc.waitForCompleted();
LOG.info("Done waiting - exec procedure for " + desc.getInstance());
LOG.info("Distributed roll log procedure is successful!");
this.done = true;
} catch (InterruptedException e) {
ForeignException ee = new ForeignException("Interrupted while waiting for roll log procdure to finish", e);
monitor.receive(ee);
Thread.currentThread().interrupt();
} catch (ForeignException e) {
ForeignException ee = new ForeignException("Exception while waiting for roll log procdure to finish", e);
monitor.receive(ee);
}
monitor.rethrowException();
}
use of org.apache.hadoop.hbase.errorhandling.ForeignException in project hbase by apache.
the class TestZKProcedure method testMultiCohortWithMemberTimeoutDuringPrepare.
/**
* Test a distributed commit with multiple cohort members, where one of the cohort members has a
* timeout exception during the prepare stage.
*/
@Test
public void testMultiCohortWithMemberTimeoutDuringPrepare() throws Exception {
String opDescription = "error injection coordination";
String[] cohortMembers = new String[] { "one", "two", "three" };
List<String> expected = Lists.newArrayList(cohortMembers);
// error constants
final int memberErrorIndex = 2;
final CountDownLatch coordinatorReceivedErrorLatch = new CountDownLatch(1);
// start running the coordinator and its controller
ZKWatcher coordinatorWatcher = newZooKeeperWatcher();
ZKProcedureCoordinator coordinatorController = new ZKProcedureCoordinator(coordinatorWatcher, opDescription, COORDINATOR_NODE_NAME);
ThreadPoolExecutor pool = ProcedureCoordinator.defaultPool(COORDINATOR_NODE_NAME, POOL_SIZE, KEEP_ALIVE);
ProcedureCoordinator coordinator = spy(new ProcedureCoordinator(coordinatorController, pool));
// start a member for each node
SubprocedureFactory subprocFactory = Mockito.mock(SubprocedureFactory.class);
List<Pair<ProcedureMember, ZKProcedureMemberRpcs>> members = new ArrayList<>(expected.size());
for (String member : expected) {
ZKWatcher watcher = newZooKeeperWatcher();
ZKProcedureMemberRpcs controller = new ZKProcedureMemberRpcs(watcher, opDescription);
ThreadPoolExecutor pool2 = ProcedureMember.defaultPool(member, 1, KEEP_ALIVE);
ProcedureMember mem = new ProcedureMember(controller, pool2, subprocFactory);
members.add(new Pair<>(mem, controller));
controller.start(member, mem);
}
// setup mock subprocedures
final List<Subprocedure> cohortTasks = new ArrayList<>();
final int[] elem = new int[1];
for (int i = 0; i < members.size(); i++) {
ForeignExceptionDispatcher cohortMonitor = new ForeignExceptionDispatcher();
final ProcedureMember comms = members.get(i).getFirst();
Subprocedure commit = Mockito.spy(new SubprocedureImpl(comms, opName, cohortMonitor, WAKE_FREQUENCY, TIMEOUT));
// This nasty bit has one of the impls throw a TimeoutException
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
int index = elem[0];
if (index == memberErrorIndex) {
LOG.debug("Sending error to coordinator");
ForeignException remoteCause = new ForeignException("TIMER", new TimeoutException("subprocTimeout", 1, 2, 0));
Subprocedure r = ((Subprocedure) invocation.getMock());
LOG.error("Remote commit failure, not propagating error:" + remoteCause);
comms.receiveAbortProcedure(r.getName(), remoteCause);
assertTrue(r.isComplete());
// notification (which ensures that we never progress past prepare)
try {
Procedure.waitForLatch(coordinatorReceivedErrorLatch, new ForeignExceptionDispatcher(), WAKE_FREQUENCY, "coordinator received error");
} catch (InterruptedException e) {
LOG.debug("Wait for latch interrupted, done:" + (coordinatorReceivedErrorLatch.getCount() == 0));
// reset the interrupt status on the thread
Thread.currentThread().interrupt();
}
}
elem[0] = ++index;
return null;
}
}).when(commit).acquireBarrier();
cohortTasks.add(commit);
}
// pass out a task per member
final AtomicInteger taskIndex = new AtomicInteger();
Mockito.when(subprocFactory.buildSubprocedure(Mockito.eq(opName), (byte[]) Mockito.argThat(new ArrayEquals(data)))).thenAnswer(new Answer<Subprocedure>() {
@Override
public Subprocedure answer(InvocationOnMock invocation) throws Throwable {
int index = taskIndex.getAndIncrement();
Subprocedure commit = cohortTasks.get(index);
return commit;
}
});
// setup spying on the coordinator
ForeignExceptionDispatcher coordinatorTaskErrorMonitor = Mockito.spy(new ForeignExceptionDispatcher());
Procedure coordinatorTask = Mockito.spy(new Procedure(coordinator, coordinatorTaskErrorMonitor, WAKE_FREQUENCY, TIMEOUT, opName, data, expected));
when(coordinator.createProcedure(any(), eq(opName), eq(data), anyListOf(String.class))).thenReturn(coordinatorTask);
// count down the error latch when we get the remote error
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
// pass on the error to the master
invocation.callRealMethod();
// then count down the got error latch
coordinatorReceivedErrorLatch.countDown();
return null;
}
}).when(coordinatorTask).receive(Mockito.any());
// ----------------------------
// start running the operation
// ----------------------------
Procedure task = coordinator.startProcedure(coordinatorTaskErrorMonitor, opName, data, expected);
assertEquals("Didn't mock coordinator task", coordinatorTask, task);
// wait for the task to complete
try {
task.waitForCompleted();
} catch (ForeignException fe) {
// this may get caught or may not
}
// -------------
// verification
// -------------
// always expect prepared, never committed, and possible to have cleanup and finish (racy since
// error case)
waitAndVerifyProc(coordinatorTask, once, never(), once, atMost(1), true);
verifyCohortSuccessful(expected, subprocFactory, cohortTasks, once, never(), once, once, true);
// close all the open things
closeAll(coordinator, coordinatorController, members);
}
use of org.apache.hadoop.hbase.errorhandling.ForeignException in project hbase by apache.
the class TestProcedureMember method testPropagateConnectionErrorBackToManager.
/**
* Fail correctly on getting an external error while waiting for the prepared latch
* @throws Exception on failure
*/
@Test
public void testPropagateConnectionErrorBackToManager() throws Exception {
// setup the operation
member = buildCohortMember();
ProcedureMember memberSpy = spy(member);
// setup the commit and the spy
final ForeignExceptionDispatcher dispatcher = new ForeignExceptionDispatcher();
ForeignExceptionDispatcher dispSpy = spy(dispatcher);
Subprocedure commit = new EmptySubprocedure(member, dispatcher);
Subprocedure spy = spy(commit);
when(mockBuilder.buildSubprocedure(op, data)).thenReturn(spy);
// fail during the prepare phase
doThrow(new ForeignException("SRC", "prepare exception")).when(spy).acquireBarrier();
// and throw a connection error when we try to tell the controller about it
doThrow(new IOException("Controller is down!")).when(mockMemberComms).sendMemberAborted(eq(spy), any());
// run the operation
// build a new operation
Subprocedure subproc = memberSpy.createSubprocedure(op, data);
memberSpy.submitSubprocedure(subproc);
// if the operation doesn't die properly, then this will timeout
memberSpy.closeAndWait(TIMEOUT);
// make sure everything ran in order
InOrder order = inOrder(mockMemberComms, spy, dispSpy);
// make sure we acquire.
order.verify(spy).acquireBarrier();
order.verify(mockMemberComms, never()).sendMemberAcquired(spy);
// TODO Need to do another refactor to get this to propagate to the coordinator.
// make sure we pass a remote exception back the controller
// order.verify(mockMemberComms).sendMemberAborted(eq(spy),
// any());
// order.verify(dispSpy).receiveError(anyString(),
// any(), any());
}
Aggregations