Merge branch 'master' of github.com:jclouds/jclouds into 1.5.x

* 'master' of github.com:jclouds/jclouds: (62 commits)
  modernized cloudwatch
  always display some error content
  added tests
  Follow up to f06d273 that addresses pull request comments.
  Follow up to e58d91e that addresses pull request comments.
  Upgrade to Guava 12.0
  Do not set member until we completely validate it
  Prefer unsynchronized StringBuilder
  Adding links to openstack-keystone admin API documentation
  Adding openstack-keystone to labs pom
  Fixing javadocs
  Renaming the service client (user operations) ServiceClient to better match up to Keystone documentation
  Fixing javadocs
  Renaming the service client (user operations) ServiceClient to better match up to Keystone documentation
  Renaming 'ServiceClient's AuthenticationClients to save confusion with user-accessible ServiceClient in keystone 2.0
  Adding unit tests for keystone 2.0 AdminURL supplier
  Adding openstack-keystone to expose additional methods available on keystone api
  Adding AdminURL supplier for keystone 2.0
  Optimize clearContainer for large folders
  Extended support to apis/cloudwatch for getting metrics.
  ...
This commit is contained in:
Adrian Cole 2012-05-01 10:18:16 -07:00
commit c5f6633c52
370 changed files with 16709 additions and 2669 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ bin/
*.DS_STORE
TAGS
.metadata/
atlassian-ide-plugin.xml

View File

@ -28,12 +28,12 @@ import org.jclouds.cloudloadbalancers.predicates.LoadBalancerActive;
import org.jclouds.cloudloadbalancers.predicates.LoadBalancerDeleted;
import org.jclouds.loadbalancer.LoadBalancerServiceContext;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
import org.testng.annotations.BeforeGroups;
import com.google.common.base.Predicate;
import com.google.common.net.HostAndPort;
import com.google.common.reflect.TypeToken;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -51,7 +51,7 @@ public class BaseCloudLoadBalancersClientLiveTest extends BaseViewLiveTest<LoadB
protected CloudLoadBalancersClient client;
protected RestContext<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> lbContext;
protected String[] regions = {};
protected Predicate<IPSocket> socketTester;
protected Predicate<HostAndPort> socketTester;
protected RetryablePredicate<LoadBalancer> loadBalancerActive;
protected RetryablePredicate<LoadBalancer> loadBalancerDeleted;

View File

@ -49,7 +49,6 @@ import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payload;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.ssh.SshClient;
@ -63,6 +62,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
import com.google.inject.Injector;
/**
@ -79,7 +79,7 @@ public class CloudServersClientLiveTest extends BaseComputeServiceContextLiveTes
protected CloudServersClient client;
protected SshClient.Factory sshFactory;
protected Predicate<IPSocket> socketTester;
protected Predicate<HostAndPort> socketTester;
@BeforeGroups(groups = { "integration", "live" })
@Override
@ -89,7 +89,7 @@ public class CloudServersClientLiveTest extends BaseComputeServiceContextLiveTes
client = injector.getInstance(CloudServersClient.class);
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<HostAndPort>(socketOpen, 120, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger
}
@ -374,7 +374,7 @@ public class CloudServersClientLiveTest extends BaseComputeServiceContextLiveTes
}
private void doCheckPass(Server newDetails, String pass) throws IOException {
IPSocket socket = new IPSocket(Iterables.get(newDetails.getAddresses().getPublicAddresses(), 0), 22);
HostAndPort socket = HostAndPort.fromParts(Iterables.get(newDetails.getAddresses().getPublicAddresses(), 0), 22);
socketTester.apply(socket);
SshClient client = sshFactory.create(socket, LoginCredentials.builder().user("root").password(pass).build());
@ -390,7 +390,7 @@ public class CloudServersClientLiveTest extends BaseComputeServiceContextLiveTes
}
private ExecResponse exec(Server details, String pass, String command) throws IOException {
IPSocket socket = new IPSocket(Iterables.get(details.getAddresses().getPublicAddresses(), 0), 22);
HostAndPort socket = HostAndPort.fromParts(Iterables.get(details.getAddresses().getPublicAddresses(), 0), 22);
socketTester.apply(socket);
SshClient client = sshFactory.create(socket, LoginCredentials.builder().user("root").password(pass).build());
try {

View File

@ -46,7 +46,6 @@ import org.jclouds.cloudsigma.util.Servers;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
@ -61,6 +60,7 @@ import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.HostAndPort;
import com.google.gson.Gson;
import com.google.inject.Guice;
@ -81,7 +81,7 @@ public class CloudSigmaClientLiveTest extends BaseComputeServiceContextLiveTest
protected String vncPassword = "Il0veVNC";
protected CloudSigmaClient client;
protected RestContext<CloudSigmaClient, CloudSigmaAsyncClient> cloudSigmaContext;
protected Predicate<IPSocket> socketTester;
protected Predicate<HostAndPort> socketTester;
protected Predicate<DriveInfo> driveNotClaimed;
@ -94,7 +94,7 @@ public class CloudSigmaClientLiveTest extends BaseComputeServiceContextLiveTest
client = cloudSigmaContext.getApi();
driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime,
1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
socketTester = new RetryablePredicate<HostAndPort>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
TimeUnit.SECONDS);
if (Strings.emptyToNull(imageId) == null) {
@ -329,9 +329,9 @@ public class CloudSigmaClientLiveTest extends BaseComputeServiceContextLiveTest
@Test(dependsOnMethods = "testCreateAndStartServer")
public void testConnectivity() throws Exception {
Logger.getAnonymousLogger().info("awaiting vnc");
assert socketTester.apply(new IPSocket(server.getVnc().getIp(), 5900)) : server;
assert socketTester.apply(HostAndPort.fromParts(server.getVnc().getIp(), 5900)) : server;
Logger.getAnonymousLogger().info("awaiting ssh");
assert socketTester.apply(new IPSocket(server.getNics().get(0).getDhcp(), 22)) : server;
assert socketTester.apply(HostAndPort.fromParts(server.getNics().get(0).getDhcp(), 22)) : server;
doConnectViaSsh(server, getSshCredentials(server));
}
@ -389,7 +389,7 @@ public class CloudSigmaClientLiveTest extends BaseComputeServiceContextLiveTest
protected void doConnectViaSsh(Server server, LoginCredentials creds) throws IOException {
SshClient ssh = Guice.createInjector(new SshjSshClientModule()).getInstance(SshClient.Factory.class)
.create(new IPSocket(server.getVnc().getIp(), 22), creds);
.create(HostAndPort.fromParts(server.getVnc().getIp(), 22), creds);
try {
ssh.connect();
ExecResponse hello = ssh.exec("echo hello");

View File

@ -32,7 +32,7 @@
//import org.jclouds.cloudstack.options.CreateInstanceOptions;
//import org.jclouds.domain.Credentials;
//import org.jclouds.http.HttpRequest;
//import org.jclouds.net.IPSocket;
//import com.google.common.net.HostAndPort;
//import org.jclouds.ssh.SshClient;
//import org.jclouds.ssh.jsch.config.JschSshClientModule;
//import org.testng.annotations.AfterGroups;
@ -79,7 +79,7 @@
// public void testConnectivity() throws Exception {
// Logger.getAnonymousLogger().info("awaiting ssh");
// // TODO
// // assert socketTester.apply(new IPSocket(Iterables.get(instance.getPublicAddresses(), 0),
// // assert socketTester.apply(HostAndPort.fromParts(Iterables.get(instance.getPublicAddresses(), 0),
// // 22)) : instance;
// // doConnectViaSsh(instance, getSshCredentials(instance));
// }
@ -119,7 +119,7 @@
//
// protected void doConnectViaSsh(Instance instance, Credentials creds) throws IOException {
// SshClient ssh = Guice.createInjector(new JschSshClientModule()).getInstance(SshClient.Factory.class)
// .create(new IPSocket(Iterables.get(instance.getPublicAddresses(), 0), 22), creds);
// .create(HostAndPort.fromParts(Iterables.get(instance.getPublicAddresses(), 0), 22), creds);
// try {
// ssh.connect();
// ExecResponse hello = ssh.exec("echo hello");

View File

@ -53,14 +53,13 @@ import org.jclouds.cloudstack.suppliers.GetCurrentUser;
import org.jclouds.cloudstack.suppliers.NetworksForCurrentUser;
import org.jclouds.cloudstack.suppliers.ZoneIdToZoneSupplier;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.ComputeTestUtils;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.ComputeTestUtils;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.annotations.Identity;
import org.testng.annotations.AfterGroups;
@ -74,6 +73,7 @@ import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.net.HostAndPort;
import com.google.common.net.InetAddresses;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
@ -180,7 +180,7 @@ public class CloudStackComputeServiceAdapterLiveTest extends BaseCloudStackClien
loginCredentials = prioritizeCredentialsFromTemplate.apply(template, vm.getCredentials());
assert InetAddresses.isInetAddress(address) : vm;
IPSocket socket = new IPSocket(address, 22);
HostAndPort socket = HostAndPort.fromParts(address, 22);
checkSSH(socket);
}

View File

@ -52,7 +52,6 @@ import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.internal.BaseGenericComputeServiceContextLiveTest;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
@ -65,6 +64,7 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
import com.google.common.reflect.TypeToken;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -156,7 +156,7 @@ public class BaseCloudStackClientLiveTest extends BaseGenericComputeServiceConte
protected CloudStackClient adminClient;
protected User user;
protected Predicate<IPSocket> socketTester;
protected Predicate<HostAndPort> socketTester;
protected RetryablePredicate<Long> jobComplete;
protected RetryablePredicate<Long> adminJobComplete;
protected RetryablePredicate<VirtualMachine> virtualMachineRunning;
@ -181,7 +181,7 @@ public class BaseCloudStackClientLiveTest extends BaseGenericComputeServiceConte
protected CloudStackGlobalClient globalAdminClient;
protected User globalAdminUser;
protected void checkSSH(IPSocket socket) {
protected void checkSSH(HostAndPort socket) {
socketTester.apply(socket);
SshClient client = sshFactory.create(socket, loginCredentials);
try {
@ -224,7 +224,7 @@ public class BaseCloudStackClientLiveTest extends BaseGenericComputeServiceConte
injector = Guice.createInjector(setupModules());
sshFactory = injector.getInstance(SshClient.Factory.class);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<HostAndPort>(new InetSocketAddressConnect(), 180, 1, 1, TimeUnit.SECONDS);
injector.injectMembers(socketTester);
jobComplete = new RetryablePredicate<Long>(new JobComplete(client), 1200, 1, 5, TimeUnit.SECONDS);
injector.injectMembers(jobComplete);

View File

@ -36,13 +36,13 @@ import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.options.CreateFirewallRuleOptions;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.net.HostAndPort;
/**
* Tests behavior of {@code FirewallClientLiveTest}
@ -112,7 +112,7 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
assertEquals(portForwardingRule.getProtocol(), PortForwardingRule.Protocol.TCP);
checkPortForwardingRule(portForwardingRule);
checkSSH(new IPSocket(ip.getIPAddress(), 22));
checkSSH(HostAndPort.fromParts(ip.getIPAddress(), 22));
}
@Test(dependsOnMethods = "testCreatePortForwardingRule")

View File

@ -35,13 +35,12 @@ import javax.annotation.Nullable;
import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.JobResult;
import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.LoadBalancerRule.State;
import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.LoadBalancerRule.State;
import org.jclouds.cloudstack.predicates.LoadBalancerRuleActive;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.ssh.SshException;
import org.testng.annotations.AfterGroups;
@ -50,6 +49,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.net.HostAndPort;
/**
* Tests behavior of {@code LoadBalancerClientLiveTest}
@ -155,7 +155,7 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
private void loopAndCheckSSH() throws IOException {
for (int i = 0; i < 5; i++) {// retry loop TODO replace with predicate.
try {
checkSSH(new IPSocket(ip.getIPAddress(), 22));
checkSSH(HostAndPort.fromParts(ip.getIPAddress(), 22));
return;
} catch (SshException e) {
e.printStackTrace();
@ -176,7 +176,7 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
rule.getId(), vm.getId())));
assertEquals(client.getLoadBalancerClient().listVirtualMachinesAssignedToLoadBalancerRule(rule.getId()).size(), 0);
assertEquals(rule.getState(), State.ADD);
checkSSH(new IPSocket(ip.getIPAddress(), 22));
checkSSH(HostAndPort.fromParts(ip.getIPAddress(), 22));
}
@AfterGroups(groups = "live")

View File

@ -33,7 +33,6 @@ import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.net.IPSocket;
import org.jclouds.util.Strings2;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.Test;
@ -41,6 +40,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
/**
* Tests behavior of {@code SecurityGroupClient}
@ -178,7 +178,7 @@ public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest {
if (vm.getPassword() != null && !loginCredentials.hasPasswordOption())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
// ingress port 22
checkSSH(new IPSocket(vm.getIPAddress(), 22));
checkSSH(HostAndPort.fromParts(vm.getIPAddress(), 22));
// ingress icmp disabled as this is platform dependent and may actually
// just try tcp port 7
// assert InetAddress.getByName(vm.getIPAddress()).isReachable(1000) : vm;

View File

@ -53,7 +53,6 @@ import org.jclouds.cloudstack.options.ListNetworkOfferingsOptions;
import org.jclouds.cloudstack.options.ListNetworksOptions;
import org.jclouds.cloudstack.options.ListTemplatesOptions;
import org.jclouds.cloudstack.options.ListVirtualMachinesOptions;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.util.InetAddresses2;
import org.testng.annotations.AfterGroups;
@ -67,6 +66,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.net.HostAndPort;
import com.google.common.net.HostSpecifier;
/**
@ -282,7 +282,7 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
assert HostSpecifier.isValid(vm.getIPAddress());
if (!InetAddresses2.isPrivateIPAddress(vm.getIPAddress())) {
// not sure if the network is public or not, so we have to test
IPSocket socket = new IPSocket(vm.getIPAddress(), 22);
HostAndPort socket = HostAndPort.fromParts(vm.getIPAddress(), 22);
System.err.printf("testing socket %s%n", socket);
System.err.printf("testing ssh %s%n", socket);
checkSSH(socket);

View File

@ -37,7 +37,6 @@ import org.jclouds.cloudstack.features.NATClientLiveTest;
import org.jclouds.cloudstack.features.VirtualMachineClientLiveTest;
import org.jclouds.cloudstack.predicates.NetworkPredicates;
import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult;
import org.jclouds.net.IPSocket;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@ -45,6 +44,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.HostAndPort;
/**
* Tests behavior of {@code StaticNATVirtualMachineInNetwork}
@ -106,7 +106,7 @@ public class StaticNATVirtualMachineInNetworkLiveTest extends NATClientLiveTest
assertEquals(rule.getStartPort(), 22);
assertEquals(rule.getProtocol(), "tcp");
checkRule(rule);
IPSocket socket = new IPSocket(ip.getIPAddress(), 22);
HostAndPort socket = HostAndPort.fromParts(ip.getIPAddress(), 22);
checkSSH(socket);
}

View File

@ -0,0 +1,87 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch;
import com.google.common.collect.AbstractIterator;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import java.util.Iterator;
/**
* Utilities for using CloudWatch.
*
* @author Jeremy Whitlock
*/
public class CloudWatch {
/**
* List metrics based on the criteria in the {@link ListMetricsOptions} passed in.
*
* @param cloudWatchClient the CloudWatch client
* @param region the region to list metrics in
* @param options the options describing the ListMetrics request
*
* @return iterable of metrics fitting the criteria
*/
public static Iterable<Metric> listMetrics(CloudWatchClient cloudWatchClient, String region,
final ListMetricsOptions options) {
final MetricClient metricClientForRegion = cloudWatchClient.getMetricClientForRegion(region);
return new Iterable<Metric>() {
public Iterator<Metric> iterator() {
return new AbstractIterator<Metric>() {
private ListMetricsOptions lastOptions = options;
private ListMetricsResponse response = metricClientForRegion.listMetrics(lastOptions);
private Iterator<Metric> iterator = response.iterator();
/**
* {@inheritDoc}
*/
@Override
protected Metric computeNext() {
while (true) {
if (iterator == null) {
lastOptions = ListMetricsOptions.builder()
.dimensions(lastOptions.getDimensions())
.metricName(lastOptions.getMetricName())
.namespace(lastOptions.getNamespace())
.nextToken(response.getNextToken())
.build();
response = metricClientForRegion.listMetrics(lastOptions);
iterator = response.iterator();
}
if (iterator.hasNext()) {
return iterator.next();
}
if (response.getNextToken() == null) {
return endOfData();
}
iterator = null;
}
}
};
}
};
}
}

View File

@ -73,7 +73,7 @@ public class CloudWatchApiMetadata extends BaseRestApiMetadata {
.name("Amazon CloudWatch Api")
.identityName("Access Key ID")
.credentialName("Secret Access Key")
.version(CloudWatchAsyncClient.VERSION)
.version("2010-08-01")
.documentation(URI.create("http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/"))
.defaultEndpoint("https://monitoring.us-east-1.amazonaws.com")
.defaultProperties(CloudWatchApiMetadata.defaultProperties())

View File

@ -28,11 +28,14 @@ import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.features.MetricAsyncClient;
import org.jclouds.cloudwatch.functions.ISO8601Format;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandler;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser;
@ -41,24 +44,32 @@ import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Provides;
/**
* Provides access to Amazon CloudWatch via the Query API
* <p/>
*
* @see <a
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html"
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference"
* />
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface CloudWatchAsyncClient {
public static final String VERSION = "2010-08-01";
/**
* @see CloudWatchClient#getMetricStatisticsInRegion
*
* @return the Region codes configured
*/
@Provides
@Region
Set<String> getConfiguredRegions();
/**
* @see MetricAsyncClient#getMetricStatistics
*/
@Deprecated
@POST
@Path("/")
@XMLResponseParser(GetMetricStatisticsResponseHandler.class)
@ -72,4 +83,11 @@ public interface CloudWatchAsyncClient {
@FormParam("Period") int period,
@FormParam("Statistics.member.1") Statistics statistics,
GetMetricStatisticsOptions... options);
/**
* Provides asynchronous access to Metric features.
*/
@Delegate
MetricAsyncClient getMetricClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
}

View File

