Hi Ryan, The warning you're getting is particular to OpenStack. jclouds provides several internal classes to provide the existing regions, region ids, their corresponding URIs, etc. A group of those classes is what we call the "implicit" location suppliers, that just return the information of one location (region, szone, whatever), that will be used if the user does not specify a region when interacting with the cloud provider.
Those implicit location suppliers are always initialized, and the default implementation looks for a region that has the same URI as the provider endpoint. In the case of OpenStack, the endpoint is always the Keystone endpoint, and that default logic does not "fit well", thus the warning you get. It just says that there is no better way to determine a "default/fallback" region than picking the first one. To be more specific, jclouds loads a Map of known region ids to endpoints, and then looking for the default region, it inspects that map and looks for the endpoint configured when creating the context. In the case of OpenStack, that map is built by inspecting the Service Catalog returned by Keystone, so the right endpoint for the service (swift, nova, etc) is configured for each region. That is done by using a custom implementation of the supplier that builds the mentioned map. You can read the implementation used for Keystone here [1]. I hope reading it will make more sense and show why you get he values you get in the map. Regarding that "FOO" key. It is just a convenience use of a Guava cache. There is an utility method to memoize a Supplier for a given amount of time, and short-circuiting any AuthenticationException to avoid having the supplier call the provider APIs when we already know authentication will fail (and this preventing potential account locks). The implementation of that supplier internally uses a Cache to deal with concurrency. It will actually hold just one value (the memoized one), and completely ignore any key (FOO) that is provided when client code asks for the cached value. I couldn't say why the Guava's LoadingCache is used instead of manually implementing the locking, or why the "Suppliers.memoizeWithExpiration" isn't used instead, which is thread-safe too. HTH! I. [1] https://github.com/jclouds/jclouds/blob/master/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java On 14 April 2017 at 00:28, Ryan Shoemaker <ryan.shoema...@enterprisedb.com> wrote: > Hi, > > I've been seeing this warning pop out of my code for awhile and have finally > gotten around to investigating it: > > org.jclouds.location.suppliers.implicit.GetRegionIdMatchingProviderURIOrNull|_ThreadID=10;_ThreadName=Thread-2;|failed > to find key for value http://keystone.domainname.com:5000/v2.0 in > {uk=http://swift.domainname.com:8080/v1/AUTH_813b8f3ec69a460caf6efc2ea32bafb8}; > choosing first: uk > > Why is there a mismatch between the uri and what's in the map? The uri is > pointing to our keystone service and the map contains our swift service. > The actual log message appears to be coming from: > > org.jclouds.suppliers.SupplyKeyMatchingValueOrNull.get() > > As I was debugging this, I noticed this code on the stack: > > org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.get() > (line 150) > > @Override > public T get() { > try { > return cache.get("FOO").orNull(); > } catch (UncheckedExecutionException e) { > throw propagate(e.getCause()); > } catch (ExecutionException e) { > throw propagate(e.getCause()); > } > } > > What's going on with that key name? Here's the calling code in my app - we > have a method to get the storage context: > > public BlobStoreContext getStorageContext(@Nullable String tenant) { > String providerOrApi = ProviderFactory.getSupportedProviderFromId( > user.getServiceProvider()).getObjectStorageProvider(); > Properties overrides = new Properties(); > overrides.setProperty(KeystoneProperties.CREDENTIAL_TYPE, > CredentialTypes.PASSWORD_CREDENTIALS); > > ContextBuilder builder = ContextBuilder.newBuilder(providerOrApi) > .credentials(tenant + ":" + serviceLogin, servicePassword) > .endpoint(identityServiceEndpoint) > .modules(ImmutableSet.of(new JDKLoggingModule(), new > JschSshClientModule())) > .overrides(overrides); > > return builder.buildView(BlobStoreContext.class); > } > > And then code grabs the context and calls getBlobStore() on it - this is > what causes the warning to be printed: > > BlobStoreContext storageContext = getStorageContext(firstTenant); > if (storageContext != null) { > BlobStore blobStore = storageContext.getBlobStore(); > etc... > > We're running jclouds 2.0.0 on OpenStack. Despite the warning, everything > appears to work fine. Thanks! --Ryan