AzureRepositoryLock implements RepositoryLock { public AzureRepositoryLock lock() throws IOException { long start = System.currentTimeMillis(); Exception ex = null; do { try { blob.openOutputStream().close(); leaseId = blob.acquireLease(INTERVAL, null); log.info("Acquired lease {}", leaseId); } catch (StorageException | IOException e) { if (ex == null) { log.info("Can't acquire the lease. Retrying every 1s. Timeout is set to {}s.", timeoutSec); } ex = e; if ((System.currentTimeMillis() - start) / 1000 < timeoutSec) { try { Thread.sleep(1000); } catch (InterruptedException e1) { throw new IOException(e1); } } else { break; } } } while (leaseId == null); if (leaseId == null) { log.error("Can't acquire the lease in {}s.", timeoutSec); throw new IOException(ex); } else { executor.submit(this::refreshLease); return this; } } AzureRepositoryLock(CloudBlockBlob blob, Runnable shutdownHook);  AzureRepositoryLock(CloudBlockBlob blob, Runnable shutdownHook, int timeoutSec); AzureRepositoryLock lock(); @Override void unlock();  }
@Test public void testFailingLock() throws URISyntaxException, IOException, StorageException { CloudBlockBlob blob = container.getBlockBlobReference("oak/repo.lock"); new AzureRepositoryLock(blob, () -> {}, 0).lock(); try { new AzureRepositoryLock(blob, () -> {}, 0).lock(); fail("The second lock should fail."); } catch (IOException e) { } }