mirror of https://github.com/apache/jclouds.git
Add GoogleComputeEngineProviderMetadata and implement dynamic Location suppliers.
This commit is contained in:
parent
c7bb9f8b17
commit
8e8f9662e1
|
@ -19,7 +19,6 @@ package org.jclouds.googlecomputeengine;
|
|||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_PROJECTS;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_PROVIDER_NAME;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE;
|
||||
|
@ -29,7 +28,6 @@ import static org.jclouds.reflect.Reflection2.typeToken;
|
|||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.apis.ApiMetadata;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.googlecomputeengine.compute.config.GoogleComputeEngineServiceContextModule;
|
||||
import org.jclouds.googlecomputeengine.config.GoogleComputeEngineHttpApiModule;
|
||||
|
@ -38,11 +36,9 @@ import org.jclouds.oauth.v2.config.OAuthAuthenticationModule;
|
|||
import org.jclouds.oauth.v2.config.OAuthModule;
|
||||
import org.jclouds.rest.internal.BaseHttpApiMetadata;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
@AutoService(ApiMetadata.class)
|
||||
public class GoogleComputeEngineApiMetadata extends BaseHttpApiMetadata<GoogleComputeEngineApi> {
|
||||
|
||||
@Override
|
||||
|
@ -64,9 +60,9 @@ public class GoogleComputeEngineApiMetadata extends BaseHttpApiMetadata<GoogleCo
|
|||
properties.put(AUDIENCE, "https://accounts.google.com/o/oauth2/token");
|
||||
properties.put(SIGNATURE_OR_MAC_ALGORITHM, "RS256");
|
||||
properties.put(PROPERTY_SESSION_INTERVAL, 3600);
|
||||
properties.setProperty(TEMPLATE, "osFamily=DEBIAN,osVersionMatches=7\\..*,locationId=us-central1-a,loginUser=jclouds");
|
||||
properties.put(OPERATION_COMPLETE_INTERVAL, 500);
|
||||
properties.put(OPERATION_COMPLETE_TIMEOUT, 600000);
|
||||
properties.put(TEMPLATE, "osFamily=DEBIAN,osVersionMatches=7\\..*,locationId=us-central1-a,loginUser=jclouds");
|
||||
properties.put(GCE_IMAGE_PROJECTS, "centos-cloud,debian-cloud,rhel-cloud,suse-cloud,opensuse-cloud,gce-nvme,coreos-cloud");
|
||||
return properties;
|
||||
}
|
||||
|
@ -74,22 +70,22 @@ public class GoogleComputeEngineApiMetadata extends BaseHttpApiMetadata<GoogleCo
|
|||
public static class Builder extends BaseHttpApiMetadata.Builder<GoogleComputeEngineApi, Builder> {
|
||||
|
||||
protected Builder() {
|
||||
id(GCE_PROVIDER_NAME)
|
||||
.name("Google Compute Engine Api")
|
||||
.identityName("Email associated with the Google API client_id")
|
||||
.credentialName("Private key literal associated with the Google API client_id")
|
||||
.documentation(URI.create("https://developers.google.com/compute/docs"))
|
||||
.version("v1")
|
||||
.defaultEndpoint("https://www.googleapis.com/compute/v1")
|
||||
.defaultProperties(GoogleComputeEngineApiMetadata.defaultProperties())
|
||||
.view(typeToken(ComputeServiceContext.class))
|
||||
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
|
||||
.add(GoogleComputeEngineHttpApiModule.class)
|
||||
.add(GoogleComputeEngineParserModule.class)
|
||||
.add(OAuthAuthenticationModule.class)
|
||||
.add(OAuthModule.class)
|
||||
.add(GoogleComputeEngineServiceContextModule.class)
|
||||
.build());
|
||||
id("google-compute-engine")
|
||||
.name("Google Compute Engine Api")
|
||||
.identityName("Email associated with the Google API client_id")
|
||||
.credentialName("Private key literal associated with the Google API client_id")
|
||||
.documentation(URI.create("https://developers.google.com/compute/docs"))
|
||||
.version("v1")
|
||||
.defaultEndpoint("https://www.googleapis.com/compute/v1")
|
||||
.defaultProperties(GoogleComputeEngineApiMetadata.defaultProperties())
|
||||
.view(typeToken(ComputeServiceContext.class))
|
||||
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
|
||||
.add(GoogleComputeEngineHttpApiModule.class)
|
||||
.add(GoogleComputeEngineParserModule.class)
|
||||
.add(OAuthAuthenticationModule.class)
|
||||
.add(OAuthModule.class)
|
||||
.add(GoogleComputeEngineServiceContextModule.class)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,30 +16,14 @@
|
|||
*/
|
||||
package org.jclouds.googlecomputeengine;
|
||||
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
public final class GoogleComputeEngineConstants {
|
||||
|
||||
public static final String GCE_PROVIDER_NAME = "google-compute-engine";
|
||||
|
||||
/**
|
||||
* The name of the project that keeps public resources.
|
||||
*/
|
||||
public static final String GOOGLE_PROJECT = "google";
|
||||
|
||||
public static final String COMPUTE_SCOPE = "https://www.googleapis.com/auth/compute";
|
||||
|
||||
public static final String COMPUTE_READONLY_SCOPE = "https://www.googleapis.com/auth/compute.readonly";
|
||||
|
||||
public static final String STORAGE_READONLY_SCOPE = "https://www.googleapis.com/auth/devstorage.read_only";
|
||||
|
||||
public static final String STORAGE_WRITEONLY_SCOPE = "https://www.googleapis.com/auth/devstorage.write_only";
|
||||
|
||||
|
||||
/**
|
||||
* The total time, in msecs, to wait for an operation to complete.
|
||||
*/
|
||||
|
@ -52,16 +36,12 @@ public final class GoogleComputeEngineConstants {
|
|||
@Beta
|
||||
public static final String OPERATION_COMPLETE_INTERVAL = "jclouds.google-compute-engine.operation-complete-interval";
|
||||
|
||||
public static final Location GOOGLE_PROVIDER_LOCATION = new LocationBuilder().scope(LocationScope.PROVIDER).id
|
||||
(GCE_PROVIDER_NAME).description(GCE_PROVIDER_NAME).build();
|
||||
|
||||
/**
|
||||
* The list of projects that will be scanned looking for images.
|
||||
*/
|
||||
@Beta
|
||||
public static final String GCE_IMAGE_PROJECTS = "jclouds.google-compute-engine.image-projects";
|
||||
|
||||
|
||||
/**
|
||||
* The key we look for in instance metadata for the URI for the image the instance was created from.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF 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.googlecomputeengine;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.providers.internal.BaseProviderMetadata;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
|
||||
/** Note: This does not set iso3166Codes as Google intentionally does not document them. */
|
||||
@AutoService(ProviderMetadata.class)
|
||||
public final class GoogleComputeEngineProviderMetadata extends BaseProviderMetadata {
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return builder().fromProviderMetadata(this);
|
||||
}
|
||||
|
||||
public GoogleComputeEngineProviderMetadata() {
|
||||
super(builder());
|
||||
}
|
||||
|
||||
public GoogleComputeEngineProviderMetadata(Builder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
public static Properties defaultProperties() {
|
||||
return new Properties(); // currently all are set in the api metadata class.
|
||||
}
|
||||
|
||||
public static final class Builder extends BaseProviderMetadata.Builder {
|
||||
|
||||
private Builder() {
|
||||
id("google-compute-engine") //
|
||||
.name("Google Compute Engine") //
|
||||
.apiMetadata(new GoogleComputeEngineApiMetadata()) //
|
||||
.homepage(URI.create("https://cloud.google.com/compute")) //
|
||||
.console(URI.create("https://console.developers.google.com/project")) //
|
||||
.defaultProperties(GoogleComputeEngineProviderMetadata.defaultProperties());
|
||||
}
|
||||
|
||||
@Override public GoogleComputeEngineProviderMetadata build() {
|
||||
return new GoogleComputeEngineProviderMetadata(this);
|
||||
}
|
||||
|
||||
@Override public Builder fromProviderMetadata(ProviderMetadata in) {
|
||||
super.fromProviderMetadata(in);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,7 +38,6 @@ import static org.jclouds.util.Predicates2.retry;
|
|||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -47,7 +46,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
|
@ -69,15 +67,16 @@ import org.jclouds.googlecomputeengine.domain.Instance.AttachedDisk.Mode;
|
|||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
import org.jclouds.googlecomputeengine.domain.templates.InstanceTemplate;
|
||||
import org.jclouds.googlecomputeengine.domain.templates.InstanceTemplate.PersistentDisk;
|
||||
import org.jclouds.googlecomputeengine.features.DiskApi;
|
||||
import org.jclouds.googlecomputeengine.features.InstanceApi;
|
||||
import org.jclouds.googlecomputeengine.options.DiskCreationOptions;
|
||||
import org.jclouds.location.Zone;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -88,11 +87,12 @@ import com.google.common.primitives.Ints;
|
|||
import com.google.common.util.concurrent.Atomics;
|
||||
import com.google.common.util.concurrent.UncheckedTimeoutException;
|
||||
|
||||
public final class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<InstanceInZone, MachineTypeInZone, Image, Zone> {
|
||||
public final class GoogleComputeEngineServiceAdapter
|
||||
implements ComputeServiceAdapter<InstanceInZone, MachineTypeInZone, Image, Location> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
private final Supplier<String> userProject;
|
||||
private final Supplier<Map<URI, ? extends Location>> zones;
|
||||
private final Supplier<Set<String>> zoneIds;
|
||||
private final Function<TemplateOptions, ImmutableMap.Builder<String, String>> metatadaFromTemplateOptions;
|
||||
private final Predicate<AtomicReference<Operation>> retryOperationDonePredicate;
|
||||
private final long operationCompleteCheckInterval;
|
||||
|
@ -107,9 +107,9 @@ public final class GoogleComputeEngineServiceAdapter implements ComputeServiceAd
|
|||
@Named("zone") Predicate<AtomicReference<Operation>> operationDonePredicate,
|
||||
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
|
||||
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout,
|
||||
@Memoized Supplier<Map<URI, ? extends Location>> zones,
|
||||
@Zone Supplier<Set<String>> zoneIds,
|
||||
FirewallTagNamingConvention.Factory firewallTagNamingConvention,
|
||||
@Named(GCE_IMAGE_PROJECTS) List<String> imageProjects) {
|
||||
@Named(GCE_IMAGE_PROJECTS) String imageProjects) {
|
||||
this.api = api;
|
||||
this.userProject = userProject;
|
||||
this.metatadaFromTemplateOptions = metatadaFromTemplateOptions;
|
||||
|
@ -117,9 +117,9 @@ public final class GoogleComputeEngineServiceAdapter implements ComputeServiceAd
|
|||
this.operationCompleteCheckTimeout = operationCompleteCheckTimeout;
|
||||
this.retryOperationDonePredicate = retry(operationDonePredicate, operationCompleteCheckTimeout,
|
||||
operationCompleteCheckInterval, TimeUnit.MILLISECONDS);
|
||||
this.zones = zones;
|
||||
this.zoneIds = zoneIds;
|
||||
this.firewallTagNamingConvention = firewallTagNamingConvention;
|
||||
this.imageProjects = imageProjects;
|
||||
this.imageProjects = Splitter.on(',').splitToList(imageProjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -241,8 +241,8 @@ public final class GoogleComputeEngineServiceAdapter implements ComputeServiceAd
|
|||
public Iterable<MachineTypeInZone> listHardwareProfiles() {
|
||||
ImmutableList.Builder<MachineTypeInZone> builder = ImmutableList.builder();
|
||||
|
||||
for (final Location zone : zones.get().values()) {
|
||||
for (Iterator<ListPage<MachineType>> i = api.getMachineTypeApi(userProject.get(), zone.getId()).list();
|
||||
for (final String zoneId : zoneIds.get()) {
|
||||
for (Iterator<ListPage<MachineType>> i = api.getMachineTypeApi(userProject.get(), zoneId).list();
|
||||
i.hasNext(); ) {
|
||||
builder.addAll(FluentIterable.from(i.next()).filter(new Predicate<MachineType>() {
|
||||
@Override public boolean apply(MachineType input) {
|
||||
|
@ -254,7 +254,6 @@ public final class GoogleComputeEngineServiceAdapter implements ComputeServiceAd
|
|||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
|
@ -288,8 +287,8 @@ public final class GoogleComputeEngineServiceAdapter implements ComputeServiceAd
|
|||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Zone> listLocations() {
|
||||
return concat(api.getZoneApi(userProject.get()).list());
|
||||
public Iterable<Location> listLocations() {
|
||||
throw new UnsupportedOperationException("Locations are configured in GoogleComputeEngineLocationModule");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -301,13 +300,13 @@ public final class GoogleComputeEngineServiceAdapter implements ComputeServiceAd
|
|||
|
||||
@Override
|
||||
public Iterable<InstanceInZone> listNodes() {
|
||||
return FluentIterable.from(zones.get().values())
|
||||
.transformAndConcat(new Function<Location, Iterable<InstanceInZone>>() {
|
||||
@Override public Iterable<InstanceInZone> apply(final Location input) {
|
||||
return transform(concat(api.getInstanceApi(userProject.get(), input.getId()).list()),
|
||||
return FluentIterable.from(zoneIds.get())
|
||||
.transformAndConcat(new Function<String, Iterable<InstanceInZone>>() {
|
||||
@Override public Iterable<InstanceInZone> apply(final String zoneId) {
|
||||
return transform(concat(api.getInstanceApi(userProject.get(), zoneId).list()),
|
||||
new Function<Instance, InstanceInZone>() {
|
||||
@Override public InstanceInZone apply(Instance arg0) {
|
||||
return InstanceInZone.create(arg0, input.getId());
|
||||
return InstanceInZone.create(arg0, zoneId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,18 +16,13 @@
|
|||
*/
|
||||
package org.jclouds.googlecomputeengine.compute.config;
|
||||
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Maps.uniqueIndex;
|
||||
import static com.google.common.base.Suppliers.memoizeWithExpiration;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
import static org.jclouds.googlecomputeengine.internal.ListPages.concat;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_PROJECTS;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -44,7 +39,6 @@ import org.jclouds.compute.extensions.SecurityGroupExtension;
|
|||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineService;
|
||||
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter;
|
||||
import org.jclouds.googlecomputeengine.compute.domain.InstanceInZone;
|
||||
|
@ -61,29 +55,21 @@ import org.jclouds.googlecomputeengine.compute.functions.InstanceInZoneToNodeMet
|
|||
import org.jclouds.googlecomputeengine.compute.functions.MachineTypeInZoneToHardware;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.NetworkToSecurityGroup;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.OrphanedGroupsFromDeadNodes;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.RegionToLocation;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.ZoneToLocation;
|
||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||
import org.jclouds.googlecomputeengine.compute.predicates.AllNodesInGroupTerminated;
|
||||
import org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
|
||||
import org.jclouds.googlecomputeengine.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||
import org.jclouds.googlecomputeengine.compute.strategy.UseNodeCredentialsButOverrideFromTemplate;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.Network;
|
||||
import org.jclouds.googlecomputeengine.domain.Region;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
import org.jclouds.net.domain.IpPermission;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
|
@ -94,8 +80,8 @@ import com.google.inject.Provides;
|
|||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
public class GoogleComputeEngineServiceContextModule
|
||||
extends ComputeServiceAdapterContextModule<InstanceInZone, MachineTypeInZone, Image, Zone> {
|
||||
public final class GoogleComputeEngineServiceContextModule
|
||||
extends ComputeServiceAdapterContextModule<InstanceInZone, MachineTypeInZone, Image, Location> {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
@ -103,192 +89,126 @@ public class GoogleComputeEngineServiceContextModule
|
|||
|
||||
bind(ComputeService.class).to(GoogleComputeEngineService.class);
|
||||
|
||||
bind(new TypeLiteral<ComputeServiceAdapter<InstanceInZone, MachineTypeInZone, Image, Zone>>() {})
|
||||
.to(GoogleComputeEngineServiceAdapter.class);
|
||||
bind(new TypeLiteral<ComputeServiceAdapter<InstanceInZone, MachineTypeInZone, Image, Location>>() {
|
||||
}).to(GoogleComputeEngineServiceAdapter.class);
|
||||
|
||||
bind(new TypeLiteral<Function<InstanceInZone, NodeMetadata>>() {})
|
||||
.to(InstanceInZoneToNodeMetadata.class);
|
||||
bind(new TypeLiteral<Function<Location, Location>>() {
|
||||
}).toInstance(Functions.<Location>identity());
|
||||
|
||||
bind(new TypeLiteral<Function<MachineTypeInZone, Hardware>>() {})
|
||||
.to(MachineTypeInZoneToHardware.class);
|
||||
bind(new TypeLiteral<Function<InstanceInZone, NodeMetadata>>() {
|
||||
}).to(InstanceInZoneToNodeMetadata.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Image, org.jclouds.compute.domain.Image>>() {})
|
||||
.to(GoogleComputeEngineImageToImage.class);
|
||||
bind(new TypeLiteral<Function<MachineTypeInZone, Hardware>>() {
|
||||
}).to(MachineTypeInZoneToHardware.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Region, Location>>() {
|
||||
})
|
||||
.to(RegionToLocation.class);
|
||||
bind(new TypeLiteral<Function<Image, org.jclouds.compute.domain.Image>>() {
|
||||
}).to(GoogleComputeEngineImageToImage.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Zone, Location>>() {})
|
||||
.to(ZoneToLocation.class);
|
||||
bind(new TypeLiteral<Function<Firewall, Iterable<IpPermission>>>() {
|
||||
}).to(FirewallToIpPermission.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Firewall, Iterable<IpPermission>>>() {})
|
||||
.to(FirewallToIpPermission.class);
|
||||
bind(new TypeLiteral<Function<Network, SecurityGroup>>() {
|
||||
}).to(NetworkToSecurityGroup.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Network, SecurityGroup>>() {})
|
||||
.to(NetworkToSecurityGroup.class);
|
||||
|
||||
bind(new TypeLiteral<Function<TemplateOptions, ImmutableMap.Builder<String, String>>>() {})
|
||||
.to(BuildInstanceMetadata.class);
|
||||
bind(new TypeLiteral<Function<TemplateOptions, ImmutableMap.Builder<String, String>>>() {
|
||||
}).to(BuildInstanceMetadata.class);
|
||||
|
||||
bind(org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy.class)
|
||||
.to(PopulateDefaultLoginCredentialsForImageStrategy.class);
|
||||
.to(PopulateDefaultLoginCredentialsForImageStrategy.class);
|
||||
|
||||
bind(org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
|
||||
CreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
|
||||
bind(org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet.class)
|
||||
.to(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
|
||||
|
||||
bind(TemplateOptions.class).to(GoogleComputeEngineTemplateOptions.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Set<String>>>() {})
|
||||
.to(OrphanedGroupsFromDeadNodes.class);
|
||||
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Set<String>>>() {
|
||||
}).to(OrphanedGroupsFromDeadNodes.class);
|
||||
|
||||
bind(new TypeLiteral<Predicate<String>>() {}).to(AllNodesInGroupTerminated.class);
|
||||
bind(new TypeLiteral<Predicate<String>>() {
|
||||
}).to(AllNodesInGroupTerminated.class);
|
||||
|
||||
bind(new TypeLiteral<Function<NetworkAndAddressRange, Network>>() {})
|
||||
.to(CreateNetworkIfNeeded.class);
|
||||
bind(new TypeLiteral<Function<NetworkAndAddressRange, Network>>() {
|
||||
}).to(CreateNetworkIfNeeded.class);
|
||||
|
||||
bind(new TypeLiteral<CacheLoader<NetworkAndAddressRange, Network>>() {})
|
||||
.to(FindNetworkOrCreate.class);
|
||||
bind(new TypeLiteral<CacheLoader<NetworkAndAddressRange, Network>>() {
|
||||
}).to(FindNetworkOrCreate.class);
|
||||
|
||||
bind(new TypeLiteral<SecurityGroupExtension>() {})
|
||||
.to(GoogleComputeEngineSecurityGroupExtension.class);
|
||||
bind(SecurityGroupExtension.class).to(GoogleComputeEngineSecurityGroupExtension.class);
|
||||
|
||||
bind(PrioritizeCredentialsFromTemplate.class).to(UseNodeCredentialsButOverrideFromTemplate.class);
|
||||
|
||||
install(new LocationsFromComputeServiceAdapterModule<InstanceInZone, MachineTypeInZone, Image, Zone>() {});
|
||||
|
||||
bind(FirewallTagNamingConvention.Factory.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Memoized
|
||||
public Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>> provideImagesMap(
|
||||
AtomicReference<AuthorizationException> authException,
|
||||
final Supplier<Set<? extends org.jclouds.compute.domain.Image>> images,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
|
||||
new Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends org.jclouds.compute.domain.Image> get() {
|
||||
return uniqueIndex(images.get(), new Function<org.jclouds.compute.domain.Image, URI>() {
|
||||
@Override
|
||||
public URI apply(org.jclouds.compute.domain.Image input) {
|
||||
return input.getUri();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
seconds, TimeUnit.SECONDS);
|
||||
@Provides @Singleton @Memoized Supplier<Map<URI, org.jclouds.compute.domain.Image>> imageByUri(
|
||||
@Memoized final Supplier<Set<? extends org.jclouds.compute.domain.Image>> imageSupplier,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return memoizeWithExpiration(new Supplier<Map<URI, org.jclouds.compute.domain.Image>>() {
|
||||
@Override public Map<URI, org.jclouds.compute.domain.Image> get() {
|
||||
ImmutableMap.Builder<URI, org.jclouds.compute.domain.Image> result = ImmutableMap.builder();
|
||||
for (org.jclouds.compute.domain.Image image : imageSupplier.get()) {
|
||||
result.put(image.getUri(), image);
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
}, seconds, SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Memoized
|
||||
public Supplier<Map<URI, ? extends Hardware>> provideHardwaresMap(
|
||||
AtomicReference<AuthorizationException> authException,
|
||||
final Supplier<Set<? extends Hardware>> hardwares,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
|
||||
new Supplier<Map<URI, ? extends Hardware>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends Hardware> get() {
|
||||
return uniqueIndex(hardwares.get(), new Function<Hardware, URI>() {
|
||||
@Override
|
||||
public URI apply(Hardware input) {
|
||||
return input.getUri();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
seconds, TimeUnit.SECONDS);
|
||||
@Provides @Singleton @Memoized Supplier<Map<URI, Hardware>> hardwareByUri(
|
||||
@Memoized final Supplier<Set<? extends Hardware>> hardwareSupplier,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return memoizeWithExpiration(new Supplier<Map<URI, Hardware>>() {
|
||||
@Override public Map<URI, Hardware> get() {
|
||||
ImmutableMap.Builder<URI, Hardware> result = ImmutableMap.builder();
|
||||
for (Hardware hardware : hardwareSupplier.get()) {
|
||||
result.put(hardware.getUri(), hardware);
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
}, seconds, SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Memoized
|
||||
public Supplier<Map<URI, ? extends Location>> provideZones(
|
||||
AtomicReference<AuthorizationException> authException,
|
||||
final GoogleComputeEngineApi api, final Function<Zone, Location> zoneToLocation,
|
||||
@UserProject final Supplier<String> userProject,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
|
||||
new Supplier<Map<URI, ? extends Location>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends Location> get() {
|
||||
return uniqueIndex(transform(concat(api.getZoneApi(userProject.get()).list()), zoneToLocation),
|
||||
new Function<Location, URI>() {
|
||||
@Override
|
||||
public URI apply(Location input) {
|
||||
return (URI) input.getMetadata().get("selfLink");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
seconds, TimeUnit.SECONDS);
|
||||
@Provides @Singleton @Memoized Supplier<Map<URI, Location>> locationsByUri(
|
||||
@Memoized final Supplier<Set<? extends Location>> locations,
|
||||
@Memoized final Supplier<Map<URI, String>> selfLinkToNames, @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return memoizeWithExpiration(new Supplier<Map<URI, Location>>() {
|
||||
@Override public Map<URI, Location> get() {
|
||||
ImmutableMap.Builder<URI, Location> result = ImmutableMap.builder();
|
||||
for (Location location : locations.get()) {
|
||||
for (Map.Entry<URI, String> entry : selfLinkToNames.get().entrySet()) {
|
||||
if (entry.getValue().equals(location.getId())) {
|
||||
result.put(entry.getKey(), location);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
}, seconds, SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Memoized
|
||||
public Supplier<Map<URI, Region>> provideRegions(
|
||||
AtomicReference<AuthorizationException> authException,
|
||||
final GoogleComputeEngineApi api,
|
||||
@UserProject final Supplier<String> userProject,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
|
||||
new Supplier<Map<URI, Region>>() {
|
||||
@Override
|
||||
public Map<URI, Region> get() {
|
||||
return uniqueIndex(concat(api.getRegionApi(userProject.get()).list()),
|
||||
new Function<Region, URI>() {
|
||||
@Override
|
||||
public URI apply(Region input) {
|
||||
return input.selfLink();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected LoadingCache<NetworkAndAddressRange, Network> networkMap(
|
||||
CacheLoader<NetworkAndAddressRange, Network> in) {
|
||||
@Provides @Singleton
|
||||
LoadingCache<NetworkAndAddressRange, Network> networkMap(CacheLoader<NetworkAndAddressRange, Network> in) {
|
||||
return CacheBuilder.newBuilder().build(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<ImageExtension> provideImageExtension(Injector i) {
|
||||
@Override protected Optional<ImageExtension> provideImageExtension(Injector i) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
|
||||
@Override protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
|
||||
return Optional.of(i.getInstance(SecurityGroupExtension.class));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus =
|
||||
ImmutableMap.<Instance.Status, NodeMetadata.Status>builder()
|
||||
.put(Instance.Status.PROVISIONING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.STAGING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.RUNNING, NodeMetadata.Status.RUNNING)
|
||||
.put(Instance.Status.STOPPING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.STOPPED, NodeMetadata.Status.SUSPENDED)
|
||||
.put(Instance.Status.TERMINATED, NodeMetadata.Status.TERMINATED).build();
|
||||
private static final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus =
|
||||
ImmutableMap.<Instance.Status, NodeMetadata.Status>builder()
|
||||
.put(Instance.Status.PROVISIONING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.STAGING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.RUNNING, NodeMetadata.Status.RUNNING)
|
||||
.put(Instance.Status.STOPPING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.STOPPED, NodeMetadata.Status.SUSPENDED)
|
||||
.put(Instance.Status.TERMINATED, NodeMetadata.Status.TERMINATED).build();
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
protected Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus() {
|
||||
@Provides Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus() {
|
||||
return toPortableNodeStatus;
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
@Named(GCE_IMAGE_PROJECTS)
|
||||
protected List<String> imageProjects(@Named(GCE_IMAGE_PROJECTS) String imageProjects) {
|
||||
return Splitter.on(',').splitToList(imageProjects);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ package org.jclouds.googlecomputeengine.compute.functions;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
@ -29,11 +27,9 @@ import com.google.common.collect.ImmutableMap;
|
|||
/**
|
||||
* Prepares metadata from the provided TemplateOptions
|
||||
*/
|
||||
@Singleton
|
||||
public class BuildInstanceMetadata implements Function<TemplateOptions, ImmutableMap.Builder<String, String>> {
|
||||
public final class BuildInstanceMetadata implements Function<TemplateOptions, ImmutableMap.Builder<String, String>> {
|
||||
|
||||
@Override
|
||||
public ImmutableMap.Builder apply(TemplateOptions input) {
|
||||
@Override public ImmutableMap.Builder apply(TemplateOptions input) {
|
||||
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||
if (input.getPublicKey() != null) {
|
||||
builder.put("sshKeys", format("%s:%s %s@localhost", checkNotNull(input.getLoginUser(),
|
||||
|
@ -42,5 +38,4 @@ public class BuildInstanceMetadata implements Function<TemplateOptions, Immutabl
|
|||
builder.putAll(input.getUserMetadata());
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,17 +25,14 @@ import static org.jclouds.util.Predicates2.retry;
|
|||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Network;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -43,9 +40,6 @@ import com.google.common.base.Supplier;
|
|||
import com.google.common.util.concurrent.Atomics;
|
||||
|
||||
public class CreateNetworkIfNeeded implements Function<NetworkAndAddressRange, Network> {
|
||||
@Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
private Logger logger = Logger.NULL;
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
private final Supplier<String> userProject;
|
||||
private final Predicate<AtomicReference<Operation>> operationDonePredicate;
|
||||
|
|
|
@ -47,22 +47,22 @@ public final class InstanceInZoneToNodeMetadata implements Function<InstanceInZo
|
|||
|
||||
private final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus;
|
||||
private final GroupNamingConvention nodeNamingConvention;
|
||||
private final Supplier<Map<URI, ? extends Image>> images;
|
||||
private final Supplier<Map<URI, ? extends Hardware>> hardwares;
|
||||
private final Supplier<Map<URI, ? extends Location>> locations;
|
||||
private final Supplier<Map<URI, Image>> images;
|
||||
private final Supplier<Map<URI, Hardware>> hardwares;
|
||||
private final Supplier<Map<URI, Location>> locationsByUri;
|
||||
private final FirewallTagNamingConvention.Factory firewallTagNamingConvention;
|
||||
|
||||
@Inject InstanceInZoneToNodeMetadata(Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus,
|
||||
GroupNamingConvention.Factory namingConvention,
|
||||
@Memoized Supplier<Map<URI, ? extends Image>> images,
|
||||
@Memoized Supplier<Map<URI, ? extends Hardware>> hardwares,
|
||||
@Memoized Supplier<Map<URI, ? extends Location>> locations,
|
||||
@Memoized Supplier<Map<URI, Image>> images,
|
||||
@Memoized Supplier<Map<URI, Hardware>> hardwares,
|
||||
@Memoized Supplier<Map<URI, Location>> locationsByUri,
|
||||
FirewallTagNamingConvention.Factory firewallTagNamingConvention) {
|
||||
this.toPortableNodeStatus = toPortableNodeStatus;
|
||||
this.nodeNamingConvention = namingConvention.createWithoutPrefix();
|
||||
this.images = images;
|
||||
this.hardwares = hardwares;
|
||||
this.locations = locations;
|
||||
this.locationsByUri = locationsByUri;
|
||||
this.firewallTagNamingConvention = checkNotNull(firewallTagNamingConvention, "firewallTagNamingConvention");
|
||||
}
|
||||
|
||||
|
@ -77,12 +77,16 @@ public final class InstanceInZoneToNodeMetadata implements Function<InstanceInZo
|
|||
|
||||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||
|
||||
Location location = checkNotNull(locations.get().get(input.zone()), "location for %s", input.zone());
|
||||
builder.id(SlashEncodedIds.from(location.getId(), input.name()).slashEncode())
|
||||
Location zone = locationsByUri.get().get(input.zone());
|
||||
if (zone == null) {
|
||||
throw new IllegalStateException(
|
||||
String.format("zone %s not present in %s", input.zone(), locationsByUri.get().keySet()));
|
||||
}
|
||||
builder.id(SlashEncodedIds.from(zone.getId(), input.name()).slashEncode())
|
||||
.name(input.name())
|
||||
.providerId(input.id())
|
||||
.hostname(input.name())
|
||||
.location(location)
|
||||
.location(zone)
|
||||
.hardware(hardwares.get().get(input.machineType()))
|
||||
.status(toPortableNodeStatus.get(input.status()))
|
||||
.tags(tags)
|
||||
|
@ -96,7 +100,7 @@ public final class InstanceInZoneToNodeMetadata implements Function<InstanceInZo
|
|||
try {
|
||||
URI imageUri = URI.create(input.metadata().items().get(GCE_IMAGE_METADATA_KEY));
|
||||
|
||||
Map<URI, ? extends Image> imagesMap = images.get();
|
||||
Map<URI, Image> imagesMap = images.get();
|
||||
|
||||
Image image = checkNotNull(imagesMap.get(imageUri),
|
||||
"no image for %s. images: %s", imageUri,
|
||||
|
|
|
@ -16,13 +16,11 @@
|
|||
*/
|
||||
package org.jclouds.googlecomputeengine.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.HardwareBuilder;
|
||||
|
@ -36,40 +34,31 @@ import org.jclouds.googlecomputeengine.compute.domain.SlashEncodedIds;
|
|||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Transforms a google compute domain specific machine type to a generic Hardware object.
|
||||
*/
|
||||
public class MachineTypeInZoneToHardware implements Function<MachineTypeInZone, Hardware> {
|
||||
public final class MachineTypeInZoneToHardware implements Function<MachineTypeInZone, Hardware> {
|
||||
|
||||
private final Supplier<Map<URI, ? extends Location>> locations;
|
||||
private final Supplier<Map<URI, Location>> locationsByUri;
|
||||
|
||||
@Inject
|
||||
public MachineTypeInZoneToHardware(@Memoized Supplier<Map<URI, ? extends Location>> locations) {
|
||||
this.locations = locations;
|
||||
@Inject MachineTypeInZoneToHardware(@Memoized Supplier<Map<URI, Location>> locationsByUri) {
|
||||
this.locationsByUri = locationsByUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hardware apply(final MachineTypeInZone input) {
|
||||
Iterable<? extends Location> zonesForMachineType = filter(locations.get().values(), new Predicate<Location>() {
|
||||
@Override
|
||||
public boolean apply(Location l) {
|
||||
return l.getId().equals(input.machineType().zone());
|
||||
}
|
||||
});
|
||||
|
||||
Location location = checkNotNull(getOnlyElement(zonesForMachineType),
|
||||
"location for %s",
|
||||
input.machineType().zone());
|
||||
public Hardware apply(MachineTypeInZone input) {
|
||||
URI zoneLink = URI.create(
|
||||
input.machineType().selfLink().toString().replace("/machineTypes/" + input.machineType().name(), ""));
|
||||
|
||||
Location zone = locationsByUri.get().get(zoneLink);
|
||||
if (zone == null) {
|
||||
throw new IllegalStateException(
|
||||
String.format("zone %s not present in %s", zoneLink, locationsByUri.get().keySet()));
|
||||
}
|
||||
return new HardwareBuilder()
|
||||
.id(SlashEncodedIds.from(input.machineType().zone(), input.machineType().name()).slashEncode())
|
||||
.location(location)
|
||||
.location(zone)
|
||||
.name(input.machineType().name())
|
||||
.hypervisor("kvm")
|
||||
.processor(new Processor(input.machineType().guestCpus(), 1.0))
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.jclouds.googlecomputeengine.compute.functions;
|
|||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
|
||||
|
@ -27,19 +26,16 @@ import com.google.common.base.Function;
|
|||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
@Singleton
|
||||
public class OrphanedGroupsFromDeadNodes implements Function<Set<? extends NodeMetadata>, Set<String>> {
|
||||
public final class OrphanedGroupsFromDeadNodes implements Function<Set<? extends NodeMetadata>, Set<String>> {
|
||||
|
||||
private final Predicate<String> isOrphanedGroupPredicate;
|
||||
|
||||
@Inject
|
||||
public OrphanedGroupsFromDeadNodes(Predicate<String> isOrphanedGroupPredicate) {
|
||||
@Inject OrphanedGroupsFromDeadNodes(Predicate<String> isOrphanedGroupPredicate) {
|
||||
this.isOrphanedGroupPredicate = isOrphanedGroupPredicate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> apply(Set<? extends NodeMetadata> deadNodes) {
|
||||
@Override public Set<String> apply(Set<? extends NodeMetadata> deadNodes) {
|
||||
Set<String> groups = Sets.newLinkedHashSet();
|
||||
for (NodeMetadata deadNode : deadNodes) {
|
||||
groups.add(deadNode.getGroup());
|
||||
|
@ -52,6 +48,4 @@ public class OrphanedGroupsFromDeadNodes implements Function<Set<? extends NodeM
|
|||
}
|
||||
return orphanedGroups;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROVIDER_LOCATION;
|
||||
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.googlecomputeengine.domain.Region;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* Transforms a google compute domain specific region to a generic Region object.
|
||||
*/
|
||||
public class RegionToLocation implements Function<Region, Location> {
|
||||
|
||||
@Override
|
||||
public Location apply(Region input) {
|
||||
return new LocationBuilder()
|
||||
.description(input.description())
|
||||
.metadata(ImmutableMap.of("selfLink", (Object) checkNotNull(input.selfLink(), "region URI")))
|
||||
.id(input.name())
|
||||
.scope(LocationScope.REGION)
|
||||
.parent(GOOGLE_PROVIDER_LOCATION)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROVIDER_LOCATION;
|
||||
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* Transforms a google compute domain specific zone to a generic Zone object.
|
||||
*/
|
||||
public class ZoneToLocation implements Function<Zone, Location> {
|
||||
|
||||
@Override
|
||||
public Location apply(Zone input) {
|
||||
return new LocationBuilder()
|
||||
.description(input.description())
|
||||
.metadata(ImmutableMap.of("selfLink", (Object) checkNotNull(input.selfLink(), "zone URI")))
|
||||
.id(input.name())
|
||||
.scope(LocationScope.ZONE)
|
||||
.parent(GOOGLE_PROVIDER_LOCATION)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ import com.google.common.collect.Lists;
|
|||
/**
|
||||
* Instance options specific to Google Compute Engine.
|
||||
*/
|
||||
public class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
||||
public final class GoogleComputeEngineTemplateOptions extends TemplateOptions {
|
||||
|
||||
private Optional<URI> network = Optional.absent();
|
||||
private List<Instance.ServiceAccount> serviceAccounts = Lists.newArrayList();
|
||||
|
|
|
@ -18,10 +18,10 @@ package org.jclouds.googlecomputeengine.config;
|
|||
|
||||
import static com.google.common.base.Suppliers.compose;
|
||||
import static com.google.inject.name.Names.named;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
@ -31,7 +31,6 @@ import org.jclouds.domain.Credentials;
|
|||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.compute.domain.SlashEncodedIds;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.domain.Project;
|
||||
import org.jclouds.googlecomputeengine.handlers.GoogleComputeEngineErrorHandler;
|
||||
import org.jclouds.googlecomputeengine.predicates.GlobalOperationDonePredicate;
|
||||
import org.jclouds.googlecomputeengine.predicates.RegionOperationDonePredicate;
|
||||
|
@ -44,8 +43,6 @@ import org.jclouds.http.annotation.ServerError;
|
|||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||
import org.jclouds.location.suppliers.implicit.FirstZone;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.ConfiguresHttpApi;
|
||||
import org.jclouds.rest.config.HttpApiModule;
|
||||
|
@ -57,14 +54,10 @@ import com.google.common.base.Splitter;
|
|||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Configures the GoogleCompute connection.
|
||||
*/
|
||||
@ConfiguresHttpApi
|
||||
public class GoogleComputeEngineHttpApiModule extends HttpApiModule<GoogleComputeEngineApi> {
|
||||
public final class GoogleComputeEngineHttpApiModule extends HttpApiModule<GoogleComputeEngineApi> {
|
||||
public GoogleComputeEngineHttpApiModule() {
|
||||
}
|
||||
|
||||
|
@ -77,7 +70,6 @@ public class GoogleComputeEngineHttpApiModule extends HttpApiModule<GoogleComput
|
|||
}).annotatedWith(named("region")).to(RegionOperationDonePredicate.class);
|
||||
bind(new TypeLiteral<Predicate<AtomicReference<Operation>>>() {
|
||||
}).annotatedWith(named("zone")).to(ZoneOperationDonePredicate.class);
|
||||
bind(ImplicitLocationSupplier.class).to(FirstZone.class).in(Scopes.SINGLETON);
|
||||
super.configure();
|
||||
}
|
||||
|
||||
|
@ -88,13 +80,21 @@ public class GoogleComputeEngineHttpApiModule extends HttpApiModule<GoogleComput
|
|||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(GoogleComputeEngineErrorHandler.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installLocations() {
|
||||
install(new GoogleComputeEngineLocationModule());
|
||||
}
|
||||
|
||||
/**
|
||||
* Since this is caching a direct api call, we memoize, but short-circuit on any auth exception. This prevents
|
||||
* excessive errors when things occur in parallel, or as peers on a function graph.
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
@UserProject
|
||||
public Supplier<String> supplyProject(@Provider final Supplier<Credentials> creds,
|
||||
final GoogleComputeEngineApi api,
|
||||
AtomicReference<AuthorizationException> authException,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
@UserProject Supplier<String> projectName(@Provider final Supplier<Credentials> creds,
|
||||
final GoogleComputeEngineApi api,
|
||||
AtomicReference<AuthorizationException> authException,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
|
||||
compose(new Function<Credentials, String>() {
|
||||
public String apply(Credentials in) {
|
||||
|
@ -111,17 +111,15 @@ public class GoogleComputeEngineHttpApiModule extends HttpApiModule<GoogleComput
|
|||
projectName = Iterables.get(Splitter.on("-").split(projectName), 0);
|
||||
}
|
||||
}
|
||||
Project project = api.getProjectApi().get(projectName);
|
||||
return project.name();
|
||||
return api.getProjectApi().get(projectName).name();
|
||||
}
|
||||
}, creds), seconds, TimeUnit.SECONDS);
|
||||
}, creds), seconds, SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("machineTypeToURI")
|
||||
public Function<String, URI> provideMachineTypeNameToURIFunction(@Provider final Supplier<URI> endpoint,
|
||||
@UserProject final Supplier<String> userProject) {
|
||||
@Named("machineTypeToURI") Function<String, URI> machineTypeNameToURI(
|
||||
@Provider final Supplier<URI> endpoint, @UserProject final Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
|
@ -135,43 +133,13 @@ public class GoogleComputeEngineHttpApiModule extends HttpApiModule<GoogleComput
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("networkToURI")
|
||||
public Function<String, URI> provideNetworkNameToURIFunction(@Provider final Supplier<URI> endpoint,
|
||||
@UserProject final Supplier<String> userProject) {
|
||||
@Named("networkToURI") Function<String, URI> networkNameToURI(@Provider final Supplier<URI> endpoint,
|
||||
@UserProject final Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
@Override public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get())
|
||||
.appendPath("/global/networks/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("zoneToURI")
|
||||
public Function<String, URI> provideZoneNameToURIFunction(@Provider final Supplier<URI> endpoint,
|
||||
@UserProject final Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get())
|
||||
.appendPath("/zones/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("regionToURI")
|
||||
public Function<String, URI> provideRegionNameToURIFunction(@Provider final Supplier<URI> endpoint,
|
||||
@UserProject final Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get())
|
||||
.appendPath("/regions/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF 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.googlecomputeengine.config;
|
||||
|
||||
import static com.google.common.base.Suppliers.compose;
|
||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
import static org.jclouds.googlecomputeengine.internal.ListPages.concat;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.Region;
|
||||
import org.jclouds.location.config.LocationModule;
|
||||
import org.jclouds.location.predicates.LocationPredicates;
|
||||
import org.jclouds.location.reference.LocationConstants;
|
||||
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||
import org.jclouds.location.suppliers.LocationsSupplier;
|
||||
import org.jclouds.location.suppliers.RegionIdToURISupplier;
|
||||
import org.jclouds.location.suppliers.RegionIdToZoneIdsSupplier;
|
||||
import org.jclouds.location.suppliers.RegionIdsSupplier;
|
||||
import org.jclouds.location.suppliers.ZoneIdToURISupplier;
|
||||
import org.jclouds.location.suppliers.ZoneIdsSupplier;
|
||||
import org.jclouds.location.suppliers.all.ZoneToRegionToProviderOrJustProvider;
|
||||
import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet;
|
||||
import org.jclouds.location.suppliers.derived.ZoneIdsFromRegionIdToZoneIdsValues;
|
||||
import org.jclouds.location.suppliers.implicit.FirstZone;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* This configures dynamic locations from {@link org.jclouds.googlecomputeengine.features.RegionApi#list}. As the only
|
||||
* assignable location for nodes are zones, this module does not directly expose regions. Rather, they can be found by
|
||||
* looking at {@link Location#getParent()} on a zone.
|
||||
|
||||
* <p/> This does not yet support constraining region or zone lists via settings {@linkplain
|
||||
* LocationConstants#PROPERTY_REGIONS} or {@linkplain LocationConstants#PROPERTY_ZONES}.
|
||||
*/
|
||||
public final class GoogleComputeEngineLocationModule extends LocationModule {
|
||||
|
||||
@Override protected void configure() {
|
||||
super.configure();
|
||||
// Unlike EC2, you cannot default GCE instances to a region. Hence, we constrain to zones.
|
||||
bind(LocationsSupplier.class).to(OnlyZonesLocationSupplier.class);
|
||||
bind(ImplicitLocationSupplier.class).to(FirstZone.class);
|
||||
|
||||
// Region and zones are derived from the same network request to RegionApi.list
|
||||
// Using these suppliers will make that consistent and also cache timeout consistently
|
||||
bind(RegionIdToZoneIdsSupplier.class).to(RegionIdToZoneIdsFromRegionList.class);
|
||||
bind(RegionIdToURISupplier.class).to(RegionIdToURISupplierFromRegionList.class);
|
||||
bind(ZoneIdToURISupplier.class).to(ZoneIdToURIFromRegionList.class);
|
||||
bind(ZoneIdsSupplier.class).to(ZoneIdsFromRegionIdToZoneIdsValues.class);
|
||||
bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class);
|
||||
}
|
||||
|
||||
/** Retain the metadata tree, including regions, just don't present anything except zones as assignable. */
|
||||
static final class OnlyZonesLocationSupplier implements LocationsSupplier {
|
||||
// This correctly links parents for zone -> region -> provider.
|
||||
private final ZoneToRegionToProviderOrJustProvider delegate;
|
||||
|
||||
@Inject OnlyZonesLocationSupplier(ZoneToRegionToProviderOrJustProvider delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override public Set<? extends Location> get() {
|
||||
return Sets.filter(delegate.get(), LocationPredicates.isZone());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Since this is caching a direct api call, we memoize, but short-circuit on any auth exception. This prevents
|
||||
* excessive errors when things occur in parallel, or as peers on a function graph.
|
||||
*/
|
||||
@Provides @Singleton @Memoized Supplier<List<Region>> regions(@UserProject Supplier<String> project,
|
||||
final GoogleComputeEngineApi api, AtomicReference<AuthorizationException> authException,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier
|
||||
.create(authException, compose(new Function<String, List<Region>>() {
|
||||
public List<Region> apply(String project) {
|
||||
return ImmutableList.copyOf(concat(api.getRegionApi(project).list()));
|
||||
}
|
||||
}, project), seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Provides @Singleton @Memoized Supplier<Map<URI, String>> selfLinkToNames(
|
||||
AtomicReference<AuthorizationException> authException, @Memoized Supplier<List<Region>> regions,
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
|
||||
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier
|
||||
.create(authException, compose(new Function<List<Region>, Map<URI, String>>() {
|
||||
public Map<URI, String> apply(List<Region> regions) {
|
||||
ImmutableMap.Builder<URI, String> selfLinkToName = ImmutableMap.builder();
|
||||
for (Region region : regions) {
|
||||
selfLinkToName.put(region.selfLink(), region.name());
|
||||
for (URI zoneSelfLink : region.zones()) {
|
||||
selfLinkToName.put(zoneSelfLink, toName(zoneSelfLink));
|
||||
}
|
||||
}
|
||||
return selfLinkToName.build();
|
||||
}
|
||||
}, regions), seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
static final class RegionIdToZoneIdsFromRegionList implements RegionIdToZoneIdsSupplier {
|
||||
private final Supplier<List<Region>> regions;
|
||||
|
||||
@Inject RegionIdToZoneIdsFromRegionList(@Memoized Supplier<List<Region>> regions) {
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
@Override public Map<String, Supplier<Set<String>>> get() {
|
||||
ImmutableMap.Builder<String, Supplier<Set<String>>> result = ImmutableMap.builder();
|
||||
for (org.jclouds.googlecomputeengine.domain.Region region : regions.get()) {
|
||||
ImmutableSet.Builder<String> zoneIds = ImmutableSet.builder();
|
||||
for (URI uri : region.zones()) {
|
||||
zoneIds.add(toName(uri));
|
||||
}
|
||||
result.put(region.name(), Suppliers.<Set<String>>ofInstance(zoneIds.build()));
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
}
|
||||
|
||||
static final class RegionIdToURISupplierFromRegionList implements RegionIdToURISupplier {
|
||||
private final Supplier<List<Region>> regions;
|
||||
|
||||
@Inject RegionIdToURISupplierFromRegionList(@Memoized Supplier<List<Region>> regions) {
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
@Override public Map<String, Supplier<URI>> get() {
|
||||
ImmutableMap.Builder<String, Supplier<URI>> result = ImmutableMap.builder();
|
||||
for (org.jclouds.googlecomputeengine.domain.Region region : regions.get()) {
|
||||
result.put(region.name(), Suppliers.ofInstance(region.selfLink()));
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
}
|
||||
|
||||
static final class ZoneIdToURIFromRegionList implements ZoneIdToURISupplier {
|
||||
private final Supplier<List<Region>> regions;
|
||||
|
||||
@Inject ZoneIdToURIFromRegionList(@Memoized Supplier<List<Region>> regions) {
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
@Override public Map<String, Supplier<URI>> get() {
|
||||
ImmutableMap.Builder<String, Supplier<URI>> result = ImmutableMap.builder();
|
||||
for (Region region : regions.get()) {
|
||||
for (URI input : region.zones()) {
|
||||
result.put(toName(input), Suppliers.ofInstance(input));
|
||||
}
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static String toName(URI link) {
|
||||
String path = link.getPath();
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
}
|
||||
}
|
|
@ -55,7 +55,7 @@ public final class GoogleComputeEngineParserModule extends AbstractModule {
|
|||
bind(GsonModule.DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
|
||||
}
|
||||
|
||||
@Provides @Singleton public Map<Type, Object> typeAdapters() {
|
||||
@Provides @Singleton Map<Type, Object> typeAdapters() {
|
||||
return new ImmutableMap.Builder<Type, Object>()
|
||||
.put(InstanceTemplate.class, new InstanceTemplateTypeAdapter())
|
||||
.put(FirewallOptions.class, new FirewallOptionsTypeAdapter())
|
||||
|
@ -63,11 +63,11 @@ public final class GoogleComputeEngineParserModule extends AbstractModule {
|
|||
}
|
||||
|
||||
// TODO: change jclouds core to use collaborative set bindings
|
||||
@Provides @Singleton public Set<TypeAdapterFactory> typeAdapterFactories() {
|
||||
@Provides @Singleton Set<TypeAdapterFactory> typeAdapterFactories() {
|
||||
return ImmutableSet.<TypeAdapterFactory>of(new MetadataTypeAdapter());
|
||||
}
|
||||
|
||||
private static class InstanceTemplateTypeAdapter implements JsonSerializer<InstanceTemplate> {
|
||||
private static final class InstanceTemplateTypeAdapter implements JsonSerializer<InstanceTemplate> {
|
||||
|
||||
@Override public JsonElement serialize(InstanceTemplate src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
InstanceTemplateInternal template = new InstanceTemplateInternal(src);
|
||||
|
@ -96,7 +96,7 @@ public final class GoogleComputeEngineParserModule extends AbstractModule {
|
|||
return instance;
|
||||
}
|
||||
|
||||
private static class InstanceTemplateInternal extends InstanceTemplate {
|
||||
private static final class InstanceTemplateInternal extends InstanceTemplate {
|
||||
private InstanceTemplateInternal(InstanceTemplate template) {
|
||||
machineType(template.machineType());
|
||||
name(template.name());
|
||||
|
@ -108,11 +108,7 @@ public final class GoogleComputeEngineParserModule extends AbstractModule {
|
|||
}
|
||||
}
|
||||
|
||||
private static class MetadataTypeAdapter extends SubtypeAdapterFactory<Metadata> {
|
||||
|
||||
private MetadataTypeAdapter() {
|
||||
super(Metadata.class);
|
||||
}
|
||||
private static final class MetadataTypeAdapter extends TypeAdapter<Metadata> implements TypeAdapterFactory {
|
||||
|
||||
@Override public void write(JsonWriter out, Metadata src) throws IOException {
|
||||
out.beginObject();
|
||||
|
@ -167,9 +163,16 @@ public final class GoogleComputeEngineParserModule extends AbstractModule {
|
|||
in.endObject();
|
||||
return Metadata.create(fingerprint, builder.build());
|
||||
}
|
||||
|
||||
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
if (!(Metadata.class.isAssignableFrom(typeToken.getRawType()))) {
|
||||
return null;
|
||||
}
|
||||
return (TypeAdapter<T>) this;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FirewallOptionsTypeAdapter implements JsonSerializer<FirewallOptions> {
|
||||
private static final class FirewallOptionsTypeAdapter implements JsonSerializer<FirewallOptions> {
|
||||
|
||||
@Override public JsonElement serialize(FirewallOptions src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject firewall = new JsonObject();
|
||||
|
@ -199,7 +202,7 @@ public final class GoogleComputeEngineParserModule extends AbstractModule {
|
|||
}
|
||||
}
|
||||
|
||||
private static class RouteOptionsTypeAdapter implements JsonSerializer<RouteOptions> {
|
||||
private static final class RouteOptionsTypeAdapter implements JsonSerializer<RouteOptions> {
|
||||
|
||||
@Override public JsonElement serialize(RouteOptions src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject route = new JsonObject();
|
||||
|
@ -244,19 +247,4 @@ public final class GoogleComputeEngineParserModule extends AbstractModule {
|
|||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private abstract static class SubtypeAdapterFactory<T> extends TypeAdapter<T> implements TypeAdapterFactory {
|
||||
private final Class<T> baseClass;
|
||||
|
||||
private SubtypeAdapterFactory(Class<T> baseClass) {
|
||||
this.baseClass = baseClass;
|
||||
}
|
||||
|
||||
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
if (!(baseClass.isAssignableFrom(typeToken.getRawType()))) {
|
||||
return null;
|
||||
}
|
||||
return (TypeAdapter<T>) this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.jclouds.collect.Memoized;
|
|||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.domain.Region;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -36,19 +35,19 @@ import com.google.common.base.Supplier;
|
|||
public final class RegionOperationDonePredicate implements Predicate<AtomicReference<Operation>> {
|
||||
private final GoogleComputeEngineApi api;
|
||||
private final Supplier<String> project;
|
||||
private final Supplier<Map<URI, Region>> regions;
|
||||
private final Supplier<Map<URI, String>> selfLinkToName;
|
||||
|
||||
@Inject RegionOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project,
|
||||
@Memoized Supplier<Map<URI, Region>> regions) {
|
||||
@Memoized Supplier<Map<URI, String>> selfLinkToName) {
|
||||
this.api = api;
|
||||
this.project = project;
|
||||
this.regions = regions;
|
||||
this.selfLinkToName = selfLinkToName;
|
||||
}
|
||||
|
||||
@Override public boolean apply(AtomicReference<Operation> input) {
|
||||
checkNotNull(input.get(), "input");
|
||||
URI region = checkNotNull(input.get().region(), "region of %s", input.get());
|
||||
String locationId = checkNotNull(regions.get().get(region), "location of %s", region).id();
|
||||
String locationId = checkNotNull(selfLinkToName.get().get(region), "location of %s", region);
|
||||
Operation current = api.getRegionOperationApi(project.get(), locationId).get(input.get().name());
|
||||
switch (current.status()) {
|
||||
case DONE:
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.util.Map;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
|
@ -39,19 +38,19 @@ public final class ZoneOperationDonePredicate implements Predicate<AtomicReferen
|
|||
|
||||
private final GoogleComputeEngineApi api;
|
||||
private final Supplier<String> project;
|
||||
private final Supplier<Map<URI, ? extends Location>> zones;
|
||||
private final Supplier<Map<URI, String>> selfLinkToName;
|
||||
|
||||
@Inject ZoneOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project,
|
||||
@Memoized Supplier<Map<URI, ? extends Location>> zones) {
|
||||
@Memoized Supplier<Map<URI, String>> selfLinkToName) {
|
||||
this.api = api;
|
||||
this.project = project;
|
||||
this.zones = zones;
|
||||
this.selfLinkToName = selfLinkToName;
|
||||
}
|
||||
|
||||
@Override public boolean apply(AtomicReference<Operation> input) {
|
||||
checkNotNull(input.get(), "input");
|
||||
URI zone = checkNotNull(input.get().zone(), "zone of %s", input.get());
|
||||
String locationId = checkNotNull(zones.get().get(zone), "location of %s", zone).getId();
|
||||
String locationId = checkNotNull(selfLinkToName.get().get(zone), "location of %s", zone);
|
||||
Operation current = api.getZoneOperationApi(project.get(), locationId).get(input.get().name());
|
||||
switch (current.status()) {
|
||||
case DONE:
|
||||
|
|
|
@ -16,27 +16,19 @@
|
|||
*/
|
||||
package org.jclouds.googlecomputeengine;
|
||||
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import org.jclouds.View;
|
||||
import org.jclouds.apis.internal.BaseApiMetadataTest;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.providers.internal.BaseProviderMetadataTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Tests that GoogleComputeApiMetadata is properly registered in ServiceLoader
|
||||
* Tests that GoogleComputeProviderMetadata is properly registered in ServiceLoader
|
||||
* <p/>
|
||||
* <pre>
|
||||
* META-INF/services/org.jclouds.apis.ApiMetadata
|
||||
* META-INF/services/org.jclouds.providers.ProviderMetadata
|
||||
* </pre>
|
||||
*/
|
||||
@Test(groups = "unit", testName = "GoogleComputeApiMetadataTest")
|
||||
public class GoogleComputeEngineApiMetadataTest extends BaseApiMetadataTest {
|
||||
public GoogleComputeEngineApiMetadataTest() {
|
||||
super(new GoogleComputeEngineApiMetadata(),
|
||||
ImmutableSet.<TypeToken<? extends View>>of(typeToken(ComputeServiceContext.class)));
|
||||
@Test(groups = "unit", testName = "GoogleComputeProviderMetadataTest")
|
||||
public class GoogleComputeEngineProviderMetadataTest extends BaseProviderMetadataTest {
|
||||
public GoogleComputeEngineProviderMetadataTest() {
|
||||
super(new GoogleComputeEngineProviderMetadata(), new GoogleComputeEngineApiMetadata());
|
||||
}
|
||||
}
|
|
@ -16,11 +16,15 @@
|
|||
*/
|
||||
package org.jclouds.googlecomputeengine.compute;
|
||||
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_BOOT_DISK_SUFFIX;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_PROJECTS;
|
||||
import static org.jclouds.googlecomputeengine.domain.Instance.Status.RUNNING;
|
||||
import static org.jclouds.googlecomputeengine.domain.Instance.Status.TERMINATED;
|
||||
import static org.jclouds.googlecomputeengine.features.GlobalOperationApiExpectTest.GET_GLOBAL_OPERATION_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.GlobalOperationApiExpectTest.GET_GLOBAL_OPERATION_RESPONSE;
|
||||
import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_CENTOS_IMAGES_REQUEST;
|
||||
|
@ -40,38 +44,33 @@ import static org.jclouds.googlecomputeengine.features.MachineTypeApiExpectTest.
|
|||
import static org.jclouds.googlecomputeengine.features.NetworkApiExpectTest.GET_NETWORK_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.ProjectApiExpectTest.GET_PROJECT_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.ProjectApiExpectTest.GET_PROJECT_RESPONSE;
|
||||
import static org.jclouds.googlecomputeengine.features.ZoneApiExpectTest.LIST_ZONES_REQ;
|
||||
import static org.jclouds.googlecomputeengine.features.ZoneApiExpectTest.LIST_ZONES_RESPONSE;
|
||||
import static org.jclouds.googlecomputeengine.features.ZoneApiExpectTest.LIST_ZONES_SHORT_RESPONSE;
|
||||
import static org.jclouds.googlecomputeengine.features.RegionApiExpectTest.LIST_REGIONS_REQ;
|
||||
import static org.jclouds.googlecomputeengine.features.ZoneOperationApiExpectTest.GET_ZONE_OPERATION_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.ZoneOperationApiExpectTest.GET_ZONE_OPERATION_RESPONSE;
|
||||
import static org.jclouds.util.Strings2.toStringAndClose;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.features.InstanceApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineServiceExpectTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -82,11 +81,11 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
private HttpRequest INSERT_NETWORK_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1/projects/myproject/global/networks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/global/networks")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromStringWithContentType("{\"name\":\"jclouds-test\",\"IPv4Range\":\"10.0.0.0/8\"}",
|
||||
MediaType.APPLICATION_JSON))
|
||||
APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
private HttpResponse GET_NETWORK_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
|
@ -100,33 +99,39 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
" \"description\": \"test network\",\n" +
|
||||
" \"IPv4Range\": \"10.0.0.0/8\",\n" +
|
||||
" \"gatewayIPv4\": \"10.0.0.1\"\n" +
|
||||
"}", MediaType.APPLICATION_JSON)).build();
|
||||
"}", APPLICATION_JSON)).build();
|
||||
|
||||
private HttpResponse SUCESSFULL_OPERATION_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
private HttpResponse SUCCESSFUL_OPERATION_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
private HttpRequest SET_TAGS_REQUEST = HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/test-1/setTags")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances/test-1/setTags")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromStringWithContentType("{\"items\":[\"aTag\"],\"fingerprint\":\"abcd\"}",
|
||||
MediaType.APPLICATION_JSON))
|
||||
APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
private HttpResponse SET_TAGS_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
private HttpResponse getInstanceResponseForInstanceAndNetworkAndStatus(String instanceName, String networkName,
|
||||
String status) throws
|
||||
IOException {
|
||||
String status) throws IOException {
|
||||
return HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
replaceInstanceNameNetworkAndStatusOnResource("/instance_get.json",
|
||||
instanceName, networkName, status),
|
||||
"application/json")).build();
|
||||
APPLICATION_JSON)).build();
|
||||
}
|
||||
|
||||
/** Reduce work implementing this test, by only using one region, zone! */
|
||||
private final HttpResponse singleRegionSingleZoneResponse = HttpResponse.builder().statusCode(200).payload(
|
||||
"{\"items\":[" + payloadFromResource("/region_get.json").getRawContent().toString()
|
||||
.replace("\"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-b\"", "")
|
||||
+ "]}")
|
||||
.build();
|
||||
|
||||
private HttpResponse getListInstancesResponseForSingleInstanceAndNetworkAndStatus(String instanceName,
|
||||
String networkName,
|
||||
String status) {
|
||||
|
@ -134,32 +139,31 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
.payload(payloadFromStringWithContentType(
|
||||
replaceInstanceNameNetworkAndStatusOnResource("/instance_list.json",
|
||||
instanceName, networkName, status),
|
||||
"application/json")).build();
|
||||
APPLICATION_JSON)).build();
|
||||
}
|
||||
|
||||
private HttpResponse getDiskResponseForInstance(String instanceName) {
|
||||
return HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
replaceDiskNameOnResource("/disk_get.json", instanceName + "-" + GCE_BOOT_DISK_SUFFIX),
|
||||
"application/json")).build();
|
||||
replaceDiskNameOnResource("/disk_get.json", instanceName + "-" + GCE_BOOT_DISK_SUFFIX),
|
||||
APPLICATION_JSON)).build();
|
||||
}
|
||||
|
||||
private String replaceDiskNameOnResource(String resourceName, String diskName) {
|
||||
try {
|
||||
return Strings2.toStringAndClose(this.getClass().getResourceAsStream(resourceName))
|
||||
.replace("testimage1", diskName);
|
||||
return toStringAndClose(this.getClass().getResourceAsStream(resourceName)).replace("testimage1", diskName);
|
||||
} catch (IOException e) {
|
||||
throw Throwables.propagate(e);
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String replaceInstanceNameNetworkAndStatusOnResource(String resourceName, String instanceName,
|
||||
String networkName, String status) {
|
||||
try {
|
||||
return Strings2.toStringAndClose(this.getClass().getResourceAsStream(resourceName)).replace("test-0",
|
||||
instanceName).replace("default", networkName).replace("RUNNING", status);
|
||||
return toStringAndClose(this.getClass().getResourceAsStream(resourceName)).replace("test-0", instanceName)
|
||||
.replace("default", networkName).replace("RUNNING", status);
|
||||
} catch (IOException e) {
|
||||
throw Throwables.propagate(e);
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,31 +171,29 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
return HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/disks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/zones/us-central1-a/disks")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromStringWithContentType("{\"name\":\"" + instanceName + "-" + GCE_BOOT_DISK_SUFFIX + "\","
|
||||
+ "\"sizeGb\":10,"
|
||||
+ "\"sourceImage\":\"https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140718\"}",
|
||||
MediaType.APPLICATION_JSON)).build();
|
||||
APPLICATION_JSON)).build();
|
||||
}
|
||||
|
||||
private HttpRequest getDiskRequestForInstance(String instanceName) {
|
||||
return HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/zones/us-central1-a/disks/"
|
||||
+ instanceName + "-" + GCE_BOOT_DISK_SUFFIX)
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/zones/us-central1-a/disks/" + instanceName + "-" + GCE_BOOT_DISK_SUFFIX)
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
}
|
||||
|
||||
private HttpRequest createInstanceRequestForInstance(String instanceName, String groupName, String networkName,
|
||||
String publicKey) {
|
||||
return HttpRequest.builder().method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances")
|
||||
.addHeader("Accept", "application/json").addHeader("Authorization", "Bearer " + TOKEN).payload(
|
||||
.endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances")
|
||||
.addHeader("Accept", APPLICATION_JSON).addHeader("Authorization", "Bearer " + TOKEN).payload(
|
||||
payloadFromStringWithContentType("{\"name\":\"" + instanceName
|
||||
+ "\",\"machineType\":\"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/machineTypes/f1-micro\",\"serviceAccounts\":[],\"disks\":[{\"type\":\"PERSISTENT\",\"mode\":\"READ_WRITE\",\"source\":\"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/disks/"
|
||||
+ instanceName + "-" + GCE_BOOT_DISK_SUFFIX
|
||||
|
@ -200,29 +202,28 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
+ "\",\"accessConfigs\":[{\"type\":\"ONE_TO_ONE_NAT\"}]}],\"metadata\":{\"kind\":\"compute#metadata\",\"items\":[{\"key\":\"sshKeys\",\"value\":\"jclouds:"
|
||||
+ publicKey + " jclouds@localhost\"},{\"key\":\"jclouds-group\",\"value\":\"" + groupName
|
||||
+ "\"},{\"key\":\"jclouds-image\",\"value\":\"https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140718\"},{\"key\":\"jclouds-delete-boot-disk\",\"value\":\"true\"}]}}",
|
||||
MediaType.APPLICATION_JSON)).build();
|
||||
APPLICATION_JSON)).build();
|
||||
}
|
||||
|
||||
private HttpRequest getInstanceRequestForInstance(String instanceName) {
|
||||
return HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/zones/us-central1-a/instances/" + instanceName)
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances/" + instanceName)
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties overrides = super.setupProperties();
|
||||
overrides.put("google-compute-engine.identity", "myproject");
|
||||
overrides.put(GCE_IMAGE_PROJECTS, "debian-cloud,centos-cloud");
|
||||
try {
|
||||
overrides.put("google-compute-engine.credential", toStringAndClose(getClass().getResourceAsStream("/testpk.pem")));
|
||||
overrides.put("google-compute-engine.credential",
|
||||
toStringAndClose(this.getClass().getResourceAsStream("/testpk.pem")));
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
propagate(e);
|
||||
}
|
||||
return overrides;
|
||||
}
|
||||
|
@ -247,7 +248,7 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
<HttpRequest, HttpResponse>builder()
|
||||
.put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
|
||||
.put(GET_PROJECT_REQUEST, GET_PROJECT_RESPONSE)
|
||||
.put(LIST_ZONES_REQ, LIST_ZONES_RESPONSE)
|
||||
.put(LIST_REGIONS_REQ, singleRegionSingleZoneResponse)
|
||||
.put(LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.put(LIST_DEBIAN_IMAGES_REQUEST, LIST_DEBIAN_IMAGES_RESPONSE)
|
||||
.put(LIST_CENTOS_IMAGES_REQUEST, LIST_CENTOS_IMAGES_RESPONSE)
|
||||
|
@ -265,7 +266,7 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
Hardware fastest = client.templateBuilder().fastest().build().getHardware();
|
||||
assertNotNull(fastest);
|
||||
|
||||
assertEquals(client.listHardwareProfiles().size(), 5);
|
||||
assertEquals(client.listHardwareProfiles().size(), 3);
|
||||
|
||||
Template toMatch = client.templateBuilder()
|
||||
.imageId(template.getImage().getId())
|
||||
|
@ -278,23 +279,20 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
|
||||
HttpRequest deleteNodeRequest = HttpRequest.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/zones/us-central1-a/instances/test-delete-networks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances/test-delete-networks")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpRequest deleteFirewallRequest = HttpRequest.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/global/firewalls/jclouds-test-delete")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/global/firewalls/jclouds-test-delete")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpRequest getNetworkRequest = HttpRequest.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/global/networks/jclouds-test-delete")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/global/networks/jclouds-test-delete")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse getNetworkResponse = HttpResponse.builder().statusCode(200)
|
||||
|
@ -302,9 +300,8 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
|
||||
HttpRequest listFirewallsRequest = HttpRequest.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/global/firewalls")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/global/firewalls")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse listFirewallsResponse = HttpResponse.builder().statusCode(200)
|
||||
|
@ -312,23 +309,21 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
|
||||
HttpRequest deleteNetworkReqquest = HttpRequest.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/global/networks/jclouds-test-delete")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/global/networks/jclouds-test-delete")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpRequest deleteDiskRequest = HttpRequest.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/zones/us-central1-a/disks/test")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/zones/us-central1-a/disks/test")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
List<HttpRequest> orderedRequests = ImmutableList.<HttpRequest>builder()
|
||||
.add(requestForScopes(COMPUTE_READONLY_SCOPE))
|
||||
.add(GET_PROJECT_REQUEST)
|
||||
.add(getInstanceRequestForInstance("test-delete-networks"))
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_REGIONS_REQ)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_DEBIAN_IMAGES_REQUEST)
|
||||
|
@ -349,56 +344,43 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
.add(GET_GLOBAL_OPERATION_REQUEST)
|
||||
.build();
|
||||
|
||||
|
||||
List<HttpResponse> orderedResponses = ImmutableList.<HttpResponse>builder()
|
||||
.add(TOKEN_RESPONSE)
|
||||
.add(GET_PROJECT_RESPONSE)
|
||||
.add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", Instance
|
||||
.Status.RUNNING.name()))
|
||||
.add(LIST_ZONES_SHORT_RESPONSE)
|
||||
.add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", RUNNING.name()))
|
||||
.add(singleRegionSingleZoneResponse)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_DEBIAN_IMAGES_RESPONSE)
|
||||
.add(LIST_CENTOS_IMAGES_RESPONSE)
|
||||
.add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", Instance
|
||||
.Status.RUNNING.name()))
|
||||
.add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", RUNNING.name()))
|
||||
.add(TOKEN_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(GET_ZONE_OPERATION_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(GET_ZONE_OPERATION_RESPONSE)
|
||||
.add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", Instance
|
||||
.Status.TERMINATED.name()))
|
||||
.add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", TERMINATED.name()))
|
||||
.add(getListInstancesResponseForSingleInstanceAndNetworkAndStatus("test-delete-networks",
|
||||
"test-network", Instance
|
||||
.Status.TERMINATED.name()))
|
||||
"test-network", TERMINATED.name()))
|
||||
.add(getNetworkResponse)
|
||||
.add(listFirewallsResponse)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(GET_GLOBAL_OPERATION_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(GET_GLOBAL_OPERATION_RESPONSE)
|
||||
.build();
|
||||
|
||||
ComputeService client = orderedRequestsSendResponses(orderedRequests, orderedResponses);
|
||||
client.destroyNode("us-central1-a/test-delete-networks");
|
||||
|
||||
}
|
||||
|
||||
public void testListLocationsWhenResponseIs2xx() throws Exception {
|
||||
public void listAssignableLocations() throws Exception {
|
||||
|
||||
ImmutableMap<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.
|
||||
<HttpRequest, HttpResponse>builder()
|
||||
.put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
|
||||
.put(GET_PROJECT_REQUEST, GET_PROJECT_RESPONSE)
|
||||
.put(LIST_ZONES_REQ, LIST_ZONES_RESPONSE)
|
||||
.put(LIST_INSTANCES_REQUEST, LIST_INSTANCES_RESPONSE)
|
||||
.put(LIST_CENTRAL1B_INSTANCES_REQUEST, LIST_CENTRAL1B_INSTANCES_RESPONSE)
|
||||
.put(LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.put(LIST_DEBIAN_IMAGES_REQUEST, LIST_DEBIAN_IMAGES_RESPONSE)
|
||||
.put(LIST_CENTOS_IMAGES_REQUEST, LIST_CENTOS_IMAGES_RESPONSE)
|
||||
.put(LIST_MACHINE_TYPES_REQUEST, LIST_MACHINE_TYPES_RESPONSE)
|
||||
.put(LIST_CENTRAL1B_MACHINE_TYPES_REQUEST, LIST_CENTRAL1B_MACHINE_TYPES_RESPONSE)
|
||||
.put(LIST_REGIONS_REQ, singleRegionSingleZoneResponse)
|
||||
.build();
|
||||
|
||||
ComputeService apiWhenServersExist = requestsSendResponses(requestResponseMap);
|
||||
|
@ -406,8 +388,38 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
Set<? extends Location> locations = apiWhenServersExist.listAssignableLocations();
|
||||
|
||||
assertNotNull(locations);
|
||||
assertEquals(locations.size(), 2);
|
||||
assertEquals(locations.iterator().next().getId(), "us-central1-a");
|
||||
assertEquals(locations.size(), 1);
|
||||
Location firstZone = locations.iterator().next();
|
||||
assertEquals(firstZone.getId(), "us-central1-a");
|
||||
assertEquals(firstZone.getDescription(), "us-central1-a");
|
||||
assertEquals(firstZone.getScope(), LocationScope.ZONE);
|
||||
|
||||
assertEquals(firstZone.getParent().getId(), "us-central1");
|
||||
assertEquals(firstZone.getParent().getDescription(), "us-central1");
|
||||
assertEquals(firstZone.getParent().getScope(), LocationScope.REGION);
|
||||
|
||||
// Google intentionally does not document locations!
|
||||
assertTrue(firstZone.getIso3166Codes().isEmpty());
|
||||
assertTrue(firstZone.getParent().getIso3166Codes().isEmpty());
|
||||
}
|
||||
|
||||
public void listNodes() throws Exception {
|
||||
|
||||
ImmutableMap<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.
|
||||
<HttpRequest, HttpResponse>builder()
|
||||
.put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
|
||||
.put(GET_PROJECT_REQUEST, GET_PROJECT_RESPONSE)
|
||||
.put(LIST_REGIONS_REQ, singleRegionSingleZoneResponse)
|
||||
.put(LIST_INSTANCES_REQUEST, LIST_INSTANCES_RESPONSE)
|
||||
.put(LIST_CENTRAL1B_INSTANCES_REQUEST, LIST_CENTRAL1B_INSTANCES_RESPONSE)
|
||||
.put(LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.put(LIST_DEBIAN_IMAGES_REQUEST, LIST_DEBIAN_IMAGES_RESPONSE)
|
||||
.put(LIST_CENTOS_IMAGES_REQUEST, LIST_CENTOS_IMAGES_RESPONSE)
|
||||
.put(LIST_MACHINE_TYPES_REQUEST, LIST_MACHINE_TYPES_RESPONSE)
|
||||
.put(LIST_CENTRAL1B_MACHINE_TYPES_REQUEST, LIST_CENTRAL1B_MACHINE_TYPES_RESPONSE)
|
||||
.build();
|
||||
|
||||
ComputeService apiWhenServersExist = requestsSendResponses(requestResponseMap);
|
||||
|
||||
assertNotNull(apiWhenServersExist.listNodes());
|
||||
assertEquals(apiWhenServersExist.listNodes().size(), 1);
|
||||
|
@ -415,54 +427,52 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
assertEquals(apiWhenServersExist.listNodes().iterator().next().getName(), "test-0");
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testListLocationsWhenResponseIs2xx")
|
||||
@Test
|
||||
public void testCreateNodeWhenNetworkNorFirewallExistDoesNotExist() throws RunNodesException, IOException {
|
||||
String payload = Strings2.toStringAndClose(InstanceApiExpectTest.class.getResourceAsStream("/instance_get.json"));
|
||||
String payload = toStringAndClose(InstanceApiExpectTest.class.getResourceAsStream("/instance_get.json"));
|
||||
payload = payload.replace("test-0", "test-1");
|
||||
|
||||
HttpResponse getInstanceResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType(payload, "application/json")).build();
|
||||
.payload(payloadFromStringWithContentType(payload, APPLICATION_JSON)).build();
|
||||
|
||||
HttpRequest getFirewallRequest = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/global/firewalls/jclouds-test-port-22")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/global/firewalls/jclouds-test-port-22")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpRequest insertFirewallRequest = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1/projects/myproject/global/firewalls")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/global/firewalls")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromStringWithContentType("{\"name\":\"jclouds-test-port-22\",\"network\":\"https://www.googleapis" +
|
||||
".com/compute/v1/projects/myproject/global/networks/jclouds-test\"," +
|
||||
"\"sourceRanges\":[\"10.0.0.0/8\",\"0.0.0.0/0\"],\"sourceTags\":[\"aTag\"],\"targetTags\":[\"jclouds-test-port-22\"],\"allowed\":[{\"IPProtocol\":\"tcp\"," +
|
||||
"\"ports\":[\"22\"]}," +
|
||||
"{\"IPProtocol\":\"udp\",\"ports\":[\"22\"]}]}",
|
||||
MediaType.APPLICATION_JSON))
|
||||
APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpRequest setTagsRequest = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/test-1/setTags")
|
||||
.addHeader("Accept", "application/json")
|
||||
.endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances/test-1/setTags")
|
||||
.addHeader("Accept", APPLICATION_JSON)
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromStringWithContentType("{\"items\":[\"jclouds-test-port-22\"],\"fingerprint\":\"abcd\"}",
|
||||
MediaType.APPLICATION_JSON))
|
||||
APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
List<HttpRequest> orderedRequests = ImmutableList.<HttpRequest>builder()
|
||||
.add(requestForScopes(COMPUTE_READONLY_SCOPE))
|
||||
.add(GET_PROJECT_REQUEST)
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_REGIONS_REQ)
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_DEBIAN_IMAGES_REQUEST)
|
||||
.add(LIST_CENTOS_IMAGES_REQUEST)
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.add(GET_NETWORK_REQUEST)
|
||||
.add(GET_NETWORK_REQUEST)
|
||||
|
@ -474,10 +484,6 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
.add(insertFirewallRequest)
|
||||
.add(GET_GLOBAL_OPERATION_REQUEST)
|
||||
.add(LIST_INSTANCES_REQUEST)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_DEBIAN_IMAGES_REQUEST)
|
||||
.add(LIST_CENTOS_IMAGES_REQUEST)
|
||||
.add(createDiskRequestForInstance("test-1"))
|
||||
.add(GET_ZONE_OPERATION_REQUEST)
|
||||
.add(getDiskRequestForInstance("test-1"))
|
||||
|
@ -497,43 +503,37 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
|
|||
List<HttpResponse> orderedResponses = ImmutableList.<HttpResponse>builder()
|
||||
.add(TOKEN_RESPONSE)
|
||||
.add(GET_PROJECT_RESPONSE)
|
||||
.add(LIST_ZONES_SHORT_RESPONSE)
|
||||
.add(singleRegionSingleZoneResponse)
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_DEBIAN_IMAGES_RESPONSE)
|
||||
.add(LIST_CENTOS_IMAGES_RESPONSE)
|
||||
.add(LIST_ZONES_SHORT_RESPONSE)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.add(HttpResponse.builder().statusCode(404).build())
|
||||
.add(HttpResponse.builder().statusCode(404).build())
|
||||
.add(TOKEN_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(GET_GLOBAL_OPERATION_RESPONSE)
|
||||
.add(GET_NETWORK_RESPONSE)
|
||||
.add(HttpResponse.builder().statusCode(404).build())
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(GET_GLOBAL_OPERATION_RESPONSE)
|
||||
.add(LIST_INSTANCES_RESPONSE)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_DEBIAN_IMAGES_RESPONSE)
|
||||
.add(LIST_CENTOS_IMAGES_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(GET_ZONE_OPERATION_RESPONSE)
|
||||
.add(getDiskResponseForInstance("test-1"))
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(GET_ZONE_OPERATION_RESPONSE)
|
||||
.add(getInstanceResponse)
|
||||
.add(SET_TAGS_RESPONSE)
|
||||
.add(GET_ZONE_OPERATION_RESPONSE)
|
||||
.add(getInstanceResponse)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_DEBIAN_IMAGES_RESPONSE)
|
||||
.add(LIST_CENTOS_IMAGES_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(SUCCESSFUL_OPERATION_RESPONSE)
|
||||
.build();
|
||||
|
||||
|
||||
ComputeService computeService = orderedRequestsSendResponses(orderedRequests, orderedResponses);
|
||||
|
||||
GoogleComputeEngineTemplateOptions options = computeService.templateOptions().as(GoogleComputeEngineTemplateOptions.class);
|
||||
|
|
|
@ -157,9 +157,9 @@ public class InstanceInZoneToNodeMetadataTest {
|
|||
|
||||
private InstanceInZoneToNodeMetadata createNodeParser(final Set<Hardware> hardware, final Set<Image> images,
|
||||
final Set<Location> locations, final String groupName) {
|
||||
Supplier<Map<URI, ? extends Location>> locationSupplier = new Supplier<Map<URI, ? extends Location>>() {
|
||||
Supplier<Map<URI, Location>> locationSupplier = new Supplier<Map<URI, Location>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends Location> get() {
|
||||
public Map<URI, Location> get() {
|
||||
return Maps.uniqueIndex(locations, new Function<Location, URI>() {
|
||||
@Override
|
||||
public URI apply(final Location input) {
|
||||
|
@ -169,9 +169,9 @@ public class InstanceInZoneToNodeMetadataTest {
|
|||
}
|
||||
};
|
||||
|
||||
Supplier<Map<URI, ? extends Hardware>> hardwareSupplier = new Supplier<Map<URI, ? extends Hardware>>() {
|
||||
Supplier<Map<URI, Hardware>> hardwareSupplier = new Supplier<Map<URI, Hardware>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends Hardware> get() {
|
||||
public Map<URI, Hardware> get() {
|
||||
return Maps.uniqueIndex(hardware, new Function<Hardware, URI>() {
|
||||
@Override
|
||||
public URI apply(final Hardware input) {
|
||||
|
@ -181,9 +181,9 @@ public class InstanceInZoneToNodeMetadataTest {
|
|||
}
|
||||
};
|
||||
|
||||
Supplier<Map<URI, ? extends Image>> imageSupplier = new Supplier<Map<URI, ? extends Image>>() {
|
||||
Supplier<Map<URI, Image>> imageSupplier = new Supplier<Map<URI, Image>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends Image> get() {
|
||||
public Map<URI, Image> get() {
|
||||
return Maps.uniqueIndex(images, new Function<Image, URI>() {
|
||||
@Override
|
||||
public URI apply(final Image input) {
|
||||
|
|
|
@ -51,13 +51,13 @@ public class OrphanedGroupsFromDeadNodesTest {
|
|||
@Test
|
||||
public void testDetectsAllOrphanedGroupsWhenAllNodesTerminated() {
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
Set<NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("a", "1", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
Set<NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("b", "2", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
Set<NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
|
||||
ComputeService mock = createMock(ComputeService.class);
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
|
@ -80,13 +80,13 @@ public class OrphanedGroupsFromDeadNodesTest {
|
|||
@Test
|
||||
public void testDetectsAllOrphanedGroupsWhenSomeNodesTerminatedAndOtherMissing() {
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
Set<NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("a", "1", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
Set<NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("b", "2", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
Set<NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
|
||||
ComputeService mock = createMock(ComputeService.class);
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
|
@ -109,13 +109,13 @@ public class OrphanedGroupsFromDeadNodesTest {
|
|||
@Test
|
||||
public void testDetectsAllOrphanedGroupsWhenSomeNodesAreAlive() {
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
Set<NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("a", "1", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
Set<NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("b", "2", NodeMetadata.Status.RUNNING)).build();
|
||||
|
||||
Set<? extends NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
Set<NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
|
||||
ComputeService mock = createMock(ComputeService.class);
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
|
|
|
@ -232,5 +232,4 @@ public class InstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
|||
// we don't really care about any exception here, so just delete away.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,16 +51,13 @@ public class RegionApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
|||
.payload(staticPayloadFromResource("/region_list.json")).build();
|
||||
|
||||
public void testGetRegionResponseIs2xx() throws Exception {
|
||||
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/region_get.json")).build();
|
||||
|
||||
RegionApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, GET_REGION_REQ, operationResponse).getRegionApi("myproject");
|
||||
|
||||
assertEquals(api.get("us-central1"),
|
||||
new ParseRegionTest().expected());
|
||||
assertEquals(api.get("us-central1"), new ParseRegionTest().expected());
|
||||
}
|
||||
|
||||
public void testGetRegionResponseIs4xx() throws Exception {
|
||||
|
|
|
@ -45,14 +45,14 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.apis.ApiMetadata;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApiMetadata;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineProviderMetadata;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.oauth.v2.OAuthConstants;
|
||||
import org.jclouds.oauth.v2.config.OAuthProperties;
|
||||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.rest.internal.BaseRestApiExpectTest;
|
||||
import org.jclouds.ssh.SshKeys;
|
||||
|
||||
|
@ -85,49 +85,49 @@ public class BaseGoogleComputeEngineExpectTest<T> extends BaseRestApiExpectTest<
|
|||
" \"expires_in\" : 3600\n" +
|
||||
"}")).build();
|
||||
|
||||
protected String openSshKey;
|
||||
private final KeyPair keyPair;
|
||||
protected final String openSshKey;
|
||||
|
||||
|
||||
public BaseGoogleComputeEngineExpectTest() {
|
||||
protected BaseGoogleComputeEngineExpectTest() {
|
||||
provider = "google-compute-engine";
|
||||
try {
|
||||
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyfactory
|
||||
.generatePrivate(privateKeySpec(ByteSource.wrap(PRIVATE_KEY.getBytes(UTF_8))));
|
||||
PublicKey publicKey = keyfactory.generatePublic(publicKeySpec(ByteSource.wrap(PUBLIC_KEY.getBytes(UTF_8))));
|
||||
keyPair = new KeyPair(publicKey, privateKey);
|
||||
openSshKey = SshKeys.encodeAsOpenSSH(RSAPublicKey.class.cast(publicKey));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw propagate(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw propagate(e);
|
||||
} catch (IOException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected ApiMetadata createApiMetadata(){
|
||||
return new GoogleComputeEngineApiMetadata();
|
||||
@Override protected ProviderMetadata createProviderMetadata(){
|
||||
return new GoogleComputeEngineProviderMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
@Override protected Module createModule() {
|
||||
|
||||
return new Module() {
|
||||
@Override
|
||||
public void configure(Binder binder) {
|
||||
// Predictable time
|
||||
binder.bind(new TypeLiteral<Supplier<Long>>() {}).toInstance(Suppliers.ofInstance(0L));
|
||||
try {
|
||||
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyfactory.generatePrivate(privateKeySpec(ByteSource.wrap(
|
||||
PRIVATE_KEY.getBytes(UTF_8))));
|
||||
PublicKey publicKey = keyfactory.generatePublic(publicKeySpec(ByteSource.wrap(PUBLIC_KEY.getBytes(UTF_8))));
|
||||
KeyPair keyPair = new KeyPair(publicKey, privateKey);
|
||||
openSshKey = SshKeys.encodeAsOpenSSH(RSAPublicKey.class.cast(publicKey));
|
||||
final Crypto crypto = createMock(Crypto.class);
|
||||
KeyPairGenerator rsaKeyPairGenerator = createMock(KeyPairGenerator.class);
|
||||
final SecureRandom secureRandom = createMock(SecureRandom.class);
|
||||
expect(crypto.rsaKeyPairGenerator()).andReturn(rsaKeyPairGenerator).anyTimes();
|
||||
rsaKeyPairGenerator.initialize(2048, secureRandom);
|
||||
expectLastCall().anyTimes();
|
||||
expect(rsaKeyPairGenerator.genKeyPair()).andReturn(keyPair).anyTimes();
|
||||
replay(crypto, rsaKeyPairGenerator, secureRandom);
|
||||
binder.bind(Crypto.class).toInstance(crypto);
|
||||
binder.bind(SecureRandom.class).toInstance(secureRandom);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
propagate(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
propagate(e);
|
||||
} catch (IOException e) {
|
||||
propagate(e);
|
||||
}
|
||||
Crypto crypto = createMock(Crypto.class);
|
||||
KeyPairGenerator rsaKeyPairGenerator = createMock(KeyPairGenerator.class);
|
||||
SecureRandom secureRandom = createMock(SecureRandom.class);
|
||||
expect(crypto.rsaKeyPairGenerator()).andReturn(rsaKeyPairGenerator).anyTimes();
|
||||
rsaKeyPairGenerator.initialize(2048, secureRandom);
|
||||
expectLastCall().anyTimes();
|
||||
expect(rsaKeyPairGenerator.genKeyPair()).andReturn(keyPair).anyTimes();
|
||||
replay(crypto, rsaKeyPairGenerator, secureRandom);
|
||||
binder.bind(Crypto.class).toInstance(crypto);
|
||||
binder.bind(SecureRandom.class).toInstance(secureRandom);
|
||||
|
||||
// predictable node names
|
||||
final AtomicInteger suffix = new AtomicInteger();
|
||||
binder.bind(new TypeLiteral<Supplier<String>>() {
|
||||
|
|
|
@ -47,7 +47,7 @@ public class ParseRegionListTest extends BaseGoogleComputeEngineParseTest<ListPa
|
|||
"us-central2", // name
|
||||
"us-central2", // description
|
||||
Region.Status.UP, // status
|
||||
ImmutableList.of(URI.create("https://www.googleapis.com/compute/v1/zones/us-central2-a")), // zones
|
||||
ImmutableList.of(URI.create(BASE_URL + "/myproject/zones/us-central2-a")), // zones
|
||||
ImmutableList.of( //
|
||||
Quota.create("INSTANCES", 0, 8), //
|
||||
Quota.create("CPUS", 0, 8), //
|
||||
|
|
|
@ -46,8 +46,8 @@ public class ParseRegionTest extends BaseGoogleComputeEngineParseTest<Region> {
|
|||
"us-central1", // description
|
||||
Region.Status.UP, // status
|
||||
ImmutableList.of(//
|
||||
URI.create("https://www.googleapis.com/compute/v1/zones/us-central1-a"),
|
||||
URI.create("https://www.googleapis.com/compute/v1/zones/us-central1-b")), // zones
|
||||
URI.create(BASE_URL + "/myproject/zones/us-central1-a"),
|
||||
URI.create(BASE_URL + "/myproject/zones/us-central1-b")), // zones
|
||||
ImmutableList.of( //
|
||||
Quota.create("INSTANCES", 0, 8), //
|
||||
Quota.create("CPUS", 0, 8), //
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
"description": "us-central1",
|
||||
"status": "UP",
|
||||
"zones": [
|
||||
"https://www.googleapis.com/compute/v1/zones/us-central1-a",
|
||||
"https://www.googleapis.com/compute/v1/zones/us-central1-b"
|
||||
"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a",
|
||||
"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-b"
|
||||
],
|
||||
"quotas": [
|
||||
{
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"description": "us-central1",
|
||||
"status": "UP",
|
||||
"zones": [
|
||||
"https://www.googleapis.com/compute/v1/zones/us-central1-a",
|
||||
"https://www.googleapis.com/compute/v1/zones/us-central1-b"
|
||||
"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a",
|
||||
"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-b"
|
||||
],
|
||||
"quotas": [
|
||||
{
|
||||
|
@ -72,7 +72,7 @@
|
|||
"description": "us-central2",
|
||||
"status": "UP",
|
||||
"zones": [
|
||||
"https://www.googleapis.com/compute/v1/zones/us-central2-a"
|
||||
"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central2-a"
|
||||
],
|
||||
"quotas": [
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue