下面列出了org.apache.http.protocol.HttpProcessor#org.apache.brooklyn.util.exceptions.Exceptions 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/** Updates the bundle file associated with the given record, creating and returning a backup if there was already such a file */
synchronized File updateManagedBundleFile(OsgiBundleInstallationResult result, File fNew) {
File fCached = fileFor(result.getMetadata());
File fBak = new File(fCached.getAbsolutePath()+".bak");
if (fBak.equals(fNew)) {
// rolling back
throw new IllegalStateException("Cannot update to a backup copy; use rollback instead");
}
if (fCached.exists()) {
log.debug("Replacing and backing up old Brooklyn local copy of bundle file "+fCached);
fCached.renameTo(fBak);
} else {
log.debug("Creating Brooklyn local copy of bundle file "+fCached);
}
try (FileInputStream fin = new FileInputStream(fNew); FileOutputStream fout = new FileOutputStream(fCached)) {
Streams.copy(fin, fout);
} catch (IOException e) {
throw Exceptions.propagate(e);
}
return fBak;
}
/**
* @return URL's to all resources matching the given name (using {@link Bundle#getResources(String)} in the referenced osgi bundles.
*/
public Iterable<URL> getResources(String name, Iterable<? extends OsgiBundleWithUrl> osgiBundles) {
Set<URL> resources = Sets.newLinkedHashSet();
for (OsgiBundleWithUrl catalogBundle : osgiBundles) {
try {
Maybe<Bundle> bundle = findBundle(catalogBundle);
if (bundle.isPresent()) {
Enumeration<URL> result = bundle.get().getResources(name);
resources.addAll(Collections.list(result));
}
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
}
}
return resources;
}
@Test
public void testParentalLoopForbiddenViaAddChild() {
Entity e = mgmt.getEntityManager().createEntity(EntitySpec.create(TestEntity.class));
Entity e2 = e.addChild(EntitySpec.create(TestEntity.class));
try {
e2.addChild(e);
Asserts.shouldHaveFailedPreviously();
} catch (Exception ex) {
Exception cause = Exceptions.getFirstThrowableOfType(ex, IllegalStateException.class);
if (cause == null || !cause.toString().contains("loop detected trying to add child")) {
throw ex;
}
}
assertEqualsIgnoringOrder(e.getChildren(), ImmutableList.of(e2));
assertEqualsIgnoringOrder(e2.getChildren(), ImmutableList.of());
assertEquals(e.getParent(), null);
assertEquals(e2.getParent(), e);
}
public static Framework newFrameworkStarted(String felixCacheDir, boolean clean, Map<?,?> extraStartupConfig) {
Map<Object,Object> cfg = MutableMap.copyOf(extraStartupConfig);
if (clean) cfg.put(Constants.FRAMEWORK_STORAGE_CLEAN, "onFirstInit");
if (felixCacheDir!=null) cfg.put(Constants.FRAMEWORK_STORAGE, felixCacheDir);
cfg.put(Constants.FRAMEWORK_BSNVERSION, Constants.FRAMEWORK_BSNVERSION_MULTIPLE);
FrameworkFactory factory = newFrameworkFactory();
Stopwatch timer = Stopwatch.createStarted();
Framework framework = factory.newFramework(cfg);
try {
framework.init();
installBootBundles(framework);
framework.start();
} catch (Exception e) {
// framework bundle start exceptions are not interesting to caller...
throw Exceptions.propagate(e);
}
LOG.debug("System bundles are: "+SYSTEM_BUNDLES);
LOG.debug("OSGi framework started in " + Duration.of(timer));
return framework;
}
private void checkValidArchive(final String url) {
// Note have seen response code 500 from repository.apache.org, for
// https://repository.apache.org/service/local/artifact/maven/redirect?r=snapshots&v=0.7.0-SNAPSHOT&g=org.apache.brooklyn&a=brooklyn-utils-common&e=jar
// Therefore willing to retry, rather than failing immediately.
Asserts.succeedsEventually(new Runnable() {
@Override public void run() {
try {
byte[] bytes = Streams.readFullyAndClose(ResourceUtils.create(this).getResourceFromUrl(url));
// confirm this follow redirects!
Assert.assertTrue(bytes.length > 100*1000, "download of "+url+" is suspect ("+Strings.makeSizeString(bytes.length)+")");
// (could also check it is a zip etc)
} catch (Exception e) {
throw Exceptions.propagate(e);
}
}});
}
protected void unmarshalStringKey(HierarchicalStreamReader reader, UnmarshallingContext context, Map map, String key) {
String type = reader.getAttribute("type");
Object value;
if (type==null && reader.hasMoreChildren()) {
reader.moveDown();
value = readItem(reader, context, map);
reader.moveUp();
} else {
Class typeC = type!=null ? mapper().realClass(type) : String.class;
try {
value = TypeCoercions.coerce(reader.getValue(), typeC);
} catch (Exception e) {
log.warn("FAILED to coerce "+reader.getValue()+" to "+typeC+": "+e);
throw Exceptions.propagate(e);
}
}
map.put(key, value);
}
public static String getErrorContent(String url) {
try {
HttpURLConnection connection = (HttpURLConnection) connectToUrl(url);
long startTime = System.currentTimeMillis();
String err;
int status;
try {
InputStream errStream = connection.getErrorStream();
err = Streams.readFullyStringAndClose(errStream);
status = connection.getResponseCode();
} finally {
closeQuietly(connection);
}
if (LOG.isDebugEnabled())
LOG.debug("read of err {} ({}ms) complete; http code {}", new Object[] { url, Time.makeTimeStringRounded(System.currentTimeMillis() - startTime), status});
return err;
} catch (Exception e) {
throw Exceptions.propagate(e);
}
}
@Test(groups = {"Integration", "WIP"})
public void canStartupAndShutdown() throws Exception {
karaf = app.createAndManageChild(EntitySpec.create(KarafContainer.class)
.configure("name", Identifiers.makeRandomId(8))
.configure("displayName", "Karaf Test"));
app.start(ImmutableList.of(localhost));
EntityAsserts.assertAttributeEqualsEventually(karaf, Attributes.SERVICE_UP, true);
Entities.dumpInfo(karaf);
final int pid = karaf.getAttribute(KarafContainer.KARAF_PID);
Entities.submit(app, SshEffectorTasks.requirePidRunning(pid).machine(localhost.obtain())).get();
karaf.stop();
EntityAsserts.assertAttributeEqualsEventually(karaf, Attributes.SERVICE_UP, false);
Asserts.succeedsEventually(new Runnable() {
@Override
public void run() {
try {
Assert.assertFalse(Entities.submit(app, SshEffectorTasks.isPidRunning(pid).machine(localhost.obtain())).get());
} catch (NoMachinesAvailableException e) {
throw Exceptions.propagate(e);
}
}});
}
/** finds a good seed, in case the effector changes */
public static void main(String[] args) throws Exception {
ActivityRestTest me = new ActivityRestTest();
me.setUpClass();
int i=0;
do {
me.initEntity(i);
try {
log.info("Trying seed "+i+"...");
me.testGood(Duration.millis(200));
break;
} catch (Throwable e) {
log.info(" "+Exceptions.collapseText(e));
// e.printStackTrace();
// continue
}
i++;
} while (true);
Dumper.dumpInfo(me.lastTask);
log.info("Seed "+i+" is good ^");
}
@SuppressWarnings("unchecked")
public static <T> Closure<T> castToClosure(Object o) {
try {
if (ScriptBytecodeAdapter.compareEqual(o, null)) {
return (Closure<T>)ScriptBytecodeAdapter.castToType(o, Closure.class);
} else if (safeGroovyIsCase(o, Closure.class)) {
return (Closure<T>)ScriptBytecodeAdapter.castToType(o, Closure.class);
} else if (o instanceof Runnable) {
return closureFromRunnable((Runnable)ScriptBytecodeAdapter.createPojoWrapper(ScriptBytecodeAdapter.castToType(o, Runnable.class), Runnable.class));
} else if (o instanceof Callable) {
return closureFromCallable((Callable<T>)ScriptBytecodeAdapter.createPojoWrapper(ScriptBytecodeAdapter.castToType(o, Callable.class), Callable.class));
} else if (o instanceof Function) {
return closureFromFunction((Function<Object, T>)ScriptBytecodeAdapter.createPojoWrapper(ScriptBytecodeAdapter.castToType(o, Function.class), Function.class));
} else {
throw new IllegalArgumentException("Cannot convert to closure: o="+o+"; type="+(o != null ? o.getClass() : null));
}
} catch (Throwable e) {
throw Exceptions.propagate(e);
}
}
/** @deprecated since 0.12.0 use {@link RegisteredType} methods instead */ @Deprecated
public static CatalogEnricherSummary catalogEnricherSummary(BrooklynRestResourceUtils b, CatalogItem<? extends Enricher,EnricherSpec<?>> item, UriBuilder ub) {
final Set<EnricherConfigSummary> config = Sets.newLinkedHashSet();
try{
final EnricherSpec<?> spec = (EnricherSpec<?>) b.getCatalog().peekSpec(item);
AtomicInteger priority = new AtomicInteger();
for (SpecParameter<?> input: spec.getParameters()) {
config.add(ConfigTransformer.of(input).uiIncrementAndSetPriorityIfPinned(priority).transformLegacyEnricherConfig());
}
}catch (Exception e) {
Exceptions.propagateIfFatal(e);
log.trace("Unable to create policy spec for "+item+": "+e, e);
}
return new CatalogEnricherSummary(item.getSymbolicName(), item.getVersion(), item.getContainingBundle(), item.getDisplayName(),
item.getJavaType(), item.getCatalogItemType().toString(), item.getPlanYaml(),
item.getDescription(), tidyIconLink(b, item, item.getIconUrl(), ub), config,
item.tags().getTags(), item.isDeprecated(), makeLinks(item, ub));
}
@Test
public void testInvokeEffectorErrorCollapsedNicely() {
FailingEntity entity = createFailingEntity();
Task<Void> task = entity.invoke(Startable.START, MutableMap.of("locations", locs));
Exception e = assertTaskFails( task );
// normal collapse should report where we started
String collapsed = Exceptions.collapseText(e);
Assert.assertFalse(Strings.containsLiteral(collapsed, "Propagated"), "Error too verbose: "+collapsed);
Assert.assertTrue(Strings.containsLiteral(collapsed, "invoking"), "Error not verbose enough: "+collapsed);
Assert.assertTrue(Strings.containsLiteral(collapsed, "start"), "Error not verbose enough: "+collapsed);
Assert.assertTrue(Strings.containsLiteral(collapsed, "FailingEntity"), "Error not verbose enough: "+collapsed);
Assert.assertTrue(Strings.containsLiteral(collapsed, entity.getId()), "Error not verbose enough: "+collapsed);
Assert.assertTrue(Strings.containsLiteral(collapsed, "Simulating"), "Error not verbose enough: "+collapsed);
// in the context of the task we should not report where we started;
// it instead of
// Error invoking start at FailingEntityImpl{id=wv6KwsPh}: Simulating entity stop failure for test
// show
// Simulating entity start failure for test
collapsed = Exceptions.collapseTextInContext(e, task);
Assert.assertFalse(Strings.containsLiteral(collapsed, "Propagated"), "Error too verbose: "+collapsed);
Assert.assertFalse(Strings.containsLiteral(collapsed, "invoking"), "Error too verbose: "+collapsed);
Assert.assertFalse(Strings.containsLiteral(collapsed, "FailingEntity"), "Error too verbose: "+collapsed);
Assert.assertFalse(Strings.containsLiteral(collapsed, entity.getId()), "Error too verbose: "+collapsed);
Assert.assertTrue(Strings.containsLiteral(collapsed, "start"), "Error not verbose enough: "+collapsed);
Assert.assertTrue(Strings.containsLiteral(collapsed, "Simulating"), "Error not verbose enough: "+collapsed);
}
protected <T extends StartableApplication> Callable<T> newProvisionAppTask(final EntitySpec<T> appSpec) {
return new Callable<T>() {
public T call() {
try {
Stopwatch stopwatch = Stopwatch.createStarted();
T app = mgmt().getEntityManager().createEntity(appSpec);
app.start(ImmutableList.of(localhost));
Duration duration = Duration.of(stopwatch.elapsed(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS);
LOG.info("Provisioning time: "+duration);
provisioningTimes.add(duration);
return app;
} catch (Throwable t) {
LOG.error("Error deploying app (rethrowing)", t);
throw Exceptions.propagate(t);
}
}
};
}
@Override
public String get() {
try {
queuedReaders.add(Thread.currentThread());
lock.readLock().lockInterruptibly();
try {
return delegate.get();
} finally {
lock.readLock().unlock();
}
} catch (InterruptedException e) {
throw Exceptions.propagate(e);
} finally {
queuedReaders.remove(Thread.currentThread());
}
}
@Override
public void preReleaseOnObtainError(JcloudsLocation location, JcloudsMachineLocation machineLocation,
Exception cause) {
Exception tothrow = null;
for (JcloudsLocationCustomizer customizer : customizers) {
try {
customizer.preReleaseOnObtainError(location, machineLocation, cause);
} catch (Exception e) {
LOG.error("Problem invoking customizer preReleaseOnObtainError for "+customizer+" for machine "+machineLocation+
", locaiton=" + location + "; ignoring and continuing, "
+ (tothrow==null ? "will throw subsequently" : "swallowing due to previous error")+": "+e, e);
if (tothrow==null) tothrow = e;
}
}
if (tothrow != null) {
throw Exceptions.propagate(tothrow);
}
}
@Override
public <T> T get(TaskAdaptable<T> task) {
final TaskInternal<T> t = (TaskInternal<T>) task.asTask();
if (t.isQueuedOrSubmitted()) {
return t.getUnchecked();
}
ContextSwitchingInfo<T> switchContextWrapper = getContextSwitchingTask(t, Collections.emptyList(), false);
if (switchContextWrapper!=null) {
return switchContextWrapper.context.get(switchContextWrapper.wrapperTask);
}
try {
return runInSameThread(t, new Callable<Maybe<T>>() {
public Maybe<T> call() throws Exception {
return Maybe.of(t.getJob().call());
}
}).get();
} catch (Exception e) {
throw Exceptions.propagate(e);
}
}
public static void addCatalogItemsAsOsgiWithoutStartingBundles(ManagementContext mgmt, String catalogYaml, VersionedName bundleName, boolean force) {
try {
BundleMaker bundleMaker = new BundleMaker(mgmt);
File bf = bundleMaker.createTempZip("test", MutableMap.of(
new ZipEntry(BasicBrooklynCatalog.CATALOG_BOM), new ByteArrayInputStream(catalogYaml.getBytes())));
ReferenceWithError<OsgiBundleInstallationResult> b = ((ManagementContextInternal)mgmt).getOsgiManager().get().installDeferredStart(
new BasicManagedBundle(bundleName.getSymbolicName(), bundleName.getVersionString(), null, null),
new FileInputStream(bf),
false);
// bundle not started (no need, and can break), and BOM not installed nor validated above;
// do BOM install and validation below manually to test the type registry approach
// but skipping the rollback / uninstall
mgmt.getCatalog().addTypesFromBundleBom(catalogYaml, b.get().getMetadata(), force, null);
Map<RegisteredType, Collection<Throwable>> validation = mgmt.getCatalog().validateTypes(
mgmt.getTypeRegistry().getMatching(RegisteredTypePredicates.containingBundle(b.get().getVersionedName())) );
if (!validation.isEmpty()) {
throw Exceptions.propagate("Brooklyn failed to load types (in tests, skipping rollback): "+validation.keySet(),
Iterables.concat(validation.values()));
}
} catch (Exception e) {
throw Exceptions.propagate(e);
}
}
@Test
public void testBrooklynCampFailDslTags() throws Exception {
try {
final Entity app = createAndStartApplication(
"services:",
"- type: " + BasicApplication.class.getName(),
" brooklyn.tags:",
" - tag1",
" - $brooklyn:object:",
" type: "+TagsTestObject.class.getName(),
" constructor.args:",
" - $brooklyn:attributeWhenReady(\"host.name\")");
Asserts.shouldHaveFailedPreviously("Should throw IllegalArgumentException exception; instead got "+app);
} catch (Exception e) {
Asserts.expectedFailureContainsIgnoreCase(e,
"brooklyn.tags should not contain DeferredSupplier",
"A DeferredSupplier is made when using $brooklyn:attributeWhenReady");
Asserts.assertStringContainsAtLeastOne(Exceptions.getFirstInteresting(e).getMessage(),
"brooklyn.tags should not contain DeferredSupplier");
}
}
/**
* {@inheritDoc}
*/
@Override
public void restart() {
// Let everyone know we're restarting (so that the GUI shows the correct icon).
setServiceState(false, Lifecycle.STARTING);
// Get an unsubmitted task for restarting all the children of this entity in parallel.
final TaskAdaptable<?> taskAdaptable = StartableMethods.restartingChildren(this);
logger.trace("{}, TaskAdaptable: {}", this, taskAdaptable);
try {
// Submit the task to the ExecutionManager so that they actually get stopped
// and then wait until all the parallel entities have completed.
submitTaskAndWait(taskAdaptable);
// Let everyone know we've started up successfully (changes the icon in the GUI).
logger.debug("Tasks successfully run. Update state of {} to RUNNING.", this);
setServiceState(true, Lifecycle.RUNNING);
} catch (Throwable t) {
logger.debug("Tasks NOT successfully run. Update state of {} to ON_FIRE.", this);
setServiceState(false, Lifecycle.ON_FIRE);
throw Exceptions.propagate(t);
}
}
@Override
public Map<String, String> get() {
if (entity == null) return ImmutableMap.of(); // See BROOKLYN-568
Map<String, Object> env = MutableMap.copyOf(entity.getConfig(BrooklynConfigKeys.SHELL_ENVIRONMENT));
// Add the shell environment entries from our configuration
if (rawSensorShellEnv != null) {
env.putAll(TypeCoercions.coerce(rawSensorShellEnv, new TypeToken<Map<String,Object>>() {}));
}
// Try to resolve the configuration in the env Map
try {
env = (Map<String, Object>) Tasks.resolveDeepValue(env, Object.class, ((EntityInternal) entity).getExecutionContext());
} catch (InterruptedException | ExecutionException e) {
Exceptions.propagateIfFatal(e);
}
// Convert the environment into strings with the serializer
ShellEnvironmentSerializer serializer = new ShellEnvironmentSerializer(((EntityInternal) entity).getManagementContext());
return serializer.serialize(env);
}
protected JsonObject apiGet(String path, ImmutableMap<String, String> headers) {
try {
String uri = Urls.mergePaths(endpoint, path);
LOG.trace("Vault request - GET: {}", uri);
HttpToolResponse response = HttpTool.httpGet(httpClient, Urls.toUri(uri), headers);
LOG.trace("Vault response - code: {} {}", response.getResponseCode(), response.getReasonPhrase());
String responseBody = new String(response.getContent(), CHARSET_NAME);
if (HttpTool.isStatusCodeHealthy(response.getResponseCode())) {
return gson.fromJson(responseBody, JsonObject.class);
} else {
throw new IllegalStateException("HTTP request returned error");
}
} catch (UnsupportedEncodingException e) {
throw Exceptions.propagate(e);
}
}
@Test
public void testParentalLoopForbiddenViaSetParent() {
Entity e = mgmt.getEntityManager().createEntity(EntitySpec.create(TestEntity.class));
Entity e2 = e.addChild(EntitySpec.create(TestEntity.class));
try {
e.setParent(e2);
Asserts.shouldHaveFailedPreviously();
} catch (Exception ex) {
Exception cause = Exceptions.getFirstThrowableOfType(ex, IllegalStateException.class);
if (cause == null || !cause.toString().contains("loop detected trying to set parent")) {
throw ex;
}
}
assertEqualsIgnoringOrder(e.getChildren(), ImmutableList.of(e2));
assertEqualsIgnoringOrder(e2.getChildren(), ImmutableList.of());
assertEquals(e.getParent(), null);
assertEquals(e2.getParent(), e);
}
@Test
public void testReducingBuilderWithNamedNonExistentFunction() {
try {
entity.enrichers().add(Enrichers.builder()
.reducing(Reducer.class, ImmutableList.<AttributeSensor<?>>of(STR1, STR2))
.from(entity)
.computing("unknown function name", ImmutableMap.<String, Object>of("separator", "-"))
.publishing(STR3)
.build()
);
Asserts.fail("Expected exception when adding reducing enricher with unknown named function");
} catch (Exception e) {
if (Exceptions.getFirstThrowableOfType(e, IllegalStateException.class) == null) {
throw e;
}
}
}
@Override
public synchronized void prepareForMasterUse() {
if (doneFirstContentiousWrite) return;
try {
if (deferredBackupNeeded) {
// defer backup and path creation until first write
// this way if node is standby or auto, the backup is not created superfluously
File backup = backupDirByCopying(basedir);
log.info("Persistence deferred backup, directory "+basedir+" backed up to "+backup.getAbsolutePath());
deferredBackupNeeded = false;
}
doneFirstContentiousWrite = true;
} catch (Exception e) {
throw Exceptions.propagate(e);
}
}
@Override
public void start(Collection<? extends Location> locations) {
ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
ServiceProblemsLogic.clearProblemsIndicator(this, START);
try {
doStart(locations);
ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
} catch (Exception e) {
ServiceProblemsLogic.updateProblemsIndicator(this, START, "Start failed with error: "+e);
ServiceStateLogic.setExpectedState(this, Lifecycle.ON_FIRE);
throw Exceptions.propagate(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public void start(Collection<? extends Location> locations) {
ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
try {
final Entity targetEntity = resolveTarget();
final String effectorName = getRequiredConfig(EFFECTOR_NAME);
final Map<String, ?> effectorParams = getConfig(EFFECTOR_PARAMS);
final Duration timeout = getConfig(TIMEOUT);
final Integer maxAttempts = getConfig(MAX_ATTEMPTS);
final Duration backoffToPeriod = getConfig(BACKOFF_TO_PERIOD);
if (!getChildren().isEmpty()) {
throw new RuntimeException(String.format("The entity [%s] cannot have child entities", getClass().getName()));
}
Maybe<Effector<?>> effector = EffectorUtils.findEffectorDeclared(targetEntity, effectorName);
if (effector.isAbsentOrNull()) {
throw new AssertionError(String.format("No effector with name [%s]", effectorName));
}
Object effectorResult = invokeEffector(targetEntity, effector.get(), effectorParams, maxAttempts, timeout, backoffToPeriod);
final List<Map<String, Object>> assertions = getAssertions(this, ASSERTIONS);
if(assertions != null && !assertions.isEmpty()){
Supplier<?> supplier = Suppliers.ofInstance(effectorResult);
TestFrameworkAssertions.checkAssertionsEventually(new AssertionOptions(effectorName, supplier)
.maxAttempts(1)
.timeout(timeout)
.assertions(assertions));
}
//Add result of effector to sensor
sensors().set(EFFECTOR_RESULT, effectorResult);
setUpAndRunState(true, Lifecycle.RUNNING);
} catch (Throwable t) {
setUpAndRunState(false, Lifecycle.ON_FIRE);
throw Exceptions.propagate(t);
}
}
private Supplier<InputStream> newInputStreamSupplier(final File file) {
return new Supplier<InputStream>() {
@Override public InputStream get() {
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
throw Exceptions.propagate(e);
}
}
};
}
@Override
public boolean isRunning() {
try {
if (entity instanceof MongoDBServerImpl && !((MongoDBServerImpl)entity).clientAccessEnabled()) {
// No direct access via MongoDB port; only use ssh-port
return newScript(MutableMap.of(USE_PID_FILE, getPidFile()), CHECK_RUNNING).execute() == 0;
} else {
return MongoDBClientSupport.forServer((AbstractMongoDBServer) entity).ping();
}
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
return false;
}
}
/** create a directory with a simple index.html so we have some content being served up */
public static String createTempWebDirWithIndexHtml(String indexHtmlContent) {
File dir = Files.createTempDir();
dir.deleteOnExit();
try {
Files.write(indexHtmlContent, new File(dir, "index.html"), Charsets.UTF_8);
} catch (IOException e) {
Exceptions.propagate(e);
}
return dir.getAbsolutePath();
}
@Override
public void run() {
String oldDetails = Tasks.setBlockingDetails(description);
LOG.debug("{} acquiring permit from {}", this, permit);
try {
permit.acquire();
hasObtainedPermit.set(true);
} catch (InterruptedException e) {
throw Exceptions.propagate(e);
} finally {
Tasks.setBlockingDetails(oldDetails);
}
}