Merge pull request #229 from jsonking/695-Terremark

Issue 695: performance statistics for hourly/daily/cpu/memory and for a date range
This commit is contained in:
Jason King 2011-12-08 09:26:47 -08:00
commit 38feabf015
15 changed files with 344 additions and 32 deletions

View File

@ -0,0 +1,55 @@
/**
* 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.tmrk.enterprisecloud.binders;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.rest.Binder;
import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder;
import java.util.Date;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* @author Jason King
*/
abstract class BindDateToQueryParam implements Binder {
private final Provider<UriBuilder> uriBuilderProvider;
private final DateService dateService;
private final String key;
public BindDateToQueryParam(Provider<UriBuilder> uriBuilderProvider, String key) {
this.uriBuilderProvider = checkNotNull(uriBuilderProvider, "uriBuilderProvider");
this.dateService = new SimpleDateFormatDateService();
this.key = key;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
if(input==null) return request;
Date date = Date.class.cast(input);
String dateString = dateService.iso8601SecondsDateFormat(date);
return ModifyRequest.addQueryParam(request, key, dateString, uriBuilderProvider.get());
}
}

View File

@ -0,0 +1,36 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.tmrk.enterprisecloud.binders;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
/**
* @author Jason King
*/
@Singleton
public class BindEndTimeQueryParam extends BindDateToQueryParam {
@Inject
public BindEndTimeQueryParam(Provider<UriBuilder> uriBuilderProvider) {
super(uriBuilderProvider,"endtime");
}
}

View File

@ -0,0 +1,36 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.tmrk.enterprisecloud.binders;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
/**
* @author Jason King
*/
@Singleton
public class BindStartTimeQueryParam extends BindDateToQueryParam {
@Inject
public BindStartTimeQueryParam(Provider<UriBuilder> uriBuilderProvider) {
super(uriBuilderProvider,"starttime");
}
}

View File

@ -20,8 +20,11 @@ package org.jclouds.tmrk.enterprisecloud.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.*;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.tmrk.enterprisecloud.binders.BindEndTimeQueryParam;
import org.jclouds.tmrk.enterprisecloud.binders.BindStartTimeQueryParam;
import org.jclouds.tmrk.enterprisecloud.domain.resource.ComputePoolPerformanceStatistics;
import org.jclouds.tmrk.enterprisecloud.domain.resource.PerformanceStatistics;
import org.jclouds.tmrk.enterprisecloud.domain.resource.cpu.ComputePoolCpuUsage;
@ -35,6 +38,7 @@ import org.jclouds.tmrk.enterprisecloud.domain.resource.storage.ComputePoolStora
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import java.net.URI;
import java.util.Date;
/**
* Provides asynchronous access to various Resources via their REST API.
@ -123,11 +127,11 @@ public interface ResourceAsyncClient {
ListenableFuture<ComputePoolPerformanceStatistics> getComputePoolPerformanceStatistics(@EndpointParam URI uri);
/**
* @see ResourceClient#getDailyCpuPerformanceStatistics
* @see ResourceClient#getPerformanceStatistics
*/
@GET
@Consumes("application/vnd.tmrk.cloud.performanceStatistics")
@JAXBResponseParser
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<PerformanceStatistics> getDailyCpuPerformanceStatistics(@EndpointParam URI uri);
ListenableFuture<PerformanceStatistics> getPerformanceStatistics(@EndpointParam URI uri, @Nullable @BinderParam(BindStartTimeQueryParam.class) Date startTime, @Nullable @BinderParam(BindEndTimeQueryParam.class) Date endTime);
}

View File

