@Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "imageDrive call failed") public void testDiskIsDestroyedIfImageFails() { Supplier<Map<String, WellKnownImage>> preInstalledImageSupplier = Suppliers.ofInstance(Maps .<String, WellKnownImage> newHashMap()); LoadingCache<String, DriveInfo> driveCache = CacheBuilder.newBuilder().build( new CacheLoader<String, DriveInfo>() { @Override public DriveInfo load(String key) throws Exception { throw new IllegalStateException("cache should not be used"); } }); ElasticStackApi api = EasyMock.createMock(ElasticStackApi.class); Predicate<DriveInfo> driveNotClaimed = Predicates.alwaysTrue(); DriveInfo mockDrive = new DriveInfo.Builder().uuid(UUID.randomUUID().toString()).name("mock") .metrics(new DriveMetrics.Builder().build()).build(); expect(api.createDrive(anyObject(DriveInfo.class))).andReturn(mockDrive); api.imageDrive(image.getId(), mockDrive.getUuid(), ImageConversionType.GUNZIP); expectLastCall().andThrow(new IllegalStateException("imageDrive call failed")); api.destroyDrive(mockDrive.getUuid()); expectLastCall(); replay(api); ElasticStackComputeServiceAdapter adapter = new ElasticStackComputeServiceAdapter(api, driveNotClaimed, preInstalledImageSupplier, driveCache, "12345678", MoreExecutors.newDirectExecutorService()); try { adapter.createNodeWithGroupEncodedIntoName("mock-group", "mock-name", template); } catch (IllegalStateException ex) { verify(api); throw ex; } }
@Override public NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024L); logger.debug(">> creating boot drive bytes(%d)", bootSize); DriveInfo drive = client .createDrive(new Drive.Builder().name(template.getImage().getId()).size(bootSize).build()); logger.debug("<< drive (%s)", drive); boolean success = driveNotClaimed.apply(drive); if (!success) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not create drive %s in time!", drive)); } logger.debug(">> imaging boot drive source(%s)", template.getImage().getId()); try { client.imageDrive(template.getImage().getId(), drive.getUuid(), ImageConversionType.GUNZIP); } catch (IllegalStateException ex) { logger.debug(">> could not image drive(%s). Cleaning up resources. [%s]", drive.getUuid(), ex.getMessage()); client.destroyDrive(drive.getUuid()); throw ex; } boolean ready = driveNotClaimed.apply(drive); if (!ready) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not image drive %s in time!", drive)); } logger.debug("<< imaged (%s)", drive); template.getOptions().userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, tag); Server toCreate = small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam()) .cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())) .tags(template.getOptions().getTags()).userMetadata(template.getOptions().getUserMetadata()).build(); ServerInfo from = client.createServer(toCreate); client.startServer(from.getUuid()); from = client.getServerInfo(from.getUuid()); return new NodeAndInitialCredentials<ServerInfo>(from, from.getUuid(), LoginCredentials.builder() .password(defaultVncPassword).build()); }
ElasticStackComputeServiceAdapter implements
      ComputeServiceAdapter<ServerInfo, Hardware, DriveInfo, Location> { @Override public NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024L); logger.debug(">> creating boot drive bytes(%d)", bootSize); DriveInfo drive = client .createDrive(new Drive.Builder().name(template.getImage().getId()).size(bootSize).build()); logger.debug("<< drive (%s)", drive); boolean success = driveNotClaimed.apply(drive); if (!success) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not create drive %s in time!", drive)); } logger.debug(">> imaging boot drive source(%s)", template.getImage().getId()); try { client.imageDrive(template.getImage().getId(), drive.getUuid(), ImageConversionType.GUNZIP); } catch (IllegalStateException ex) { logger.debug(">> could not image drive(%s). Cleaning up resources. [%s]", drive.getUuid(), ex.getMessage()); client.destroyDrive(drive.getUuid()); throw ex; } boolean ready = driveNotClaimed.apply(drive); if (!ready) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not image drive %s in time!", drive)); } logger.debug("<< imaged (%s)", drive); template.getOptions().userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, tag); Server toCreate = small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam()) .cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())) .tags(template.getOptions().getTags()).userMetadata(template.getOptions().getUserMetadata()).build(); ServerInfo from = client.createServer(toCreate); client.startServer(from.getUuid()); from = client.getServerInfo(from.getUuid()); return new NodeAndInitialCredentials<ServerInfo>(from, from.getUuid(), LoginCredentials.builder() .password(defaultVncPassword).build()); } }
ElasticStackComputeServiceAdapter implements
      ComputeServiceAdapter<ServerInfo, Hardware, DriveInfo, Location> { @Override public NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024L); logger.debug(">> creating boot drive bytes(%d)", bootSize); DriveInfo drive = client .createDrive(new Drive.Builder().name(template.getImage().getId()).size(bootSize).build()); logger.debug("<< drive (%s)", drive); boolean success = driveNotClaimed.apply(drive); if (!success) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not create drive %s in time!", drive)); } logger.debug(">> imaging boot drive source(%s)", template.getImage().getId()); try { client.imageDrive(template.getImage().getId(), drive.getUuid(), ImageConversionType.GUNZIP); } catch (IllegalStateException ex) { logger.debug(">> could not image drive(%s). Cleaning up resources. [%s]", drive.getUuid(), ex.getMessage()); client.destroyDrive(drive.getUuid()); throw ex; } boolean ready = driveNotClaimed.apply(drive); if (!ready) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not image drive %s in time!", drive)); } logger.debug("<< imaged (%s)", drive); template.getOptions().userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, tag); Server toCreate = small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam()) .cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())) .tags(template.getOptions().getTags()).userMetadata(template.getOptions().getUserMetadata()).build(); ServerInfo from = client.createServer(toCreate); client.startServer(from.getUuid()); from = client.getServerInfo(from.getUuid()); return new NodeAndInitialCredentials<ServerInfo>(from, from.getUuid(), LoginCredentials.builder() .password(defaultVncPassword).build()); } @Inject  ElasticStackComputeServiceAdapter(ElasticStackApi client, Predicate<DriveInfo> driveNotClaimed,
         @Memoized Supplier<Map<String, WellKnownImage>> preinstalledImages, LoadingCache<String, DriveInfo> cache,
         @Named(ElasticStackConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword,
         @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor); }
