Push metering data from within a service instance.
Usage notes
-
This operation pushes metering data only for pay-as-you-go Compute Nest service instances. The reporting method for the billable items must be set to Reported by Service Provider.
-
For ECS or ACK instances created by a Compute Nest service, you can call this operation directly from within the instance to push metering data. To call this operation by using OpenAPI, see Call PushMeteringData by using OpenAPI.
Request parameters
|
Parameter |
Type |
Required |
Description |
Example |
|
Metering |
String |
Yes |
The metering data as a JSON string. The following parameters are included:
Note
|
|
|
Token |
String |
Yes |
A token used by Compute Nest to verify that the request is from a legitimate service provider. The token is the 32-character lowercase MD5 hash of a string. This string is constructed by concatenating the
|
|
Response parameters
|
Parameter |
Type |
Description |
Example |
||
|
RequestId |
String |
The request ID returned by Compute Nest. |
e6862d3a-9305-4289-8dd3-9c52a680228b |
||
|
Success |
Boolean |
Indicates whether the request was successful. |
true |
||
|
PushMeteringDataRequestId |
String |
The request ID returned by Alibaba Cloud Marketplace. |
7lc658a2-tr41---c25es45vc248 |
||
|
Token |
String |
The returned digital signature. You can use this token to verify the response. For more information, see Verify a digital signature from Compute Nest. |
50130a063c6acf833280d23169898bd4 |
Examples
This example shows how to call the operation from an ECS instance that was created by a pay-as-you-go Compute Nest service from Alibaba Cloud Marketplace.
curl example
-
Obtain the region ID of the ECS instance
Before calling this operation, obtain the region ID of the ECS instance where your application is deployed. You will need this ID in a later step.
-
Run the following command to query the region ID from the instance metadata service:
curl http://100.100.100.200/latest/meta-data/region-id -
Sample response:
cn-hangzhou
-
-
Prepare the parameters
"Metering":"[{\"StartTime\":\"1664451045\",\"EndTime\":\"1664451198\",\"Entities\":[{\"Key\":\"Frequency\",\"Value\":\"6\"}]}]","Token":"7aa81300b2aea77984b772495c8e4e83"-
Metering:[{\"StartTime\":\"1664451045\",\"EndTime\":\"1664451198\",\"Entities\":[{\"Key\":\"Frequency\",\"Value\":\"6\"}]}]NoteBecause this example uses a curl command, the JSON string for the
Meteringparameter must be escaped with the\character. If you call the operation from your code, you do not need to escape the string. -
Token: Generate the token by creating a 32-character lowercase MD5 hash of the string that concatenates the stringifiedMeteringJSON, an ampersand (&), and your service key. The token in this example is7aa81300b2aea77984b772495c8e4e83.
-
-
Send the request
curl -H "Content-Type: application/json" -XPOST https://cn-hangzhou.axt.aliyun.com/computeNest/marketplace/push_metering_data -d '{"Metering":"[{\"StartTime\":\"1664451045\",\"EndTime\":\"1664451198\",\"Entities\":[{\"Key\":\"Frequency\",\"Value\":\"6\"}]}]","Token":"7aa81300b2aea77984b772495c8e4e83"}'NoteIn
https://cn-hangzhou.axt.aliyun.com,cn-hangzhouis the region that you obtained in Step 1. When you make a call, replace the region information with your actual region. -
View the response
{ "RequestId":"4ca591b5-bc30-****-****-c4d0ec5d24ed", "Success":"true", "PushMeteringDataRequestId":"7lc658a2-tr41-****-****-c25es45vc248", "Token":"50130a063c6acf833280d23169898bd4" }
Code examples
Python
import requests
import json
import hashlib
import time
import sys
from urllib.request import urlopen
def get_region_id():
"""Gets the region ID from the Alibaba Cloud instance metadata service."""
try:
with urlopen(
"http://100.100.100.200/latest/meta-data/region-id",
timeout=2
) as response:
return response.read().decode().strip()
except Exception as e:
print(f"Failed to get region ID: {str(e)}", file=sys.stderr)
sys.exit(1)
def push_metering_data(entities_map, service_key):
# Get the current time as a UNIX timestamp in seconds.
current_time = int(time.time())
start_time = current_time
end_time = current_time + 1
# Construct the Metering data.
metering_data = [
{
"StartTime": str(start_time),
"EndTime": str(end_time),
"Entities": [
{"Key": key, "Value": str(value)}
for key, value in entities_map.items()
]
}
]
metering_str = json.dumps(metering_data)
# Get the region ID and construct the request URL.
region_id = get_region_id()
url = f"https://{region_id}.axt.aliyun.com/computeNest/marketplace/push_metering_data"
# Calculate the token.
token_str = metering_str + "&" + service_key
token = hashlib.md5(token_str.encode()).hexdigest().lower()
# Send the POST request.
try:
response = requests.post(
url,
json={
"Metering": metering_str,
"Token": token
},
headers={"Content-Type": "application/json"}
)
print(f"Request URL: {url}")
print(f"Status Code: {response.status_code}")
print(f"Response: {response.text}")
except Exception as e:
print(f"Request Failed: {str(e)}", file=sys.stderr)
if __name__ == "__main__":
# Sample parameters. Replace the key with your billable item and the value with the metered quantity.
entities = {
"Frequency": "6"
}
# Your service key.
service_key = "your_service_key_here"
# Call the function.
push_metering_data(entities, service_key)
Sample run:
[root@xxx aZ ~]# vim push.py
[root@xxx aZ ~]# python3 push.py
Request URL: https://cn-hangzhou.axt.aliyun.com/computeNest/marketplace/push_metering_data
Status Code: 200
Response: {"code":200,"requestId":"5979658a-7d11-4c61-xxx","instanceId":"i-bp140hj xxx","result":{"RequestId":"B3588CBD-6C3F-51C7-xxx","PushMeteringDataRequestId":"88D8CADB-2417-5417-504-xxx","Token":"xxx"},"Success":true}
Java
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
public class MeteringPusher {
public static void main(String[] args) {
try {
// Get the region ID dynamically.
String regionId = getRegionId();
System.out.println("Detected Region ID: " + regionId);
// Construct the request body.
Map<String, String> entities = new HashMap<>(); // Construct the Entities. Replace with your actual data.
entities.put("Frequency", "6");
String serviceKey = "your_service_key_here"; // Replace with your actual service key.
JSONObject payload = generateDynamicRequest(regionId, entities, serviceKey);
String paylodString = payload.toString();
// For testing purposes, you can comment out the dynamic generation and use a static payload string. Remember to replace the parameters.
// String paylodString = "{\"Metering\":\"[{\\\"StartTime\\\":\\\"1664451045\\\",\\\"EndTime\\\":\\\"1664451198\\\",\\\"Entities\\\":[{\\\"Key\\\":\\\"Frequency\\\",\\\"Value\\\":\\\"6\\\"}]}]\",\"Token\":\"7aa81300b2aea77984b772495c8e4e83\"}";
// Send the POST request.
String urlStr = "https://" + regionId + ".axt.aliyun.com/computeNest/marketplace/push_metering_data";
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = paylodString.getBytes("UTF-8");
os.write(input, 0, input.length);
}
// Read the response.
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String responseLine;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine);
}
conn.disconnect();
System.out.println("Response: " + response.toString());
System.out.println("Request URL: " + urlStr);
} catch (Exception e) {
e.printStackTrace();
}
}
// Get the region ID from the Alibaba Cloud instance metadata service.
private static String getRegionId() throws Exception {
String regionIdUrl = "http://100.100.100.200/latest/meta-data/region-id";
HttpURLConnection conn = (HttpURLConnection) new URL(regionIdUrl).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(2000); // 2-second timeout
conn.setReadTimeout(2000);
try (BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()))) {
return in.readLine().trim();
}
}
// Generate the request data dynamically.
private static JSONObject generateDynamicRequest(String regionId, Map<String, String> entities, String serviceKey) throws Exception {
// Get the current timestamp.
long currentTime = System.currentTimeMillis() / 1000;
long startTime = currentTime;
long endTime = currentTime + 1;
// Construct the Metering data.
JSONArray meteringArray = new JSONArray();
JSONObject meteringItem = new JSONObject();
meteringItem.put("StartTime", String.valueOf(startTime));
meteringItem.put("EndTime", String.valueOf(endTime));
JSONArray entitiesArray = new JSONArray();
for (Map.Entry<String, String> entry : entities.entrySet()) {
entitiesArray.put(new JSONObject()
.put("Key", entry.getKey())
.put("Value", entry.getValue()));
}
meteringItem.put("Entities", entitiesArray);
meteringArray.put(meteringItem);
// Calculate the token.
String meteringStr = meteringArray.toString();
String tokenStr = meteringStr + "&" + serviceKey;
String token = md5(tokenStr);
// Construct the complete request payload.
JSONObject payload = new JSONObject();
payload.put("Metering", meteringStr);
payload.put("Token", token);
return payload;
}
// Computes the MD5 hash of a string.
private static String md5(String input) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : messageDigest) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}
Sample run:
[root@xxx ~]# javac MeteringPusher.java
[root@xxx ~]# java MeteringPusher
Detected Region ID: cn-hangzhou
Response: {"code":200,"requestId":"20a00ad2-bb10-4abxxx","instanceId":"i-bp140hjfmsqcuqanv6ea","result":{"RequestId":"3FF6B8A8-F72F-5Bxxx","PushMeteringDataRequestId":"E2E_862fc9bfd36fe02bf7b7380ed437ba7","Success":true}}
Request URL: https://cn-hangzhou.axt.aliyun.com/computeNest/marketplace/push_metering_data
Ensure that your project includes the org.json library. For example, if you use Maven, add the following dependency:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20230618</version>
</dependency>
Error codes
|
Error code |
Error message |
Description |
|
OperationDenied |
The service instance does not support pushing metering data. |
Pushing metering data is not supported because the service instance is not a pay-as-you-go instance. |
|
Only metering entities classified as Custom and associated with a service can be pushed. The entity ${EntityId} is invalid. |
The specified billable item does not support data pushing. Ensure that its reporting method is set to Reported by Service Provider and that it is correctly associated with the service. |
|
|
MissingParameter.${parametersName} |
The required parameter "${parametersName}" is missing. |
A required parameter is missing. |
|
InvalidParameter.${parametersName} |
The provided parameter "${parametersName}" is invalid. |
The specified parameter is invalid. |
|
EntityNotExist.ServiceInstance |
The specified service instance cannot be found. |
The service instance does not exist. This may occur if the instance was not created by Compute Nest. |