From e22a8fab588ebfcf4440b9795b77db0d3e7bd037 Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Mon, 31 Aug 2026 14:54:29 +0530 Subject: [PATCH 1/8] Add SAP HANA client JAR staging support When SAP_HANA_CLIENT_ENABLED is set to a non-empty value, the buildpack fetches ngdbc.jar from Maven Central and places it in model/lib/userlib/ so the Mendix runtime can load it via the project-userlib classpath. SAP_HANA_CLIENT_URL can be set to override the default Maven Central URL (e.g. to point to a CDN-hosted version or a different ngdbc version). Co-Authored-By: Claude Sonnet 4.6 --- buildpack/core/runtime.py | 41 +++++++++++++++++++++++++++++++++++++++ buildpack/stage.py | 1 + dependencies.yml | 5 +++++ 3 files changed, 47 insertions(+) diff --git a/buildpack/core/runtime.py b/buildpack/core/runtime.py index c6e047f83..2794265ea 100644 --- a/buildpack/core/runtime.py +++ b/buildpack/core/runtime.py @@ -57,6 +57,47 @@ def is_version_maintained(version): return False +SAP_HANA_CLIENT_ENABLED_KEY = "SAP_HANA_CLIENT_ENABLED" +SAP_HANA_CLIENT_URL_KEY = "SAP_HANA_CLIENT_URL" +_SAP_HANA_CLIENT_DEPENDENCY = "sap.hana.client" + + +def is_sap_hana_client_enabled(): + return bool(os.environ.get(SAP_HANA_CLIENT_ENABLED_KEY, "").strip()) + + +def stage_hana_client(buildpack_dir, build_dir, cache_dir): + if not is_sap_hana_client_enabled(): + return + + logging.debug("Staging SAP HANA client JAR...") + dest = os.path.join(build_dir, "model", "lib", "userlib") + util.mkdir_p(dest) + + custom_url = os.environ.get(SAP_HANA_CLIENT_URL_KEY, "").strip() + if custom_url: + dependency = { + "name": ["sap", "hana", "client"], + "artifact": custom_url, + } + util.resolve_dependency( + dependency, + dest, + buildpack_dir=buildpack_dir, + cache_dir=cache_dir, + unpack=False, + ) + else: + util.resolve_dependency( + _SAP_HANA_CLIENT_DEPENDENCY, + dest, + buildpack_dir=buildpack_dir, + cache_dir=cache_dir, + unpack=False, + ) + logging.info("SAP HANA client JAR staged to [%s]", dest) + + def stage(buildpack_dir, build_path, cache_path): logging.debug("Creating directory structure for Mendix runtime...") for name in ["runtimes", "log", "database", "data", "bin"]: diff --git a/buildpack/stage.py b/buildpack/stage.py index 2f37be179..34147a5c2 100755 --- a/buildpack/stage.py +++ b/buildpack/stage.py @@ -217,6 +217,7 @@ def cleanup_dependency_cache(cached_dir, dependency_list): metering.stage(BUILDPACK_DIR, BUILD_DIR, CACHE_DIR) database.stage(BUILDPACK_DIR, BUILD_DIR) runtime.stage(BUILDPACK_DIR, BUILD_DIR, CACHE_DIR) + runtime.stage_hana_client(BUILDPACK_DIR, BUILD_DIR, CACHE_DIR) logs.stage(BUILDPACK_DIR, BUILD_DIR, CACHE_DIR) nginx.stage(BUILDPACK_DIR, BUILD_DIR, CACHE_DIR) logging.info("Mendix Cloud Foundry Buildpack staging completed") diff --git a/dependencies.yml b/dependencies.yml index 2fb38101f..1ba3caff4 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -88,6 +88,11 @@ dependencies: commit: 5fed98f8 fs: cflinuxfs4 version: 3.2.2 + sap: + hana: + client: + artifact: "https://repo1.maven.org/maven2/com/sap/cloud/db/jdbc/ngdbc/{{ version }}/ngdbc-{{ version }}.jar" + version: "2.27.7" telegraf: agent: artifact: telegraf/telegraf-{{ version }}_linux_amd64.tar.gz From ae5810516351d374d760787c4fb6544b318f6503 Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Mon, 31 Aug 2026 15:01:21 +0530 Subject: [PATCH 2/8] Handle staging failure gracefully and log JAR version If fetching the HANA client JAR fails, log a warning and continue deployment instead of failing the staging process. Also log the JAR filename (including version) and destination path on success. Co-Authored-By: Claude Sonnet 4.6 --- buildpack/core/runtime.py | 42 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/buildpack/core/runtime.py b/buildpack/core/runtime.py index 2794265ea..d42f76aac 100644 --- a/buildpack/core/runtime.py +++ b/buildpack/core/runtime.py @@ -70,16 +70,23 @@ def stage_hana_client(buildpack_dir, build_dir, cache_dir): if not is_sap_hana_client_enabled(): return - logging.debug("Staging SAP HANA client JAR...") - dest = os.path.join(build_dir, "model", "lib", "userlib") - util.mkdir_p(dest) - - custom_url = os.environ.get(SAP_HANA_CLIENT_URL_KEY, "").strip() - if custom_url: - dependency = { - "name": ["sap", "hana", "client"], - "artifact": custom_url, - } + try: + logging.debug("Staging SAP HANA client JAR...") + dest = os.path.join(build_dir, "model", "lib", "userlib") + util.mkdir_p(dest) + + custom_url = os.environ.get(SAP_HANA_CLIENT_URL_KEY, "").strip() + if custom_url: + dependency = { + "name": ["sap", "hana", "client"], + "artifact": custom_url, + } + jar_name = custom_url.split("/")[-1] + else: + dependency = _SAP_HANA_CLIENT_DEPENDENCY + dep = util.get_dependency(_SAP_HANA_CLIENT_DEPENDENCY, buildpack_dir=buildpack_dir) + jar_name = "ngdbc-{}.jar".format(dep["version"]) + util.resolve_dependency( dependency, dest, @@ -87,15 +94,16 @@ def stage_hana_client(buildpack_dir, build_dir, cache_dir): cache_dir=cache_dir, unpack=False, ) - else: - util.resolve_dependency( - _SAP_HANA_CLIENT_DEPENDENCY, + logging.info( + "SAP HANA client JAR [%s] staged to [%s]", + jar_name, dest, - buildpack_dir=buildpack_dir, - cache_dir=cache_dir, - unpack=False, ) - logging.info("SAP HANA client JAR staged to [%s]", dest) + except Exception: + logging.warning( + "Failed to stage SAP HANA client JAR, continuing deployment...", + exc_info=True, + ) def stage(buildpack_dir, build_path, cache_path): From 844c93cec7f365998a9ccfbfe95cf64e22fdf3cc Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Tue, 1 Sep 2026 12:15:14 +0530 Subject: [PATCH 3/8] Use Mendix Nexus proxy for SAP HANA client JAR Co-Authored-By: Claude Sonnet 4.6 --- dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.yml b/dependencies.yml index 1ba3caff4..c02d48b84 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -91,7 +91,7 @@ dependencies: sap: hana: client: - artifact: "https://repo1.maven.org/maven2/com/sap/cloud/db/jdbc/ngdbc/{{ version }}/ngdbc-{{ version }}.jar" + artifact: "https://nexus.rnd.mendix.com/repository/repo1-proxy/com/sap/cloud/db/jdbc/ngdbc/{{ version }}/ngdbc-{{ version }}.jar" version: "2.27.7" telegraf: agent: From 3b367661375832c86284dcf0d1b7e842505f8b9f Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Tue, 1 Sep 2026 16:41:51 +0530 Subject: [PATCH 4/8] Use Mendix CDN for SAP HANA client JAR Co-Authored-By: Claude Sonnet 4.6 --- dependencies.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.yml b/dependencies.yml index c02d48b84..3337a3eb0 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -91,8 +91,8 @@ dependencies: sap: hana: client: - artifact: "https://nexus.rnd.mendix.com/repository/repo1-proxy/com/sap/cloud/db/jdbc/ngdbc/{{ version }}/ngdbc-{{ version }}.jar" - version: "2.27.7" + artifact: "/mx-cdn/mcdep/sap-hana-client/ngdbc-{{ version }}.jar" + version: "2.29.11" telegraf: agent: artifact: telegraf/telegraf-{{ version }}_linux_amd64.tar.gz From 9d9f109ca8246699c16065fd7d952ef3139d1a5e Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Tue, 1 Sep 2026 16:51:59 +0530 Subject: [PATCH 5/8] Fix SAP HANA client JAR CDN artifact path Co-Authored-By: Claude Sonnet 4.6 --- dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.yml b/dependencies.yml index 3337a3eb0..7d79a35a9 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -91,7 +91,7 @@ dependencies: sap: hana: client: - artifact: "/mx-cdn/mcdep/sap-hana-client/ngdbc-{{ version }}.jar" + artifact: "ngdbc-{{ version }}.jar" version: "2.29.11" telegraf: agent: From 4ecbf561813fa18b40a989200cda9ae9b2a79ee5 Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Wed, 2 Sep 2026 12:06:32 +0530 Subject: [PATCH 6/8] Update SAP HANA client JAR CDN path to sap-hana-client subdirectory Co-Authored-By: Claude Sonnet 4.6 --- dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.yml b/dependencies.yml index 7d79a35a9..ad2c21200 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -91,7 +91,7 @@ dependencies: sap: hana: client: - artifact: "ngdbc-{{ version }}.jar" + artifact: "sap-hana-client/ngdbc-{{ version }}.jar" version: "2.29.11" telegraf: agent: From a7e01e483ed189c1d7b5a17cfb6df86195238dd1 Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Wed, 2 Sep 2026 14:09:27 +0530 Subject: [PATCH 7/8] Use private getter functions for SAP HANA client env vars Co-Authored-By: Claude Sonnet 4.6 --- buildpack/core/runtime.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/buildpack/core/runtime.py b/buildpack/core/runtime.py index d42f76aac..76d2f15d2 100644 --- a/buildpack/core/runtime.py +++ b/buildpack/core/runtime.py @@ -57,17 +57,19 @@ def is_version_maintained(version): return False -SAP_HANA_CLIENT_ENABLED_KEY = "SAP_HANA_CLIENT_ENABLED" -SAP_HANA_CLIENT_URL_KEY = "SAP_HANA_CLIENT_URL" _SAP_HANA_CLIENT_DEPENDENCY = "sap.hana.client" -def is_sap_hana_client_enabled(): - return bool(os.environ.get(SAP_HANA_CLIENT_ENABLED_KEY, "").strip()) +def _is_sap_hana_client_enabled(): + return bool(os.environ.get("SAP_HANA_CLIENT_ENABLED", "").strip()) + + +def _get_sap_hana_client_url(): + return os.environ.get("SAP_HANA_CLIENT_URL", "").strip() def stage_hana_client(buildpack_dir, build_dir, cache_dir): - if not is_sap_hana_client_enabled(): + if not _is_sap_hana_client_enabled(): return try: @@ -75,7 +77,7 @@ def stage_hana_client(buildpack_dir, build_dir, cache_dir): dest = os.path.join(build_dir, "model", "lib", "userlib") util.mkdir_p(dest) - custom_url = os.environ.get(SAP_HANA_CLIENT_URL_KEY, "").strip() + custom_url = _get_sap_hana_client_url() if custom_url: dependency = { "name": ["sap", "hana", "client"], From b18c544535d5b3c8b55032207fc1a1bbe9ca479e Mon Sep 17 00:00:00 2001 From: "priyal.chawda@mendix.com" Date: Wed, 2 Sep 2026 14:16:49 +0530 Subject: [PATCH 8/8] Remove unused SAP_HANA_CLIENT_URL override, simplify stage_hana_client Co-Authored-By: Claude Sonnet 4.6 --- buildpack/core/runtime.py | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/buildpack/core/runtime.py b/buildpack/core/runtime.py index 76d2f15d2..a13d9fb20 100644 --- a/buildpack/core/runtime.py +++ b/buildpack/core/runtime.py @@ -64,33 +64,17 @@ def _is_sap_hana_client_enabled(): return bool(os.environ.get("SAP_HANA_CLIENT_ENABLED", "").strip()) -def _get_sap_hana_client_url(): - return os.environ.get("SAP_HANA_CLIENT_URL", "").strip() - - def stage_hana_client(buildpack_dir, build_dir, cache_dir): if not _is_sap_hana_client_enabled(): return try: - logging.debug("Staging SAP HANA client JAR...") dest = os.path.join(build_dir, "model", "lib", "userlib") util.mkdir_p(dest) - - custom_url = _get_sap_hana_client_url() - if custom_url: - dependency = { - "name": ["sap", "hana", "client"], - "artifact": custom_url, - } - jar_name = custom_url.split("/")[-1] - else: - dependency = _SAP_HANA_CLIENT_DEPENDENCY - dep = util.get_dependency(_SAP_HANA_CLIENT_DEPENDENCY, buildpack_dir=buildpack_dir) - jar_name = "ngdbc-{}.jar".format(dep["version"]) - + dep = util.get_dependency(_SAP_HANA_CLIENT_DEPENDENCY, buildpack_dir=buildpack_dir) + jar_name = "ngdbc-{}.jar".format(dep["version"]) util.resolve_dependency( - dependency, + _SAP_HANA_CLIENT_DEPENDENCY, dest, buildpack_dir=buildpack_dir, cache_dir=cache_dir,