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) @ImplementedBy(ContextImpl.class)
public interface Context extends Location, Closeable { public interface Context extends Location, Closeable {
/**
* Identifies the Context.
* @return
*/
String getName();
/** /**
* will be removed in jclouds 1.6 * 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.find;
import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayList;
import static org.jclouds.Constants.PROPERTY_API; import static org.jclouds.Constants.*;
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.util.Throwables2.propagateAuthorizationOrOriginalException; import static org.jclouds.util.Throwables2.propagateAuthorizationOrOriginalException;
import java.util.ArrayList; import java.util.ArrayList;
@ -53,6 +46,7 @@ import org.jclouds.concurrent.MoreExecutors;
import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ConfiguresExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.config.BindNameToContext;
import org.jclouds.config.BindPropertiesToExpandedValues; import org.jclouds.config.BindPropertiesToExpandedValues;
import org.jclouds.config.BindRestContextWithWildcardExtendsExplicitAndRawType; import org.jclouds.config.BindRestContextWithWildcardExtendsExplicitAndRawType;
import org.jclouds.domain.Credentials; 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 Optional<ProviderMetadata> providerMetadata = Optional.absent();
protected final String providerId; protected final String providerId;
protected Optional<String> endpoint = Optional.absent(); protected Optional<String> endpoint = Optional.absent();
@ -196,6 +191,11 @@ public class ContextBuilder {
this(null, apiMetadata); 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) { public ContextBuilder credentials(String identity, @Nullable String credential) {
this.identity = Optional.of(checkNotNull(identity, "identity")); this.identity = Optional.of(checkNotNull(identity, "identity"));
this.credential = credential; this.credential = credential;
@ -258,7 +258,10 @@ public class ContextBuilder {
ProviderMetadata providerMetadata = new UpdateProviderMetadataFromProperties(apiMetadata, this.providerMetadata).apply(expanded); 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) { private static String getAndRemove(Properties expanded, String key) {
@ -302,7 +305,7 @@ public class ContextBuilder {
return Guice.createInjector(new BindPropertiesToExpandedValues(resolved)).getInstance(Properties.class); 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(); List<Module> modules = newArrayList();
modules.addAll(inputModules); modules.addAll(inputModules);
boolean restModuleSpecifiedByUser = restClientModulePresent(inputModules); boolean restModuleSpecifiedByUser = restClientModulePresent(inputModules);
@ -318,6 +321,7 @@ public class ContextBuilder {
addCredentialStoreIfNotPresent(modules); addCredentialStoreIfNotPresent(modules);
modules.add(new LifeCycleModule()); modules.add(new LifeCycleModule());
modules.add(new BindProviderMetadataContextAndCredentials(providerMetadata, creds)); modules.add(new BindProviderMetadataContextAndCredentials(providerMetadata, creds));
modules.add(new BindNameToContext(name));
Injector returnVal = Guice.createInjector(Stage.PRODUCTION, modules); Injector returnVal = Guice.createInjector(Stage.PRODUCTION, modules);
returnVal.getInstance(ExecutionList.class).execute(); returnVal.getInstance(ExecutionList.class).execute();
return returnVal; 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; package org.jclouds.internal;
import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import java.net.URI; import com.google.common.io.Closeables;
import java.util.Map; import com.google.inject.Singleton;
import java.util.Set;
import javax.inject.Inject;
import org.jclouds.Context; import org.jclouds.Context;
import org.jclouds.annotations.Name;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
@ -35,10 +32,12 @@ import org.jclouds.providers.ProviderMetadata;
import org.jclouds.rest.Utils; import org.jclouds.rest.Utils;
import org.jclouds.rest.annotations.Identity; import org.jclouds.rest.annotations.Identity;
import com.google.common.base.Objects; import javax.inject.Inject;
import com.google.common.collect.ImmutableMap; import java.net.URI;
import com.google.common.io.Closeables; import java.util.Map;
import com.google.inject.Singleton; import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -50,14 +49,16 @@ public class ContextImpl implements Context {
private final String identity; private final String identity;
private final Utils utils; private final Utils utils;
private final Closer closer; private final Closer closer;
private final String name;
@Inject @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.providerMetadata = checkNotNull(providerMetadata, "providerMetadata");
this.identity = checkNotNull(identity, "identity"); this.identity = checkNotNull(identity, "identity");
this.utils = checkNotNull(utils, "utils"); this.utils = checkNotNull(utils, "utils");
this.closer = checkNotNull(closer, "closer"); this.closer = checkNotNull(closer, "closer");
} this.name = checkNotNull(name, "name");
}
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -75,7 +76,15 @@ public class ContextImpl implements Context {
return providerMetadata; return providerMetadata;
} }
/** /**
* {@inheritDoc}
*/
@Override
public String getName() {
return name;
}
/**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override

View File

@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.annotations.Name;
import org.jclouds.internal.ContextImpl; import org.jclouds.internal.ContextImpl;
import org.jclouds.lifecycle.Closer; import org.jclouds.lifecycle.Closer;
import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.ProviderMetadata;
@ -44,9 +45,9 @@ public class RestContextImpl<S, A> extends ContextImpl implements RestContext<S,
private final S syncApi; private final S syncApi;
@Inject @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) { Injector injector, TypeLiteral<S> syncApi, TypeLiteral<A> asyncApi) {
super(providerMetadata, identity, utils, closer); super(name, providerMetadata, identity, utils, closer);
checkNotNull(injector, "injector"); checkNotNull(injector, "injector");
this.asyncApi = injector.getInstance(Key.get(checkNotNull(asyncApi, "asyncApi"))); this.asyncApi = injector.getInstance(Key.get(checkNotNull(asyncApi, "asyncApi")));
this.syncApi = injector.getInstance(Key.get(checkNotNull(syncApi, "syncApi"))); 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")); 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 @Test
public void testProviderMetadataBoundWithCorrectEndpoint() { public void testProviderMetadataBoundWithCorrectEndpoint() {
ContextBuilder withVariablesToReplace = testContextBuilder().endpoint("http://${jclouds.identity}.service.com") ContextBuilder withVariablesToReplace = testContextBuilder().endpoint("http://${jclouds.identity}.service.com")

View File

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

View File

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

View File

@ -21,6 +21,7 @@ package org.jclouds.vcloud.director.v1_5.internal;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.annotations.Name;
import org.jclouds.lifecycle.Closer; import org.jclouds.lifecycle.Closer;
import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.ProviderMetadata;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
@ -45,9 +46,9 @@ public class VCloudDirectorContextImpl extends RestContextImpl<VCloudDirectorApi
private final RestContext<VCloudDirectorAdminApi, VCloudDirectorAdminAsyncApi> adminContext; private final RestContext<VCloudDirectorAdminApi, VCloudDirectorAdminAsyncApi> adminContext;
@Inject @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) { 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)); TypeLiteral.get(VCloudDirectorAsyncApi.class));
this.adminContext = adminContext; this.adminContext = adminContext;
} }