summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorØyvind Grønnesby <oyving@verizonmedia.com>2020-02-11 21:02:14 +0100
committerGitHub <noreply@github.com>2020-02-11 21:02:14 +0100
commit9b2d74a9f81fc973a858ff80a2f9b3cc568526b2 (patch)
tree006f4dfa65d505e4af7d9ddd6a05a70988a9d2f5
parent0200e6c6c57c69f4a877d3f5eccb0b9eeb79f293 (diff)
parent7ee5738452cbae5413bfc6fb904290a0474dd0ae (diff)
Merge pull request #12155 from vespa-engine/olaa/get-raw-snapshot-history
Get raw snapshot history for tenant
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringClient.java6
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringData.java (renamed from controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringInfo.java)4
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMeteringClient.java24
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java15
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java1
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java39
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java20
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/metering.json18
9 files changed, 112 insertions, 19 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringClient.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringClient.java
index 3e06b24c6be..1047e1a02a4 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringClient.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringClient.java
@@ -4,7 +4,9 @@ package com.yahoo.vespa.hosted.controller.api.integration.resource;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.TenantName;
+import java.time.YearMonth;
import java.util.Collection;
+import java.util.List;
/**
* Consumes and retrieves snapshots of resources allocated per application.
@@ -15,6 +17,8 @@ public interface MeteringClient {
void consume(Collection<ResourceSnapshot> resources);
- MeteringInfo getResourceSnapshots(TenantName tenantName, ApplicationName applicationName);
+ MeteringData getMeteringData(TenantName tenantName, ApplicationName applicationName);
+
+ List<ResourceSnapshot> getSnapshotHistoryForTenant(TenantName tenantName, YearMonth yearMonth);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringInfo.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringData.java
index d6cb8f7fe76..e9a6c81e636 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringInfo.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/MeteringData.java
@@ -9,14 +9,14 @@ import java.util.Map;
/**
* @author olaa
*/
-public class MeteringInfo {
+public class MeteringData {
private final ResourceAllocation thisMonth;
private final ResourceAllocation lastMonth;
private final ResourceAllocation currentSnapshot;
Map<ApplicationId, List<ResourceSnapshot>> snapshotHistory;
- public MeteringInfo(ResourceAllocation thisMonth, ResourceAllocation lastMonth, ResourceAllocation currentSnapshot, Map<ApplicationId, List<ResourceSnapshot>> snapshotHistory) {
+ public MeteringData(ResourceAllocation thisMonth, ResourceAllocation lastMonth, ResourceAllocation currentSnapshot, Map<ApplicationId, List<ResourceSnapshot>> snapshotHistory) {
this.thisMonth = thisMonth;
this.lastMonth = lastMonth;
this.currentSnapshot = currentSnapshot;
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMeteringClient.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMeteringClient.java
index 45ead36f622..80caef1709d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMeteringClient.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMeteringClient.java
@@ -3,16 +3,19 @@ package com.yahoo.vespa.hosted.controller.api.integration.stubs;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.TenantName;
-import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringInfo;
+import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringData;
import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceAllocation;
import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceSnapshot;
import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringClient;
+import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import java.util.stream.Collectors;
/**
* @author olaa
@@ -20,7 +23,7 @@ import java.util.Optional;
public class MockMeteringClient implements MeteringClient {
private Collection<ResourceSnapshot> resources = new ArrayList<>();
- private Optional<MeteringInfo> meteringInfo;
+ private Optional<MeteringData> meteringData;
@Override
public void consume(Collection<ResourceSnapshot> resources){
@@ -28,18 +31,25 @@ public class MockMeteringClient implements MeteringClient {
}
@Override
- public MeteringInfo getResourceSnapshots(TenantName tenantName, ApplicationName applicationName) {
- return meteringInfo.orElseGet(() -> {
+ public MeteringData getMeteringData(TenantName tenantName, ApplicationName applicationName) {
+ return meteringData.orElseGet(() -> {
ResourceAllocation emptyAllocation = new ResourceAllocation(0, 0, 0);
- return new MeteringInfo(emptyAllocation, emptyAllocation, emptyAllocation, Collections.emptyMap());
+ return new MeteringData(emptyAllocation, emptyAllocation, emptyAllocation, Collections.emptyMap());
});
}
+ @Override
+ public List<ResourceSnapshot> getSnapshotHistoryForTenant(TenantName tenantName, YearMonth yearMonth) {
+ return new ArrayList<>(resources);
+ }
+
public Collection<ResourceSnapshot> consumedResources() {
return this.resources;
}
- public void setMeteringInfo(MeteringInfo meteringInfo) {
- this.meteringInfo = Optional.of(meteringInfo);
+ public void setMeteringData(MeteringData meteringData) {
+ this.meteringData = Optional.of(meteringData);
+ this.resources = meteringData.getSnapshotHistory().entrySet().stream().map(Map.Entry::getValue).flatMap(List::stream).collect(Collectors.toList());
+ boolean a = false;
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index bf1b6c5ab84..f37304025ac 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -56,7 +56,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision;
import com.yahoo.vespa.hosted.controller.api.integration.resource.CostInfo;
-import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringInfo;
+import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringData;
import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceAllocation;
import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceSnapshot;
import com.yahoo.vespa.hosted.controller.api.role.Role;
@@ -1272,33 +1272,34 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
}
private HttpResponse metering(String tenant, String application, HttpRequest request) {
+
Slime slime = new Slime();
Cursor root = slime.setObject();
- MeteringInfo meteringInfo = controller.serviceRegistry()
+ MeteringData meteringData = controller.serviceRegistry()
.meteringService()
- .getResourceSnapshots(TenantName.from(tenant), ApplicationName.from(application));
+ .getMeteringData(TenantName.from(tenant), ApplicationName.from(application));
- ResourceAllocation currentSnapshot = meteringInfo.getCurrentSnapshot();
+ ResourceAllocation currentSnapshot = meteringData.getCurrentSnapshot();
Cursor currentRate = root.setObject("currentrate");
currentRate.setDouble("cpu", currentSnapshot.getCpuCores());
currentRate.setDouble("mem", currentSnapshot.getMemoryGb());
currentRate.setDouble("disk", currentSnapshot.getDiskGb());
- ResourceAllocation thisMonth = meteringInfo.getThisMonth();
+ ResourceAllocation thisMonth = meteringData.getThisMonth();
Cursor thismonth = root.setObject("thismonth");
thismonth.setDouble("cpu", thisMonth.getCpuCores());
thismonth.setDouble("mem", thisMonth.getMemoryGb());
thismonth.setDouble("disk", thisMonth.getDiskGb());
- ResourceAllocation lastMonth = meteringInfo.getLastMonth();
+ ResourceAllocation lastMonth = meteringData.getLastMonth();
Cursor lastmonth = root.setObject("lastmonth");
lastmonth.setDouble("cpu", lastMonth.getCpuCores());
lastmonth.setDouble("mem", lastMonth.getMemoryGb());
lastmonth.setDouble("disk", lastMonth.getDiskGb());
- Map<ApplicationId, List<ResourceSnapshot>> history = meteringInfo.getSnapshotHistory();
+ Map<ApplicationId, List<ResourceSnapshot>> history = meteringData.getSnapshotHistory();
Cursor details = root.setObject("details");
Cursor detailsCpu = details.setObject("cpu");
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java
index ad847621c3e..ea3559a92ae 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java
@@ -70,6 +70,7 @@ public class ControllerApiHandler extends AuditLoggingRequestHandler {
if (path.matches("/controller/v1/auditlog/")) return new AuditLogResponse(controller.auditLogger().readLog());
if (path.matches("/controller/v1/maintenance/")) return new JobsResponse(maintenance.jobControl());
if (path.matches("/controller/v1/jobs/upgrader")) return new UpgraderResponse(maintenance.upgrader());
+ if (path.matches("/controller/v1/metering/tenant/{tenant}/month/{month}")) return new MeteringResponse(controller.serviceRegistry().meteringService(), path.get("tenant"), path.get("month"));
return notFound(path);
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java
new file mode 100644
index 00000000000..23e3195db01
--- /dev/null
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/MeteringResponse.java
@@ -0,0 +1,39 @@
+// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.restapi.controller;
+
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.restapi.SlimeJsonResponse;
+import com.yahoo.slime.Cursor;
+import com.yahoo.slime.Slime;
+import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringClient;
+import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceSnapshot;
+
+import java.time.YearMonth;
+import java.util.List;
+
+/**
+ * @author olaa
+ */
+public class MeteringResponse extends SlimeJsonResponse {
+
+ public MeteringResponse(MeteringClient meteringClient, String tenantName, String month) {
+ super(toSlime(meteringClient, tenantName, month));
+ }
+
+ private static Slime toSlime(MeteringClient meteringClient, String tenantName, String month) {
+ Slime slime = new Slime();
+ Cursor root = slime.setArray();
+ List<ResourceSnapshot> snapshots = meteringClient.getSnapshotHistoryForTenant(TenantName.from(tenantName), YearMonth.parse(month));
+ snapshots.forEach(snapshot -> {
+ Cursor object = root.addObject();
+ object.setString("applicationId", snapshot.getApplicationId().toShortString());
+ object.setLong("timestamp", snapshot.getTimestamp().toEpochMilli());
+ object.setString("zoneId", snapshot.getZoneId().value());
+ object.setDouble("cpu", snapshot.getCpuCores());
+ object.setDouble("memory", snapshot.getMemoryGb());
+ object.setDouble("disk", snapshot.getDiskGb());
+ });
+ return slime;
+ }
+
+}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index 0f846ab57e4..fb7d54759f8 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -40,7 +40,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
import com.yahoo.vespa.hosted.controller.api.integration.resource.CostInfo;
-import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringInfo;
+import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringData;
import com.yahoo.vespa.hosted.controller.api.integration.resource.MockTenantCost;
import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceAllocation;
import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceSnapshot;
@@ -944,7 +944,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
new ResourceSnapshot(applicationId, 1, 2,3, Instant.ofEpochMilli(246), ZoneId.defaultId()),
new ResourceSnapshot(applicationId, 1, 2,3, Instant.ofEpochMilli(492), ZoneId.defaultId())));
- mockMeteringClient.setMeteringInfo(new MeteringInfo(thisMonth, lastMonth, currentSnapshot, snapshotHistory));
+ mockMeteringClient.setMeteringData(new MeteringData(thisMonth, lastMonth, currentSnapshot, snapshotHistory));
tester.assertResponse(request("/application/v4/tenant/doesnotexist/application/doesnotexist/metering", GET)
.userIdentity(USER_ID)
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java
index b21c588235e..8029d650b75 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiTest.java
@@ -2,8 +2,11 @@
package com.yahoo.vespa.hosted.controller.restapi.controller;
import com.yahoo.application.container.handler.Request;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.test.ManualClock;
+import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceSnapshot;
import com.yahoo.vespa.hosted.controller.auditlog.AuditLogger;
import com.yahoo.vespa.hosted.controller.restapi.ContainerTester;
import com.yahoo.vespa.hosted.controller.restapi.ControllerContainerTest;
@@ -15,6 +18,7 @@ import java.io.File;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
+import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertFalse;
@@ -156,4 +160,20 @@ public class ControllerApiTest extends ControllerContainerTest {
tester.assertResponse(authenticatedRequest("http://localhost:8080/controller/v1/auditlog/"), new File("auditlog.json"));
}
+ @Test
+ public void testMeteringApi() {
+ ApplicationId applicationId = ApplicationId.from("tenant", "app", "instance");
+ Instant timestamp = Instant.ofEpochMilli(123456789);
+ ZoneId zoneId = ZoneId.defaultId();
+ List<ResourceSnapshot> snapshots = List.of(
+ new ResourceSnapshot(applicationId, 12,48,1200, timestamp, zoneId),
+ new ResourceSnapshot(applicationId, 24, 96,2400, timestamp, zoneId)
+ );
+ tester.controller().serviceRegistry().meteringService().consume(snapshots);
+ tester.assertResponse(
+ operatorRequest("http://localhost:8080/controller/v1/metering/tenant/tenantName/month/2020-02", "", Request.Method.GET),
+ new File("metering.json")
+ );
+ }
+
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/metering.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/metering.json
new file mode 100644
index 00000000000..b64e8f26a63
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/metering.json
@@ -0,0 +1,18 @@
+[
+ {
+ "applicationId": "tenant.app.instance",
+ "timestamp": 123456789,
+ "zoneId": "prod.default",
+ "cpu": 12.0,
+ "memory": 48.0,
+ "disk": 1200.0
+ },
+ {
+ "applicationId": "tenant.app.instance",
+ "timestamp": 123456789,
+ "zoneId": "prod.default",
+ "cpu": 24.0,
+ "memory": 96.0,
+ "disk": 2400.0
+ }
+] \ No newline at end of file