@ -24,22 +24,36 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.concurrent.Timeout;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import com.google.inject.Provides;
/**
* Provides access to Amazon CloudWatch via the Query API
* <p/>
*
* @see <a
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html"
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference"
* />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface CloudWatchClient {
/**
*
* @return the Region codes configured
*/
@Provides
@Region
Set<String> getConfiguredRegions();
/**
* This call returns data for one or more statistics of given a metric. For more information, see
* Statistic and Metric.
@ -76,8 +90,15 @@ public interface CloudWatchClient {
* The statistics to be returned for the given metric. ex. Average
* @param options
* more filtering options (e.g. instance ID)
* @see MetricsClient#getMetricStatistics
*/
@Deprecated
Set<Datapoint> getMetricStatisticsInRegion(@Nullable String region, String metricName, String namespace,
Date startTime, Date endTime, int period, Statistics statistics, GetMetricStatisticsOptions... options);
Date startTime, Date endTime, int period, Statistics statistics, GetMetricStatisticsOptions... options);
/**
* Provides synchronous access to Metric features.
*/
@Delegate
MetricClient getMetricClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
}

View File

@ -0,0 +1,80 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.binders;
import javax.inject.Inject;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.date.DateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableMultimap;
/**
* Binds the metrics request to the http request
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html"
* />
*
* @author Jeremy Whitlock, Adrian Cole
*/
@Beta
public class GetMetricStatisticsBinder implements org.jclouds.rest.Binder {
private final DateService dateService;
@Inject
protected GetMetricStatisticsBinder(DateService dateService){
this.dateService =dateService;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object payload) {
GetMetricStatistics getRequest = GetMetricStatistics.class.cast(payload);
int dimensionIndex = 1;
int statisticIndex = 1;
ImmutableMultimap.Builder<String, String> formParameters = ImmutableMultimap.<String, String> builder();
for (Dimension dimension : getRequest.getDimensions()) {
formParameters.put("Dimensions.member." + dimensionIndex + ".Name", dimension.getName());
formParameters.put("Dimensions.member." + dimensionIndex + ".Value", dimension.getValue());
dimensionIndex++;
}
formParameters.put("EndTime", dateService.iso8601SecondsDateFormat(getRequest.getEndTime()));
formParameters.put("MetricName", getRequest.getMetricName());
formParameters.put("Namespace", getRequest.getNamespace());
formParameters.put("Period", Integer.toString(getRequest.getPeriod()));
formParameters.put("StartTime", dateService.iso8601SecondsDateFormat(getRequest
.getStartTime()));
for (Statistics statistic : getRequest.getStatistics()) {
formParameters.put("Statistics.member." + statisticIndex, statistic.toString());
statisticIndex++;
}
formParameters.put("Unit", getRequest.getUnit().toString());
return ModifyRequest.putFormParams(request, formParameters.build());
}
}

View File

@ -18,11 +18,18 @@
*/
package org.jclouds.cloudwatch.config;
import java.util.Map;
import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.cloudwatch.CloudWatchClient;
import org.jclouds.cloudwatch.features.MetricAsyncClient;
import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.rest.ConfiguresRestClient;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
/**
* Configures the Monitoring connection.
*
@ -30,5 +37,12 @@ import org.jclouds.rest.ConfiguresRestClient;
*/
@ConfiguresRestClient
public class CloudWatchRestClientModule extends FormSigningRestClientModule<CloudWatchClient, CloudWatchAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(MetricClient.class, MetricAsyncClient.class)
.build();
public CloudWatchRestClientModule() {
super(TypeToken.of(CloudWatchClient.class), TypeToken.of(CloudWatchAsyncClient.class), DELEGATE_MAP);
}
}

View File

@ -0,0 +1,48 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#as-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface AutoScalingConstants {
public static class Dimension {
public static final String AUTO_SCALING_GROUP_NAME = "AutoScalingGroupName";
}
public static class MetricName {
public static final String GROUP_DESIRED_CAPACITY = "GroupDesiredCapacity";
public static final String GROUP_IN_SERVICE_INSTANCES = "GroupInServiceInstances";
public static final String GROUP_MAX_SIZE = "GroupMaxSize";
public static final String GROUP_MIN_SIZE = "GroupMinSize";
public static final String GROUP_PENDING_INSTANCES = "GroupPendingInstances";
public static final String GROUP_TERMINATING_INSTANCES = "GroupTerminatingInstances";
public static final String GROUP_TOTAL_INSTANCES = "GroupTotalInstances";
}
}

View File

@ -18,12 +18,13 @@
*/
package org.jclouds.cloudwatch.domain;
import java.util.Date;
import com.google.common.base.Objects;
import org.jclouds.javax.annotation.Nullable;
import java.util.Date;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html?DT_Datapoint.html"
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference?DT_Datapoint.html"
* />
*
* @author Adrian Cole
@ -118,17 +119,7 @@ public class Datapoint {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((average == null) ? 0 : average.hashCode());
result = prime * result + ((customUnit == null) ? 0 : customUnit.hashCode());
result = prime * result + ((maximum == null) ? 0 : maximum.hashCode());
result = prime * result + ((minimum == null) ? 0 : minimum.hashCode());
result = prime * result + ((samples == null) ? 0 : samples.hashCode());
result = prime * result + ((sum == null) ? 0 : sum.hashCode());
result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode());
result = prime * result + ((unit == null) ? 0 : unit.hashCode());
return result;
return Objects.hashCode(average, customUnit, maximum, minimum, samples, sum, timestamp, unit);
}
@Override
@ -140,53 +131,27 @@ public class Datapoint {
if (getClass() != obj.getClass())
return false;
Datapoint other = (Datapoint) obj;
if (average == null) {
if (other.average != null)
return false;
} else if (!average.equals(other.average))
return false;
if (customUnit == null) {
if (other.customUnit != null)
return false;
} else if (!customUnit.equals(other.customUnit))
return false;
if (maximum == null) {
if (other.maximum != null)
return false;
} else if (!maximum.equals(other.maximum))
return false;
if (minimum == null) {
if (other.minimum != null)
return false;
} else if (!minimum.equals(other.minimum))
return false;
if (samples == null) {
if (other.samples != null)
return false;
} else if (!samples.equals(other.samples))
return false;
if (sum == null) {
if (other.sum != null)
return false;
} else if (!sum.equals(other.sum))
return false;
if (timestamp == null) {
if (other.timestamp != null)
return false;
} else if (!timestamp.equals(other.timestamp))
return false;
if (unit == null) {
if (other.unit != null)
return false;
} else if (!unit.equals(other.unit))
return false;
return true;
return Objects.equal(this.average, other.average) &&
Objects.equal(this.customUnit, other.customUnit) &&
Objects.equal(this.maximum, other.maximum) &&
Objects.equal(this.minimum, other.minimum) &&
Objects.equal(this.samples, other.samples) &&
Objects.equal(this.sum, other.sum) &&
Objects.equal(this.timestamp, other.timestamp) &&
Objects.equal(this.unit, other.unit);
}
@Override
public String toString() {
return "[average=" + average + ", customUnit=" + customUnit + ", maximum=" + maximum + ", minimum=" + minimum
+ ", samples=" + samples + ", sum=" + sum + ", timestamp=" + timestamp + ", unit=" + unit + "]";
return Objects.toStringHelper(this)
.add("timestamp", timestamp)
.add("customUnit", customUnit)
.add("maximum", maximum)
.add("minimum", minimum)
.add("average", average)
.add("sum", sum)
.add("samples", samples)
.add("unit", unit).toString();
}
}

View File

@ -16,45 +16,50 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.net;
package org.jclouds.cloudwatch.domain;
import java.io.Serializable;
import com.google.common.base.Objects;
/**
* As google appengine prohibits use of java.net classes, this will serve as a replacement.
*
* @author Adrian Cole
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_Dimension.html" />
*
* @author Jeremy Whitlock
*/
public class IPSocket implements Serializable {
public class Dimension {
/** The serialVersionUID */
private static final long serialVersionUID = 2978329372952402188L;
private final String name;
private final String value;
private final String address;
private final int port;
public IPSocket(String address, int port) {
this.address = address;
this.port = port;
public Dimension(String name, String value) {
this.name = name;
this.value = value;
}
public String getAddress() {
return address;
/**
* return the dimension name.
*/
public String getName() {
return name;
}
public int getPort() {
return port;
/**
* return the dimension value.
*/
public String getValue() {
return value;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + port;
return result;
return Objects.hashCode(name, value);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
@ -63,20 +68,19 @@ public class IPSocket implements Serializable {
return false;
if (getClass() != obj.getClass())
return false;
IPSocket other = (IPSocket) obj;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (port != other.port)
return false;
return true;
Dimension other = (Dimension)obj;
return Objects.equal(this.name, other.name) &&
Objects.equal(this.value, other.value);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "[address=" + address + ", port=" + port + "]";
return Objects.toStringHelper(this)
.add("name", name)
.add("value", value).toString();
}
}

View File

@ -0,0 +1,49 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#dynamo-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface DynamoDBConstants {
public static class Dimension {
public static final String OPERATION = "Operation";
public static final String TABLE_NAME = "TableName";
}
public static class MetricName {
public static final String CONSUMED_READ_CAPACITY_UNITS = "ConsumedReadCapacityUnits";
public static final String CONSUMED_WRITE_CAPACITY_UNITS = "ConsumedWriteCapacityUnits";
public static final String SUCCESSFUL_REQUEST_LATENCY = "SuccessfulRequestLatency";
public static final String RETURNED_ITEM_COUNT = "ReturnedItemCount";
public static final String SYSTEM_ERRORS = "SystemErrors";
public static final String THROTTLED_REQUESTS = "ThrottledRequests";
public static final String USER_ERRORS = "UserErrors";
}
}

View File

@ -0,0 +1,49 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#ebs-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface EBSConstants {
public static class Dimension {
public static final String VOLUME_ID = "VolumeId";
}
public static class MetricName {
public static final String VOLUME_IDLE_TIME = "VolumeIdleTime";
public static final String VOLUME_QUEUE_LENGTH = "VolumeQueueLength";
public static final String VOLUME_READ_BYTES = "VolumeReadBytes";
public static final String VOLUME_READ_OPS = "VolumeReadOps";
public static final String VOLUME_TOTAL_READ_TIME = "VolumeTotalReadTime";
public static final String VOLUME_TOTAL_WRITE_TIME = "VolumeTotalWriteTime";
public static final String VOLUME_WRITE_BYTES = "VolumeWriteBytes";
public static final String VOLUME_WRITE_OPS = "VolumeWriteOps";
}
}

View File

@ -0,0 +1,51 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#ec2-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface EC2Constants {
public static class Dimension {
public static final String AUTO_SCALING_GROUP_NAME = "AutoScalingGroupName";
public static final String IMAGE_ID = "ImageId";
public static final String INSTANCE_ID = "InstanceId";
public static final String INSTANCE_TYPE = "InstanceType";
}
public static class MetricName {
public static final String CPU_UTILIZATION = "CPUUtilization";
public static final String DISK_READ_BYTES = "DiskReadBytes";
public static final String DISK_READ_OPS = "DiskReadOps";
public static final String DISK_WRITE_BYTES = "DiskWriteBytes";
public static final String DISK_WRITE_OPS = "DiskWriteOps";
public static final String NETWORK_IN = "NetworkIn";
public static final String NETWORK_OUT = "NetworkOut";
}
}

View File

@ -0,0 +1,52 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#elb-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface ELBConstants {
public static class Dimension {
public static final String AVAILABILITY_ZONE = "AvailabilityZone";
public static final String LOAD_BALANCER_NAME = "LoadBalancerName";
}
public static class MetricName {
public static final String HEALTHY_HOST_COUNT = "HealthyHostCount";
public static final String HTTP_CODE_BACKEND_2XX = "HTTPCode_Backend_2XX";
public static final String HTTP_CODE_BACKEND_3XX = "HTTPCode_Backend_3XX";
public static final String HTTP_CODE_BACKEND_4XX = "HTTPCode_Backend_4XX";
public static final String HTTP_CODE_BACKEND_5XX = "HTTPCode_Backend_5XX";
public static final String HTTP_CODE_ELB_4XX = "HTTPCode_ELB_4XX";
public static final String HTTP_CODE_ELB_5XX = "HTTPCode_ELB_5XX";
public static final String LATENCY = "Latency";
public static final String REQUEST_COUNT = "RequestCount";
public static final String UNHEALTHY_HOST_COUNT = "UnHealthyHostCount";
}
}

View File

@ -0,0 +1,65 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#emr-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface EMRConstants {
public static class Dimension {
public static final String JOB_FLOW_ID = "JobFlowId";
public static final String JOB_ID = "JobId";
}
public static class MetricName {
public static final String CORE_NODES_PENDING = "CoreNodesPending";
public static final String CORE_NODES_RUNNING = "CoreNodesRunning";
public static final String HDFS_BYTES_READ = "HDFSBytesRead";
public static final String HDFS_BYTES_WRITTEN = "HDFSBytesWritten";
public static final String HDFS_UTILIZATION = "HDFSUtilization";
public static final String IS_IDLE = "IsIdle";
public static final String JOBS_FAILED = "JobsFailed";
public static final String JOBS_RUNNING = "JobsRunning";
public static final String LIVE_DATA_NODES = "LiveDataNodes";
public static final String LIVE_TASK_TRACKERS = "LiveTaskTrackers";
public static final String MAP_SLOTS_OPEN = "MapSlotsOpen";
public static final String MISSING_BLOCKS = "MissingBlocks";
public static final String REDUCE_SLOTS_OPEN = "ReduceSlotsOpen";
public static final String REMAINING_MAP_TASKS = "RemainingMapTasks";
public static final String REMAINING_MAP_TASKS_PER_SLOT = "RemainingMapTasksPerSlot";
public static final String REMAINING_REDUCE_TASKS = "RemainingReduceTasks";
public static final String RUNNING_MAP_TASKS = "RunningMapTasks";
public static final String RUNNING_REDUCE_TASKS = "RunningReduceTasks";
public static final String S3_BYTES_READ = "S3BytesRead";
public static final String S3_BYTES_WRITTEN = "S3BytesWritten";
public static final String TASK_NODES_PENDING = "TaskNodesPending";
public static final String TASK_NODES_RUNNING = "TaskNodesRunning";
public static final String TOTAL_LOAD = "TotalLoad";
}
}

View File

