Merge pull request #873 from iocanel/master

Added name property to Context.
This commit is contained in:
Ioannis Canellos 2012-10-06 00:26:07 -07:00
commit 76beeee55b
10 changed files with 138 additions and 31 deletions

View File

@ -46,6 +46,12 @@ import com.google.inject.ImplementedBy;
@ImplementedBy(ContextImpl.class)
public interface Context extends Location, Closeable {
/**
* Identifies the Context.
* @return
*/
String getName();
/**
* will be removed in jclouds 1.6
*

View File

@ -30,14 +30,7 @@ import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
import static org.jclouds.Constants.PROPERTY_API;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
import static org.jclouds.Constants.PROPERTY_PROVIDER;
import static org.jclouds.Constants.*;
import static org.jclouds.util.Throwables2.propagateAuthorizationOrOriginalException;
import java.util.ArrayList;
@ -53,6 +46,7 @@ import org.jclouds.concurrent.MoreExecutors;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.concurrent.config.ConfiguresExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.config.BindNameToContext;
import org.jclouds.config.BindPropertiesToExpandedValues;
import org.jclouds.config.BindRestContextWithWildcardExtendsExplicitAndRawType;
import org.jclouds.domain.Credentials;
@ -154,6 +148,7 @@ public class ContextBuilder {
}
}
protected Optional<String> name = Optional.absent();
protected Optional<ProviderMetadata> providerMetadata = Optional.absent();
protected final String providerId;
protected Optional<String> endpoint = Optional.absent();
@ -196,6 +191,11 @@ public class ContextBuilder {
this(null, apiMetadata);
}
public ContextBuilder name(String name) {
this.name = Optional.of(checkNotNull(name, "name"));
return this;
}
public ContextBuilder credentials(String identity, @Nullable String credential) {
this.identity = Optional.of(checkNotNull(identity, "identity"));
this.credential = credential;
@ -258,7 +258,10 @@ public class ContextBuilder {
ProviderMetadata providerMetadata = new UpdateProviderMetadataFromProperties(apiMetadata, this.providerMetadata).apply(expanded);
return buildInjector(providerMetadata, creds, modules);
//We use either the specified name (optional) or a hash of provider/api, endpoint, api version & identity. Hash is used to be something readable.
String name = this.name.isPresent() ? this.name.get() : String.valueOf(Objects.hashCode(providerMetadata.getId(), providerMetadata.getEndpoint() , apiVersion , identity.get()));
return buildInjector(name, providerMetadata, creds, modules);
}
private static String getAndRemove(Properties expanded, String key) {
@ -302,7 +305,7 @@ public class ContextBuilder {
return Guice.createInjector(new BindPropertiesToExpandedValues(resolved)).getInstance(Properties.class);
}
public static Injector buildInjector(ProviderMetadata providerMetadata, Credentials creds, List<Module> inputModules) {
public static Injector buildInjector(String name, ProviderMetadata providerMetadata, Credentials creds, List<Module> inputModules) {
List<Module> modules = newArrayList();
modules.addAll(inputModules);
boolean restModuleSpecifiedByUser = restClientModulePresent(inputModules);
@ -318,6 +321,7 @@ public class ContextBuilder {
addCredentialStoreIfNotPresent(modules);
modules.add(new LifeCycleModule());
modules.add(new BindProviderMetadataContextAndCredentials(providerMetadata, creds));
modules.add(new BindNameToContext(name));
Injector returnVal = Guice.createInjector(Stage.PRODUCTION, modules);
returnVal.getInstance(ExecutionList.class).execute();
return returnVal;

View File

@ -0,0 +1,36 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.annotations;
import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Designates that this Resource qualifies an object to a context name.
*/
@Target( { ANNOTATION_TYPE, FIELD, METHOD, PARAMETER })
@Retention(RUNTIME)
@Qualifier
public @interface Name {
}

View File

@ -0,0 +1,39 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.config;
import com.google.inject.AbstractModule;
import org.jclouds.annotations.Name;
/**
* Binds name to Context.
*/
public class BindNameToContext extends AbstractModule {
private final String name;
public BindNameToContext(String name) {
this.name = name;
}
@Override
protected void configure() {
bind(String.class).annotatedWith(Name.class).toInstance(name);
}
}

View File

@ -18,15 +18,12 @@
*/
package org.jclouds.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Closeables;
import com.google.inject.Singleton;
import org.jclouds.Context;
import org.jclouds.annotations.Name;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
@ -35,10 +32,12 @@ import org.jclouds.providers.ProviderMetadata;
import org.jclouds.rest.Utils;
import org.jclouds.rest.annotations.Identity;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Closeables;
import com.google.inject.Singleton;
import javax.inject.Inject;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* @author Adrian Cole
@ -50,13 +49,15 @@ public class ContextImpl implements Context {
private final String identity;
private final Utils utils;
private final Closer closer;
private final String name;
@Inject
protected ContextImpl(ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer) {
protected ContextImpl(@Name String name, ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer) {
this.providerMetadata = checkNotNull(providerMetadata, "providerMetadata");
this.identity = checkNotNull(identity, "identity");
this.utils = checkNotNull(utils, "utils");
this.closer = checkNotNull(closer, "closer");
this.name = checkNotNull(name, "name");
}
/**
@ -75,6 +76,14 @@ public class ContextImpl implements Context {
return providerMetadata;
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/

View File

@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import org.jclouds.annotations.Name;
import org.jclouds.internal.ContextImpl;
import org.jclouds.lifecycle.Closer;
import org.jclouds.providers.ProviderMetadata;
@ -44,9 +45,9 @@ public class RestContextImpl<S, A> extends ContextImpl implements RestContext<S,
private final S syncApi;
@Inject
protected RestContextImpl(ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer,
protected RestContextImpl(@Name String name, ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer,
Injector injector, TypeLiteral<S> syncApi, TypeLiteral<A> asyncApi) {
super(providerMetadata, identity, utils, closer);
super(name, providerMetadata, identity, utils, closer);
checkNotNull(injector, "injector");
this.asyncApi = injector.getInstance(Key.get(checkNotNull(asyncApi, "asyncApi")));
this.syncApi = injector.getInstance(Key.get(checkNotNull(syncApi, "syncApi")));

View File

@ -82,6 +82,14 @@ public class ContextBuilderTest {
assertEquals(endpoint, URI.create("http://foo.service.com"));
}
@Test
public void testContextName() {
ContextBuilder withNoName = testContextBuilder().endpoint("http://${jclouds.identity}.service.com").name("mytest")
.credentials("foo", "bar");
Context context = withNoName.build();
assertEquals(context.getName(), "mytest");
}
@Test
public void testProviderMetadataBoundWithCorrectEndpoint() {
ContextBuilder withVariablesToReplace = testContextBuilder().endpoint("http://${jclouds.identity}.service.com")

View File

@ -73,6 +73,7 @@ public class BindRestContextWithWildcardExtendsExplicitAndRawTypeTest {
private Injector injectorFor(ProviderMetadata md) {
return Guice.createInjector(
new BindNameToContext("test"),
new BindProviderMetadataContextAndCredentials(md, new Credentials("user", "pass")),
new BindRestContextWithWildcardExtendsExplicitAndRawType(RestApiMetadata.class.cast(md
.getApiMetadata())),

View File

@ -19,6 +19,7 @@
package org.jclouds.internal;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotEquals;
@ -36,10 +37,11 @@ import com.google.common.reflect.TypeToken;
*/
@Test(groups = "unit", testName = "BaseViewTest")
public class BaseViewTest {
private static class Water extends ContextImpl {
protected Water() {
super(createMock(ProviderMetadata.class), "identity", createMock(Utils.class), createMock(Closer.class));
super("water", createMock(ProviderMetadata.class), "identity", createMock(Utils.class), createMock(Closer.class));
}
@Override
@ -55,7 +57,7 @@ public class BaseViewTest {
private static class PeanutButter extends ContextImpl {
protected PeanutButter() {
super(createMock(ProviderMetadata.class), "identity", createMock(Utils.class), createMock(Closer.class));
super("peanutbutter", createMock(ProviderMetadata.class), "identity", createMock(Utils.class), createMock(Closer.class));
}
@Override

View File

@ -21,6 +21,7 @@ package org.jclouds.vcloud.director.v1_5.internal;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.annotations.Name;
import org.jclouds.lifecycle.Closer;
import org.jclouds.providers.ProviderMetadata;
import org.jclouds.rest.RestContext;
@ -45,9 +46,9 @@ public class VCloudDirectorContextImpl extends RestContextImpl<VCloudDirectorApi
private final RestContext<VCloudDirectorAdminApi, VCloudDirectorAdminAsyncApi> adminContext;
@Inject
VCloudDirectorContextImpl(ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer,
VCloudDirectorContextImpl(@Name String name, ProviderMetadata providerMetadata, @Identity String identity, Utils utils, Closer closer,
Injector injector, RestContext<VCloudDirectorAdminApi, VCloudDirectorAdminAsyncApi> adminContext) {
super(providerMetadata, identity, utils, closer, injector, TypeLiteral.get(VCloudDirectorApi.class),
super(name, providerMetadata, identity, utils, closer, injector, TypeLiteral.get(VCloudDirectorApi.class),
TypeLiteral.get(VCloudDirectorAsyncApi.class));
this.adminContext = adminContext;
}