@Test public void testDeleteSnapshot() throws Exception { String snapshotName = "completed"; SnapshotDescription snapshot = SnapshotDescription.newBuilder().setName(snapshotName).build(); try { master.deleteSnapshot(new HSnapshotDescription(snapshot)); fail("Master didn't throw exception when attempting to delete snapshot that doesn't exist"); } catch (IOException e) { LOG.debug("Correctly failed delete of non-existant snapshot:" + e.getMessage()); } // write one snapshot to the fs Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName, rootDir); SnapshotDescriptionUtils.writeSnapshotInfo(snapshot, snapshotDir, fs); // then delete the existing snapshot,which shouldn't cause an exception to be thrown master.deleteSnapshot(new HSnapshotDescription(snapshot)); }
/** * List completed snapshots. * @return a list of snapshot descriptors for completed snapshots * @throws IOException if a network error occurs */ public List<SnapshotDescription> listSnapshots() throws IOException { List<SnapshotDescription> snapshots = new LinkedList<SnapshotDescription>(); try { for (HSnapshotDescription snapshot : getMaster().getCompletedSnapshots()) { snapshots.add(snapshot.getProto()); } } catch (RemoteException e) { throw RemoteExceptionHandler.decodeRemoteException(e); } return snapshots; }
/** * Delete an existing snapshot. * @param snapshotName name of the snapshot * @throws IOException if a remote or network exception occurs */ public void deleteSnapshot(final byte[] snapshotName) throws IOException { // make sure the snapshot is possibly valid HTableDescriptor.isLegalTableName(snapshotName); // do the delete SnapshotDescription snapshot = SnapshotDescription.newBuilder() .setName(Bytes.toString(snapshotName)).build(); try { getMaster().deleteSnapshot(new HSnapshotDescription(snapshot)); } catch (RemoteException e) { throw RemoteExceptionHandler.decodeRemoteException(e); } }
/** * List the currently available/stored snapshots. Any in-progress snapshots are ignored */ @Override public List<HSnapshotDescription> getCompletedSnapshots() throws IOException { List<HSnapshotDescription> availableSnapshots = new ArrayList<HSnapshotDescription>(); List<SnapshotDescription> snapshots = snapshotManager.getCompletedSnapshots(); // convert to writables for (SnapshotDescription snapshot: snapshots) { availableSnapshots.add(new HSnapshotDescription(snapshot)); } return availableSnapshots; }
/** * Execute Delete Snapshot operation. * @throws ServiceException wrapping SnapshotDoesNotExistException if specified snapshot did not * exist. */ @Override public void deleteSnapshot(final HSnapshotDescription request) throws IOException { try { this.snapshotManager.checkSnapshotSupport(); } catch (UnsupportedOperationException e) { throw new IOException(e); } snapshotManager.deleteSnapshot(request.getProto()); }
/** * Make sure that we validate the snapshot name and the table name before we pass anything across * the wire * @throws Exception on failure */ @Test public void testValidateSnapshotName() throws Exception { HConnectionManager.HConnectionImplementation mockConnection = Mockito .mock(HConnectionManager.HConnectionImplementation.class); Configuration conf = HBaseConfiguration.create(); Mockito.when(mockConnection.getConfiguration()).thenReturn(conf); HBaseAdmin admin = new HBaseAdmin(mockConnection); SnapshotDescription.Builder builder = SnapshotDescription.newBuilder(); // check that invalid snapshot names fail failSnapshotStart(admin, builder.setName(HConstants.SNAPSHOT_DIR_NAME).build()); failSnapshotStart(admin, builder.setName("-snapshot").build()); failSnapshotStart(admin, builder.setName("snapshot fails").build()); failSnapshotStart(admin, builder.setName("snap$hot").build()); // check the table name also get verified failSnapshotStart(admin, builder.setName("snapshot").setTable(".table").build()); failSnapshotStart(admin, builder.setName("snapshot").setTable("-table").build()); failSnapshotStart(admin, builder.setName("snapshot").setTable("table fails").build()); failSnapshotStart(admin, builder.setName("snapshot").setTable("tab%le").build()); // mock the master connection HMasterInterface master = Mockito.mock(HMasterInterface.class); Mockito.when(mockConnection.getMaster()).thenReturn(master); Mockito.when( master.snapshot(Mockito.any(HSnapshotDescription.class))).thenReturn((long)0); Mockito.when( master.isSnapshotDone( Mockito.any(HSnapshotDescription.class))).thenReturn(true); // make sure that we can use valid names admin.snapshot(builder.setName("snapshot").setTable("table").build()); }
@Test public void testGetCompletedSnapshots() throws Exception { // first check when there are no snapshots List<HSnapshotDescription> snapshots = master.getCompletedSnapshots(); assertEquals("Found unexpected number of snapshots", 0, snapshots.size()); // write one snapshot to the fs String snapshotName = "completed"; Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName, rootDir); SnapshotDescription snapshot = SnapshotDescription.newBuilder().setName(snapshotName).build(); SnapshotDescriptionUtils.writeSnapshotInfo(snapshot, snapshotDir, fs); // check that we get one snapshot snapshots = master.getCompletedSnapshots(); assertEquals("Found unexpected number of snapshots", 1, snapshots.size()); List<HSnapshotDescription> expected = Lists.newArrayList(new HSnapshotDescription(snapshot)); assertEquals("Returned snapshots don't match created snapshots", expected, snapshots); // write a second snapshot snapshotName = "completed_two"; snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName, rootDir); snapshot = SnapshotDescription.newBuilder().setName(snapshotName).build(); SnapshotDescriptionUtils.writeSnapshotInfo(snapshot, snapshotDir, fs); expected.add(new HSnapshotDescription(snapshot)); // check that we get one snapshot snapshots = master.getCompletedSnapshots(); assertEquals("Found unexpected number of snapshots", 2, snapshots.size()); assertEquals("Returned snapshots don't match created snapshots", expected, snapshots); }
/** * List completed snapshots. * @return a list of snapshot descriptors for completed snapshots * @throws IOException if a network error occurs */ public List<SnapshotDescription> listSnapshots() throws IOException { List<SnapshotDescription> snapshots = new LinkedList<SnapshotDescription>(); try { for (HSnapshotDescription snapshot: getMaster().getCompletedSnapshots()) { snapshots.add(snapshot.getProto()); } } catch (RemoteException e) { throw RemoteExceptionHandler.decodeRemoteException(e); } return snapshots; }
/** * Helper method for testing async snapshot operations. Just waits for the given snapshot to * complete on the server by repeatedly checking the master. * @param master running the snapshot * @param snapshot to check * @param sleep amount to sleep between checks to see if the snapshot is done * @throws IOException if the snapshot fails */ public static void waitForSnapshotToComplete(HMaster master, HSnapshotDescription snapshot, long sleep) throws IOException { boolean done = false; while (!done) { done = master.isSnapshotDone(snapshot); try { Thread.sleep(sleep); } catch (InterruptedException e) { throw new IOException(e); } } }
/** * Expect the snapshot to throw an error when checking if the snapshot is complete * @param master master to check * @param snapshot the {@link HSnapshotDescription} request to pass to the master * @param clazz expected exception from the master */ public static void expectSnapshotDoneException(HMaster master, HSnapshotDescription snapshot, Class<? extends HBaseSnapshotException> clazz) { try { boolean res = master.isSnapshotDone(snapshot); Assert.fail("didn't fail to lookup a snapshot: res=" + res); } catch (HBaseSnapshotException e) { assertEquals("Threw wrong snapshot exception!", clazz, e.getClass()); } catch (Throwable t) { Assert.fail("Threw an unexpected exception:" + t); } }