ElasticStackComputeServiceAdapter implements
      ComputeServiceAdapter<ServerInfo, Hardware, DriveInfo, Location> { @Override public NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024L); logger.debug(">> creating boot drive bytes(%d)", bootSize); DriveInfo drive = client .createDrive(new Drive.Builder().name(template.getImage().getId()).size(bootSize).build()); logger.debug("<< drive (%s)", drive); boolean success = driveNotClaimed.apply(drive); if (!success) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not create drive %s in time!", drive)); } logger.debug(">> imaging boot drive source(%s)", template.getImage().getId()); try { client.imageDrive(template.getImage().getId(), drive.getUuid(), ImageConversionType.GUNZIP); } catch (IllegalStateException ex) { logger.debug(">> could not image drive(%s). Cleaning up resources. [%s]", drive.getUuid(), ex.getMessage()); client.destroyDrive(drive.getUuid()); throw ex; } boolean ready = driveNotClaimed.apply(drive); if (!ready) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not image drive %s in time!", drive)); } logger.debug("<< imaged (%s)", drive); template.getOptions().userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, tag); Server toCreate = small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam()) .cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())) .tags(template.getOptions().getTags()).userMetadata(template.getOptions().getUserMetadata()).build(); ServerInfo from = client.createServer(toCreate); client.startServer(from.getUuid()); from = client.getServerInfo(from.getUuid()); return new NodeAndInitialCredentials<ServerInfo>(from, from.getUuid(), LoginCredentials.builder() .password(defaultVncPassword).build()); } @Inject  ElasticStackComputeServiceAdapter(ElasticStackApi client, Predicate<DriveInfo> driveNotClaimed,
         @Memoized Supplier<Map<String, WellKnownImage>> preinstalledImages, LoadingCache<String, DriveInfo> cache,
         @Named(ElasticStackConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword,
         @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor); @Override NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template); @Override Iterable<Hardware> listHardwareProfiles(); @Override Iterable<DriveInfo> listImages(); @Override Iterable<ServerInfo> listNodes(); @Override Iterable<ServerInfo> listNodesByIds(final Iterable<String> ids); @Override Iterable<Location> listLocations(); @Override ServerInfo getNode(String id); @Override DriveInfo getImage(String id); @Override void destroyNode(String id); @Override void rebootNode(String id); @Override void resumeNode(String id); @Override void suspendNode(String id); }
ElasticStackComputeServiceAdapter implements
      ComputeServiceAdapter<ServerInfo, Hardware, DriveInfo, Location> { @Override public NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024L); logger.debug(">> creating boot drive bytes(%d)", bootSize); DriveInfo drive = client .createDrive(new Drive.Builder().name(template.getImage().getId()).size(bootSize).build()); logger.debug("<< drive (%s)", drive); boolean success = driveNotClaimed.apply(drive); if (!success) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not create drive %s in time!", drive)); } logger.debug(">> imaging boot drive source(%s)", template.getImage().getId()); try { client.imageDrive(template.getImage().getId(), drive.getUuid(), ImageConversionType.GUNZIP); } catch (IllegalStateException ex) { logger.debug(">> could not image drive(%s). Cleaning up resources. [%s]", drive.getUuid(), ex.getMessage()); client.destroyDrive(drive.getUuid()); throw ex; } boolean ready = driveNotClaimed.apply(drive); if (!ready) { client.destroyDrive(drive.getUuid()); throw new IllegalStateException(String.format("could not image drive %s in time!", drive)); } logger.debug("<< imaged (%s)", drive); template.getOptions().userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, tag); Server toCreate = small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam()) .cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())) .tags(template.getOptions().getTags()).userMetadata(template.getOptions().getUserMetadata()).build(); ServerInfo from = client.createServer(toCreate); client.startServer(from.getUuid()); from = client.getServerInfo(from.getUuid()); return new NodeAndInitialCredentials<ServerInfo>(from, from.getUuid(), LoginCredentials.builder() .password(defaultVncPassword).build()); } @Inject  ElasticStackComputeServiceAdapter(ElasticStackApi client, Predicate<DriveInfo> driveNotClaimed,
         @Memoized Supplier<Map<String, WellKnownImage>> preinstalledImages, LoadingCache<String, DriveInfo> cache,
         @Named(ElasticStackConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword,
         @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor); @Override NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String tag, String name, Template template); @Override Iterable<Hardware> listHardwareProfiles(); @Override Iterable<DriveInfo> listImages(); @Override Iterable<ServerInfo> listNodes(); @Override Iterable<ServerInfo> listNodesByIds(final Iterable<String> ids); @Override Iterable<Location> listLocations(); @Override ServerInfo getNode(String id); @Override DriveInfo getImage(String id); @Override void destroyNode(String id); @Override void rebootNode(String id); @Override void resumeNode(String id); @Override void suspendNode(String id);  }