@ -30,6 +30,7 @@ import org.jclouds.tmrk.enterprisecloud.domain.resource.memory.ComputePoolMemory
import org.jclouds.tmrk.enterprisecloud.domain.resource.storage.ComputePoolStorageUsageDetail;
import java.net.URI;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
@ -155,18 +156,62 @@ public interface ResourceClient {
ComputePoolPerformanceStatistics getComputePoolPerformanceStatistics(URI uri);
/**
* The Get Resources Performance Statistics Processor Daily call returns daily
* information regarding processor performance for a specified compute pool
* <h2>Introduction</h2>
*
* returns statistics for the previous seven days.
* The getPerformanceStatistics call returns information regarding performance for a specified compute pool.
* There are 2 time periods available: daily and hourly
* There is information for cpu (processor) and memory.
* To determine the correct URI to use, first call {@code getComputePoolPerformanceStatistics}
* then select the desired statistic from the result (e.g. hourly or daily then cpu or memory)
*
* The default endTime is midnight the beginning of the current day and the default
* startTime is midnight seven days prior to the endTime.
* For example, if the call is made at 2011-07-12T14:48:00Z, then startTime is 2011-07-05T00:00:00Z
* and endTime is 2011-07-12T00:00:00Z.
* @param uri uri the uri of the call based upon the compute pool
* e.g. /cloudapi/ecloud/computepools/{id}/usage/cpu/performanceStatistics/daily
* @return
* <h2>Default Mode</h2>
*
* <h3>Daily Statistics</h2>
* Daily statistics return results for the previous seven days.
*
* The default endTime is midnight the beginning of the current day
* and the default startTime is midnight seven days prior to the endTime.
* For example, if the call is made at 2011-07-12T14:48:00Z,
* then startTime is 2011-07-05T00:00:00Z and endTime is 2011-07-12T00:00:00Z.
*
* <h3>Hourly Statistics</h3>
* Hourly statistics return results for the previous 24 hours
*
* The default endTime is the end of the hour prior to the current time
* and the default startTime is the beginning of the hour 24 hours prior to the endTime.
* For example, if the call is made at 2011-07- 12T14:48:00Z,
* then startTime is 2011-07-11T13:00:00Z and endTime is 2011-07-12T14:00:00Z.
*
* <h2>Query Mode</h2>
*
* <h3>Daily Statistics with startTime and endTime</h3>
*
* If startTime and endTime are present returns statistics for the complete days
* between the requested dates.
*
* If either parameter is missing, the default value is used.
* Only complete days are returned.
* For example, 2011-06-20T00:00:00Z to 2011-06-22T00:00:00Z returns information for 2 days:
* June 20 and June 21.
* Conversely, 2011-06-20T22:00:00Z to 2011-06-21T22:30:00Z returns no information
* as no complete days are in the requested interval.
*
* <h3>Hourly Statistics with startTime and endTime</h3>
*
* If startTime and endTime are present returns statistics for the complete hours
* between the requested dates.
*
* If either parameter is missing, the default value is used.
* Only complete hours are returned.
* For example, 2011-06-22T06:00:00Z to 2011-06-22T08:00:00Z returns information for 2 hours:
* the 06:00 hour and the 07:00 hour.
* Conversely, 2011-06-21T14:10:00Z to 2011-06-21T15:50:00Z returns no information
* as no complete hours are in the requested interval.
*
* @param uri uri the uri of the call.
* @param startTime the desired start time for the statistics (optional).
* @param endTime the desired end time for the statistics (optional).
* @return the performance statistics for the desired period and metric
*/
PerformanceStatistics getDailyCpuPerformanceStatistics(URI uri);
PerformanceStatistics getPerformanceStatistics(URI uri, Date startTime, Date endTime);
}

View File

@ -0,0 +1,76 @@
/**
* 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.tmrk.enterprisecloud.binders;
import com.sun.jersey.api.uri.UriBuilderImpl;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.HttpRequest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder;
import java.net.URI;
import java.util.Date;
import static org.testng.Assert.assertEquals;
/**
* Tests {@code BindDateToQueryParam}
* @author Jason King
*/
@Test(groups = "unit", testName = "BindDateToQueryParamTest")
public class BindDateToQueryParamTest {
private DateService dateService;
private BindDateToQueryParam binder;
@BeforeMethod
public void setUp() {
dateService = new SimpleDateFormatDateService();
Provider<UriBuilder> uriBuilderProvider = new Provider<UriBuilder>() {
@Override
public UriBuilder get() {
return new UriBuilderImpl();
}
};
binder = new BindMyDateToQueryParam(uriBuilderProvider);
}
public void testNullDate() {
HttpRequest request = new HttpRequest("GET", URI.create("https://localhost:9999"));
HttpRequest result = binder.bindToRequest(request, null);
assertEquals(result.getRequestLine(),"GET https://localhost:9999 HTTP/1.1");
}
public void testDatePresent() {
HttpRequest request = new HttpRequest("GET", URI.create("https://localhost:9999"));
Date date = dateService.iso8601SecondsDateParse("2011-12-08T15:09:33Z");
HttpRequest result = binder.bindToRequest(request, date);
assertEquals(result.getRequestLine(),"GET https://localhost:9999?mydate=2011-12-08T15%3A09%3A33Z HTTP/1.1");
}
private static class BindMyDateToQueryParam extends BindDateToQueryParam {
public BindMyDateToQueryParam(Provider<UriBuilder> uriBuilderProvider) {
super(uriBuilderProvider, "mydate");
}
}
}

View File