@ -0,0 +1,342 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
import java.util.Date;
import java.util.Set;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
/**
* Options use to get statistics for the specified metric.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html" />
*
* @author Jeremy Whitlock
*/
@Beta
public class GetMetricStatistics {
private final Set<Dimension> dimensions;
private final Date endTime;
private final String metricName;
private final String namespace;
private final int period;
private final Date startTime;
private final Set<Statistics> statistics;
private final Unit unit;
/**
* Private constructor to enforce using {@link Builder}.
*/
private GetMetricStatistics(@Nullable Set<Dimension> dimensions, Date endTime, String metricName,
String namespace, int period, Date startTime, Set<Statistics> statistics,
Unit unit) {
this.dimensions = dimensions;
this.endTime = endTime;
this.metricName = metricName;
this.namespace = namespace;
this.period = period;
this.startTime = startTime;
this.statistics = statistics;
this.unit = unit;
}
/**
* return the set of dimensions for this request
*/
@Nullable
public Set<Dimension> getDimensions() {
return dimensions;
}
/**
* return the end time for this request
*/
public Date getEndTime() {
return endTime;
}
/**
* return the metric name for this request
*/
public String getMetricName() {
return metricName;
}
/**
* return the namespace for this request
*/
public String getNamespace() {
return namespace;
}
/**
* return the period for this request
*/
public int getPeriod() {
return period;
}
/**
* return the start time for this request
*/
public Date getStartTime() {
return startTime;
}
/**
* return the statistics for this request
*/
public Set<Statistics> getStatistics() {
return statistics;
}
/**
* return the unit for this request
*/
public Unit getUnit() {
return unit;
}
/**
* Returns a new builder. The generated builder is equivalent to the builder
* created by the {@link Builder} constructor.
*/
public static Builder builder() {
return new Builder();
}
public static class Builder {
private Set<Dimension> dimensions = Sets.newLinkedHashSet();
private Date endTime;
private String metricName;
private String namespace;
private int period;
private Date startTime;
private Set<Statistics> statistics = Sets.newLinkedHashSet();
private Unit unit;
/**
* Creates a new builder. The returned builder is equivalent to the builder
* generated by {@link ListMetricsOptions#builder}.
*/
public Builder() {}
/**
* A list of dimensions describing qualities of the metric. (Set can be 10 or less items.)
*
* @param dimensions the dimensions describing the qualities of the metric
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if this is invoked more than 10 times
*/
public Builder dimensions(Set<Dimension> dimensions) {
if (dimensions != null) {
Preconditions.checkArgument(dimensions.size() <= 10, "dimensions can have 10 or fewer members.");
this.dimensions = dimensions;
}
return this;
}
/**
* A dimension describing qualities of the metric. (Can be called multiple times up to a maximum of 10 times.)
*
* @param dimension the dimension describing the qualities of the metric
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if the number of dimensions would be greater than 10 after adding
*/
public Builder dimension(Dimension dimension) {
if (dimension != null) {
Preconditions.checkArgument(dimensions.size() < 10, "dimension member maximum count of 10 exceeded.");
this.dimensions.add(dimension);
}
return this;
}
/**
* The time stamp to use for determining the last datapoint to return. The value specified is exclusive so
* results will include datapoints up to the time stamp specified. (Should be called once. Subsequent calls
* will overwrite the previous value.)
*
* @param endTime the timestamp to use for determining the last datapoint to return
*
* @return this {@code Builder} object
*
* @throws NullPointerException if endTime is null
*/
public Builder endTime(Date endTime) {
Preconditions.checkNotNull(endTime, "endTime cannot be null.");
this.endTime = endTime;
return this;
}
/**
* The name of the metric. (Should be called once. Subsequent calls will overwrite the previous value.)
*
* @param metricName the metric name to filter against
*
* @return this {@code Builder} object
*
* @throws NullPointerException if metricName is null
* @throws IllegalArgumentException if metricName is empty
*/
public Builder metricName(String metricName) {
Preconditions.checkNotNull(metricName, "metricName cannot be null.");
Preconditions.checkArgument(metricName.length() > 1, "metricName must not be empty.");
this.metricName = metricName;
return this;
}
/**
* The namespace of the metric. (Should be called once. Subsequent calls will overwrite the previous value.
* See {@link org.jclouds.cloudwatch.domain.Namespaces} for the known list of namespaces.)
*
* @param namespace the namespace to filter against
*
* @return this {@code Builder} object
*
* @throws NullPointerException if namespace is null
* @throws IllegalArgumentException if namespace is empty
*/
public Builder namespace(String namespace) {
Preconditions.checkNotNull(namespace, "namespace cannot be null.");
Preconditions.checkArgument(namespace.length() > 1, "namespace must not be empty.");
this.namespace = namespace;
return this;
}
/**
* The granularity, in seconds, of the returned datapoints. Period must be at least 60 seconds and must be a
* multiple of 60. The default value is 60. (Should be called once. Subsequent calls will overwrite the
* previous value.)
*
* @param period the granularity, in seconds, of the returned datapoints
*
* @return this {@code Builder} object
*
* @throws NullPointerException if period is null
* @throws IllegalArgumentException if period is less than 60 or not a multiple of 60
*/
public Builder period(int period) {
Preconditions.checkNotNull(period, "period cannot be null.");
Preconditions.checkArgument(period >= 60 && period % 60 == 0, "period must be greater than 60 and as a " +
"multiple of 60.");
this.period = period;
return this;
}
/**
* The time stamp to use for determining the first datapoint to return. The value specified is inclusive so
* results include datapoints with the time stamp specified. (Should be called once. Subsequent calls will
* overwrite the previous value.)
*
* @param startTime The time stamp to use for determining the first datapoint to return
*
* @return this {@code Builder} object
*
* @throws NullPointerException if startTime is null
*/
public Builder startTime(Date startTime) {
Preconditions.checkNotNull(startTime, "startTime cannot be null.");
this.startTime = startTime;
return this;
}
/**
* The metric statistics to return. (Should be called once. Subsequent calls will overwrite the previous
* value.)
*
* @param statistics the metric statistics to return.
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if the number of statistics is greater than 5
* @throws NullPointerException if statistics is null
*/
public Builder statistics(Set<Statistics> statistics) {
Preconditions.checkNotNull(statistics, "statistics cannot be null.");
Preconditions.checkArgument(statistics.size() <= 5, "statistics can have 5 or fewer members.");
this.statistics = statistics;
return this;
}
/**
* The metric statistic to return. (Can be called multiple times up to a maximum of 5 times.)
*
* @param statistic the metric statistic to return
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if the number of statistics would be greater than 5 after adding
* @throws NullPointerException if statistic is null
*/
public Builder statistic(Statistics statistic) {
Preconditions.checkNotNull(statistic, "statistic cannot be null.");
Preconditions.checkArgument(statistics.size() < 5, "statistics member maximum count of 5 exceeded.");
this.statistics.add(statistic);
return this;
}
/**
* The unit for the metric. (Should be called once. Subsequent calls will overwrite the previous value.)
*
* @param unit the unit for the metric
*
* @return this {@code Builder} object
*
* @throws NullPointerException if unit is null
*/
public Builder unit(Unit unit) {
Preconditions.checkNotNull(unit, "unit cannot be null.");
this.unit = unit;
return this;
}
/**
* Returns a newly-created {@code GetMetricStatisticsOptionsV2} based on the contents of
* the {@code Builder}.
*
* @throws NullPointerException if any of the required fields are null
* @throws IllegalArgumentException if any of the provided fields don't meet required criteria
*/
public GetMetricStatistics build() {
Preconditions.checkNotNull(endTime, "endTime cannot be null.");
Preconditions.checkNotNull(metricName, "metricName cannot be null.");
Preconditions.checkNotNull(namespace, "namespace cannot be null.");
Preconditions.checkNotNull(period, "period cannot be null.");
Preconditions.checkNotNull(startTime, "startTime cannot be null.");
Preconditions.checkNotNull(statistics, "statistics cannot be null.");
Preconditions.checkNotNull(unit, "unit cannot be null.");
Preconditions.checkArgument(statistics.size() >= 1, "statistics must have at least one member");
return new GetMetricStatistics(dimensions, endTime, metricName,namespace, period, startTime, statistics, unit);
}
}
}

View File

@ -0,0 +1,97 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.ImmutableSet;
/**
* the list of {@link Datapoint} for the metric
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html" />
*
* @author Jeremy Whitlock
*/
public class GetMetricStatisticsResponse extends ForwardingSet<Datapoint> {
private final Set<Datapoint> datapoints;
private final String label;
public GetMetricStatisticsResponse(@Nullable Set<Datapoint> datapoints, String label) {
// Default to an empty set
if (datapoints == null) {
this.datapoints = ImmutableSet.<Datapoint>of();
} else {
this.datapoints = ImmutableSet.<Datapoint>copyOf(datapoints);
}
this.label = label;
}
/**
* return the label describing the specified metric
*/
public String getLabel() {
return label;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hashCode(datapoints, label);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
GetMetricStatisticsResponse other = (GetMetricStatisticsResponse)obj;
return Objects.equal(this.datapoints, other.datapoints) &&
Objects.equal(this.label, other.label);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("label", label)
.add("datapoints", datapoints).toString();
}
@Override
protected Set<Datapoint> delegate() {
return datapoints;
}
}

View File

@ -0,0 +1,97 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.ImmutableSet;
/**
* list of {@link Metric}
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html" />
*
* @author Jeremy Whitlock
*/
public class ListMetricsResponse extends ForwardingSet<Metric>{
private final Set<Metric> metrics;
private final String nextToken;
public ListMetricsResponse(@Nullable Set<Metric> metrics, @Nullable String nextToken) {
// Default to an empty set
if (metrics == null) {
this.metrics = ImmutableSet.<Metric>of();
} else {
this.metrics = ImmutableSet.<Metric>copyOf(metrics);
}
this.nextToken = nextToken;
}
/**
* return the next token or null if there is none.
*/
@Nullable
public String getNextToken() {
return nextToken;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hashCode(metrics, nextToken);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ListMetricsResponse other = (ListMetricsResponse)obj;
return Objects.equal(this.metrics, other.metrics) &&
Objects.equal(this.nextToken, other.nextToken);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("metrics", metrics)
.add("nextToken", nextToken).toString();
}
@Override
protected Set<Metric> delegate() {
return metrics;
}
}

View File

@ -0,0 +1,108 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
import com.google.common.base.Objects;
import com.google.common.collect.Sets;
import org.jclouds.javax.annotation.Nullable;
import java.util.Set;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_Metric.html" />
*
* @author Jeremy Whitlock
*/
public class Metric {
private final Set<Dimension> dimensions;
private final String metricName;
private final String namespace;
public Metric (String metricName, String namespace, @Nullable Set<Dimension> dimensions) {
// Default to an empty set
if (dimensions == null) {
this.dimensions = Sets.newLinkedHashSet();
} else {
this.dimensions = dimensions;
}
this.metricName = metricName;
this.namespace = namespace;
}
/**
* return the metric name for the metric.
*/
public String getMetricName() {
return metricName;
}
/**
* return the namespace for the metric
*/
public String getNamespace() {
return namespace;
}
/**
* return the available dimensions for the metric
*/
@Nullable
public Set<Dimension> getDimensions() {
return dimensions;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hashCode(dimensions, metricName, namespace);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Metric other = (Metric)obj;
return Objects.equal(this.dimensions, other.dimensions) &&
Objects.equal(this.metricName, other.metricName) &&
Objects.equal(this.namespace, other.namespace);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("namespace", namespace)
.add("metricName", metricName)
.add("dimension", dimensions).toString();
}
}

View File

@ -0,0 +1,41 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS provided namespaces as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#aws-namespaces" />
*
* @author Jeremy Whitlock
*/
public interface Namespaces {
public static final String AUTO_SCALING = "AWS/AutoScaling";
public static final String DYNAMODB = "AWS/DynamoDB";
public static final String EBS = "AWS/EBS";
public static final String EC2 = "AWS/EC2";
public static final String ELB = "AWS/ELB";
public static final String EMR = "AWS/EMR";
public static final String RDS = "AWS/RDS";
public static final String SNS = "AWS/SNS";
public static final String SQS = "AWS/SQS";
public static final String STORAGE_GATEWAY = "AWS/StorageGateway";
}

View File

@ -0,0 +1,56 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#rds-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface RDSConstants {
public static class Dimension {
public static final String DB_INSTANCE_IDENTIFIER = "DBInstanceIdentifier";
public static final String DATABASE_CLASS = "DatabaseClass";
public static final String ENGINE_NAME = "EngineName";
}
public static class MetricName {
public static final String BIN_LOG_DISK_USAGE = "BinLogDiskUsage";
public static final String CPU_UTILIZATION = "CPUUtilization";
public static final String DATABASE_CONNECTIONS = "DatabaseConnections";
public static final String FREEABLE_MEMORY = "FreeableMemory";
public static final String FREE_STORAGE_SPACE = "FreeStorageSpace";
public static final String REPLICA_LAG = "ReplicaLag";
public static final String READ_IO_OPS = "ReadIOPS";
public static final String READ_LATENCY = "ReadLatency";
public static final String READ_THROUGHPUT = "ReadThroughput";
public static final String SWAP_USAGE = "SwapUsage";
public static final String WRITE_IO_OPS = "WriteIOPS";
public static final String WRITE_LATENCY = "WriteLtency";
public static final String WRITE_THROUGHPUT = "WriteThroughput";
}
}

View File

@ -0,0 +1,45 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#sns-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface SNSConstants {
public static class Dimension {
public static final String TOPIC_NAME = "TopicName";
}
public static class MetricName {
public static final String NUMBER_OF_MESSAGES_PUBLISHED = "NumberOfMessagesPublished";
public static final String NUMBER_OF_NOTIFICATIONS_DELIVERED = "NumberOfNotificationsDelivered";
public static final String NUMBER_OF_NOTIFICATIONS_FAILED = "NumberOfNotificationsFailed";
public static final String PUBLISH_SIZE = "PublishSize";
}
}

View File

@ -0,0 +1,49 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#sqs-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface SQSConstants {
public static class Dimension {
public static final String QUEUE_NAME = "QueueName";
}
public static class MetricName {
public static final String APPROXIMATE_NUMBER_OF_MESSAGES_DELAYED = "ApproximateNumberOfMessagesDelayed";
public static final String APPROXIMATE_NUMBER_OF_MESSAGES_NOT_VISIBLE = "ApproximateNumberOfMessagesNotVisible";
public static final String APPROXIMATE_NUMBER_OF_MESSAGES_VISIBLE = "ApproximateNumberOfMessagesVisible";
public static final String NUMBER_OF_EMPTY_RECEIVES = "NumberOfEmptyReceives";
public static final String NUMBER_OF_MESSAGES_DELETED = "NumberOfMessagesDeleted";
public static final String NUMBER_OF_MESSAGES_RECEIVED = "NumberOfMessagesReceived";
public static final String NUMBER_OF_MESSAGES_SENT = "NumberOfMessagesSent";
public static final String SENT_MESSAGES_SIZE = "SentMessageSize";
}
}

View File

@ -0,0 +1,57 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.domain;
/**
* Constants interface for the AWS AutoScaling dimensions and metric names as of 2012-04-24.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#awssg-metricscollected" />
*
* @author Jeremy Whitlock
*/
public interface StorageGatewayConstants {
public static class Dimension {
public static final String GATEWAY_ID = "GatewayId";
public static final String GATEWAY_NAME = "GatewayName";
public static final String VOLUME_ID = "VolumeId";
}
public static class MetricName {
// Applicable for all Dimensions
public static final String QUEUED_WRITES = "QueuedWrites";
public static final String READ_BYTES = "ReadBytes";
public static final String READ_TIME = "ReadTime";
public static final String WRITE_BYTES = "WriteBytes";
public static final String WRITE_TIME = "WriteTime";
// Applicable for only GatewayId and GatewayName Dimensions
public static final String CLOUD_BYTES_DOWNLOADED = "CloudBytesDownloaded";
public static final String CLOUD_BYTES_UPLOADED = "CloudBytesUploaded";
public static final String CLOUD_DOWNLOAD_LATENCY = "CloudDownloadLatency";
public static final String WORKING_STORAGE_FREE = "WorkingStorageFree";
public static final String WORKING_STORAGE_PERCENT_USED = "WorkingStoragePercentUsed";
public static final String WORKING_STORAGE_USED = "WorkingStorageUsed";
}
}

View File

@ -0,0 +1,91 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.features;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.cloudwatch.binders.GetMetricStatisticsBinder;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandlerV2;
import org.jclouds.cloudwatch.xml.ListMetricsResponseHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Amazon CloudWatch via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference" />
* @author Jeremy Whitlock
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface MetricAsyncClient {
/**
* @see MetricClient#listMetrics()
*/
@POST
@Path("/")
@XMLResponseParser(ListMetricsResponseHandler.class)
@FormParams(keys = "Action", values = "ListMetrics")
ListenableFuture<? extends ListMetricsResponse> listMetrics();
/**
* @see MetricClient#listMetrics(ListMetricsOptions)
*/
@POST
@Path("/")
@XMLResponseParser(ListMetricsResponseHandler.class)
@FormParams(keys = "Action", values = "ListMetrics")
ListenableFuture<? extends ListMetricsResponse> listMetrics(ListMetricsOptions options);
/**
* @see MetricClient#getMetricStatistics(GetMetricStatistics)
*/
@POST
@Path("/")
@XMLResponseParser(GetMetricStatisticsResponseHandlerV2.class)
@FormParams(keys = "Action", values = "GetMetricStatistics")
ListenableFuture<? extends GetMetricStatisticsResponse> getMetricStatistics(
@BinderParam(GetMetricStatisticsBinder.class) GetMetricStatistics statistics);
/**
* @see MetricClient#getMetricStatistics(GetMetricStatistics, GetMetricStatisticsOptions)
*/
@POST
@Path("/")
@XMLResponseParser(GetMetricStatisticsResponseHandlerV2.class)
@FormParams(keys = "Action", values = "GetMetricStatistics")
ListenableFuture<? extends GetMetricStatisticsResponse> getMetricStatistics(
@BinderParam(GetMetricStatisticsBinder.class) GetMetricStatistics statistics,
GetMetricStatisticsOptions options);
}

View File

@ -0,0 +1,73 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.concurrent.Timeout;
/**
* Provides access to Amazon CloudWatch via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference" />
* @author Jeremy Whitlock
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface MetricClient {
/**
* Returns a list of valid metrics stored for the AWS account owner.
*
* <p/>
* <h3>Note</h3> Up to 500 results are returned for any one call. To retrieve further results,
* use returned NextToken (
* {@link org.jclouds.cloudwatch.domain.ListMetricsResponse#getNextToken()}) value with
* subsequent calls .To retrieve all available metrics with one call, use
* {@link #list(MetricsClient, String, org.jclouds.cloudwatch.options.ListMetricsOptions)}.
*
* @param options
* the options describing the metrics query
*
* @return the response object
*/
ListMetricsResponse listMetrics(ListMetricsOptions options);
ListMetricsResponse listMetrics();
/**
* Gets statistics for the specified metric.
*
* @param statistics
* the statistics to gather
* @param options
* the options describing the metric statistics query
*
* @return the response object
*/
GetMetricStatisticsResponse getMetricStatistics(GetMetricStatistics statistics, GetMetricStatisticsOptions options);
GetMetricStatisticsResponse getMetricStatistics(GetMetricStatistics statistics);
}

View File

@ -20,22 +20,64 @@ package org.jclouds.cloudwatch.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
/**
* Options used to control metric statistics are returned
*
* @see <a
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/index.html?API_GetMetricStatistics.html"
* />
* @author Andrei Savu
* @author Andrei Savu, Jeremy Whitlock
*/
public class GetMetricStatisticsOptions extends BaseHttpRequestOptions {
public static final GetMetricStatisticsOptions NONE = new GetMetricStatisticsOptions();
private Set<Dimension> dimensions = Sets.newLinkedHashSet();
/**
* A dimension describing qualities of the metric. (Can be called multiple times up to a maximum of 10 times.)
*
* @param dimension the dimension describing the qualities of the metric
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if the number of dimensions would be greater than 10 after adding
*/
public GetMetricStatisticsOptions dimension(Dimension dimension) {
if (dimension != null) {
Preconditions.checkArgument(dimensions.size() < 10, "dimension member maximum count of 10 exceeded.");
this.dimensions.add(dimension);
}
return this;
}
/**
* A list of dimensions describing qualities of the metric. (Set can be 10 or less items.)
*
* @param dimensions the dimensions describing the qualities of the metric
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if this is invoked more than 10 times
*/
public GetMetricStatisticsOptions dimensions(Set<Dimension> dimensions) {
if (dimensions != null) {
Preconditions.checkArgument(dimensions.size() <= 10, "dimensions can have 10 or fewer members.");
this.dimensions = ImmutableSet.<Dimension>copyOf(dimensions);
}
return this;
}
/**
* @param instanceId
* filter metrics by instance Id
@ -73,5 +115,34 @@ public class GetMetricStatisticsOptions extends BaseHttpRequestOptions {
GetMetricStatisticsOptions options = new GetMetricStatisticsOptions();
return options.unit(unit);
}
/**
* @see GetMetricStatisticsOptions#dimension
*/
public static GetMetricStatisticsOptions dimension(Dimension dimension) {
GetMetricStatisticsOptions options = new GetMetricStatisticsOptions();
return options.dimension(dimension);
}
/**
* @see GetMetricStatisticsOptions#dimensions
*/
public static GetMetricStatisticsOptions dimensions(Set<Dimension> dimensions) {
GetMetricStatisticsOptions options = new GetMetricStatisticsOptions();
return options.dimensions(dimensions);
}
}
@Override
public Multimap<String, String> buildFormParameters() {
Multimap<String, String> formParameters = super.buildFormParameters();
int dimensionIndex = 1;
for (Dimension dimension : dimensions) {
formParameters.put("Dimensions.member." + dimensionIndex + ".Name", dimension.getName());
formParameters.put("Dimensions.member." + dimensionIndex + ".Value", dimension.getValue());
dimensionIndex++;
}
return formParameters;
}
}

