public BackupProcessor(DistributedLockManager lockManager, MetadataStorage<BackupMetadata> metadataStorage, FileStorage localStorage, FileStorage offsiteStorage, CodecFactory codecFactory, ExecutorService offsiteUploadWorkers, Size chunkSize, FileStorage logStorage, String nodeName, Set<String> compressedFileExtensions, MetricRegistry metricRegistry, List<BackupProcessorListener> listeners) { super (lockManager, metadataStorage, logStorage, nodeName); this.localStorage = localStorage; this.offsiteStorage = offsiteStorage; this.codecFactory = codecFactory; this.offsiteUploadWorkers = MoreExecutors.listeningDecorator(offsiteUploadWorkers); this.chunkSize = chunkSize; this.compressedFileExtensions = compressedFileExtensions; this.listeners = listeners; ACTIVE_STORES = metricRegistry.counter("active-stores"); STORE_SIZES = metricRegistry.histogram("store-sizes"); STORE_TIMES = metricRegistry.timer("store-times"); ACTIVE_UPLOADS = metricRegistry.counter("active-uploads"); UPLOAD_SIZES = metricRegistry.histogram("upload-sizes"); UPLOAD_TIMES = metricRegistry.timer("upload-times"); ACTIVE_DOWNLOADS = metricRegistry.counter("active-downloads"); DOWNLOAD_SIZES = metricRegistry.histogram("download-sizes"); DOWNLOAD_TIMES = metricRegistry.timer("download-times"); }
@Test public void testBoundaries() throws IOException { final MinebdConfig cfg = new MinebdConfig(); cfg.bucketSize = Size.bytes(16); //buckets for ants cfg.maxOpenFiles = 3; cfg.parentDirs = Collections.singletonList("tinyfiles"); final MineboxExport underTest = buildMineboxExport(cfg); final byte[] data = new byte[257]; for (int i = 0; i < data.length; i++) { data[i] = (byte) i; } Assert.assertEquals(0, data[0]); Assert.assertEquals(127, data[127]); Assert.assertEquals(-1, data[255]); Assert.assertEquals(0, data[256]); underTest.write(0, ByteBuffer.wrap(data), false); final ByteBuffer read = underTest.read(0, 257); Assert.assertEquals (0, read.get(0)); Assert.assertEquals(0, read.get(256)); Assert.assertEquals(25, read.get(25)); }
public static MinebdConfig createSampleConfig() { final MinebdConfig config = new MinebdConfig(); config.bucketSize = Size.megabytes(40); config.parentDirs = Collections.singletonList("testJunit"); config.reportedSize = Size.gigabytes(4); config.maxOpenFiles = 10; return config; }
@JsonIgnore public ChannelFuture build(@Nonnull final Environment environment, @Nonnull final Uploader uploader, @Nonnull final Size maxUploadSize) { final UploadInitializer initializer = new UploadInitializer(this, uploader, maxUploadSize.toBytes()); final EventLoopGroup bossGroup = Netty.newBossEventLoopGroup(); final EventLoopGroup workerGroup = Netty.newWorkerEventLoopGroup(); environment.lifecycle().manage(new EventLoopGroupManager(bossGroup)); environment.lifecycle().manage(new EventLoopGroupManager(workerGroup)); final ServerBootstrap bootstrap = new ServerBootstrap(); // Start the server final ChannelFuture future = bootstrap.group(bossGroup, workerGroup) .handler(new LoggingHandler(LogLevel.INFO)) .option(ChannelOption.SO_BACKLOG, 128) .channel(Netty.serverChannelType()) .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(initializer).bind(listenPort); environment.lifecycle().manage(new ChannelFutureManager(future)); return future; }
@Override protected Result check() throws IOException { final Size freeSpace = storage.getFreeSpace(); if (freeSpace.toBytes() > minStorage.toBytes()) { LOG.trace("Free space {} is greater than threshold {}, skipping", freeSpace, minStorage); return Result.healthy(); } LOG.warn("Free space {} is less than threshold {}", freeSpace, minStorage); return Result.unhealthy(freeSpace.toString()); }
@Override public Size getUsedSpace() { final Size totalSpace = this.getTotalSpace(); final Size freeSpace = this.getFreeSpace(); return Size.bytes(totalSpace.toBytes() - freeSpace.toBytes()); }
@Override public Size getUsedSpace() throws IOException { for (int i = 0;i < 2;i++) { try { return this.getUsedSpace(-i); } catch (StorageException | IOException e) { LOG.debug("Failed to fetch storage space for day offset: " + (-i), e); } } throw new IOException("There is no capacity data available"); }
private Size getUsedSpace(int daysOffset) throws StorageException, IOException { final String partitionKey = getAzureMetricsPartitionKey(daysOffset); final AzureCapacityEntity capacity; try { capacity = capacityCache.get(partitionKey, new Callable<AzureCapacityEntity>() { @Override public AzureCapacityEntity call() throws StorageException, IOException { final TableOperation readCapacityOperation = TableOperation.retrieve(partitionKey, AZURE_METRICS_KEY, AzureCapacityEntity.class); final AzureCapacityEntity result = tableClient.execute(AZURE_METRICS_TABLE, readCapacityOperation).getResultAsType(); if (result == null) { throw new IOException("No capacity details for " + partitionKey); } return result; } }); } catch (ExecutionException e) { final Throwable cause = e.getCause(); if (cause instanceof StorageException) { throw (StorageException) cause; } if (cause instanceof IOException) { throw (IOException) cause; } LOG.warn("Failed to fetch azure storage capacity", e); return Size.bytes(0); } return Size.bytes(capacity.getCapacity()); }
@Override public Size getFreeSpace() throws IOException { final Size totalSpace = this.getTotalSpace(); final Size usedSpace = this.getUsedSpace(); return Size.bytes(totalSpace.toBytes() - usedSpace.toBytes()); }
public StorageStatus(Size localCapacity, Size localUsedCapacity, Size localFreeCapacity, Size offsiteCapacity, Size offsiteUsedCapacity, Size offsiteFreeCapacity) { this.localCapacity = localCapacity; this.localUsedCapacity = localUsedCapacity; this.localFreeCapacity = localFreeCapacity; this.offsiteCapacity = offsiteCapacity; this.offsiteUsedCapacity = offsiteUsedCapacity; this.offsiteFreeCapacity = offsiteFreeCapacity; }
@JsonProperty public Size getMaxLength() { return maxLength; }
@JsonProperty public void setMaxLength(Size maxLength) { this.maxLength = maxLength; }
@Override public Optional<Size> getMaxThriftFrameSize() { return _maxThriftFrameSize; }
public CassandraConfiguration setMaxThriftFrameSize(Optional<Size> maxThriftFrameSize) { _maxThriftFrameSize = maxThriftFrameSize; return this; }
public KeyspaceConfiguration setMaxThriftFrameSize(Optional<Size> maxThriftFrameSize) { _maxThriftFrameSize = maxThriftFrameSize; return this; }
@Override public Optional<Size> getMaxThriftFrameSize() { return _maxThriftFrameSize.or(_config.getMaxThriftFrameSize()); }
public void setMaxThriftFrameSize(Size maxThriftFrameSize) { _maxThriftFrameSize = Optional.of(maxThriftFrameSize); }
@JsonProperty public Size getMaxUploadSize() { return maxUploadSize; }
@JsonProperty public void setMaxUploadSize(Size size) { this.maxUploadSize = size; }
@JsonProperty public Size getMinimumUploadPartSize() { return minimumUploadPartSize; }
@JsonProperty public void setMinimumUploadPartSize(Size size) { this.minimumUploadPartSize = size; }
public Optional<Size> getMaximumSize() { return _maximumSize; }
@JsonProperty public void setMaximumSize(Optional<Size> maximumMemory) { checkNotNull(maximumMemory); checkArgument(!maximumMemory.isPresent() || maximumMemory.get().getQuantity() >= 0, "maximumMemory must be >= 0 (value: {})", maximumMemory); _maximumSize = maximumMemory; }
public StorageCapacityHealthCheck(FileStorage storage, Size minStorage) { this.storage = storage; this.minStorage = minStorage; }
public Size getChunkSize() { return chunkSize; }
@Test // This uploads 1MB, but never calls finish so they never make it as far as Azure public void testStoreMultipleSimultaneousFiles() throws IOException, InterruptedException { final BackupMetadata backup = processor.create(namespace, "127.0.0.1"); assertEquals(BackupMetadata.State.WAITING, backup.getState()); final int threads = 10; final ExecutorService executor = Executors.newFixedThreadPool(threads); final CountDownLatch latch = new CountDownLatch(threads); for (int i = 0;i < threads;i++) { final String filename = String.format("testfile-%d", i); executor.submit(new Runnable() { @Override public void run() { final byte[] bytes = new byte[(int) Size.kilobytes(100).toBytes()]; RANDOM.nextBytes(bytes); try (final InputStream in = new ByteArrayInputStream(bytes)) { processor.store(backup, Optional.<String>absent(), in, filename); } catch (Exception e) { e.printStackTrace(); throw Throwables.propagate(e); } finally { latch.countDown(); } } }); } // Wait for all threads to complete latch.await(); // Re-fetch the backup since we aren't necessarily using an inmemory reference final BackupMetadata backupResult = metadataStorage.get(backup.getService(), backup.getId()).get(); assertEquals(BackupMetadata.State.WAITING, backupResult.getState()); assertFalse(backupResult.getChunks().isEmpty()); for (Chunk chunk : backupResult.getChunks()) { verify(localStorage, times(1)).upload(eq(backupResult.getService()), eq(chunk.getPath())); } }
@Before public void setUp() { storage = mock(FileStorage.class); healthCheck = new StorageCapacityHealthCheck(storage, Size.megabytes(10)); }
@Test public void testInsufficientStorage() throws IOException { when(storage.getFreeSpace()).thenReturn(Size.megabytes(9)); assertFalse(healthCheck.check().isHealthy()); }
@Test public void testSufficientStorage() throws IOException{ when(storage.getFreeSpace()).thenReturn(Size.megabytes(11)); assertTrue(healthCheck.check().isHealthy()); }
@Override public Size getTotalSpace() { return Size.bytes(root.getTotalSpace()); }
@Override public Size getFreeSpace() { return Size.bytes(root.getFreeSpace()); }
public Size getMinCapacity() { return minCapacity; }
@Override public Size getTotalSpace() throws IOException { return AZURE_STORAGE_SIZE; }
public void setMinCapacity(Size minCapacity) { this.minCapacity = minCapacity; }