PushMeteringData - Push metering data

更新时间:
复制 MD 格式

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:

  • StartTime: The start time of the metering period, specified as a UNIX timestamp in seconds.

  • EndTime: The end time of the metering period, specified as a UNIX timestamp in seconds.

  • Entities: The metering entities.

    • Key: The name of the billable item. Valid values include:

      • Frequency: The number of times the service was used.

      • Period: The usage duration. Unit: seconds.

        Important

        The unit for this parameter is seconds, but the billing unit is hours. The system converts seconds to hours for billing. For example, if you report a usage of 1,800 seconds from 19:00 to 20:00 at a rate of CNY 1 per hour, the hourly charge is calculated as (1800 / 3600) × 1 = CNY 0.5. The result is truncated to two decimal places.

      • Storage: The storage space used. Unit: bytes.

        Important

        The unit for this parameter is bytes, but the billing unit is megabytes (MB). The system converts bytes to MB for billing. For example, if you report a usage of 524,288 bytes from 19:00 to 20:00 at a rate of CNY 1 per MB, the hourly charge is calculated as (524288 / 1024 / 1024) × 1 = CNY 0.5. The result is truncated to two decimal places.

      • NetworkOut: The outbound traffic. Unit: bytes.

        Important

        The unit for this parameter is bytes, but the billing unit is megabytes (MB). The system converts bytes to MB for billing. For example, if you report a usage of 524,288 bytes from 19:00 to 20:00 at a rate of CNY 1 per MB, the hourly charge is calculated as (524288 / 1024 / 1024) × 1 = CNY 0.5. The result is truncated to two decimal places.

      • NetworkIn: The inbound traffic. Unit: bytes.

        Important

        The unit for this parameter is bytes, but the billing unit is megabytes (MB). The system converts bytes to MB for billing. For example, if you report a usage of 524,288 bytes from 19:00 to 20:00 at a rate of CNY 1 per MB, the hourly charge is calculated as (524288 / 1024 / 1024) × 1 = CNY 0.5. The result is truncated to two decimal places.

      • Character: The number of characters.

      • DailyActiveUser: The number of daily active users (DAUs).

      • PeriodMin: The usage duration. Unit: minutes.

      • VirtualCpu: The number of vCPU cores.

        • Unit: The number of units.

        • Memory: The memory size in GB.

    • Value: The metered value. The value must be a non-negative integer.

Note
  • If the product is billed in real time, you can specify any time range, but EndTime must be later than StartTime.

  • If the product is billed by cycle, such as hourly, daily, or monthly, the interval between StartTime and EndTime must be longer than 5 minutes.

[{"StartTime":"1664451045","EndTime":"1664451198","Entities":[{"Key":"Frequency","Value":"6"}]}]

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 Metering JSON string, an ampersand (&), and your service key. The components are conceptually represented by Metering&Key.

  • Metering: The value of the Metering parameter. Example: [{"StartTime":"1664451045","EndTime":"1664451198","Entities":[{"Key":"Frequency","Value":"6"}]}]. For more information, see the description of the Metering parameter.

  • Key: The service key. Example: e98893f5ecc3ae1ctest. You can obtain the service key from the service details page.

    Note

    The service key is unique and does not change with service versions.

  • String to be hashed: Metering=[{"StartTime":"1664451045","EndTime":"1664451198","Entities":[{"Key":"Frequency","Value":"6"}]}]&Key=e98893f5ecc3ae1ctest

  • Resulting token: 7aa81300b2aea77984b772495c8e4e83

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

  1. 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.

    1. 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
    2. Sample response:

      cn-hangzhou
  2. 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\"}]}]

      Note

      Because this example uses a curl command, the JSON string for the Metering parameter 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 stringified Metering JSON, an ampersand (&), and your service key. The token in this example is 7aa81300b2aea77984b772495c8e4e83.

  3. 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"}'
    Note

    In https://cn-hangzhou.axt.aliyun.com, cn-hangzhou is the region that you obtained in Step 1. When you make a call, replace the region information with your actual region.

  4. 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
Note

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.