View File

@ -0,0 +1,219 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.options;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.http.options.BaseHttpRequestOptions;
import org.jclouds.javax.annotation.Nullable;
import java.util.Set;
/**
* Options used to list available metrics.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html" />
*
* @author Jeremy Whitlock
*/
public class ListMetricsOptions extends BaseHttpRequestOptions {
private final Set<Dimension> dimensions;
private final String metricName;
private final String namespace;
private final String nextToken;
/**
* Private constructor to enforce using {@link Builder}.
*/
private ListMetricsOptions(@Nullable String namespace, @Nullable String metricName,
@Nullable Set<Dimension> dimensions, @Nullable String nextToken) {
this.dimensions = dimensions;
this.metricName = metricName;
this.namespace = namespace;
this.nextToken = nextToken;
}
/**
* return the set of dimensions for this request
*/
@Nullable
public Set<Dimension> getDimensions() {
return dimensions;
}
/**
* return the metric name for this request
*/
@Nullable
public String getMetricName() {
return metricName;
}
/**
* return the namespace for this request
*/
@Nullable
public String getNamespace() {
return namespace;
}
/**
* return the next token for this request
*/
@Nullable
public String getNextToken() {
return nextToken;
}
/**
* Returns a new builder. The generated builder is equivalent to the builder
* created by the {@link Builder} constructor.
*/
public static Builder builder() {
return new Builder();
}
public static class Builder {
private Set<Dimension> dimensions = Sets.newLinkedHashSet();
private String metricName;
private String namespace;
private String nextToken;
/**
* Creates a new builder. The returned builder is equivalent to the builder
* generated by {@link ListMetricsOptions#builder}.
*/
public Builder() {}
/**
* The namespace to filter against. (Should be called once. Subsequent calls will overwrite the previous value.
* See {@link org.jclouds.cloudwatch.domain.Namespaces} for the known list of namespaces.)
*
* @param namespace the namespace to filter against
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if namespace is empty
*/
public Builder namespace(String namespace) {
if (namespace != null) {
Preconditions.checkArgument(namespace.length() > 1, "namespace must not be empty.");
}
this.namespace = namespace;
return this;
}
/**
* The name of the metric to filter against. (Should be called once. Subsequent calls will overwrite the
* previous value.)
*
* @param metricName the metric name to filter against
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if metricName is empty
*/
public Builder metricName(String metricName) {
if (metricName != null) {
Preconditions.checkArgument(metricName.length() > 1, "metricName must not be empty.");
}
this.metricName = metricName;
return this;
}
/**
* A list of dimensions to filter against. (Set can be 10 or less items.)
*
* @param dimensions the dimensions to filter against
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if the number of dimensions would be greater than 10 after adding
*/
public Builder dimensions(Set<Dimension> dimensions) {
if (dimensions != null) {
Preconditions.checkArgument(dimensions.size() <= 10, "dimensions can have 10 or fewer members.");
this.dimensions = dimensions;
}
return this;
}
/**
* A dimension to filter the available metrics by. (Can be called multiple times up to a maximum of 10 times.)
*
* @param dimension a dimension to filter the returned metrics by
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if this is invoked more than 10 times
*/
public Builder dimension(Dimension dimension) {
if (dimension != null) {
Preconditions.checkArgument(dimensions.size() < 10, "dimension member maximum count of 10 exceeded.");
this.dimensions.add(dimension);
}
return this;
}
/**
* The token returned by a previous call to indicate that there is more data available.
*
* @param nextToken the next token indicating that there is more data available
*
* @return this {@code Builder} object
*/
public Builder nextToken(String nextToken) {
this.nextToken = nextToken;
return this;
}
/**
* Returns a newly-created {@code ListMetricsOptions} based on the contents of
* the {@code Builder}.
*/
public ListMetricsOptions build() {
ListMetricsOptions lmo = new ListMetricsOptions(namespace, metricName, dimensions, nextToken);
int dimensionIndex = 1;
if (namespace != null) {
lmo.formParameters.put("Namespace", namespace);
}
if (metricName != null) {
lmo.formParameters.put("MetricName", metricName);
}
for (Dimension dimension : dimensions) {
lmo.formParameters.put("Dimensions.member." + dimensionIndex + ".Name", dimension.getName());
lmo.formParameters.put("Dimensions.member." + dimensionIndex + ".Value", dimension.getValue());
dimensionIndex++;
}
if (nextToken != null) {
lmo.formParameters.put("NextToken", nextToken);
}
return lmo;
}
}
}

View File

@ -0,0 +1,72 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.xml;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils;
import org.xml.sax.SAXException;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_Dimension.html" />
*
* @author Jeremy Whitlock
*/
public class DimensionHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Dimension> {
private StringBuilder currentText = new StringBuilder();
private String name;
private String value;
/**
* {@inheritDoc}
*/
@Override
public Dimension getResult() {
Dimension dimension = new Dimension(name, value);
// Reset since this handler is created once but produces N results
name = null;
value = null;
return dimension;
}
/**
* {@inheritDoc}
*/
@Override
public void endElement(String uri, String name, String qName) throws SAXException {
if (qName.equals("Name")) {
this.name = SaxUtils.currentOrNull(currentText);
} else if (qName.equals("Value")) {
value = SaxUtils.currentOrNull(currentText);
}
currentText = new StringBuilder();
}
/**
* {@inheritDoc}
*/
@Override
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,90 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.xml;
import com.google.common.collect.Sets;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import javax.inject.Inject;
import java.util.Set;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html" />
*
* @author Jeremy Whitlock
*/
public class GetMetricStatisticsResponseHandlerV2 extends ParseSax.HandlerWithResult<GetMetricStatisticsResponse> {
private StringBuilder currentText = new StringBuilder();
private Set<Datapoint> datapoints = Sets.newLinkedHashSet();
private String label;
private final DatapointHandler datapointHandler;
private boolean inDatapoints;
@Inject
public GetMetricStatisticsResponseHandlerV2(DatapointHandler DatapointHandler) {
this.datapointHandler = DatapointHandler;
}
public GetMetricStatisticsResponse getResult() {
return new GetMetricStatisticsResponse(datapoints, label);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("Datapoints")) {
inDatapoints = true;
}
if (inDatapoints) {
datapointHandler.startElement(uri, localName, qName, attributes);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (inDatapoints) {
if (qName.equals("Datapoints")) {
inDatapoints = false;
} else {
datapointHandler.endElement(uri, localName, qName);
if (qName.equals("member")) {
this.datapoints.add(datapointHandler.getResult());
}
}
} else if (qName.equals("Label")) {
label = SaxUtils.currentOrNull(currentText);
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
if (inDatapoints) {
datapointHandler.characters(ch, start, length);
} else {
currentText.append(ch, start, length);
}
}
}

View File

@ -0,0 +1,104 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.xml;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import java.util.Set;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html" />
*
* @author Jeremy Whitlock
*/
public class ListMetricsResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<ListMetricsResponse> {
private final MetricHandler metricHandler;
private StringBuilder currentText = new StringBuilder();
private Set<Metric> metrics = Sets.newLinkedHashSet();
private boolean inMetrics;
private String nextToken;
@Inject
public ListMetricsResponseHandler(MetricHandler metricHandler) {
this.metricHandler = metricHandler;
}
/**
* {@inheritDoc}
*/
@Override
public ListMetricsResponse getResult() {
return new ListMetricsResponse(metrics, nextToken);
}
/**
* {@inheritDoc}
*/
@Override
public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException {
if (SaxUtils.equalsOrSuffix(qName, "Metrics")) {
inMetrics = true;
}
if (inMetrics) {
metricHandler.startElement(url, name, qName, attributes);
}
}
/**
* {@inheritDoc}
*/
@Override
public void endElement(String uri, String name, String qName) throws SAXException {
if (inMetrics) {
if (qName.equals("Metrics")) {
inMetrics = false;
} else if (qName.equals("member") && !metricHandler.inDimensions()) {
metrics.add(metricHandler.getResult());
} else {
metricHandler.endElement(uri, name, qName);
}
} else if (qName.equals("NextToken")) {
nextToken = SaxUtils.currentOrNull(currentText);
}
currentText = new StringBuilder();
}
/**
* {@inheritDoc}
*/
@Override
public void characters(char ch[], int start, int length) {
if (inMetrics) {
metricHandler.characters(ch, start, length);
} else {
currentText.append(ch, start, length);
}
}
}

View File

@ -0,0 +1,118 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.xml;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import java.util.Set;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_Metric.html" />
*
* @author Jeremy Whitlock
*/
public class MetricHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Metric> {
private final DimensionHandler dimensionHandler;
private StringBuilder currentText = new StringBuilder();
private Set<Dimension> dimensions = Sets.newLinkedHashSet();
private boolean inDimensions;
private String metricName;
private String namespace;
@Inject
public MetricHandler(DimensionHandler dimensionHandler) {
this.dimensionHandler = dimensionHandler;
}
public boolean inDimensions() {
return inDimensions;
}
/**
* {@inheritDoc}
*/
@Override
public Metric getResult() {
Metric metric = new Metric(metricName, namespace, dimensions);
// Reset since this handler is created once but produces N results
dimensions = Sets.newLinkedHashSet();
metricName = null;
namespace = null;
return metric;
}
/**
* {@inheritDoc}
*/
@Override
public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException {
if (!inDimensions && SaxUtils.equalsOrSuffix(qName, "member")) {
inDimensions = true;
}
if (inDimensions) {
dimensionHandler.startElement(url, name, qName, attributes);
}
}
/**
* {@inheritDoc}
*/
@Override
public void endElement(String uri, String name, String qName) throws SAXException {
if (inDimensions) {
if (qName.equals("Dimensions")) {
inDimensions = false;
} else if (qName.equals("member")) {
dimensions.add(dimensionHandler.getResult());
} else {
dimensionHandler.endElement(uri, name, qName);
}
} else if (qName.equals("MetricName")) {
metricName = SaxUtils.currentOrNull(currentText);
} else if (qName.equals("Namespace")) {
namespace = SaxUtils.currentOrNull(currentText);
}
currentText = new StringBuilder();
}
/**
* {@inheritDoc}
*/
@Override
public void characters(char ch[], int start, int length) {
if (inDimensions) {
dimensionHandler.characters(ch, start, length);
} else {
currentText.append(ch, start, length);
}
}
}

View File

@ -61,6 +61,7 @@ import com.google.inject.TypeLiteral;
// NOTE:without testName, this will not call @Before* and fail w/NPE during
// surefire
@Test(groups = "unit", testName = "CloudWatchAsyncClientTest")
@Deprecated
public class CloudWatchAsyncClientTest extends BaseAsyncClientTest<CloudWatchAsyncClient> {
public void testRegisterInstancesWithMeasure() throws SecurityException, NoSuchMethodException, IOException {
@ -90,7 +91,7 @@ public class CloudWatchAsyncClientTest extends BaseAsyncClientTest<CloudWatchAsy
};
}
@ConfiguresRestClient
@ConfiguresRestClient
private static final class TestMonitoringRestClientModule extends CloudWatchRestClientModule {
@Override

View File

@ -40,7 +40,8 @@ import com.google.common.reflect.TypeToken;
*
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true)
@Test(groups = "live", testName ="CloudWatchClientLiveTest", singleThreaded = true)
@Deprecated
public class CloudWatchClientLiveTest extends BaseContextLiveTest<RestContext<CloudWatchClient, CloudWatchAsyncClient>> {
public CloudWatchClientLiveTest() {
provider = "cloudwatch";
@ -55,10 +56,6 @@ public class CloudWatchClientLiveTest extends BaseContextLiveTest<RestContext<Cl
client = context.getApi();
}
@Test
protected void testGetMetricStatisticsInRegion() {
getEC2MetricStatisticsInRegion(null);
}
protected Set<Datapoint> getEC2MetricStatisticsInRegion(String region) {
Calendar cal = Calendar.getInstance();
@ -74,4 +71,5 @@ public class CloudWatchClientLiveTest extends BaseContextLiveTest<RestContext<Cl
protected TypeToken<RestContext<CloudWatchClient, CloudWatchAsyncClient>> contextType() {
return CloudWatchApiMetadata.CONTEXT_TOKEN;
}
}

View File

@ -0,0 +1,61 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch;
import com.google.common.reflect.TypeToken;
import org.jclouds.apis.BaseContextLiveTest;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.rest.RestContext;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Tests behavior of {@code CloudWatch}.
*
* @author Jeremy Whitlock
*/
public class CloudWatchLiveTest extends BaseContextLiveTest<RestContext<CloudWatchClient, CloudWatchAsyncClient>> {
public CloudWatchLiveTest() {
provider = "cloudwatch";
}
private CloudWatchClient client;
@Override
@BeforeClass(groups = { "integration", "live" })
public void setupContext() {
super.setupContext();
client = context.getApi();
}
@Override
protected TypeToken<RestContext<CloudWatchClient, CloudWatchAsyncClient>> contextType() {
return CloudWatchApiMetadata.CONTEXT_TOKEN;
}
@Test
protected void testCloudWatchListMetrics() {
// Just make sure there is at least one metric returned (Much better if the account you use has more than 500)
checkArgument(CloudWatch.listMetrics(client, null, ListMetricsOptions.builder().build()).iterator().hasNext());
}
}

View File

@ -0,0 +1,100 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import org.easymock.EasyMock;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
* Tests behavior of {@code CloudWatch}.
*
* @author Jeremy Whitlock
*/
public class CloudWatchTest {
/**
* Tests {@link CloudWatch#listMetrics(CloudWatchClient, String, org.jclouds.cloudwatch.options.ListMetricsOptions)}
* where a single response returns all results.
*
* @throws Exception if anything goes wrong
*/
@Test
public void testSinglePageResult() throws Exception {
CloudWatchClient client = createMock(CloudWatchClient.class);
MetricClient metricClient = createMock(MetricClient.class);
ListMetricsOptions options = ListMetricsOptions.builder().build();
ListMetricsResponse response = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), null);
expect(client.getMetricClientForRegion(null))
.andReturn(metricClient)
.atLeastOnce();
expect(metricClient.listMetrics(options))
.andReturn(response)
.once();
EasyMock.replay(client, metricClient);
Assert.assertEquals(1, Iterables.size(CloudWatch.listMetrics(client, null, options)));
}
/**
* Tests {@link CloudWatch#listMetrics(CloudWatchClient, String, org.jclouds.cloudwatch.options.ListMetricsOptions)}
* where retrieving all results requires multiple requests.
*
* @throws Exception if anything goes wrong
*/
@Test
public void testMultiPageResult() throws Exception {
CloudWatchClient client = createMock(CloudWatchClient.class);
MetricClient metricClient = createMock(MetricClient.class);
ListMetricsOptions options = ListMetricsOptions.builder().build();
ListMetricsResponse response1 = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), "NEXTTOKEN");
ListMetricsResponse response2 = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), null);
// Using EasyMock.eq("") because EasyMock makes it impossible to pass null as a String value here
expect(client.getMetricClientForRegion(EasyMock.eq("")))
.andReturn(metricClient)
.atLeastOnce();
expect(metricClient.listMetrics(anyObject(ListMetricsOptions.class)))
.andReturn(response1)
.once();
expect(metricClient.listMetrics(anyObject(ListMetricsOptions.class)))
.andReturn(response2)
.once();
EasyMock.replay(client, metricClient);
Assert.assertEquals(2, Iterables.size(CloudWatch.listMetrics(client, "", options)));
}
}

View File

