From 2d9b71dcff2194ed64908c737fed4ed20df003e9 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Wed, 8 Apr 2026 00:18:24 +0530 Subject: [PATCH 1/6] added the metering code --- buildpack/telemetry/metering.py | 126 +++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 19 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index 603b60e54..a05a11bd1 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -27,6 +27,19 @@ def _is_usage_metering_enabled(): return True +def _should_use_license_server(): + use_license_server = os.environ.get("MXRUNTIME_License.UseLicenseServer", "").lower() + return use_license_server == "true" + + +def _get_sap_metering_endpoint(): + return os.environ.get("MXRUNTIME_License.MeteringEndpoint", "").strip() or None + + +def _get_sap_metering_token(): + return os.environ.get("MXRUNTIME_License.MeteringToken", "").strip() or None + + def _get_project_id(file_path): try: with open(file_path) as file_handle: @@ -89,29 +102,104 @@ def _is_sidecar_installed(): return False -def stage(buildpack_path, build_path, cache_dir): - try: - if _is_usage_metering_enabled(): - logging.info("Usage metering is enabled") - _download(buildpack_path, build_path, cache_dir) +def _download_sap_sidecar(build_path, endpoint, token): + """Download SAP metering sidecar binary from HTTPS endpoint.""" + import requests + + logging.info("=== SAP METERING SIDECAR DOWNLOAD ===") + + # Reuse existing variables - same directory structure as Mendix sidecar + sidecar_dir = os.path.join(build_path, NAMESPACE) + destination = os.path.join(sidecar_dir, BINARY) + + logging.info("Source endpoint: %s", endpoint) + logging.info("Target directory: %s", sidecar_dir) + logging.info("Target file: %s", destination) + + util.mkdir_p(sidecar_dir) + logging.info("Created target directory: %s", sidecar_dir) + + logging.info("Downloading SAP metering sidecar from [%s]...", endpoint) + + # Download binary file via HTTPS with auth-token header + response = requests.get( + endpoint, + headers={"auth-token": token}, + stream=True, + timeout=60, + ) + response.raise_for_status() + + # Stream binary content to disk + with open(destination, "wb") as file_handle: + for chunk in response.iter_content(chunk_size=8192): + if chunk: + file_handle.write(chunk) - project_id = _get_project_id( - os.path.join(build_path, "model", "metadata.json") + logging.info("SAP metering sidecar downloaded successfully to [%s]", destination) + + # Verify file exists and get size + if os.path.exists(destination): + file_size = os.path.getsize(destination) + logging.info("Binary file size: %.2f MB", file_size / (1024 * 1024)) + else: + logging.error("Binary file not found after download: %s", destination) + raise Exception(f"Binary file not found: {destination}") + + util.set_executable(destination) + logging.info("Set executable permissions for: %s", BINARY) + + logging.info("=== SAP METERING SIDECAR DOWNLOAD COMPLETE ===") + return destination + + +def stage(buildpack_path, build_path, cache_dir): + if _should_use_license_server(): + # UseLicenseServer = true: original Mendix metering flow + try: + if _is_usage_metering_enabled(): + logging.info("Usage metering is enabled") + _download(buildpack_path, build_path, cache_dir) + + project_id = _get_project_id( + os.path.join(build_path, "model", "metadata.json") + ) + config = {"ProjectID": project_id} + + logging.debug("Writing metering sidecar configuration file...") + write_file( + os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE), + config, + ) + else: + logging.info("Usage metering is NOT enabled") + except Exception: + logging.info( + "Encountered an exception while staging the metering sidecar. " + "This is nothing to worry about." ) - config = {"ProjectID": project_id} + else: + # UseLicenseServer = false: attempt SAP metering sidecar download + endpoint = _get_sap_metering_endpoint() + token = _get_sap_metering_token() + + if not endpoint or not token: + logging.warning( + "SAP metering sidecar NOT downloaded: " + "MXRUNTIME_License.MeteringEndpoint or MXRUNTIME_License.MeteringToken " + "is missing or empty. Continuing buildpack execution." + ) + return - logging.debug("Writing metering sidecar configuration file...") - write_file( - os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE), - config, + try: + _download_sap_sidecar(build_path, endpoint, token) + logging.info("SAP metering sidecar staged successfully") + except Exception: + logging.error( + "Encountered an exception while staging the SAP metering sidecar. " + "Continuing buildpack execution.", + exc_info=True, ) - else: - logging.info("Usage metering is NOT enabled") - except Exception: - logging.info( - "Encountered an exception while staging the metering sidecar. " - "This is nothing to worry about." - ) def run(): From 1f6eaf5db1eee7a45a817de23f1e631cd29eebf1 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Wed, 8 Apr 2026 14:40:32 +0530 Subject: [PATCH 2/6] added logging --- buildpack/telemetry/metering.py | 36 ++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index a05a11bd1..82e599373 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -29,7 +29,13 @@ def _is_usage_metering_enabled(): def _should_use_license_server(): use_license_server = os.environ.get("MXRUNTIME_License.UseLicenseServer", "").lower() - return use_license_server == "true" + result = use_license_server == "true" + logging.info( + "License server usage check: MXRUNTIME_License.UseLicenseServer=%r, result=%s", + use_license_server, + result, + ) + return result def _get_sap_metering_endpoint(): @@ -154,23 +160,27 @@ def _download_sap_sidecar(build_path, endpoint, token): def stage(buildpack_path, build_path, cache_dir): + logging.info("Starting metering stage (buildpack_path=%s, build_path=%s)", buildpack_path, build_path) if _should_use_license_server(): + logging.info("Using Mendix license server flow for metering") # UseLicenseServer = true: original Mendix metering flow try: if _is_usage_metering_enabled(): logging.info("Usage metering is enabled") + logging.info("Downloading Mendix metering sidecar...") _download(buildpack_path, build_path, cache_dir) + logging.info("Mendix metering sidecar downloaded successfully") - project_id = _get_project_id( - os.path.join(build_path, "model", "metadata.json") - ) + metadata_path = os.path.join(build_path, "model", "metadata.json") + logging.info("Reading project ID from: %s", metadata_path) + project_id = _get_project_id(metadata_path) + logging.info("Project ID: %s", project_id) config = {"ProjectID": project_id} - logging.debug("Writing metering sidecar configuration file...") - write_file( - os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE), - config, - ) + config_path = os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE) + logging.info("Writing metering sidecar configuration file to: %s", config_path) + write_file(config_path, config) + logging.info("Metering sidecar configuration file written successfully") else: logging.info("Usage metering is NOT enabled") except Exception: @@ -179,9 +189,15 @@ def stage(buildpack_path, build_path, cache_dir): "This is nothing to worry about." ) else: + logging.info("License server not used; attempting SAP metering sidecar flow") # UseLicenseServer = false: attempt SAP metering sidecar download endpoint = _get_sap_metering_endpoint() token = _get_sap_metering_token() + logging.info( + "SAP metering config: endpoint=%s, token_present=%s", + endpoint, + bool(token), + ) if not endpoint or not token: logging.warning( @@ -192,6 +208,7 @@ def stage(buildpack_path, build_path, cache_dir): return try: + logging.info("Downloading SAP metering sidecar from endpoint: %s", endpoint) _download_sap_sidecar(build_path, endpoint, token) logging.info("SAP metering sidecar staged successfully") except Exception: @@ -200,6 +217,7 @@ def stage(buildpack_path, build_path, cache_dir): "Continuing buildpack execution.", exc_info=True, ) + logging.info("Metering stage completed") def run(): From 4f742524e21e68d5003309edd44b9f334bc1efd6 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Thu, 9 Apr 2026 12:28:22 +0530 Subject: [PATCH 3/6] added the sap metering sidecar --- buildpack/telemetry/metering.py | 137 ++++++++++++-------------------- 1 file changed, 49 insertions(+), 88 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index 82e599373..eb33aa9d3 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -27,15 +27,21 @@ def _is_usage_metering_enabled(): return True -def _should_use_license_server(): - use_license_server = os.environ.get("MXRUNTIME_License.UseLicenseServer", "").lower() - result = use_license_server == "true" - logging.info( - "License server usage check: MXRUNTIME_License.UseLicenseServer=%r, result=%s", - use_license_server, - result, - ) - return result +def _is_sap_metering_configured(): + use_license_server = os.environ.get("MXRUNTIME_License.UseLicenseServer", "false").lower() + if use_license_server == "true": + return False + + endpoint = _get_sap_metering_endpoint() + token = _get_sap_metering_token() + + if not endpoint or not token: + logging.warning( + "Missing configuration for SAP metering sidecar." + ) + return False + + return True def _get_sap_metering_endpoint(): @@ -108,24 +114,13 @@ def _is_sidecar_installed(): return False -def _download_sap_sidecar(build_path, endpoint, token): +def _copy_sap_metering_sidecar(build_path, endpoint, token): """Download SAP metering sidecar binary from HTTPS endpoint.""" import requests - logging.info("=== SAP METERING SIDECAR DOWNLOAD ===") - - # Reuse existing variables - same directory structure as Mendix sidecar sidecar_dir = os.path.join(build_path, NAMESPACE) destination = os.path.join(sidecar_dir, BINARY) - - logging.info("Source endpoint: %s", endpoint) - logging.info("Target directory: %s", sidecar_dir) - logging.info("Target file: %s", destination) - util.mkdir_p(sidecar_dir) - logging.info("Created target directory: %s", sidecar_dir) - - logging.info("Downloading SAP metering sidecar from [%s]...", endpoint) # Download binary file via HTTPS with auth-token header response = requests.get( @@ -142,82 +137,48 @@ def _download_sap_sidecar(build_path, endpoint, token): if chunk: file_handle.write(chunk) - logging.info("SAP metering sidecar downloaded successfully to [%s]", destination) - - # Verify file exists and get size - if os.path.exists(destination): - file_size = os.path.getsize(destination) - logging.info("Binary file size: %.2f MB", file_size / (1024 * 1024)) - else: - logging.error("Binary file not found after download: %s", destination) - raise Exception(f"Binary file not found: {destination}") - + logging.info("SAP metering sidecar downloaded successfully") util.set_executable(destination) - logging.info("Set executable permissions for: %s", BINARY) - - logging.info("=== SAP METERING SIDECAR DOWNLOAD COMPLETE ===") return destination def stage(buildpack_path, build_path, cache_dir): - logging.info("Starting metering stage (buildpack_path=%s, build_path=%s)", buildpack_path, build_path) - if _should_use_license_server(): - logging.info("Using Mendix license server flow for metering") - # UseLicenseServer = true: original Mendix metering flow - try: - if _is_usage_metering_enabled(): - logging.info("Usage metering is enabled") - logging.info("Downloading Mendix metering sidecar...") - _download(buildpack_path, build_path, cache_dir) - logging.info("Mendix metering sidecar downloaded successfully") - - metadata_path = os.path.join(build_path, "model", "metadata.json") - logging.info("Reading project ID from: %s", metadata_path) - project_id = _get_project_id(metadata_path) - logging.info("Project ID: %s", project_id) - config = {"ProjectID": project_id} - - config_path = os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE) - logging.info("Writing metering sidecar configuration file to: %s", config_path) - write_file(config_path, config) - logging.info("Metering sidecar configuration file written successfully") - else: - logging.info("Usage metering is NOT enabled") - except Exception: - logging.info( - "Encountered an exception while staging the metering sidecar. " - "This is nothing to worry about." - ) - else: - logging.info("License server not used; attempting SAP metering sidecar flow") - # UseLicenseServer = false: attempt SAP metering sidecar download - endpoint = _get_sap_metering_endpoint() - token = _get_sap_metering_token() - logging.info( - "SAP metering config: endpoint=%s, token_present=%s", - endpoint, - bool(token), - ) + try: + if _is_usage_metering_enabled(): + # Original Mendix metering flow + logging.info("Usage metering is enabled") + _download(buildpack_path, build_path, cache_dir) - if not endpoint or not token: - logging.warning( - "SAP metering sidecar NOT downloaded: " - "MXRUNTIME_License.MeteringEndpoint or MXRUNTIME_License.MeteringToken " - "is missing or empty. Continuing buildpack execution." + project_id = _get_project_id( + os.path.join(build_path, "model", "metadata.json") ) - return + config = {"ProjectID": project_id} - try: - logging.info("Downloading SAP metering sidecar from endpoint: %s", endpoint) - _download_sap_sidecar(build_path, endpoint, token) - logging.info("SAP metering sidecar staged successfully") - except Exception: - logging.error( - "Encountered an exception while staging the SAP metering sidecar. " - "Continuing buildpack execution.", - exc_info=True, + logging.debug("Writing metering sidecar configuration file...") + write_file( + os.path.join(build_path, NAMESPACE, SIDECAR_CONFIG_FILE), + config, ) - logging.info("Metering stage completed") + elif _is_sap_metering_configured(): + # UseLicenseServer = false with valid SAP endpoint and token + endpoint = _get_sap_metering_endpoint() + token = _get_sap_metering_token() + try: + _copy_sap_metering_sidecar(build_path, endpoint, token) + logging.info("SAP metering sidecar staged successfully") + except Exception: + logging.error( + "Encountered an exception while staging the SAP metering sidecar. " + "Continuing buildpack execution." + ) + logging.debug("SAP metering sidecar staging exception details:", exc_info=True) + else: + logging.info("Usage metering is NOT enabled") + except Exception: + logging.info( + "Encountered an exception while staging the metering sidecar. " + "This is nothing to worry about." + ) def run(): From b57808922a734975b988eaece7ee0731f31c0ce2 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Tue, 14 Apr 2026 14:54:23 +0530 Subject: [PATCH 4/6] updated the auth token usage --- buildpack/telemetry/metering.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index eb33aa9d3..09eb63ff7 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -33,9 +33,8 @@ def _is_sap_metering_configured(): return False endpoint = _get_sap_metering_endpoint() - token = _get_sap_metering_token() - if not endpoint or not token: + if not endpoint: logging.warning( "Missing configuration for SAP metering sidecar." ) @@ -45,11 +44,11 @@ def _is_sap_metering_configured(): def _get_sap_metering_endpoint(): - return os.environ.get("MXRUNTIME_License.MeteringEndpoint", "").strip() or None + return os.environ.get("MXRUNTIME_License.MeteringEndpoint", "").strip() def _get_sap_metering_token(): - return os.environ.get("MXRUNTIME_License.MeteringToken", "").strip() or None + return os.environ.get("MXRUNTIME_License.MeteringToken", "").strip() def _get_project_id(file_path): From 0452f16f6c320e825d2a137918c40bd2053aa398 Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Tue, 14 Apr 2026 15:06:48 +0530 Subject: [PATCH 5/6] updated the comments --- buildpack/telemetry/metering.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index 09eb63ff7..7ac40bf75 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -121,7 +121,6 @@ def _copy_sap_metering_sidecar(build_path, endpoint, token): destination = os.path.join(sidecar_dir, BINARY) util.mkdir_p(sidecar_dir) - # Download binary file via HTTPS with auth-token header response = requests.get( endpoint, headers={"auth-token": token}, @@ -130,7 +129,6 @@ def _copy_sap_metering_sidecar(build_path, endpoint, token): ) response.raise_for_status() - # Stream binary content to disk with open(destination, "wb") as file_handle: for chunk in response.iter_content(chunk_size=8192): if chunk: @@ -144,7 +142,6 @@ def _copy_sap_metering_sidecar(build_path, endpoint, token): def stage(buildpack_path, build_path, cache_dir): try: if _is_usage_metering_enabled(): - # Original Mendix metering flow logging.info("Usage metering is enabled") _download(buildpack_path, build_path, cache_dir) @@ -159,7 +156,6 @@ def stage(buildpack_path, build_path, cache_dir): config, ) elif _is_sap_metering_configured(): - # UseLicenseServer = false with valid SAP endpoint and token endpoint = _get_sap_metering_endpoint() token = _get_sap_metering_token() try: From 241305fb4a07626037513ff31fea9881e982298c Mon Sep 17 00:00:00 2001 From: "bhavin.shah" Date: Fri, 17 Apr 2026 16:35:54 +0530 Subject: [PATCH 6/6] updated the env vars --- buildpack/telemetry/metering.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildpack/telemetry/metering.py b/buildpack/telemetry/metering.py index 7ac40bf75..680b4f197 100644 --- a/buildpack/telemetry/metering.py +++ b/buildpack/telemetry/metering.py @@ -44,11 +44,11 @@ def _is_sap_metering_configured(): def _get_sap_metering_endpoint(): - return os.environ.get("MXRUNTIME_License.MeteringEndpoint", "").strip() + return os.environ.get("METERING_BINARY_PATH", "").strip() def _get_sap_metering_token(): - return os.environ.get("MXRUNTIME_License.MeteringToken", "").strip() + return os.environ.get("METERING_BINARY_TOKEN", "").strip() def _get_project_id(file_path):