diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java index a25690f52a..123f6e326e 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java @@ -27,6 +27,8 @@ import org.jclouds.azurecompute.arm.features.ImageApi; import org.jclouds.azurecompute.arm.features.JobApi; import org.jclouds.azurecompute.arm.features.LoadBalancerApi; import org.jclouds.azurecompute.arm.features.LocationApi; +import org.jclouds.azurecompute.arm.features.MetricDefinitionsApi; +import org.jclouds.azurecompute.arm.features.MetricsApi; import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi; import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi; import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi; @@ -208,4 +210,22 @@ public interface AzureComputeApi extends Closeable { */ @Delegate ImageApi getVirtualMachineImageApi(@PathParam("resourcegroup") String resourcegroup); + + /** + * The metrics API includes operations to get insights into entities within your + * subscription. + * + * @see docs + */ + @Delegate + MetricsApi getMetricsApi(@PathParam("resourceid") String resourceid); + + /** + * The metric definitions API includes operations to get insights available for entities within your + * subscription. + * + * @see docs + */ + @Delegate + MetricDefinitionsApi getMetricsDefinitionsApi(@PathParam("resourceid") String resourceid); } diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java index c35455cd9e..6a5c587b4d 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java @@ -44,6 +44,8 @@ import org.jclouds.azurecompute.arm.features.ImageApi; import org.jclouds.azurecompute.arm.features.LoadBalancerApi; import org.jclouds.azurecompute.arm.features.LocationApi; import org.jclouds.azurecompute.arm.features.DiskApi; +import org.jclouds.azurecompute.arm.features.MetricDefinitionsApi; +import org.jclouds.azurecompute.arm.features.MetricsApi; import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi; import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi; import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi; @@ -115,6 +117,8 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata { properties.put(API_VERSION_PREFIX + AvailabilitySetApi.class.getSimpleName(), "2016-04-30-preview"); properties.put(API_VERSION_PREFIX + DiskApi.class.getSimpleName(), "2017-03-30"); properties.put(API_VERSION_PREFIX + ImageApi.class.getSimpleName(), "2016-04-30-preview"); + properties.put(API_VERSION_PREFIX + MetricDefinitionsApi.class.getSimpleName(), "2017-05-01-preview"); + properties.put(API_VERSION_PREFIX + MetricsApi.class.getSimpleName(), "2016-09-01"); return properties; } diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Metric.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Metric.java new file mode 100644 index 0000000000..0320db24c8 --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Metric.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.domain; + +import java.util.List; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; + +/** + * A Metric with its values for a resource + */ +@AutoValue +public abstract class Metric { + + public abstract List data(); + + public abstract String id(); + + @Nullable + public abstract MetricName name(); + + public abstract String type(); + + public abstract String unit(); + + @SerializedNames({ "data", "id", "name", "type", "unit" }) + public static Metric create(final List data, final String id, final MetricName name, final String type, + final String unit) { + return new AutoValue_Metric(data == null ? ImmutableList. of() : ImmutableList.copyOf(data), id, name, + type, unit); + } + +} diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricData.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricData.java new file mode 100644 index 0000000000..29e810e4b2 --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricData.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.domain; + +import java.util.Date; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import com.google.auto.value.AutoValue; + +/** + * + */ +@AutoValue +public abstract class MetricData +{ + + /** + * The timestamp for the metric value in ISO 8601 format. + */ + public abstract Date timeStamp(); + + /** + * The average value in the time range + */ + @Nullable + public abstract Double total(); + + /** + * The sum of all of the values in the time range. + */ + @Nullable + public abstract Double average(); + + /** + * The least value in the time range. + */ + @Nullable + public abstract Double minimum(); + + /** + * The greatest value in the time range. + */ + @Nullable + public abstract Double maximum(); + + /** + * The number of samples in the time range. + */ + @Nullable + public abstract Long count(); + + @SerializedNames({"timeStamp", "total", "average", "minimum", "maximum", "count"}) + public static MetricData create(final Date timeStamp, final Double total, final Double average, + final Double minimum, final Double maximum, final Long count) + { + return new AutoValue_MetricData(timeStamp, total, average, minimum, maximum, count); + } +} diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricDefinition.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricDefinition.java new file mode 100644 index 0000000000..95f8d47a17 --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricDefinition.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.domain; + +import java.util.List; + +import org.jclouds.azurecompute.arm.util.GetEnumValue; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; + +/** + * A Metric definition for a resource + */ +@AutoValue +public abstract class MetricDefinition { + + public enum AggregationType { + None("None"), Average("Average"), Count("Count"), Total("Total"), Minimum("Minimum"), Maximum( + "Maximum"), UNRECOGNIZED("Unrecognized"); + + private final String label; + + AggregationType(String label) { + this.label = label; + } + + public static AggregationType fromValue(final String text) { + return (AggregationType) GetEnumValue.fromValueOrDefault(text, AggregationType.UNRECOGNIZED); + } + + @Override + public String toString() { + return label; + } + } + + @Nullable + public abstract String resourceId(); + + public abstract MetricName name(); + + @Nullable + public abstract Boolean isDimensionRequired(); + + public abstract String unit(); + + public abstract AggregationType primaryAggregationType(); + + public abstract List metricAvailabilities(); + + public abstract String id(); + + @SerializedNames({ "resourceId", "name", "isDimensionRequired", "unit", "primaryAggregationType", + "metricAvailabilities", "id" }) + public static MetricDefinition create(final String resourceId, final MetricName name, + final Boolean isDimensionRequired, final String unit, final AggregationType primaryAggregationType, + List metricAvailabilities, final String id) { + return new AutoValue_MetricDefinition(resourceId, name, isDimensionRequired, unit, primaryAggregationType, + metricAvailabilities == null ? + ImmutableList. of() : + ImmutableList.copyOf(metricAvailabilities), id); + } + + @AutoValue + public abstract static class MetricAvailability { + + public abstract String timeGrain(); + + public abstract String retention(); + + MetricAvailability() { + + } + + @SerializedNames({ "timeGrain", "retention" }) + public static MetricDefinition.MetricAvailability create(String timeGrain, String retention) { + return new AutoValue_MetricDefinition_MetricAvailability(timeGrain, retention); + } + } +} diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricName.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricName.java new file mode 100644 index 0000000000..7caf52ed67 --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/MetricName.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.domain; + +import org.jclouds.json.SerializedNames; + +import com.google.auto.value.AutoValue; + +/** + * A Metric with its values for a resource + */ +@AutoValue +public abstract class MetricName { + + public abstract String value(); + + public abstract String localizedValue(); + + @SerializedNames({ "value", "localizedValue" }) + public static MetricName create(String value, String localizedValue) { + return new AutoValue_MetricName(value, localizedValue); + } + +} diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApi.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApi.java new file mode 100644 index 0000000000..ba62a28ecf --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApi.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.features; + +import java.util.List; +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404; +import org.jclouds.azurecompute.arm.domain.MetricDefinition; +import org.jclouds.azurecompute.arm.filters.ApiVersionFilter; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.oauth.v2.filters.OAuthFilter; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SelectJson; + +/** + * This Azure Resource Manager API provides all the metric definitions available for a given resource + *

+ * + * @see docs + */ +@Path("/{resourceid}") +@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class }) +@Consumes(MediaType.APPLICATION_JSON) +public interface MetricDefinitionsApi { + @Named("metrics:list") + @Path("/providers/microsoft.insights/metricdefinitions") + @GET + @SelectJson("value") + @Fallback(EmptyListOnNotFoundOr404.class) + List list(@Nullable @QueryParam("$filter") String filter); +} diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/MetricsApi.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/MetricsApi.java new file mode 100644 index 0000000000..03d19a193b --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/MetricsApi.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.features; + +import java.util.List; +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404; +import org.jclouds.azurecompute.arm.domain.Metric; +import org.jclouds.azurecompute.arm.filters.ApiVersionFilter; +import org.jclouds.oauth.v2.filters.OAuthFilter; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SelectJson; + +/** + * This Azure Resource Manager API provides all the metric data available for a given resource + *

+ * + * @see docs + */ +@Path("/{resourceid}") +@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class }) +@Consumes(MediaType.APPLICATION_JSON) +public interface MetricsApi { + @Named("metrics:list") + @Path("/providers/microsoft.insights/metrics") + @GET + @SelectJson("value") + @Fallback(EmptyListOnNotFoundOr404.class) + List list(@QueryParam("$filter") String filter); +} diff --git a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApiLiveTest.java b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApiLiveTest.java new file mode 100644 index 0000000000..cb8027face --- /dev/null +++ b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApiLiveTest.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.features; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.getOnlyElement; +import static org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions.Builder.resourceGroup; +import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED; +import static org.jclouds.compute.predicates.NodePredicates.inGroup; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.net.URI; +import java.util.List; +import java.util.Properties; + +import org.jclouds.azurecompute.arm.AzureComputeApi; +import org.jclouds.azurecompute.arm.domain.IdReference; +import org.jclouds.azurecompute.arm.domain.MetricDefinition; +import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils; +import org.jclouds.compute.RunNodesException; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import com.google.inject.name.Names; + +@Test(groups = "live", singleThreaded = true) +public class MetricDefinitionsApiLiveTest extends BaseComputeServiceContextLiveTest { + + private Predicate resourceDeleted; + private AzureComputeApi api; + + private String location; + private MetricDefinitionsApi metricDefinitionsApi; + + private String group; + + public MetricDefinitionsApiLiveTest() { + provider = "azurecompute-arm"; + group = getClass().getSimpleName().toLowerCase(); + } + + @Override + protected Properties setupProperties() { + Properties properties = super.setupProperties(); + AzureLiveTestUtils.defaultProperties(properties); + checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint"); + return properties; + } + + @Override + protected void initializeContext() { + super.initializeContext(); + resourceDeleted = context.utils().injector().getInstance(Key.get(new TypeLiteral>() { + }, Names.named(TIMEOUT_RESOURCE_DELETED))); + api = view.unwrapApi(AzureComputeApi.class); + } + + @Override + @BeforeClass + public void setupContext() { + super.setupContext(); + NodeMetadata node = null; + try { + node = getOnlyElement(view.getComputeService().createNodesInGroup(group, 1, resourceGroup(group))); + } catch (RunNodesException e) { + fail(); + } + String resourceId = String.format("/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s", + IdReference.extractResourceGroup(node.getProviderId()), IdReference.extractName(node.getProviderId())); + + location = view.getComputeService().templateBuilder().build().getLocation().getId(); + view.unwrapApi(AzureComputeApi.class).getResourceGroupApi().create(group, location, null); + metricDefinitionsApi = api.getMetricsDefinitionsApi(resourceId); + } + + @Override + @AfterClass(alwaysRun = true) + protected void tearDownContext() { + try { + view.getComputeService().destroyNodesMatching(inGroup(group)); + } finally { + try { + URI uri = api.getResourceGroupApi().delete(group); + assertResourceDeleted(uri); + } finally { + super.tearDownContext(); + } + } + } + + public void listVirtualMachineMetricDefinitions() { + List result = metricDefinitionsApi.list("name.value eq 'Percentage CPU'"); + + // verify we have something + assertNotNull(result); + assertTrue(result.size() > 1); + assertEquals(result.get(0).name().value(), "Percentage CPU"); + } + + private void assertResourceDeleted(final URI uri) { + if (uri != null) { + assertTrue(resourceDeleted.apply(uri), + String.format("Resource %s was not deleted in the configured timeout", uri)); + } + } + +} + diff --git a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApiMockTest.java b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApiMockTest.java new file mode 100644 index 0000000000..8fd06b8d6f --- /dev/null +++ b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricDefinitionsApiMockTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.features; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import org.jclouds.azurecompute.arm.domain.MetricDefinition; +import org.jclouds.azurecompute.arm.domain.MetricName; +import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.squareup.okhttp.mockwebserver.MockResponse; + +@Test(groups = "unit", testName = "MetricDefinitionsApiMockTest", singleThreaded = true) +public class MetricDefinitionsApiMockTest extends BaseAzureComputeApiMockTest { + + private final String resourceId = "resourceGroups/myresourceGroup/providers/Microsoft.Compute/virtualMachines/myvm"; + private final String filter = "(name.value eq 'Percentage CPU')"; + + public void testList() throws Exception { + server.enqueue(jsonResponse("/metricdefinitions.json")); + final MetricDefinitionsApi metricDefinitionsApi = api.getMetricsDefinitionsApi(resourceId); + assertEquals(metricDefinitionsApi.list(filter), ImmutableList.of(MetricDefinition.create( + "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup/providers/Microsoft" + + ".Compute/virtualMachines/myvm", MetricName.create("Percentage CPU", "Percentage CPU"), + Boolean.FALSE, "Percent", MetricDefinition.AggregationType.Average, + ImmutableList. of( + MetricDefinition.MetricAvailability.create("PT1M", "P30D"), + MetricDefinition.MetricAvailability.create("PT1H", "P30D")), + "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup/providers" + + "/Microsoft.Compute/virtualMachines/myvm/providers/microsoft" + + ".insights/metricdefinitions/Percentage " + "CPU"))); + assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourceGroup/providers/Microsoft" + + ".Compute/virtualMachines/myvm/providers/microsoft.insights/metricdefinitions?$filter=%28name" + + ".value%20eq%20%27Percentage%20CPU%27%29&api-version=2017-05-01-preview"); + } + + public void testEmptyList() throws Exception { + server.enqueue(new MockResponse().setResponseCode(404)); + + final MetricDefinitionsApi metricDefinitionsApi = api.getMetricsDefinitionsApi(resourceId); + + assertTrue(metricDefinitionsApi.list(filter).isEmpty()); + + assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourceGroup/providers/Microsoft" + + ".Compute/virtualMachines/myvm/providers/microsoft.insights/metricdefinitions?$filter=%28name" + + ".value%20eq%20%27Percentage%20CPU%27%29&api-version=2017-05-01-preview"); + } +} diff --git a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricsApiLiveTest.java b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricsApiLiveTest.java new file mode 100644 index 0000000000..5fe19db348 --- /dev/null +++ b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricsApiLiveTest.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.features; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.getOnlyElement; +import static org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions.Builder.resourceGroup; +import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED; +import static org.jclouds.compute.predicates.NodePredicates.inGroup; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.net.URI; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import org.jclouds.azurecompute.arm.AzureComputeApi; +import org.jclouds.azurecompute.arm.domain.IdReference; +import org.jclouds.azurecompute.arm.domain.Metric; +import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils; +import org.jclouds.compute.RunNodesException; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import com.google.inject.name.Names; + +@Test(groups = "live", singleThreaded = true) +public class MetricsApiLiveTest extends BaseComputeServiceContextLiveTest { + + private Predicate resourceDeleted; + private AzureComputeApi api; + + private String location; + private MetricsApi metricsApi; + + private String group; + + private String startTime; + private SimpleDateFormat dateFormat; + + public MetricsApiLiveTest() { + provider = "azurecompute-arm"; + group = getClass().getSimpleName().toLowerCase(); + } + + @Override + protected Properties setupProperties() { + Properties properties = super.setupProperties(); + AzureLiveTestUtils.defaultProperties(properties); + checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint"); + return properties; + } + + @Override + protected void initializeContext() { + super.initializeContext(); + resourceDeleted = context.utils().injector().getInstance(Key.get(new TypeLiteral>() { + }, Names.named(TIMEOUT_RESOURCE_DELETED))); + api = view.unwrapApi(AzureComputeApi.class); + } + + @Override + @BeforeClass + public void setupContext() { + super.setupContext(); + + dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + startTime = dateFormat.format(new Date()); + + NodeMetadata node = null; + try { + node = getOnlyElement(view.getComputeService().createNodesInGroup(group, 1, resourceGroup(group))); + } catch (RunNodesException e) { + fail(); + } + String resourceId = String.format("/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s", + IdReference.extractResourceGroup(node.getProviderId()), IdReference.extractName(node.getProviderId())); + + location = view.getComputeService().templateBuilder().build().getLocation().getId(); + view.unwrapApi(AzureComputeApi.class).getResourceGroupApi().create(group, location, null); + metricsApi = api.getMetricsApi(resourceId); + } + + @Override + @AfterClass(alwaysRun = true) + protected void tearDownContext() { + try { + view.getComputeService().destroyNodesMatching(inGroup(group)); + } finally { + try { + URI uri = api.getResourceGroupApi().delete(group); + assertResourceDeleted(uri); + } finally { + super.tearDownContext(); + } + } + } + + public void listVirtualMachineMetrics() throws RunNodesException { + List result = metricsApi + .list("(name.value eq 'Percentage CPU') and startTime eq " + startTime + " and endTime eq " + dateFormat + .format(new Date()) + " and timeGrain eq duration'PT1M'"); + + // verify we have something + assertNotNull(result); + assertEquals(result.size(), 1); + assertEquals(result.get(0).name().value(), "Percentage CPU"); + assertTrue(result.get(0).data().size() > 1); + } + + private void assertResourceDeleted(final URI uri) { + if (uri != null) { + assertTrue(resourceDeleted.apply(uri), + String.format("Resource %s was not deleted in the configured timeout", uri)); + } + } + +} + diff --git a/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricsApiMockTest.java b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricsApiMockTest.java new file mode 100644 index 0000000000..c6e30c1c4d --- /dev/null +++ b/providers/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/MetricsApiMockTest.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.features; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.Locale; + +import org.jclouds.azurecompute.arm.domain.Metric; +import org.jclouds.azurecompute.arm.domain.MetricData; +import org.jclouds.azurecompute.arm.domain.MetricName; +import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.squareup.okhttp.mockwebserver.MockResponse; + +@Test(groups = "unit", testName = "MetricsApiMockTest", singleThreaded = true) +public class MetricsApiMockTest extends BaseAzureComputeApiMockTest { + + private final String resourceId = "resourceGroups/myresourceGroup/providers/Microsoft.Compute/virtualMachines/myvm"; + private final String filter = "(name.value eq 'Percentage CPU') and startTime eq 2017-06-01T11:14:00Z and " + + "endTime eq 2017-06-01T11:23:00Z and timeGrain eq duration'PT1M'"; + + public void testList() throws Exception { + server.enqueue(jsonResponse("/metrics.json")); + final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US); + final MetricsApi metricsApi = api.getMetricsApi(resourceId); + assertEquals(metricsApi.list(filter), ImmutableList.of(Metric.create(ImmutableList.of(MetricData + .create(dateFormat.parse("2017-06-01T07:14:00", new ParsePosition(0)), null, + Double.valueOf(0.295), null, null, null)), + "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup/providers" + + "/Microsoft.Compute/virtualMachines/myvm/providers/Microsoft.Insights/metrics/Percentage CPU", + MetricName.create("Percentage CPU", "Percentage CPU"), "Microsoft.Insights/metrics", "Percent"))); + assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourceGroup/providers/Microsoft" + + ".Compute/virtualMachines/myvm/providers/microsoft.insights/metrics?$filter=%28name" + + ".value%20eq%20%27Percentage%20CPU%27%29%20and%20startTime%20eq%202017-06-01T11%3A14%3A00Z%20and" + + "%20endTime%20eq%202017-06-01T11%3A23%3A00Z%20and%20timeGrain%20eq%20duration%27PT1M%27&api-version" + + "=2016-09-01"); + } + + public void testEmptyList() throws Exception { + server.enqueue(new MockResponse().setResponseCode(404)); + + final MetricsApi metricsAPI = api.getMetricsApi(resourceId); + + assertTrue(metricsAPI.list(filter).isEmpty()); + + assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourceGroup/providers/Microsoft" + + ".Compute/virtualMachines/myvm/providers/microsoft.insights/metrics?$filter=%28name" + + ".value%20eq%20%27Percentage%20CPU%27%29%20and%20startTime%20eq%202017-06-01T11%3A14%3A00Z%20and" + + "%20endTime%20eq%202017-06-01T11%3A23%3A00Z%20and%20timeGrain%20eq%20duration%27PT1M%27&api-version" + + "=2016-09-01"); + } +} diff --git a/providers/azurecompute-arm/src/test/resources/metricdefinitions.json b/providers/azurecompute-arm/src/test/resources/metricdefinitions.json new file mode 100644 index 0000000000..3df0a84089 --- /dev/null +++ b/providers/azurecompute-arm/src/test/resources/metricdefinitions.json @@ -0,0 +1,25 @@ +{ + "value": [ + { + "id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup/providers/Microsoft.Compute/virtualMachines/myvm/providers/microsoft.insights/metricdefinitions/Percentage CPU", + "resourceId": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup/providers/Microsoft.Compute/virtualMachines/myvm", + "name": { + "value": "Percentage CPU", + "localizedValue": "Percentage CPU" + }, + "isDimensionRequired": false, + "unit": "Percent", + "primaryAggregationType": "Average", + "metricAvailabilities": [ + { + "timeGrain": "PT1M", + "retention": "P30D" + }, + { + "timeGrain": "PT1H", + "retention": "P30D" + } + ] + } + ] +} diff --git a/providers/azurecompute-arm/src/test/resources/metrics.json b/providers/azurecompute-arm/src/test/resources/metrics.json new file mode 100644 index 0000000000..754e5d19c1 --- /dev/null +++ b/providers/azurecompute-arm/src/test/resources/metrics.json @@ -0,0 +1,19 @@ +{ + "value": [ + { + "data": [ + { + "timeStamp": "2017-06-01T11:14:00Z", + "average": 0.295 + } + ], + "id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup/providers/Microsoft.Compute/virtualMachines/myvm/providers/Microsoft.Insights/metrics/Percentage CPU", + "name": { + "value": "Percentage CPU", + "localizedValue": "Percentage CPU" + }, + "type": "Microsoft.Insights/metrics", + "unit": "Percent" + } + ] +}