@ -0,0 +1,236 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unles 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 expres or implied. See the License for the
* specific language governing permisions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.features;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.Date;
import org.jclouds.cloudwatch.CloudWatchClient;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.EC2Constants;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.Namespaces;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.internal.BaseCloudWatchClientExpectTest;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
/**
* @author Jeremy Whitlock, Adrian Cole
*/
@Test(groups = "unit", testName = "MetricClientExpectTest")
public class MetricClientExpectTest extends BaseCloudWatchClientExpectTest {
HttpRequest listMetrics = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://monitoring.us-east-1.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "monitoring.us-east-1.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
new StringBuilder()
.append("Action=ListMetrics").append('&')
.append("Signature=KSh9oQydCR0HMAV6QPYwDzqwQIpxs8I%2Fig7brYgHVZU%3D").append('&')
.append("SignatureMethod=HmacSHA256").append('&')
.append("SignatureVersion=2").append('&')
.append("Timestamp=2009-11-08T15%3A54%3A08.897Z").append('&')
.append("Version=2010-08-01").append('&')
.append("AWSAccessKeyId=identity").toString(), "application/x-www-form-urlencoded"))
.build();
public void testListMetricsWhenResponseIs2xx() throws Exception {
HttpResponse listMetricsResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_metrics.xml", "text/xml")).build();
CloudWatchClient clientWhenMetricsExist = requestSendsResponse(
listMetrics, listMetricsResponse);
assertEquals(clientWhenMetricsExist.getMetricClientForRegion(null).listMetrics().toString(),
"ListMetricsResponse{metrics=[Metric{namespace=AWS/EC2, metricName=CPUUtilization, dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}], nextToken=null}");
}
// TODO: this should really be an empty set
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testListMetricsWhenResponseIs404() throws Exception {
HttpResponse listMetricsResponse = HttpResponse.builder().statusCode(404).build();
CloudWatchClient clientWhenMetricsDontExist = requestSendsResponse(
listMetrics, listMetricsResponse);
clientWhenMetricsDontExist.getMetricClientForRegion(null).listMetrics();
}
public void testListMetricsWithOptionsWhenResponseIs2xx() throws Exception {
HttpRequest listMetricsWithOptions = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://monitoring.us-east-1.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "monitoring.us-east-1.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
new StringBuilder()
.append("Action=ListMetrics").append('&')
.append("Dimensions.member.1.Name=InstanceId").append('&')
.append("Dimensions.member.1.Value=SOMEINSTANCEID").append('&')
.append("MetricName=CPUUtilization").append('&')
.append("Namespace=SOMENEXTTOKEN").append('&')
.append("NextToken=AWS%2FEC2").append('&')
.append("Signature=G05HKEx9FJpGZBk02OVYwt3u4g%2FilAY9nU5hJI9LDXA%3D").append('&')
.append("SignatureMethod=HmacSHA256").append('&')
.append("SignatureVersion=2").append('&')
.append("Timestamp=2009-11-08T15%3A54%3A08.897Z").append('&')
.append("Version=2010-08-01").append('&')
.append("AWSAccessKeyId=identity").toString(), "application/x-www-form-urlencoded"))
.build();
HttpResponse listMetricsWithOptionsResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_metrics.xml", "text/xml")).build();
CloudWatchClient clientWhenMetricsWithOptionsExist = requestSendsResponse(listMetricsWithOptions,
listMetricsWithOptionsResponse);
assertEquals(
clientWhenMetricsWithOptionsExist.getMetricClientForRegion(null).listMetrics(
ListMetricsOptions.builder()
.dimension(new Dimension(EC2Constants.Dimension.INSTANCE_ID, "SOMEINSTANCEID"))
.metricName(EC2Constants.MetricName.CPU_UTILIZATION)
.namespace("SOMENEXTTOKEN")
.nextToken( Namespaces.EC2)
.build()).toString(),
"ListMetricsResponse{metrics=[Metric{namespace=AWS/EC2, metricName=CPUUtilization, dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}], nextToken=null}");
}
GetMetricStatistics stats = GetMetricStatistics.builder()
.endTime(new Date(10000000l))
.metricName(EC2Constants.MetricName.CPU_UTILIZATION)
.namespace(Namespaces.EC2)
.period(60)
.startTime(new Date(10000000l))
.statistic(Statistics.MAXIMUM)
.statistic(Statistics.MINIMUM)
.unit(Unit.PERCENT).build();
HttpRequest getMetricStatistics = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://monitoring.us-east-1.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "monitoring.us-east-1.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
new StringBuilder()
.append("Action=GetMetricStatistics").append('&')
.append("EndTime=1970-01-01T02%3A46%3A40Z").append('&')
.append("MetricName=CPUUtilization").append('&')
.append("Namespace=AWS%2FEC2").append('&')
.append("Period=60").append('&')
.append("Signature=rmg8%2Ba7w4ycy%2FKfO8rnuj6rDL0jNE96m8GKfjh3SWcw%3D").append('&')
.append("SignatureMethod=HmacSHA256").append('&')
.append("SignatureVersion=2").append('&')
.append("StartTime=1970-01-01T02%3A46%3A40Z").append('&')
.append("Statistics.member.1=Maximum").append('&')
.append("Statistics.member.2=Minimum").append('&')
.append("Timestamp=2009-11-08T15%3A54%3A08.897Z").append('&')
.append("Unit=Percent").append('&').append("Version=2010-08-01").append('&')
.append("AWSAccessKeyId=identity").toString(), "application/x-www-form-urlencoded"))
.build();
public void testGetMetricStatisticsWhenResponseIs2xx() throws Exception {
HttpResponse getMetricStatisticsResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/get_metric_statistics.xml", "text/xml")).build();
CloudWatchClient clientWhenMetricsExist = requestSendsResponse(getMetricStatistics, getMetricStatisticsResponse);
assertEquals(
clientWhenMetricsExist.getMetricClientForRegion(null).getMetricStatistics(stats).toString(),
// TODO: make an object for this
"GetMetricStatisticsResponse{label=CPUUtilization, datapoints=[Datapoint{timestamp=Thu Jan 15 16:00:00 PST 2009, customUnit=null, maximum=null, minimum=null, average=0.17777777777777778, sum=null, samples=9.0, unit=Percent}, Datapoint{timestamp=Thu Jan 15 16:01:00 PST 2009, customUnit=null, maximum=null, minimum=null, average=0.1, sum=null, samples=8.0, unit=Percent}]}");
}
// TODO: this should really be an empty set
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testGetMetricStatisticsWhenResponseIs404() throws Exception {
HttpResponse getMetricStatisticsResponse = HttpResponse.builder().statusCode(404).build();
CloudWatchClient clientWhenMetricsDontExist = requestSendsResponse(getMetricStatistics, getMetricStatisticsResponse);
clientWhenMetricsDontExist.getMetricClientForRegion(null).getMetricStatistics(stats);
}
public void testGetMetricStatisticsWithOptionsWhenResponseIs2xx() throws Exception {
HttpRequest getMetricStatistics = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://monitoring.us-east-1.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "monitoring.us-east-1.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
new StringBuilder()
.append("Action=GetMetricStatistics").append('&')
.append("Dimensions.member.1.Name=InstanceId").append('&')
.append("Dimensions.member.1.Value=SOMEINSTANCEID").append('&')
.append("Dimensions.member.2.Name=InstanceType").append('&')
.append("Dimensions.member.2.Value=t1.micro").append('&')
.append("EndTime=1970-01-01T02%3A46%3A40Z").append('&')
.append("MetricName=CPUUtilization").append('&')
.append("Namespace=AWS%2FEC2").append('&')
.append("Period=60").append('&')
.append("Signature=e0WyI%2FNm4hN2%2BMEm1mjRUzsvgvMCdFXbVJWi4ORpwic%3D").append('&')
.append("SignatureMethod=HmacSHA256").append('&')
.append("SignatureVersion=2").append('&')
.append("StartTime=1970-01-01T02%3A46%3A40Z").append('&')
.append("Statistics.member.1=Maximum").append('&')
.append("Statistics.member.2=Minimum").append('&')
.append("Timestamp=2009-11-08T15%3A54%3A08.897Z").append('&')
.append("Unit=Percent").append('&')
.append("Version=2010-08-01").append('&')
.append("AWSAccessKeyId=identity").toString(), "application/x-www-form-urlencoded"))
.build();
HttpResponse getMetricStatisticsResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/get_metric_statistics.xml", "text/xml")).build();
CloudWatchClient clientWhenMetricsExist = requestSendsResponse(getMetricStatistics, getMetricStatisticsResponse);
Dimension dimension1 = new Dimension(EC2Constants.Dimension.INSTANCE_ID, "SOMEINSTANCEID");
Dimension dimension2 = new Dimension(EC2Constants.Dimension.INSTANCE_TYPE, "t1.micro");
assertEquals(
clientWhenMetricsExist.getMetricClientForRegion(null).getMetricStatistics(stats,
GetMetricStatisticsOptions.Builder.dimension(dimension1).dimension(dimension2)).toString(),
// TODO: make an object for this
"GetMetricStatisticsResponse{label=CPUUtilization, datapoints=[Datapoint{timestamp=Thu Jan 15 16:00:00 PST 2009, customUnit=null, maximum=null, minimum=null, average=0.17777777777777778, sum=null, samples=9.0, unit=Percent}, Datapoint{timestamp=Thu Jan 15 16:01:00 PST 2009, customUnit=null, maximum=null, minimum=null, average=0.1, sum=null, samples=8.0, unit=Percent}]}");
}
}

View File

@ -0,0 +1,214 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.features;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Calendar;
import java.util.Date;
import java.util.Set;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.EC2Constants;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.Namespaces;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.internal.BaseCloudWatchClientLiveTest;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* @author Jeremy Whitlock, Adrian Cole
*/
@Test(groups = "live", testName = "MetricClientLiveTest")
public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
// TODO: change this test to retrieve pre-seeded custom metrics
@Test
protected void testGetMetricStatistics() {
ListMetricsResponse metricsResponse = client().listMetrics();
// Walk through all datapoints in all metrics until we find a metric datapoint that returns statistics
if (metricsResponse.size() > 0) {
for (Metric metric : metricsResponse) {
Set<Dimension> dimensions = metric.getDimensions();
boolean testRan = false;
for (Dimension dimension : dimensions) {
Date endTime = new Date();
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -60 * 24); // 24 hours
GetMetricStatistics options =
GetMetricStatistics.builder()
.dimension(dimension)
.endTime(endTime)
.metricName(metric.getMetricName())
.namespace(metric.getNamespace())
.period(300)
.startTime(cal.getTime())
.statistics(ImmutableSet.of(Statistics.MAXIMUM,
Statistics.MINIMUM))
.unit(Unit.PERCENT).build();
GetMetricStatisticsResponse response = client().getMetricStatistics(options);
if (response.size() > 0) {
checkNotNull(response.getLabel());
for (Datapoint datapoint : response) {
checkArgument(datapoint.getAverage() == null);
checkNotNull(datapoint.getMaximum());
checkNotNull(datapoint.getMinimum());
}
testRan = true;
break;
}
}
if (testRan) {
break;
}
}
}
}
@Test
protected void testListMetrics() {
ListMetricsResponse response;
String testNamespace = Namespaces.EC2;
String testMetricName = EC2Constants.MetricName.CPU_UTILIZATION;
String testDimensionName = EC2Constants.Dimension.INSTANCE_TYPE;
String testDimensionValue = "t1.micro";
// Test an empty request (pulls all stored metric options across all products)
response = client().listMetrics();
performDefaultMetricsTests(response);
if (response.size() > 0) {
Metric metric = response.iterator().next();
testMetricName = metric.getMetricName();
testNamespace = metric.getNamespace();
if (metric.getDimensions().size() > 0) {
Dimension dimension = metric.getDimensions().iterator().next();
testDimensionName = dimension.getName();
testDimensionValue = dimension.getValue();
}
if (testDimensionName == null) {
for (Metric metric1 : response) {
Set<Dimension> dimensions = metric1.getDimensions();
if (dimensions.size() > 0) {
Dimension dimension = metric.getDimensions().iterator().next();
testDimensionName = dimension.getName();
testDimensionValue = dimension.getValue();
break;
}
}
}
}
// Test with a NextToken, even if it's null
response = client().listMetrics(ListMetricsOptions.builder().nextToken(response.getNextToken()).build());
performDefaultMetricsTests(response);
// Test with a Namespace
response = client().listMetrics(ListMetricsOptions.builder().namespace(testNamespace).build());
performDefaultMetricsTests(response);
for (Metric metric : response) {
checkArgument(metric.getNamespace().equals(testNamespace),
"All metrics should have the " + testNamespace + " Namespace.");
}
// Test with a MetricName
response = client().listMetrics(ListMetricsOptions.builder().metricName(testMetricName).build());
performDefaultMetricsTests(response);
for (Metric metric : response) {
checkArgument(metric.getMetricName().equals(testMetricName),
"All metrics should have the " + testMetricName + " MetricName.");
}
// Test with a Dimension
if (testDimensionName != null) {
Dimension testDimension = new Dimension(testDimensionName, testDimensionValue);
response = client().listMetrics(ListMetricsOptions.builder().dimension(testDimension).build());
performDefaultMetricsTests(response);
for (Metric metric : response) {
Set<Dimension> dimensions = metric.getDimensions();
checkArgument(dimensions.size() == 1, "There should only be one Dimension.");
Dimension dimension = dimensions.iterator().next();
checkArgument(dimension.equals(testDimension),
"The retrieved Dimension and test Dimension should be equal.");
}
}
}
private void performDefaultMetricsTests(ListMetricsResponse response) {
// If there are less than 500 metrics, NextToken should be null
if (response.size() < 500) {
checkArgument(response.getNextToken() == null,
"NextToken should be null for response with fewer than 500 metrics.");
}
for (Metric metric : response) {
Set<Dimension> dimensions = metric.getDimensions();
checkArgument(dimensions.size() <= 10, "Dimensions set cannot be greater than 10 items.");
for (Dimension dimension : dimensions) {
checkNotNull(dimension.getName(), "Name cannot be null for a Dimension.");
checkNotNull(dimension.getValue(), "Value cannot be null for a Dimension.");
}
checkNotNull(metric.getMetricName(), "MetricName cannot be null for a Metric.");
checkNotNull(metric.getNamespace(), "Namespace cannot be null for a Metric.");
}
}
protected MetricClient client() {
return context.getApi().getMetricClientForRegion(null);
}
}

View File

@ -0,0 +1,38 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.internal;
import java.util.Properties;
import org.jclouds.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import com.google.common.base.Function;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class BaseCloudWatchAsyncClientExpectTest extends BaseCloudWatchExpectTest<CloudWatchAsyncClient> {
public CloudWatchAsyncClient createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
return createInjector(fn, module, props).getInstance(CloudWatchAsyncClient.class);
}
}

View File

@ -0,0 +1,29 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.internal;
import org.jclouds.cloudwatch.CloudWatchClient;
/**
*
* @author Adrian Cole
*/
public class BaseCloudWatchClientExpectTest extends BaseCloudWatchExpectTest<CloudWatchClient> {
}

View File

@ -0,0 +1,46 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.internal;
import org.jclouds.apis.BaseContextLiveTest;
import org.jclouds.cloudwatch.CloudWatchApiMetadata;
import org.jclouds.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.cloudwatch.CloudWatchClient;
import org.jclouds.rest.RestContext;
import org.testng.annotations.Test;
import com.google.common.reflect.TypeToken;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class BaseCloudWatchClientLiveTest extends BaseContextLiveTest<RestContext<CloudWatchClient, CloudWatchAsyncClient>> {
public BaseCloudWatchClientLiveTest() {
provider = "cloudwatch";
}
@Override
protected TypeToken<RestContext<CloudWatchClient, CloudWatchAsyncClient>> contextType() {
return CloudWatchApiMetadata.CONTEXT_TOKEN;
}
}

View File

@ -0,0 +1,82 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.internal;
import static com.google.common.collect.Maps.transformValues;
import java.net.URI;
import java.util.Map;
import javax.inject.Named;
import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.cloudwatch.config.CloudWatchRestClientModule;
import org.jclouds.date.DateService;
import org.jclouds.location.config.LocationModule;
import org.jclouds.location.suppliers.RegionIdToURISupplier;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.internal.BaseRestClientExpectTest;
import org.jclouds.util.Suppliers2;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class BaseCloudWatchExpectTest<T> extends BaseRestClientExpectTest<T> {
public BaseCloudWatchExpectTest() {
provider = "cloudwatch";
}
@ConfiguresRestClient
private static final class TestMonitoringRestClientModule extends CloudWatchRestClientModule {
@Override
protected void installLocations() {
install(new LocationModule());
bind(RegionIdToURISupplier.class).toInstance(new RegionIdToURISupplier() {
@Override
public Map<String, Supplier<URI>> get() {
return transformValues(ImmutableMap.<String, URI> of(Region.EU_WEST_1, URI
.create("https://ec2.eu-west-1.amazonaws.com"), Region.US_EAST_1, URI
.create("https://ec2.us-east-1.amazonaws.com"), Region.US_WEST_1, URI
.create("https://ec2.us-west-1.amazonaws.com")), Suppliers2.<URI> ofInstanceFunction());
}
});
}
@Override
protected String provideTimeStamp(final DateService dateService,
@Named(Constants.PROPERTY_SESSION_INTERVAL) int expiration) {
return "2009-11-08T15:54:08.897Z";
}
}
@Override
protected Module createModule() {
return new TestMonitoringRestClientModule();
}
}

View File

@ -26,6 +26,7 @@ import java.util.Set;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
@ -40,13 +41,9 @@ import com.google.common.collect.ImmutableSet;
@Test(groups = "unit", testName = "GetMetricStatisticsResponseHandlerTest")
public class GetMetricStatisticsResponseHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/get_metric_statistics.xml");
Set<Datapoint> expected = ImmutableSet.of(new Datapoint(0.17777777777777778, null, null, dateService
.iso8601SecondsDateParse("2009-01-16T00:00:00Z"), 9.0, null, Unit.PERCENT, null), new Datapoint(
0.1, null, null, dateService.iso8601SecondsDateParse("2009-01-16T00:01:00Z"), 8.0, null,
Unit.PERCENT, null));
Set<Datapoint> expected = expected();
GetMetricStatisticsResponseHandler handler = injector.getInstance(GetMetricStatisticsResponseHandler.class);
Set<Datapoint> result = factory.create(handler).parse(is);
@ -54,4 +51,14 @@ public class GetMetricStatisticsResponseHandlerTest extends BaseHandlerTest {
assertEquals(result, expected);
}
DateService dateService = new SimpleDateFormatDateService();
public Set<Datapoint> expected() {
Set<Datapoint> expected = ImmutableSet.of(new Datapoint(0.17777777777777778, null, null, dateService
.iso8601SecondsDateParse("2009-01-16T00:00:00Z"), 9.0, null, Unit.PERCENT, null), new Datapoint(0.1,
null, null, dateService.iso8601SecondsDateParse("2009-01-16T00:01:00Z"), 8.0, null, Unit.PERCENT, null));
return expected;
}
}

View File

@ -0,0 +1,16 @@
<ListMetricsResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
<ListMetricsResult>
<Metrics>
<member>
<Dimensions>
<member>
<Name>InstanceId</Name>
<Value>i-689fcf0f</Value>
</member>
</Dimensions>
<MetricName>CPUUtilization</MetricName>
<Namespace>AWS/EC2</Namespace>
</member>
</Metrics>
</ListMetricsResult>
</ListMetricsResponse>

View File