@ -34,7 +34,7 @@ import static org.testng.Assert.assertTrue;
/**
* @author Jason King
*/
@Test(groups = "unit", testName = "ActionsTest")
@Test(groups = "unit", testName = "VirtualMachinesTest")
public class VirtualMachinesTest {
private VirtualMachine virtualMachine;

View File

@ -39,7 +39,7 @@ import com.google.inject.Module;
*
* @author Adrian Cole
*/
@Test(groups = "live")
@Test(groups = "live", testName = "BaseTerremarkEnterpriseCloudClientLiveTest")
public class BaseTerremarkEnterpriseCloudClientLiveTest extends BaseVersionedServiceLiveTest {
protected RestContext<TerremarkEnterpriseCloudClient, TerremarkEnterpriseCloudAsyncClient> context;

View File

@ -19,25 +19,36 @@
package org.jclouds.tmrk.enterprisecloud.features;
import com.google.inject.TypeLiteral;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseXMLWithJAXB;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
/**
* Tests annotation parsing of {@code ResourceAsyncClient}
*
* @author Jason King
*/
@Test(groups = "unit", testName = "ResourceAsyncClient")
@Test(groups = "unit", testName = "ResourceAsyncClientTest")
public class ResourceAsyncClientTest extends BaseTerremarkEnterpriseCloudAsyncClientTest<ResourceAsyncClient> {
private DateService dateService;
@BeforeMethod
public void setUp() {
dateService = new SimpleDateFormatDateService();
}
public void testGetResourceSummaries() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
Method method = ResourceAsyncClient.class.getMethod("getResourceSummaries", URI.class);
HttpRequest httpRequest = processor.createRequest(method, new URI("/cloudapi/ecloud/computepools/environments/77/resourcesummarylist"));
@ -158,9 +169,9 @@ public class ResourceAsyncClientTest extends BaseTerremarkEnterpriseCloudAsyncCl
checkFilters(httpRequest);
}
public void testGetDailyCpuPerformanceStatistics() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
Method method = ResourceAsyncClient.class.getMethod("getDailyCpuPerformanceStatistics", URI.class);
HttpRequest httpRequest = processor.createRequest(method, URI.create("/cloudapi/ecloud/computepools/89/usage/cpu/performancestatistics/daily"));
public void testGetPerformanceStatisticsNoDates() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
Method method = ResourceAsyncClient.class.getMethod("getPerformanceStatistics", URI.class,Date.class,Date.class);
HttpRequest httpRequest = processor.createRequest(method, URI.create("/cloudapi/ecloud/computepools/89/usage/cpu/performancestatistics/daily"),null,null);
assertRequestLineEquals(httpRequest, "GET https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/computepools/89/usage/cpu/performancestatistics/daily HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest,
@ -173,6 +184,24 @@ public class ResourceAsyncClientTest extends BaseTerremarkEnterpriseCloudAsyncCl
checkFilters(httpRequest);
}
public void testGetPerformanceStatisticsWithDates() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
Method method = ResourceAsyncClient.class.getMethod("getPerformanceStatistics", URI.class,Date.class,Date.class);
Date startTime = dateService.iso8601SecondsDateParse("2011-12-08T15:00:00Z");
Date endTime = dateService.iso8601SecondsDateParse("2011-12-08T16:30:00Z");;
HttpRequest httpRequest = processor.createRequest(method, URI.create("/cloudapi/ecloud/computepools/89/usage/cpu/performancestatistics/daily"),startTime,endTime);
assertRequestLineEquals(httpRequest, "GET https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/computepools/89/usage/cpu/performancestatistics/daily?endtime=2011-12-08T16%3A30%3A00Z&starttime=2011-12-08T15%3A00%3A00Z HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest,
"Accept: application/vnd.tmrk.cloud.performanceStatistics\nx-tmrk-version: 2011-07-01\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<ResourceAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<ResourceAsyncClient>>() {

View File

@ -18,12 +18,11 @@
*/
package org.jclouds.tmrk.enterprisecloud.features;
import com.google.common.collect.Iterables;
import org.jclouds.tmrk.enterprisecloud.domain.Link;
import org.jclouds.tmrk.enterprisecloud.domain.internal.ResourceCapacity;
import org.jclouds.tmrk.enterprisecloud.domain.resource.PerformanceStatistics;
import org.jclouds.tmrk.enterprisecloud.domain.resource.*;
import org.jclouds.tmrk.enterprisecloud.domain.resource.cpu.ComputePoolCpuUsage;
import org.jclouds.tmrk.enterprisecloud.domain.resource.ComputePoolResourceSummary;
import org.jclouds.tmrk.enterprisecloud.domain.resource.ComputePoolResourceSummaryList;
import org.jclouds.tmrk.enterprisecloud.domain.resource.cpu.ComputePoolCpuUsageDetail;
import org.jclouds.tmrk.enterprisecloud.domain.resource.memory.ComputePoolMemoryUsage;
import org.jclouds.tmrk.enterprisecloud.domain.resource.memory.ComputePoolMemoryUsageDetail;
@ -32,10 +31,10 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import java.net.URI;
import java.util.Date;
import java.util.Set;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.*;
/**
* Tests behavior of {@code ResourceClient}
@ -122,8 +121,38 @@ public class ResourceClientLiveTest extends BaseTerremarkEnterpriseCloudClientLi
assertNotNull(usage);
}
public void testGetDailyCpuPerformanceStatistics() throws Exception {
PerformanceStatistics stats = client.getDailyCpuPerformanceStatistics(URI.create("/cloudapi/ecloud/computepools/89/usage/cpu/performancestatistics/daily"));
public void testGetPerformanceStatistics() throws Exception {
ComputePoolPerformanceStatistics statistics = client.getComputePoolPerformanceStatistics(URI.create("/cloudapi/ecloud/computepools/89/performancestatistics"));
assertNotNull(statistics);
testPerformanceStatistic(statistics.getDaily().getCpu().getHref());
testPerformanceStatistic(statistics.getDaily().getMemory().getHref());
testPerformanceStatistic(statistics.getHourly().getCpu().getHref());
testPerformanceStatistic(statistics.getHourly().getMemory().getHref());
}
private void testPerformanceStatistic(URI uri) {
PerformanceStatistics stats = client.getPerformanceStatistics(uri,null,null);
assertNotNull(stats);
}
public void testGetPerformanceStatisticsWithDateRange() {
ComputePoolPerformanceStatistics statistics = client.getComputePoolPerformanceStatistics(URI.create("/cloudapi/ecloud/computepools/89/performancestatistics"));
URI uri = statistics.getDaily().getCpu().getHref();
Set<PerformanceStatistic> set = getStatsForFirstVM(uri,null,null);
assertEquals(set.size(), 7);
// A subset of the entire results
Date start = Iterables.get(set, 1).getTime();
Date end = Iterables.get(set, set.size()-1).getTime();
Set<PerformanceStatistic> result = getStatsForFirstVM(uri, start, end);
assertEquals(result.size(), 5);
}
private Set<PerformanceStatistic> getStatsForFirstVM(URI uri, Date start, Date end) {
PerformanceStatistics stats = client.getPerformanceStatistics(uri, start, end);
Set<VirtualMachinePerformanceStatistic> virtualMachines = stats.getStatistics().getVirtualMachinesPerformanceStatistics();
return Iterables.getFirst(virtualMachines,null).getStatistics();
}
}

View File

@ -60,7 +60,7 @@ import static org.testng.Assert.assertNull;
*
* @author Jason King
*/
@Test(groups = "unit", testName = "ComputePoolResourceSummaryListJAXBParsingTest")
@Test(groups = "unit", testName = "ComputePoolCpuUsageDetailJAXBParsingTest")
public class ComputePoolCpuUsageDetailJAXBParsingTest extends BaseRestClientTest {
private SimpleDateFormatDateService dateService;

View File

@ -60,7 +60,7 @@ import static org.testng.Assert.assertNull;
*
* @author Jason King
*/
@Test(groups = "unit", testName = "ComputePoolResourceSummaryListJAXBParsingTest")
@Test(groups = "unit", testName = "ComputePoolMemoryUsageDetailJAXBParsingTest")
public class ComputePoolMemoryUsageDetailJAXBParsingTest extends BaseRestClientTest {
private SimpleDateFormatDateService dateService;

View File

@ -61,6 +61,7 @@ import static org.testng.AssertJUnit.assertNotNull;
* @author Jason King
*
*/
@Test(groups = "unit", testName = "HardwareConfigurationJAXBParsingTest")
public class HardwareConfigurationJAXBParsingTest extends BaseRestClientTest {
@BeforeClass

View File

@ -47,6 +47,7 @@ import javax.inject.Named;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Date;
import java.util.Set;
import static org.jclouds.io.Payloads.newInputStreamPayload;
@ -95,8 +96,8 @@ public class PerformanceStatisticsJAXBParsingTest extends BaseRestClientTest {
public void testParseWithJAXB() throws Exception {
Method method = ResourceAsyncClient.class.getMethod("getDailyCpuPerformanceStatistics", URI.class);
HttpRequest request = factory(ResourceAsyncClient.class).createRequest(method,new URI("/1"));
Method method = ResourceAsyncClient.class.getMethod("getPerformanceStatistics", URI.class, Date.class, Date.class);
HttpRequest request = factory(ResourceAsyncClient.class).createRequest(method,new URI("/1"),null,null);
assertResponseParserClassEquals(method, request, ParseXMLWithJAXB.class);
Function<HttpResponse, PerformanceStatistics> parser = (Function<HttpResponse, PerformanceStatistics>) RestAnnotationProcessor

View File

@ -59,7 +59,7 @@ import static org.testng.Assert.assertTrue;
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "TaskHandlerTest")
@Test(groups = "unit", testName = "TaskJAXBParsingTest")
public class TaskJAXBParsingTest extends BaseRestClientTest {
private SimpleDateFormatDateService dateService;
private Task expected1;