@ -32,7 +32,6 @@ import org.jclouds.deltacloud.domain.TransitionOnAction;
import org.jclouds.deltacloud.options.CreateInstanceOptions;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.http.HttpRequest;
import org.jclouds.net.IPSocket;
import org.jclouds.ssh.SshClient;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.AfterClass;
@ -40,6 +39,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
import com.google.gson.Gson;
import com.google.inject.Guice;
@ -95,7 +95,7 @@ public class DeltacloudClientLiveTest extends ReadOnlyDeltacloudClientLiveTest {
@Test(dependsOnMethods = "testCreateInstance")
public void testConnectivity() throws Exception {
Logger.getAnonymousLogger().info("awaiting ssh");
assert socketTester.apply(new IPSocket(Iterables.get(instance.getPublicAddresses(), 0), 22)) : instance;
assert socketTester.apply(HostAndPort.fromParts(Iterables.get(instance.getPublicAddresses(), 0), 22)) : instance;
if (creds != null) {
Logger.getAnonymousLogger().info("will connect ssh");
doConnectViaSsh(instance, creds);
@ -136,7 +136,7 @@ public class DeltacloudClientLiveTest extends ReadOnlyDeltacloudClientLiveTest {
protected void doConnectViaSsh(Instance instance, LoginCredentials creds) throws IOException {
SshClient ssh = Guice.createInjector(new SshjSshClientModule()).getInstance(SshClient.Factory.class).create(
new IPSocket(Iterables.get(instance.getPublicAddresses(), 0), 22), creds);
HostAndPort.fromParts(Iterables.get(instance.getPublicAddresses(), 0), 22), creds);
try {
ssh.connect();
ExecResponse hello = ssh.exec("echo hello");

View File

@ -30,12 +30,11 @@ import org.jclouds.deltacloud.domain.DeltacloudCollection;
import org.jclouds.deltacloud.domain.HardwareProfile;
import org.jclouds.deltacloud.domain.Image;
import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.Transition;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.deltacloud.predicates.InstanceFinished;
import org.jclouds.deltacloud.predicates.InstanceRunning;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.sshj.config.SshjSshClientModule;
@ -48,6 +47,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.net.HostAndPort;
import com.google.inject.Module;
/**
@ -64,7 +64,7 @@ public class ReadOnlyDeltacloudClientLiveTest extends BaseComputeServiceContextL
protected DeltacloudClient client;
protected Predicate<IPSocket> socketTester;
protected Predicate<HostAndPort> socketTester;
protected ImmutableMap<State, Predicate<Instance>> stateChanges;
@Override
@ -72,7 +72,7 @@ public class ReadOnlyDeltacloudClientLiveTest extends BaseComputeServiceContextL
public void setupContext() {
super.setupContext();
client = view.unwrap(DeltacloudApiMetadata.CONTEXT_TOKEN).getApi();
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<HostAndPort>(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS);
stateChanges = ImmutableMap.<Instance.State, Predicate<Instance>> of(//
Instance.State.RUNNING, new RetryablePredicate<Instance>(new InstanceRunning(client), 600, 1,
TimeUnit.SECONDS),//

View File

@ -37,6 +37,7 @@ import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.IpProtocol;
@ -44,12 +45,10 @@ import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.predicates.InstanceHasIpAddress;
import org.jclouds.ec2.predicates.InstanceStateRunning;
import org.jclouds.http.HttpResponseException;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.scriptbuilder.ScriptBuilder;
@ -63,6 +62,7 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.net.HostAndPort;
import com.google.inject.Injector;
/**
@ -88,7 +88,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest extends BaseComputeS
private String instanceId;
private String address;
private RetryablePredicate<IPSocket> socketTester;
private RetryablePredicate<HostAndPort> socketTester;
private RetryablePredicate<RunningInstance> hasIpTester;
private RetryablePredicate<RunningInstance> runningTester;
@ -102,7 +102,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest extends BaseComputeS
TimeUnit.SECONDS);
hasIpTester = new RetryablePredicate<RunningInstance>(new InstanceHasIpAddress(client), 180, 5, TimeUnit.SECONDS);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 180, 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<HostAndPort>(socketOpen, 180, 1, TimeUnit.SECONDS);
}
@Test(enabled = false)
@ -296,7 +296,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest extends BaseComputeS
Thread.sleep(1000);
instance = getInstance(instanceId);
blockUntilWeCanSshIntoInstance(instance);
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(), 22),
SshClient ssh = sshFactory.create(HostAndPort.fromParts(instance.getIpAddress(), 22),
LoginCredentials.builder().user("root").privateKey(keyPair.getKeyMaterial()).build());
try {
ssh.connect();
@ -357,14 +357,14 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest extends BaseComputeS
assert hasIpTester.apply(instance);
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(), instance.getIpAddress());
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 22));
assert socketTester.apply(HostAndPort.fromParts(instance.getIpAddress(), 22));
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance.getDnsName());
sshPing(instance);
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), instance.getId());
System.out.printf("%d: %s awaiting http service to start%n", System.currentTimeMillis(), instance.getIpAddress());
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 80));
assert socketTester.apply(HostAndPort.fromParts(instance.getIpAddress(), 80));
System.out.printf("%d: %s http service started%n", System.currentTimeMillis(), instance.getDnsName());
return instance;
}
@ -401,7 +401,7 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest extends BaseComputeS
}
private void doCheckKey(String address) {
SshClient ssh = sshFactory.create(new IPSocket(address, 22),
SshClient ssh = sshFactory.create(HostAndPort.fromParts(address, 22),
LoginCredentials.builder().user("root").privateKey(keyPair.getKeyMaterial()).build());
try {
ssh.connect();

View File

@ -39,6 +39,8 @@ import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.Image;
import org.jclouds.ec2.domain.Image.Architecture;
import org.jclouds.ec2.domain.Image.ImageType;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.IpProtocol;
@ -48,8 +50,6 @@ import org.jclouds.ec2.domain.RootDeviceType;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.Snapshot;
import org.jclouds.ec2.domain.Volume;
import org.jclouds.ec2.domain.Image.Architecture;
import org.jclouds.ec2.domain.Image.ImageType;
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.predicates.InstanceStateRunning;
import org.jclouds.ec2.predicates.InstanceStateStopped;
@ -59,7 +59,6 @@ import org.jclouds.ec2.predicates.VolumeAttached;
import org.jclouds.ec2.predicates.VolumeAvailable;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payloads;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.scriptbuilder.InitScript;
@ -76,6 +75,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.net.HostAndPort;
import com.google.inject.Injector;
/**
@ -107,7 +107,7 @@ public class EBSBootEC2ClientLiveTest extends BaseComputeServiceContextLiveTest
private KeyPair keyPair;
private String securityGroupName;
private RetryablePredicate<IPSocket> socketTester;
private RetryablePredicate<HostAndPort> socketTester;
private RetryablePredicate<Attachment> attachTester;
private RetryablePredicate<Volume> volumeTester;
private RunningInstance instance;
@ -130,7 +130,7 @@ public class EBSBootEC2ClientLiveTest extends BaseComputeServiceContextLiveTest
client = injector.getInstance(EC2Client.class);
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<HostAndPort>(socketOpen, 120, 1, TimeUnit.SECONDS);
VolumeAvailable volumeAvailable = injector.getInstance(VolumeAvailable.class);
volumeTester = new RetryablePredicate<Volume>(volumeAvailable, 60, 1, TimeUnit.SECONDS);
@ -273,7 +273,7 @@ public class EBSBootEC2ClientLiveTest extends BaseComputeServiceContextLiveTest
@Test(enabled = false, dependsOnMethods = "testCreateAndAttachVolume")
void testBundleInstance() {
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(), 22),
SshClient ssh = sshFactory.create(HostAndPort.fromParts(instance.getIpAddress(), 22),
LoginCredentials.builder().user("ubuntu").privateKey(keyPair.getKeyMaterial()).build());
try {
ssh.connect();
@ -510,7 +510,7 @@ public class EBSBootEC2ClientLiveTest extends BaseComputeServiceContextLiveTest
}
private void doCheckKey(String address) {
SshClient ssh = sshFactory.create(new IPSocket(address, 22),
SshClient ssh = sshFactory.create(HostAndPort.fromParts(address, 22),
LoginCredentials.builder().user("ubuntu").privateKey(keyPair.getKeyMaterial()).build());
try {
ssh.connect();
@ -538,7 +538,7 @@ public class EBSBootEC2ClientLiveTest extends BaseComputeServiceContextLiveTest
instance = Iterables.getOnlyElement(Iterables.getOnlyElement(reservations));
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(), instance.getIpAddress());
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 22));
assert socketTester.apply(HostAndPort.fromParts(instance.getIpAddress(), 22));
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance.getDnsName());
sshPing(instance);
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), instance.getId());

View File

@ -54,7 +54,6 @@ import org.jclouds.ec2.services.ElasticBlockStoreClient;
import org.jclouds.ec2.services.InstanceClient;
import org.jclouds.ec2.services.KeyPairClient;
import org.jclouds.ec2.services.SecurityGroupClient;
import org.jclouds.net.IPSocket;
import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.util.InetAddresses2;
@ -65,6 +64,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.net.HostAndPort;
import com.google.inject.Module;
/**
@ -198,7 +198,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
// Check that the address is public and port 22 is accessible
String ip = Iterables.getOnlyElement(publicIps);
assertFalse(InetAddresses2.isPrivateIPAddress(ip));
IPSocket socket = new IPSocket(ip, 22);
HostAndPort socket = HostAndPort.fromParts(ip, 22);
assertTrue(socketTester.apply(socket), String.format("failed to open socket %s on node %s", socket, node));
// check that there is an elastic ip correlating to it

View File

@ -43,7 +43,6 @@ import org.jclouds.elasticstack.domain.ServerStatus;
import org.jclouds.elasticstack.predicates.DriveClaimed;
import org.jclouds.elasticstack.util.Servers;
import org.jclouds.io.Payloads;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
@ -59,6 +58,7 @@ import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.HostAndPort;
import com.google.gson.Gson;
import com.google.inject.Guice;
@ -81,7 +81,7 @@ public class ElasticStackClientLiveTest
protected String vncPassword = "Il0veVNC";
protected ElasticStackClient client;
protected RestContext<ElasticStackClient, ElasticStackAsyncClient> cloudStackContext;
protected Predicate<IPSocket> socketTester;
protected Predicate<HostAndPort> socketTester;
protected Predicate<DriveInfo> driveNotClaimed;
@BeforeGroups(groups = { "integration", "live" })
@ -93,7 +93,7 @@ public class ElasticStackClientLiveTest
client = cloudStackContext.getApi();
driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime,
1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
socketTester = new RetryablePredicate<HostAndPort>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
TimeUnit.SECONDS);
if (Strings.emptyToNull(imageId) == null) {
@ -229,10 +229,10 @@ public class ElasticStackClientLiveTest
@Test(dependsOnMethods = "testCreateAndStartServer")
public void testConnectivity() throws Exception {
IPSocket vncsocket = new IPSocket(server.getVnc().getIp(), 5900);
HostAndPort vncsocket = HostAndPort.fromParts(server.getVnc().getIp(), 5900);
Logger.getAnonymousLogger().info("awaiting vnc: " + vncsocket);
assert socketTester.apply(vncsocket) : server;
IPSocket sshsocket = new IPSocket(server.getNics().get(0).getDhcp(), 22);
HostAndPort sshsocket = HostAndPort.fromParts(server.getNics().get(0).getDhcp(), 22);
Logger.getAnonymousLogger().info("awaiting ssh: " + sshsocket);
assert socketTester.apply(sshsocket) : server;
doConnectViaSsh(server, getSshCredentials(server));
@ -290,7 +290,7 @@ public class ElasticStackClientLiveTest
protected void doConnectViaSsh(Server server, LoginCredentials creds) throws IOException {
SshClient ssh = Guice.createInjector(new SshjSshClientModule()).getInstance(SshClient.Factory.class).create(
new IPSocket(server.getVnc().getIp(), 22), creds);
HostAndPort.fromParts(server.getVnc().getIp(), 22), creds);
try {
ssh.connect();
ExecResponse hello = ssh.exec("echo hello");

View File

@ -36,7 +36,6 @@ import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payload;
import org.jclouds.net.IPSocket;
import org.jclouds.openstack.nova.domain.Flavor;
import org.jclouds.openstack.nova.domain.Image;
import org.jclouds.openstack.nova.domain.ImageStatus;
@ -56,6 +55,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
import com.google.inject.Injector;
/**
@ -72,7 +72,7 @@ public class NovaClientLiveTest extends BaseComputeServiceContextLiveTest {
protected NovaClient client;
protected SshClient.Factory sshFactory;
protected Predicate<IPSocket> socketTester;
protected Predicate<HostAndPort> socketTester;
@BeforeGroups(groups = { "integration", "live" })
@Override
@ -82,7 +82,7 @@ public class NovaClientLiveTest extends BaseComputeServiceContextLiveTest {
client = injector.getInstance(NovaClient.class);
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<HostAndPort>(socketOpen, 120, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger
}
@ -296,7 +296,7 @@ public class NovaClientLiveTest extends BaseComputeServiceContextLiveTest {
}
private void doCheckPass(Server newDetails, String pass) throws IOException {
IPSocket socket = new IPSocket(Iterables.get(newDetails.getAddresses().getPublicAddresses(), 0).getAddress(), 22);
HostAndPort socket = HostAndPort.fromParts(Iterables.get(newDetails.getAddresses().getPublicAddresses(), 0).getAddress(), 22);
socketTester.apply(socket);
SshClient client = sshFactory.create(socket, LoginCredentials.builder().user("root").password(pass).build());

View File

@ -28,7 +28,6 @@ import static org.testng.Assert.assertNotNull;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.net.IPSocket;
import org.jclouds.vcloud.VCloudApiMetadata;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
@ -41,6 +40,7 @@ import org.jclouds.vcloud.internal.BaseVCloudClientLiveTest;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
/**
* This tests that we can use guest customization as an alternative to bootstrapping with ssh. There
@ -157,8 +157,8 @@ public class VmClientLiveTest extends BaseVCloudClientLiveTest {
assertEquals(apiOutput, script.replace("\n", ""));
}
protected IPSocket getSocket(NodeMetadata node) {
return new IPSocket(get(node.getPublicAddresses(), 0), 22);
protected HostAndPort getSocket(NodeMetadata node) {
return HostAndPort.fromParts(get(node.getPublicAddresses(), 0), 22);
}
}

View File

@ -179,11 +179,13 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
final String finalMarker = options.getMarker();
StorageMetadata lastMarkerMetadata = find(contents, new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata metadata) {
return metadata.getName().equals(finalMarker);
return metadata.getName().compareTo(finalMarker) >= 0;
}
});
contents = contents.tailSet(lastMarkerMetadata);
contents.remove(lastMarkerMetadata);
if (finalMarker.equals(lastMarkerMetadata.getName())) {
contents.remove(lastMarkerMetadata);
}
}
final String prefix = options.getDir();

View File

@ -140,8 +140,9 @@ public class ListContainerOptions extends ListOptions implements Cloneable {
*
*/
public ListContainerOptions inDirectory(String dir) {
this.dir = checkNotNull(dir, "dir");
checkNotNull(dir, "dir");
checkArgument(!dir.equals("/"), "dir must not be a slash");
this.dir = dir;
return this;
}

View File

@ -22,6 +22,7 @@ import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursi
import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@ -31,17 +32,18 @@ import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.internal.BlobRuntimeException;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.blobstore.strategy.ClearContainerStrategy;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.blobstore.strategy.ListContainerStrategy;
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
@ -57,7 +59,6 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr
@Named(BlobStoreConstants.BLOBSTORE_LOGGER)
protected Logger logger = Logger.NULL;
protected final ListContainerStrategy listContainer;
protected final BackoffLimitedRetryHandler retryHandler;
private final ExecutorService userExecutor;
@ -71,12 +72,11 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr
@Inject
DeleteAllKeysInList(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
AsyncBlobStore connection, ListContainerStrategy listContainer,
AsyncBlobStore connection,
BackoffLimitedRetryHandler retryHandler) {
this.userExecutor = userExecutor;
this.connection = connection;
this.listContainer = listContainer;
this.retryHandler = retryHandler;
}
@ -84,19 +84,31 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr
execute(containerName, recursive());
}
public void execute(final String containerName, final ListContainerOptions options) {
public void execute(final String containerName, ListContainerOptions options) {
String message = options.getDir() != null ? String.format("clearing path %s/%s",
containerName, options.getDir()) : String.format("clearing container %s",
containerName);
options = options.clone();
if (options.isRecursive())
message = message + " recursively";
Map<StorageMetadata, Exception> exceptions = Maps.newHashMap();
PageSet<? extends StorageMetadata> listing;
Iterable<? extends StorageMetadata> toDelete;
for (int i = 0; i < 3; i++) { // TODO parameterize
toDelete = getResourcesToDelete(containerName, options);
if (Iterables.isEmpty(toDelete)) {
break;
int maxErrors = 3; // TODO parameterize
for (int i = 0; i < maxErrors; ) {
try {
listing = connection.list(containerName, options).get();
} catch (ExecutionException ee) {
++i;
if (i == maxErrors) {
throw new BlobRuntimeException("list error", ee.getCause());
}
retryHandler.imposeBackoffExponentialDelay(i, message);
continue;
} catch (InterruptedException ie) {
throw Throwables.propagate(ie);
}
toDelete = filterListing(listing, options);
Map<StorageMetadata, Future<?>> responses = Maps.newHashMap();
try {
@ -127,24 +139,30 @@ public class DeleteAllKeysInList implements ClearListStrategy, ClearContainerStr
exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, message);
}
if (!exceptions.isEmpty()) {
retryHandler.imposeBackoffExponentialDelay(i + 1, message);
++i;
retryHandler.imposeBackoffExponentialDelay(i, message);
continue;
}
String marker = listing.getNextMarker();
if (marker == null) {
break;
}
options = options.afterMarker(marker);
}
if (!exceptions.isEmpty())
throw new BlobRuntimeException(String.format("error %s: %s", message, exceptions));
toDelete = getResourcesToDelete(containerName, options);
assert Iterables.isEmpty(toDelete) : String.format("items remaining %s: %s", message,
toDelete);
}
private boolean parentIsFolder(final ListContainerOptions options, final StorageMetadata md) {
return (options.getDir() != null && md.getName().indexOf('/') == -1);
}
private Iterable<? extends StorageMetadata> getResourcesToDelete(final String containerName,
private Iterable<? extends StorageMetadata> filterListing(
final PageSet<? extends StorageMetadata> listing,
final ListContainerOptions options) {
Iterable<? extends StorageMetadata> toDelete = Iterables.filter(listContainer.execute(
containerName, options), new Predicate<StorageMetadata>() {
Iterable<? extends StorageMetadata> toDelete = Iterables.filter(listing,
new Predicate<StorageMetadata>() {
@Override
public boolean apply(StorageMetadata input) {

View File

@ -0,0 +1,82 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.blobstore.strategy.internal;
import static org.testng.Assert.assertEquals;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
import com.google.common.io.Closeables;
import com.google.inject.Injector;
/**
*
* @author Adrian Cole
*/
@Test(testName = "ConcatenateContainerListsTest", singleThreaded = true)
public class ConcatenateContainerListsTest {
private BlobStore blobstore;
private ConcatenateContainerLists concatter;
@BeforeClass
void setupBlobStore() {
Injector injector = ContextBuilder.newBuilder("transient").buildInjector();
blobstore = injector.getInstance(BlobStore.class);
concatter = injector.getInstance(ConcatenateContainerLists.class);
}
public void testLargerThanOnePageNoOptions() {
blobstore.createContainerInLocation(null, "goodies");
for (int i = 0; i < 1001; i++) {
blobstore.putBlob("goodies", blobstore.blobBuilder(i + "").payload(i + "").build());
}
Iterable<? extends StorageMetadata> listing = concatter.execute("goodies", new ListContainerOptions());
assertEquals(Iterables.size(listing), 1001);
}
public void testLargerThanOnePageInDirAndRecursive() {
blobstore.createContainerInLocation(null, "foo");
for (int i = 0; i < 1001; i++) {
blobstore.putBlob("foo", blobstore.blobBuilder(i + "").payload(i + "").build());
}
for (int i = 0; i < 1001; i++) {
blobstore.putBlob("foo", blobstore.blobBuilder("dir/" + i + "").payload(i + "").build());
}
Iterable<? extends StorageMetadata> listing = concatter.execute("foo", new ListContainerOptions());
// TODO: this looks broke. seems we should have 1002 (1001 + directory foo), not 1003
assertEquals(Iterables.size(listing), 1003);
listing = concatter.execute("foo", ListContainerOptions.Builder.inDirectory("dir"));
assertEquals(Iterables.size(listing), 1001);
listing = concatter.execute("foo", ListContainerOptions.Builder.recursive());
assertEquals(Iterables.size(listing), 2002);
}
@AfterClass
void close() {
if (blobstore != null)
Closeables.closeQuietly(blobstore.getContext());
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.blobstore.strategy.internal;
import static org.testng.Assert.assertEquals;
import org.jclouds.ContextBuilder;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.io.Closeables;
import com.google.inject.Injector;
/**
*
* @author Adrian Cole
*/
@Test(testName = "DeleteAllKeysInListTest", singleThreaded = true)
public class DeleteAllKeysInListTest {
private BlobStore blobstore;
private DeleteAllKeysInList deleter;
@BeforeClass
void setupBlobStore() {
Injector injector = ContextBuilder.newBuilder("transient").buildInjector();
blobstore = injector.getInstance(BlobStore.class);
deleter = injector.getInstance(DeleteAllKeysInList.class);
}
public void testExecuteWithoutOptionsClearsRecursively() {
blobstore.createContainerInLocation(null, "goodies");
for (int i = 0; i < 1001; i++) {
blobstore.putBlob("goodies", blobstore.blobBuilder(i + "").payload(i + "").build());
}
assertEquals(blobstore.countBlobs("goodies"), 1001);
deleter.execute("goodies");
assertEquals(blobstore.countBlobs("goodies"), 0);
}
public void testExecuteNonRecursive() {
blobstore.createContainerInLocation(null, "foo");
for (int i = 0; i < 1001; i++) {
blobstore.putBlob("foo", blobstore.blobBuilder(i + "").payload(i + "").build());
}
for (int i = 0; i < 1001; i++) {
blobstore.putBlob("foo", blobstore.blobBuilder("dir/" + i + "").payload(i + "").build());
}
assertEquals(blobstore.countBlobs("foo"), 2002);
deleter.execute("foo", ListContainerOptions.Builder.inDirectory("dir"));
assertEquals(blobstore.countBlobs("foo"), 1001);
}
@AfterClass
void close() {
if (blobstore != null)
Closeables.closeQuietly(blobstore.getContext());
}
}

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.aws.handlers;
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
import static org.jclouds.http.HttpUtils.releasePayload;
import java.io.IOException;
@ -65,7 +66,9 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
Exception exception = new HttpResponseException(command, response);
try {
AWSError error = null;
String message = null;
// it is important to always read fully and close streams
byte[] data = closeClientButKeepContentStream(response);
String message = data != null ? new String(data) : null;
if (response.getPayload() != null) {
String contentType = response.getPayload().getContentMetadata().getContentType();
if (contentType != null && (contentType.indexOf("xml") != -1 || contentType.indexOf("unknown") != -1)) {

View File

@ -35,17 +35,17 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides asynchronous access to Service via their REST API.
* <p/>
*
* @see ServiceClient
* @see AuthenticationClient
* @see <a href=
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
* />
* @author Adrian Cole
*/
@Path("/v1.1")
public interface ServiceAsyncClient {
public interface AuthenticationAsyncClient {
/**
* @see ServiceClient#authenticate
* @see AuthenticationClient#authenticate
*/
@POST
@SelectJson("auth")

View File

@ -27,13 +27,13 @@ import org.jclouds.openstack.keystone.v1_1.domain.Auth;
* Provides synchronous access to the KeyStone Service API.
* <p/>
*
* @see ServiceAsyncClient
* @see AuthenticationAsyncClient
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
* />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface ServiceClient {
public interface AuthenticationClient {
/**
* Authenticate to generate a token.

View File

@ -35,8 +35,8 @@ import org.jclouds.http.annotation.ClientError;
import org.jclouds.location.Provider;
import org.jclouds.location.suppliers.RegionIdToURISupplier;
import org.jclouds.openstack.Authentication;
import org.jclouds.openstack.keystone.v1_1.ServiceAsyncClient;
import org.jclouds.openstack.keystone.v1_1.ServiceClient;
import org.jclouds.openstack.keystone.v1_1.AuthenticationAsyncClient;
import org.jclouds.openstack.keystone.v1_1.AuthenticationClient;
import org.jclouds.openstack.keystone.v1_1.domain.Auth;
import org.jclouds.openstack.keystone.v1_1.handlers.RetryOnRenew;
import org.jclouds.openstack.keystone.v1_1.suppliers.RegionIdToURIFromAuthForServiceSupplier;
@ -63,7 +63,7 @@ public class AuthenticationServiceModule extends AbstractModule {
}).to(GetAuth.class);
// ServiceClient is used directly for filters and retry handlers, so let's bind it
// explicitly
bindClientAndAsyncClient(binder(), ServiceClient.class, ServiceAsyncClient.class);
bindClientAndAsyncClient(binder(), AuthenticationClient.class, AuthenticationAsyncClient.class);
install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
RegionIdToURIFromAuthForServiceSupplier.class).build(RegionIdToURISupplier.Factory.class));
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
@ -88,7 +88,7 @@ public class AuthenticationServiceModule extends AbstractModule {
public static class GetAuth extends RetryOnTimeOutExceptionFunction<Credentials, Auth> {
@Inject
public GetAuth(final ServiceClient client) {
public GetAuth(final AuthenticationClient client) {
super(new Function<Credentials, Auth>() {
@Override

View File

@ -37,16 +37,16 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides asynchronous access to Service via their REST API.
* <p/>
*
* @see ServiceClient
* @see AuthenticationClient
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
* />
* @author Adrian Cole
*/
@Path("/v2.0")
public interface ServiceAsyncClient {
public interface AuthenticationAsyncClient {
/**
* @see ServiceClient#authenticateTenantWithCredentials(String,PasswordCredentials)
* @see AuthenticationClient#authenticateTenantWithCredentials(String,PasswordCredentials)
*/
@POST
@SelectJson("access")
@ -57,7 +57,7 @@ public interface ServiceAsyncClient {
PasswordCredentials passwordCredentials);
/**
* @see ServiceClient#authenticateTenantWithCredentials(String,ApiAccessKeyCredentials)
* @see AuthenticationClient#authenticateTenantWithCredentials(String,ApiAccessKeyCredentials)
*/
@POST
@SelectJson("access")

View File

@ -29,13 +29,13 @@ import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
* Provides synchronous access to the KeyStone Service API.
* <p/>
*
* @see ServiceAsyncClient
* @see AuthenticationAsyncClient
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
* />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface ServiceClient {
public interface AuthenticationClient {
/**
* Authenticate to generate a token.

View File

@ -40,12 +40,14 @@ import org.jclouds.location.suppliers.ZoneIdsSupplier;
import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet;
import org.jclouds.location.suppliers.derived.ZoneIdsFromZoneIdToURIKeySet;
import org.jclouds.openstack.Authentication;
import org.jclouds.openstack.keystone.v2_0.ServiceAsyncClient;
import org.jclouds.openstack.keystone.v2_0.ServiceClient;
import org.jclouds.openstack.keystone.v2_0.AuthenticationAsyncClient;
import org.jclouds.openstack.keystone.v2_0.AuthenticationClient;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.functions.AuthenticateApiAccessKeyCredentials;
import org.jclouds.openstack.keystone.v2_0.functions.AuthenticatePasswordCredentials;
import org.jclouds.openstack.keystone.v2_0.handlers.RetryOnRenew;
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersionSupplier;
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToURIFromAccessForTypeAndVersionSupplier;
import org.jclouds.openstack.keystone.v2_0.suppliers.ZoneIdToURIFromAccessForTypeAndVersionSupplier;
import org.jclouds.rest.annotations.ApiVersion;
@ -85,6 +87,8 @@ public class KeystoneAuthenticationModule extends AbstractModule {
protected void configure() {
install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
RegionIdToURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToURISupplier.Factory.class));
install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
RegionIdToAdminURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToAdminURISupplier.Factory.class));
// dynamically build the region list as opposed to from properties
bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class);
}
@ -98,6 +102,16 @@ public class KeystoneAuthenticationModule extends AbstractModule {
RegionIdToURISupplier.Factory factory) {
return factory.createForApiTypeAndVersion(serviceType, apiVersion);
}
// supply the region to id to AdminURL map from keystone, based on the servicetype and api version in
// config
@Provides
@Singleton
protected RegionIdToAdminURISupplier provideRegionIdToAdminURISupplierForApiVersion(
@Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
RegionIdToAdminURISupplier.Factory factory) {
return factory.createForApiTypeAndVersion(serviceType, apiVersion);
}
}
@ -132,7 +146,7 @@ public class KeystoneAuthenticationModule extends AbstractModule {
bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
// ServiceClient is used directly for filters and retry handlers, so let's bind it
// explicitly
bindClientAndAsyncClient(binder(), ServiceClient.class, ServiceAsyncClient.class);
bindClientAndAsyncClient(binder(), AuthenticationClient.class, AuthenticationAsyncClient.class);
install(locationModule);
}

View File

@ -0,0 +1,170 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collections;
import java.util.Date;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.domain.Link;
import org.jclouds.openstack.domain.Resource;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.gson.annotations.SerializedName;
/**
* Class ApiMetadata
*/
public class ApiMetadata extends Resource {
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().fromApiMetadata(this);
}
public static class Builder extends Resource.Builder {
private String status;
private Date updated;
private Set<MediaType> mediaTypes = Sets.newLinkedHashSet();
public Builder status(String status) {
this.status = status;
return this;
}
public Builder updated(Date updated) {
this.updated = updated;
return this;
}
public Builder mediaTypes(Set<MediaType> mediaTypes) {
this.mediaTypes = mediaTypes;
return this;
}
public ApiMetadata build() {
return new ApiMetadata(id, name, links, updated, status, mediaTypes);
}
public Builder fromApiMetadata(ApiMetadata in) {
return fromResource(in)
.status(in.getStatus())
.updated(in.getUpdated())
.mediaTypes(in.getMediaTypes());
}
/**
* {@inheritDoc}
*/
@Override
public Builder id(String id) {
return Builder.class.cast(super.id(id));
}
/**
* {@inheritDoc}
*/
@Override
public Builder name(String name) {
return Builder.class.cast(super.name(name));
}
/**
* {@inheritDoc}
*/
@Override
public Builder links(Set<Link> links) {
return Builder.class.cast(super.links(links));
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromResource(Resource in) {
return Builder.class.cast(super.fromResource(in));
}
}
private final String status;
private final Date updated;
@SerializedName("media-types")
private final Set<MediaType> mediaTypes;
protected ApiMetadata(String id, String name, Set<Link> links, Date updated, String status, Set<MediaType> mediaTypes) {
super(id, name, links);
this.status = status;
this.updated = updated;
this.mediaTypes = ImmutableSet.copyOf(checkNotNull(mediaTypes, "mediaTypes"));
}
/**
*/
@Nullable
public String getStatus() {
return this.status;
}
/**
*/
@Nullable
public Date getUpdated() {
return this.updated;
}
/**
*/
@Nullable
public Set<MediaType> getMediaTypes() {
return Collections.unmodifiableSet(this.mediaTypes);
}
@Override
public int hashCode() {
return Objects.hashCode(status, updated, mediaTypes);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
ApiMetadata that = ApiMetadata.class.cast(obj);
return Objects.equal(this.status, that.status)
&& Objects.equal(this.updated, that.updated)
&& Objects.equal(this.mediaTypes, that.mediaTypes)
;
}
protected ToStringHelper string() {
return super.string()
.add("status", status)
.add("updated", updated)
.add("mediaTypes", mediaTypes);
}
}

View File

@ -55,6 +55,7 @@ public class Endpoint implements Comparable<Endpoint> {
protected String region;
protected URI publicURL;
protected URI internalURL;
protected URI adminURL;
protected String tenantId;
/**
@ -89,6 +90,14 @@ public class Endpoint implements Comparable<Endpoint> {
return this;
}
/**
* @see Endpoint#getInternalURL()
*/
public Builder adminURL(URI adminURL) {
this.adminURL = checkNotNull(adminURL, "adminURL");
return this;
}
/**
* @see Endpoint#getTenantId()
*/
@ -98,7 +107,7 @@ public class Endpoint implements Comparable<Endpoint> {
}
public Endpoint build() {
return new Endpoint(versionId, region, publicURL, internalURL, tenantId);
return new Endpoint(versionId, region, publicURL, internalURL, adminURL, tenantId);
}
public Builder fromEndpoint(Endpoint from) {
@ -113,17 +122,20 @@ public class Endpoint implements Comparable<Endpoint> {
protected final String region;
protected final URI publicURL;
protected final URI internalURL;
protected final URI adminURL;
// renamed half-way through
@Deprecated
protected String tenantName;
protected final String tenantId;
protected Endpoint(String versionId, String region, @Nullable URI publicURL, @Nullable URI internalURL,
@Nullable String tenantId) {
@Nullable URI adminURL, @Nullable String tenantId) {
this.versionId = checkNotNull(versionId, "versionId");
this.region = checkNotNull(region, "region");
this.publicURL = publicURL;
this.internalURL = internalURL;
this.adminURL = adminURL;
this.tenantId = tenantId;
}
@ -160,6 +172,14 @@ public class Endpoint implements Comparable<Endpoint> {
return internalURL;
}
/**
* @return the admin url of the endpoint
*/
@Nullable
public URI getAdminURL() {
return adminURL;
}
/**
* @return the tenant versionId of the endpoint or null
*/
@ -176,7 +196,7 @@ public class Endpoint implements Comparable<Endpoint> {
if (object instanceof Endpoint) {
final Endpoint other = Endpoint.class.cast(object);
return equal(getVersionId(), other.getVersionId()) && equal(region, other.region) && equal(publicURL, other.publicURL)
&& equal(internalURL, other.internalURL) && equal(getTenantId(), other.getTenantId());
&& equal(internalURL, other.internalURL) && equal(adminURL, other.adminURL) && equal(getTenantId(), other.getTenantId());
} else {
return false;
}
@ -184,13 +204,13 @@ public class Endpoint implements Comparable<Endpoint> {
@Override
public int hashCode() {
return Objects.hashCode(getVersionId(), region, publicURL, internalURL, getTenantId());
return Objects.hashCode(getVersionId(), region, publicURL, internalURL, adminURL, getTenantId());
}
@Override
public String toString() {
return toStringHelper("").add("versionId", getVersionId()).add("region", region).add("publicURL", publicURL).add("internalURL",
internalURL).add("tenantId", getTenantId()).toString();
internalURL).add("adminURL", adminURL).add("tenantId", getTenantId()).toString();
}
@Override

View File

@ -0,0 +1,111 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.domain;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
/**
* Class MediaType
*/
public class MediaType {
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().fromMediaType(this);
}
public static class Builder {
private String base;
private String type;
public Builder base(String base) {
this.base = base;
return this;
}
public Builder type(String type) {
this.type = type;
return this;
}
public MediaType build() {
return new MediaType(this);
}
public Builder fromMediaType(MediaType in) {
return this.base(in.getBase()).type(in.getType());
}
}
private final String base;
private final String type;
protected MediaType(Builder builder) {
this.base = builder.base;
this.type = builder.type;
}
/**
*/
@Nullable
public String getBase() {
return this.base;
}
/**
*/
@Nullable
public String getType() {
return this.type;
}
@Override
public int hashCode() {
return Objects.hashCode(base, type);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
MediaType that = MediaType.class.cast(obj);
return Objects.equal(this.base, that.base)
&& Objects.equal(this.type, that.type)
;
}
protected ToStringHelper string() {
return Objects.toStringHelper("")
.add("base", base)
.add("type", type);
}
@Override
public String toString() {
return string().toString();
}
}

View File

@ -52,7 +52,7 @@ public class Service implements Comparable<Service> {
protected Set<Endpoint> endpoints = ImmutableSet.of();
/**
* @see Service#getId()
* @see Service#getType()
*/
public Builder type(String type) {
this.type = checkNotNull(type, "type");

View File

@ -23,12 +23,16 @@ import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.ws.rs.DefaultValue;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
/**
* A container used to group or isolate resources and/or identity objects. Depending on the service
* operator, a tenant may map to a customer, account, organization, or project.
*
*
* @author Adrian Cole
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Identity-Service-Concepts-e1362.html"
* />
@ -46,6 +50,7 @@ public class Tenant implements Comparable<Tenant> {
public static class Builder {
protected String id;
protected String name;
protected String description;
/**
* @see Tenant#getId()
@ -63,8 +68,16 @@ public class Tenant implements Comparable<Tenant> {
return this;
}
/**
* @see Tenant#getDescription()
*/
public Builder description(String description) {
this.description = description;
return this;
}
public Tenant build() {
return new Tenant(id, name);
return new Tenant(id, name, description);
}
public Builder fromTenant(Tenant from) {
@ -74,15 +87,17 @@ public class Tenant implements Comparable<Tenant> {
protected final String id;
protected final String name;
protected final String description;
public Tenant(String id, String name) {
protected Tenant(String id, String name, String description) {
this.id = checkNotNull(id, "id");
this.name = checkNotNull(name, "name");
this.description = description;
}
/**
* When providing an ID, it is assumed that the tenant exists in the current OpenStack deployment
*
*
* @return the id of the tenant in the current OpenStack deployment
*/
public String getId() {
@ -96,6 +111,14 @@ public class Tenant implements Comparable<Tenant> {
return name;
}
/**
* @return the description of the tenant
*/
@Nullable
public String getDescription() {
return description;
}
@Override
public boolean equals(Object object) {
if (this == object) {
@ -103,7 +126,8 @@ public class Tenant implements Comparable<Tenant> {
}
if (object instanceof Tenant) {
final Tenant other = Tenant.class.cast(object);
return equal(id, other.id) && equal(name, other.name);
return equal(id, other.id) && equal(name, other.name)
&& equal(description, other.description);
} else {
return false;
}
@ -111,12 +135,12 @@ public class Tenant implements Comparable<Tenant> {
@Override
public int hashCode() {
return Objects.hashCode(id, name);
return Objects.hashCode(id, name, description);
}
@Override
public String toString() {
return toStringHelper("").add("id", id).add("name", name).toString();
return toStringHelper("").add("id", id).add("name", name).add("description", description).toString();
}
@Override

View File

@ -98,11 +98,17 @@ public class User implements Comparable<User> {
protected final String name;
protected final Set<Role> roles;
public User(String id, String name, Set<Role> roles) {
protected User(String id, String name, Set<Role> roles) {
this.id = checkNotNull(id, "id");
this.name = checkNotNull(name, "name");
this.roles = ImmutableSet.copyOf(checkNotNull(roles, "roles"));
}
protected User() {
id = null;
name = null;
roles = ImmutableSet.of();
}
/**
* When providing an ID, it is assumed that the user exists in the current OpenStack deployment

View File

@ -0,0 +1,43 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.functions;
import java.net.URI;
import javax.inject.Singleton;
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
/**
* @author Adam Lowe
*/
@Singleton
public class AdminURL implements EndpointToSupplierAdminURI {
@Override
public Supplier<URI> apply(Endpoint input) {
return Suppliers.ofInstance(input.getAdminURL());
}
public String toString() {
return "supplyAdminURL()";
}
}

View File

@ -22,7 +22,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.domain.Credentials;
import org.jclouds.openstack.keystone.v2_0.ServiceClient;
import org.jclouds.openstack.keystone.v2_0.AuthenticationClient;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
import org.jclouds.rest.AuthorizationException;
@ -31,10 +31,10 @@ import com.google.common.base.Function;
@Singleton
public class AuthenticateApiAccessKeyCredentials implements Function<Credentials, Access> {
private final ServiceClient client;
private final AuthenticationClient client;
@Inject
public AuthenticateApiAccessKeyCredentials(ServiceClient client) {
public AuthenticateApiAccessKeyCredentials(AuthenticationClient client) {
this.client = client;
}

View File

@ -20,7 +20,7 @@ package org.jclouds.openstack.keystone.v2_0.functions;
import javax.inject.Inject;
import org.jclouds.domain.Credentials;
import org.jclouds.openstack.keystone.v2_0.ServiceClient;
import org.jclouds.openstack.keystone.v2_0.AuthenticationClient;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
import org.jclouds.rest.AuthorizationException;
@ -28,10 +28,10 @@ import org.jclouds.rest.AuthorizationException;
import com.google.common.base.Function;
public class AuthenticatePasswordCredentials implements Function<Credentials, Access> {
private final ServiceClient client;
private final AuthenticationClient client;
@Inject
public AuthenticatePasswordCredentials(ServiceClient client) {
public AuthenticatePasswordCredentials(AuthenticationClient client) {
this.client = client;
}

View File

@ -0,0 +1,28 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.functions;
import com.google.inject.ImplementedBy;
/**
* @author Adam Lowe
*/
@ImplementedBy(AdminURL.class)
public interface EndpointToSupplierAdminURI extends EndpointToSupplierURI {
}

View File

@ -0,0 +1,16 @@
package org.jclouds.openstack.keystone.v2_0.functions;
import javax.inject.Inject;
import org.jclouds.location.functions.RegionToEndpoint;
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
/**
* @author Adam Lowe
*/
public class RegionToAdminEndpointURI extends RegionToEndpoint {
@Inject
public RegionToAdminEndpointURI(RegionIdToAdminURISupplier regionToEndpointSupplier) {
super(regionToEndpointSupplier);
}
}

View File

@ -0,0 +1,45 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.suppliers;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.functions.EndpointToRegion;
import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierAdminURI;
import com.google.common.base.Supplier;
import com.google.inject.assistedinject.Assisted;
@Singleton
public class RegionIdToAdminURIFromAccessForTypeAndVersionSupplier extends
LocationIdToURIFromAccessForTypeAndVersionSupplier implements RegionIdToAdminURISupplier {
@Inject
public RegionIdToAdminURIFromAccessForTypeAndVersionSupplier(Supplier<Access> access,
EndpointToSupplierAdminURI endpointToSupplierURI, EndpointToRegion endpointToRegion,
@Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) {
super(access, endpointToSupplierURI, endpointToRegion, apiType, apiVersion);
}
@Override
public String toString() {
return "regionIdToAdminURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
}
}

View File

@ -0,0 +1,28 @@
package org.jclouds.openstack.keystone.v2_0.suppliers;
import java.net.URI;
import java.util.Map;
import com.google.common.base.Supplier;
import com.google.inject.ImplementedBy;
import com.google.inject.assistedinject.Assisted;
/**
* @author Adam Lowe
*/
@ImplementedBy(RegionIdToAdminURIFromAccessForTypeAndVersionSupplier.class)
public interface RegionIdToAdminURISupplier extends Supplier<Map<String, Supplier<URI>>> {
static interface Factory {
/**
*
* @param apiType
* type of the api, according to the provider. ex. {@code compute} {@code
* object-store}
* @param apiVersion
* version of the api
* @return regions mapped to default uri
*/
RegionIdToAdminURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
@Assisted("apiVersion") String apiVersion);
}
}

View File

@ -41,4 +41,8 @@ public interface ServiceType {
* Image Service (Glance)
*/
public static final String IMAGE = "image";
/**
* Identity Service (Keystone)
*/
public static final String IDENTITY = "identity";
}

View File

@ -0,0 +1,50 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.functions;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
import org.testng.annotations.Test;
/**
* @author Adam Lowe
*/
@Test(groups = "unit", testName = "AdminURLTest")
public class AdminURLTest {
private final AdminURL fn = new AdminURL();
public void testAdminURL() {
assertEquals(fn.apply(
Endpoint.builder().region("LON").versionId("1.0").adminURL(
URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
.build()).get(), URI
.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"));
}
public void testPublicURLNullReturnsInternalURL() {
assertEquals(fn
.apply(
Endpoint.builder().region("lon").versionId("1.0")
.internalURL(URI.create("https://192.168.1.1")).build()).get(), null);
}
}

View File

@ -67,11 +67,13 @@ public class ParseAccessTest extends BaseItemParserTest<Access> {
Service.builder().name("Object Storage").type("object-store").endpoints(
Endpoint.builder().tenantId("40806637803162").publicURL(
URI.create("https://objects.jclouds.org/v1.0/40806637803162"))
.adminURL(URI.create("https://objects.jclouds.org/v1.0/"))
.region("region-a.geo-1").versionId("1.0").build()).build(),
Service.builder().name("Identity").type("identity").endpoints(
Endpoint.builder().publicURL(URI.create("https://csnode.jclouds.org/v2.0/")).region(
"region-a.geo-1").versionId("2.0").build()).build(),
Endpoint.builder().publicURL(URI.create("https://csnode.jclouds.org/v2.0/"))
.adminURL(URI.create("https://csnode.jclouds.org:35357/v2.0/"))
.region("region-a.geo-1").versionId("2.0").build()).build(),
Service.builder().name("Image Management").type("image").endpoints(
Endpoint.builder().tenantId("40806637803162").publicURL(

View File

@ -0,0 +1,70 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.parse;
import java.net.URI;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.openstack.domain.Link;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
import org.jclouds.openstack.keystone.v2_0.domain.Role;
import org.jclouds.openstack.keystone.v2_0.domain.Service;
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
import org.jclouds.openstack.keystone.v2_0.domain.Token;
import org.jclouds.openstack.keystone.v2_0.domain.User;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* @author Adam Lowe
*/
@Test(groups = "unit", testName = "ParseApiMetadataTest")
public class ParseApiMetadataTest extends BaseItemParserTest<ApiMetadata> {
@Override
public String resource() {
return "/apiMetadataResponse.json";
}
@Override
@SelectJson("version")
@Consumes(MediaType.APPLICATION_JSON)
public ApiMetadata expected() {
return ApiMetadata.builder().id("v2.0")
.links(ImmutableSet.of(Link.builder().relation(Link.Relation.SELF).href(URI.create("http://172.16.89.140:5000/v2.0/")).build(),
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("text/html").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/content/")).build(),
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("application/pdf").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf")).build()
))
.status("beta")
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-11-19T00:00:00Z"))
.mediaTypes(ImmutableSet.of(
org.jclouds.openstack.keystone.v2_0.domain.MediaType.builder().base("application/json").type("application/vnd.openstack.identity-v2.0+json").build(),
org.jclouds.openstack.keystone.v2_0.domain.MediaType.builder().base("application/xml").type("application/vnd.openstack.identity-v2.0+xml").build()
))
.build();
}
}

View File

@ -0,0 +1,71 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.suppliers;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Provides;
import com.google.inject.assistedinject.FactoryModuleBuilder;
/**
* @author Adam Lowe
*/
@Test(groups = "unit", testName = "RegionIdToAdminURIFromAccessForTypeAndVersionSupplierTest")
public class RegionIdToAdminURIFromAccessForTypeAndVersionSupplierTest {
private final RegionIdToAdminURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
RegionIdToAdminURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToAdminURISupplier.Factory.class));
}
@SuppressWarnings("unused")
@Provides
@Singleton
public Supplier<Access> provide() {
return Suppliers.ofInstance(new ParseAccessTest().expected());
}
}).getInstance(RegionIdToAdminURISupplier.Factory.class);
public void testRegionMatches() {
assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("identity", "2.0").get(), Suppliers
.<URI> supplierFunction()), ImmutableMap.of("region-a.geo-1", URI.create("https://csnode.jclouds.org:35357/v2.0/")));
Map<String, URI> map = Maps.newLinkedHashMap();
map.put("region-a.geo-1", null);
assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.1").get(), Suppliers
.<URI> supplierFunction()), map);
}
}

View File

@ -0,0 +1 @@
{"version": {"status": "beta", "updated": "2011-11-19T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json"}, {"base": "application/xml", "type": "application/vnd.openstack.identity-v2.0+xml"}], "id": "v2.0", "links": [{"href": "http://172.16.89.140:5000/v2.0/", "rel": "self"}, {"href": "http://docs.openstack.org/api/openstack-identity-service/2.0/content/", "type": "text/html", "rel": "describedby"}, {"href": "http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf", "type": "application/pdf", "rel": "describedby"}]}}

View File

@ -56,9 +56,11 @@
"type": "identity",
"endpoints": [
{
"adminURL": "https://csnode.jclouds.org:35357/v2.0/",
"publicURL": "https://csnode.jclouds.org/v2.0/",
"region": "region-a.geo-1",
"id": "2.0",
"versionId":"2.0",
"list": "https://csnode.jclouds.org/extension"
}
]

View File

@ -32,9 +32,9 @@ import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@ -43,14 +43,13 @@ import org.jclouds.cim.CIMPredicates;
import org.jclouds.cim.ResourceAllocationSettingData;
import org.jclouds.cim.ResourceAllocationSettingData.ResourceType;
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.RestContext;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
import org.jclouds.ssh.SshClient.Factory;
import org.jclouds.ssh.SshException;
import org.jclouds.trmk.vcloud_0_8.domain.Catalog;
import org.jclouds.trmk.vcloud_0_8.domain.CatalogItem;
import org.jclouds.trmk.vcloud_0_8.domain.CustomizationParameters;
@ -80,6 +79,7 @@ import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.net.HostAndPort;
import com.google.inject.Injector;
@Test(groups = "live", singleThreaded = true)
@ -93,7 +93,7 @@ public abstract class TerremarkClientLiveTest<S extends TerremarkVCloudClient, A
protected InternetService is;
protected Node node;
protected VApp vApp;
protected RetryablePredicate<IPSocket> socketTester;
protected RetryablePredicate<HostAndPort> socketTester;
protected RetryablePredicate<URI> successTester;
protected Injector injector;
@ -107,7 +107,7 @@ public abstract class TerremarkClientLiveTest<S extends TerremarkVCloudClient, A
public TerremarkClientLiveTest() {
this.provider = "trmk-vcloudexpress";
StringBuffer name = new StringBuffer();
StringBuilder name = new StringBuilder();
for (int i = 0; i < 15; i++)
name.append("d");
serverName = name.toString();// "adriantest";
@ -287,7 +287,7 @@ public abstract class TerremarkClientLiveTest<S extends TerremarkVCloudClient, A
assert successTester.apply(connection.powerOffVApp(vApp.getHref()).getHref());
System.out.printf("%d: done powering off vApp%n", System.currentTimeMillis());
StringBuffer name = new StringBuffer();
StringBuilder name = new StringBuilder();
for (int i = 0; i < 15; i++)
name.append("b");
String newName = name.toString();
@ -429,7 +429,7 @@ public abstract class TerremarkClientLiveTest<S extends TerremarkVCloudClient, A
}
protected void doCheckPass(String address) throws IOException {
IPSocket socket = new IPSocket(address, 22);
HostAndPort socket = HostAndPort.fromParts(address, 22);
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(), socket);
assert socketTester.apply(socket);
@ -448,7 +448,7 @@ public abstract class TerremarkClientLiveTest<S extends TerremarkVCloudClient, A
}
}
protected abstract SshClient getConnectionFor(IPSocket socket);
protected abstract SshClient getConnectionFor(HostAndPort socket);
@AfterGroups(groups = { "live" })
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
@ -485,7 +485,7 @@ public abstract class TerremarkClientLiveTest<S extends TerremarkVCloudClient, A
injector = view.utils().injector();
sshFactory = injector.getInstance(SshClient.Factory.class);
socketTester = new RetryablePredicate<IPSocket>(injector.getInstance(SocketOpen.class), 300, 10, TimeUnit.SECONDS);// make
socketTester = new RetryablePredicate<HostAndPort>(injector.getInstance(SocketOpen.class), 300, 10, TimeUnit.SECONDS);// make
// it
// longer
// then

View File

@ -22,7 +22,6 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
@ -33,6 +32,7 @@ import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.net.HostAndPort;
import com.google.inject.Injector;
import com.google.inject.Module;
@ -51,7 +51,7 @@ public abstract class BaseTerremarkClientLiveTest<S extends TerremarkVCloudClien
provider = "trmk-ecloud";
}
protected RetryablePredicate<IPSocket> socketTester;
protected RetryablePredicate<HostAndPort> socketTester;
protected Factory sshFactory;
protected S connection;
@ -61,7 +61,7 @@ public abstract class BaseTerremarkClientLiveTest<S extends TerremarkVCloudClien
public void setupContext() {
super.setupContext();
Injector injector = view.utils().injector();
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 300, 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<HostAndPort>(new InetSocketAddressConnect(), 300, 1, TimeUnit.SECONDS);
sshFactory = injector.getInstance(Factory.class);
connection = (S) RestContext.class.cast(view.unwrap()).getApi();
}

View File

@ -26,10 +26,10 @@ import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
import org.jclouds.compute.util.ComputeServiceUtils;
import org.jclouds.net.IPSocket;
import org.jclouds.ssh.SshClient;
import com.google.common.base.Function;
import com.google.common.net.HostAndPort;
import com.google.inject.Inject;
/**
@ -55,7 +55,7 @@ public class CreateSshClientOncePortIsListeningOnNode implements Function<NodeMe
checkNotNull(node.getCredentials().identity, "no login identity found for node %s", node.getId());
checkNotNull(node.getCredentials().credential, "no credential found for %s on node %s", node
.getCredentials().identity, node.getId());
IPSocket socket = ComputeServiceUtils.findReachableSocketOnNode(socketTester, node, node.getLoginPort());
HostAndPort socket = ComputeServiceUtils.findReachableSocketOnNode(socketTester, node, node.getLoginPort());
return sshFactory.create(socket, node.getCredentials());
}
}

View File

@ -27,11 +27,11 @@ import javax.inject.Named;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import com.google.common.base.Predicate;
import com.google.common.net.HostAndPort;
/**
*
@ -41,7 +41,7 @@ import com.google.common.base.Predicate;
* @author Adrian Cole
*
*/
public class RetryIfSocketNotYetOpen implements Predicate<IPSocket> {
public class RetryIfSocketNotYetOpen implements Predicate<HostAndPort> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
private Logger logger = Logger.NULL;
@ -84,11 +84,11 @@ public class RetryIfSocketNotYetOpen implements Predicate<IPSocket> {
}
@Override
public boolean apply(IPSocket socket) {
public boolean apply(HostAndPort socket) {
logger.debug(">> blocking on socket %s for %d %s", socket, timeoutValue, timeoutUnits);
// Specify a retry period of 1s, expressed in the same time units.
long period = timeoutUnits.convert(1, TimeUnit.SECONDS);
RetryablePredicate<IPSocket> tester = new RetryablePredicate<IPSocket>(socketTester, timeoutValue, period, timeoutUnits);
RetryablePredicate<HostAndPort> tester = new RetryablePredicate<HostAndPort>(socketTester, timeoutValue, period, timeoutUnits);
boolean passed = tester.apply(socket);
if (passed)
logger.debug("<< socket %s opened", socket);

View File

@ -33,7 +33,6 @@ import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.rest.annotations.Identity;
@ -41,6 +40,7 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.net.HostAndPort;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@ -128,10 +128,10 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
}
@Override
public boolean apply(IPSocket input) {
if (input.getAddress().indexOf(publicIpPrefix) == -1)
public boolean apply(HostAndPort input) {
if (input.getHostText().indexOf(publicIpPrefix) == -1)
return false;
String id = input.getAddress().replace(publicIpPrefix, "");
String id = input.getHostText().replace(publicIpPrefix, "");
NodeMetadata node = nodes.get(id);
return node != null && node.getState() == NodeState.RUNNING;
}

Some files were not shown because too many files have changed in this diff Show More