From 7bac92e07e265447192c3feeb780a3b24d98d2ea Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Mon, 7 Jul 2025 16:11:59 -0500 Subject: [PATCH 01/25] Added graal vm plugin to pom.xml and classes to reflection-config.json --- ice/pom.xml | 37 +++++ ice/src/main/resources/reflection-config.json | 134 ++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 ice/src/main/resources/reflection-config.json diff --git a/ice/pom.xml b/ice/pom.xml index b200694b..f7dd3d0d 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -667,5 +667,42 @@ + + native + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + + + build-native + + compile-no-fork + + package + + + + ice + com.altinity.ice.cli.Main + + --initialize-at-build-time=ch.qos.logback + -H:ReflectionConfigurationFiles=src/main/resources/reflection-config.json + --trace-class-initialization=ch.qos.logback.classic.Logger + --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker + --trace-object-instantiation=ch.qos.logback.classic.Logger + --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-build-time=ch.qos.logback.classic.Logger + --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout + + + + + + + diff --git a/ice/src/main/resources/reflection-config.json b/ice/src/main/resources/reflection-config.json new file mode 100644 index 00000000..1d9866a5 --- /dev/null +++ b/ice/src/main/resources/reflection-config.json @@ -0,0 +1,134 @@ +[ + { + "name": "ch.qos.logback.classic.AsyncAppender", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.Logger.effectiveLevelInt", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.Logger.loggerContext", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.DateConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.LevelConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.LineSeparatorConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.LoggerConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.MessageConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.ThreadConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.core.ConsoleAppender", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.core.FileAppender", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + } +] From 27d6cfa24e440c211b21cb7b0e2b8959a462ca42 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 19 Nov 2025 19:20:07 -0600 Subject: [PATCH 02/25] Fixed steps to build ice native image --- .github/workflows/verify.yaml | 16 ++++++ README.md | 32 +++++++++++- build-native.sh | 95 +++++++++++++++++++++++++++++++++++ ice/pom.xml | 85 ++++++++++++++++++++++++++++++- 4 files changed, 225 insertions(+), 3 deletions(-) create mode 100755 build-native.sh diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 053511ae..a48026c9 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -57,3 +57,19 @@ jobs: ./mvnw -pl ice-rest-catalog failsafe:integration-test failsafe:verify -Dit.test=DockerScenarioBasedIT -Ddocker.image=altinity/ice-rest-catalog:debug-with-ice-latest-master-amd64 + native-build: + name: Build and test native image + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'graalvm' + cache: maven + - name: Install musl for static linking + run: sudo apt-get update && sudo apt-get install -y musl-tools + - name: Build native image (amd64 static with musl) + run: ./build-native.sh + env: + ARCH: amd64 diff --git a/README.md b/README.md index f308e5fc..e83f3fdf 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,14 @@ Create/delete tables, insert data with `ice insert -p ns1.table1 file://example. ## Installation -Pre-built binaries\* (+ links to Docker images for [ice](https://hub.docker.com/r/altinity/ice) and [ice-rest-catalog](https://hub.docker.com/r/altinity/ice-rest-catalog)) are available from [GitHub Releases](https://github.com/Altinity/ice/releases) page. -> \* currently require `java` 21+ to run (available [here](https://adoptium.net/installation/)). +Pre-built binaries (+ links to Docker images for [ice](https://hub.docker.com/r/altinity/ice) and [ice-rest-catalog](https://hub.docker.com/r/altinity/ice-rest-catalog)) are available from [GitHub Releases](https://github.com/Altinity/ice/releases) page. + +**Two types of binaries are available:** + +1. **Java-based binaries** - Require Java 21+ to run (available [here](https://adoptium.net/installation/)) +2. **Native binaries** - Standalone executables with no Java dependency + - `ice-native-amd64` - Static binary (musl) for x86_64 Linux (no dependencies) + - `ice-native-arm64` - Dynamic binary for ARM64 Linux (requires glibc) ## Usage @@ -19,6 +25,8 @@ See [examples/](examples/). ## Development +### Standard Build (Java-based) + Install [sdkman](https://sdkman.io/install), then ```shell @@ -35,6 +43,26 @@ sdk env ./mvnw ``` +### Native Image Build (Standalone) + +Build standalone native binaries with no Java dependency: + +```shell +# Install prerequisites +sdk env # or ensure Java 21+ and GraalVM are available + +# For amd64 (static with musl - no dependencies) +./build-native.sh +# Produces: ice/target/ice (static binary) + +# Or use Maven directly +mvn -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true + +# For ARM64 (dynamic with glibc) +ARCH=arm64 ./build-native.sh +# Or: mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true + + ## License Copyright (c) 2025, Altinity Inc and/or its affiliates. All rights reserved. diff --git a/build-native.sh b/build-native.sh new file mode 100755 index 00000000..891d534f --- /dev/null +++ b/build-native.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# Build native images for ice CLI +# Supports: amd64 (static with musl), arm64 (dynamic) + +set -e + +VERSION="${VERSION:-0.0.0-SNAPSHOT}" +ARCH="${ARCH:-$(uname -m)}" + +# Convert architecture names +case "$ARCH" in + x86_64) + ARCH="amd64" + PROFILE="native-amd64-static" + ;; + aarch64|arm64) + ARCH="arm64" + PROFILE="native-arm64" + ;; + *) + echo "Unsupported architecture: $ARCH" + echo "Supported: x86_64/amd64, aarch64/arm64" + exit 1 + ;; +esac + +echo "============================================" +echo "Building native ice binary" +echo "Architecture: $ARCH" +echo "Profile: $PROFILE" +echo "Version: $VERSION" +echo "============================================" +echo "" + +# Check for musl-gcc on amd64 builds +if [ "$ARCH" = "amd64" ]; then + if ! command -v x86_64-linux-musl-gcc &> /dev/null && ! command -v musl-gcc &> /dev/null; then + echo " WARNING: musl compiler not found!" + echo "" + echo "For static builds on amd64, you need musl-tools installed." + echo "" + echo "Install it with:" + echo " Ubuntu/Debian: sudo apt-get install musl-tools" + echo " Fedora/RHEL: sudo dnf install musl-gcc musl-libc-static" + echo " Alpine: apk add musl-dev gcc" + echo "" + echo "Or build without static linking using the 'native' profile:" + echo " mvn -Pnative -pl ice clean package -Dmaven.test.skip=true" + echo "" + read -p "Continue anyway? (y/N) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + else + echo "✓ musl compiler found" + fi +fi +echo "" + +# Set version +./mvnw -am -pl ice versions:set -DnewVersion=${VERSION} + +# Build native image +echo "Building native image..." +./mvnw -Pno-check -P${PROFILE} -pl ice clean package -Dmaven.test.skip=true + +echo "" +echo "============================================" +echo "✓ Native binary built successfully!" +echo "============================================" +echo "" +echo "Binary location: ice/target/ice" +echo "" +echo "Test the binary:" +echo " ./ice/target/ice --version" +echo " ./ice/target/ice check" +echo "" + +# Show binary info +if [ -f "ice/target/ice" ]; then + ls -lh ice/target/ice + file ice/target/ice || true + + if [ "$ARCH" = "amd64" ]; then + echo "" + echo "Static binary (no dependencies):" + ldd ice/target/ice 2>&1 || echo " ✓ Statically linked (expected for amd64)" + else + echo "" + echo "Dynamic binary dependencies:" + ldd ice/target/ice || true + fi +fi + diff --git a/ice/pom.xml b/ice/pom.xml index f7dd3d0d..098bfff0 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -690,7 +690,7 @@ com.altinity.ice.cli.Main --initialize-at-build-time=ch.qos.logback - -H:ReflectionConfigurationFiles=src/main/resources/reflection-config.json + -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json --trace-class-initialization=ch.qos.logback.classic.Logger --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker --trace-object-instantiation=ch.qos.logback.classic.Logger @@ -704,5 +704,88 @@ + + native-amd64-static + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + + + build-native + + compile-no-fork + + package + + + + ice + com.altinity.ice.cli.Main + + + --initialize-at-build-time=ch.qos.logback + -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json + --trace-class-initialization=ch.qos.logback.classic.Logger + --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker + --trace-object-instantiation=ch.qos.logback.classic.Logger + --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-build-time=ch.qos.logback.classic.Logger + --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout + + --static + --libc=musl + + -H:+RemoveUnusedSymbols + -H:+ReportExceptionStackTraces + + + + + + + + native-arm64 + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + + + build-native + + compile-no-fork + + package + + + + ice + com.altinity.ice.cli.Main + + + --initialize-at-build-time=ch.qos.logback + -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json + --trace-class-initialization=ch.qos.logback.classic.Logger + --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker + --trace-object-instantiation=ch.qos.logback.classic.Logger + --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-build-time=ch.qos.logback.classic.Logger + --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout + + -H:+RemoveUnusedSymbols + -H:+ReportExceptionStackTraces + + + + + + From b1bef04b1e3ab21bf9f9db0f8393f03522721191 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 19 Nov 2025 19:23:18 -0600 Subject: [PATCH 03/25] include amd64 in supported architecture --- build-native.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-native.sh b/build-native.sh index 891d534f..1b6c26c0 100755 --- a/build-native.sh +++ b/build-native.sh @@ -9,7 +9,7 @@ ARCH="${ARCH:-$(uname -m)}" # Convert architecture names case "$ARCH" in - x86_64) + x86_64|amd64) ARCH="amd64" PROFILE="native-amd64-static" ;; From a2f6743c474faff2dcdf9d7e61493a7f00d46753 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 19 Nov 2025 19:28:49 -0600 Subject: [PATCH 04/25] Added runtime depedencies for native image. --- ice/pom.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ice/pom.xml b/ice/pom.xml index 098bfff0..35c59eee 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -695,6 +695,9 @@ --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=org.slf4j.LoggerFactory + --initialize-at-run-time=org.slf4j.helpers.Reporter + --initialize-at-run-time=picocli.CommandLine$Help$Ansi --initialize-at-build-time=ch.qos.logback.classic.Logger --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout @@ -733,6 +736,9 @@ --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=org.slf4j.LoggerFactory + --initialize-at-run-time=org.slf4j.helpers.Reporter + --initialize-at-run-time=picocli.CommandLine$Help$Ansi --initialize-at-build-time=ch.qos.logback.classic.Logger --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout @@ -776,6 +782,9 @@ --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=org.slf4j.LoggerFactory + --initialize-at-run-time=org.slf4j.helpers.Reporter + --initialize-at-run-time=picocli.CommandLine$Help$Ansi --initialize-at-build-time=ch.qos.logback.classic.Logger --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout From fc1d23a5e55a35758cca7347d9b15e5edcec44f4 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 19 Nov 2025 19:35:12 -0600 Subject: [PATCH 05/25] Added runtime depedencies for native image. --- ice/pom.xml | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/ice/pom.xml b/ice/pom.xml index 35c59eee..367dde56 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -689,17 +689,9 @@ ice com.altinity.ice.cli.Main - --initialize-at-build-time=ch.qos.logback -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --trace-class-initialization=ch.qos.logback.classic.Logger - --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker - --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask - --initialize-at-run-time=org.slf4j.LoggerFactory - --initialize-at-run-time=org.slf4j.helpers.Reporter - --initialize-at-run-time=picocli.CommandLine$Help$Ansi - --initialize-at-build-time=ch.qos.logback.classic.Logger - --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout + -H:+ReportExceptionStackTraces @@ -730,17 +722,8 @@ com.altinity.ice.cli.Main - --initialize-at-build-time=ch.qos.logback -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --trace-class-initialization=ch.qos.logback.classic.Logger - --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker - --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask - --initialize-at-run-time=org.slf4j.LoggerFactory - --initialize-at-run-time=org.slf4j.helpers.Reporter - --initialize-at-run-time=picocli.CommandLine$Help$Ansi - --initialize-at-build-time=ch.qos.logback.classic.Logger - --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout --static --libc=musl @@ -776,17 +759,8 @@ com.altinity.ice.cli.Main - --initialize-at-build-time=ch.qos.logback -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --trace-class-initialization=ch.qos.logback.classic.Logger - --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker - --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask - --initialize-at-run-time=org.slf4j.LoggerFactory - --initialize-at-run-time=org.slf4j.helpers.Reporter - --initialize-at-run-time=picocli.CommandLine$Help$Ansi - --initialize-at-build-time=ch.qos.logback.classic.Logger - --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout -H:+RemoveUnusedSymbols -H:+ReportExceptionStackTraces From 371c0f8bcee579f23e2fac49129a8d163de06702 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Fri, 21 Nov 2025 07:50:21 -0600 Subject: [PATCH 06/25] Fixed reflection-config.json --- .github/workflows/verify.yaml | 16 +++++++++----- ice/pom.xml | 9 +++++--- ice/src/main/resources/reflection-config.json | 22 ------------------- 3 files changed, 16 insertions(+), 31 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index a48026c9..85bad765 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -67,9 +67,13 @@ jobs: java-version: '21' distribution: 'graalvm' cache: maven - - name: Install musl for static linking - run: sudo apt-get update && sudo apt-get install -y musl-tools - - name: Build native image (amd64 static with musl) - run: ./build-native.sh - env: - ARCH: amd64 + - name: Build native image (dynamic linking - no musl required) + run: ./mvnw -Pnative -pl ice clean package -Dmaven.test.skip=true + - name: Test native binary + run: ./test-native-binary.sh + - name: Upload native binary as artifact + uses: actions/upload-artifact@v4 + with: + name: ice-native-amd64-dynamic + path: ice/target/ice + if-no-files-found: error diff --git a/ice/pom.xml b/ice/pom.xml index 367dde56..3b1db9bf 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -690,7 +690,8 @@ com.altinity.ice.cli.Main -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=io.netty + --initialize-at-run-time=ch.qos.logback -H:+ReportExceptionStackTraces @@ -723,7 +724,8 @@ -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=io.netty + --initialize-at-run-time=ch.qos.logback --static --libc=musl @@ -760,7 +762,8 @@ -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=io.netty + --initialize-at-run-time=ch.qos.logback -H:+RemoveUnusedSymbols -H:+ReportExceptionStackTraces diff --git a/ice/src/main/resources/reflection-config.json b/ice/src/main/resources/reflection-config.json index 1d9866a5..15a1a7b5 100644 --- a/ice/src/main/resources/reflection-config.json +++ b/ice/src/main/resources/reflection-config.json @@ -10,28 +10,6 @@ "allDeclaredClasses": true, "allPublicClasses": true }, - { - "name": "ch.qos.logback.classic.Logger.effectiveLevelInt", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.Logger.loggerContext", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, { "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder", "allDeclaredConstructors": true, From ddbcf9fcdc4243814f0a4066fbe416a00b6cabfb Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Fri, 21 Nov 2025 08:57:32 -0600 Subject: [PATCH 07/25] remove verify binary step. --- .github/workflows/verify.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 85bad765..50736f6a 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -69,8 +69,6 @@ jobs: cache: maven - name: Build native image (dynamic linking - no musl required) run: ./mvnw -Pnative -pl ice clean package -Dmaven.test.skip=true - - name: Test native binary - run: ./test-native-binary.sh - name: Upload native binary as artifact uses: actions/upload-artifact@v4 with: From 303357d83c6728c9045b33ed7e99c62a18b5af93 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Fri, 21 Nov 2025 09:23:46 -0600 Subject: [PATCH 08/25] Add support for ARM. --- .github/workflows/verify.yaml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 50736f6a..099facc5 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -58,8 +58,19 @@ jobs: -Dit.test=DockerScenarioBasedIT -Ddocker.image=altinity/ice-rest-catalog:debug-with-ice-latest-master-amd64 native-build: - name: Build and test native image - runs-on: ubuntu-24.04 + name: Build and test native image (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} + strategy: + matrix: + include: + - arch: amd64 + runner: ubuntu-24.04 + profile: native + artifact: ice-native-amd64-dynamic + - arch: arm64 + runner: ubuntu-24.04-arm + profile: native-arm64 + artifact: ice-native-arm64-dynamic steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 @@ -68,10 +79,10 @@ jobs: distribution: 'graalvm' cache: maven - name: Build native image (dynamic linking - no musl required) - run: ./mvnw -Pnative -pl ice clean package -Dmaven.test.skip=true + run: ./mvnw -P${{ matrix.profile }} -pl ice clean package -Dmaven.test.skip=true - name: Upload native binary as artifact uses: actions/upload-artifact@v4 with: - name: ice-native-amd64-dynamic + name: ${{ matrix.artifact }} path: ice/target/ice if-no-files-found: error From 12ef6b0cbef62e7d6705cbc4f846b9c99554da82 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sat, 22 Nov 2025 08:55:09 -0600 Subject: [PATCH 09/25] Added Dockerfile. --- docker-build-native.sh | 55 ++++++++++++++++++ ice/Dockerfile.native | 52 +++++++++++++++++ ice/Dockerfile.native-amd64-static | 33 +++++++++++ ice/Dockerfile.native-arm64 | 33 +++++++++++ ice/Dockerfile.native-builder | 91 ++++++++++++++++++++++++++++++ 5 files changed, 264 insertions(+) create mode 100755 docker-build-native.sh create mode 100644 ice/Dockerfile.native create mode 100644 ice/Dockerfile.native-amd64-static create mode 100644 ice/Dockerfile.native-arm64 create mode 100644 ice/Dockerfile.native-builder diff --git a/docker-build-native.sh b/docker-build-native.sh new file mode 100755 index 00000000..f300e81c --- /dev/null +++ b/docker-build-native.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Build ICE native images using Docker +# Usage: ./docker-build-native.sh [amd64|arm64|both] + +set -euo pipefail + +ARCH="${1:-$(uname -m)}" + +# Normalize architecture names +case "$ARCH" in + x86_64|amd64) + BUILD_ARCH="amd64" + PLATFORM="linux/amd64" + ;; + aarch64|arm64) + BUILD_ARCH="arm64" + PLATFORM="linux/arm64" + ;; + both) + echo "Building for both architectures..." + $0 amd64 + $0 arm64 + exit 0 + ;; + *) + echo "Unsupported architecture: $ARCH" + echo "Usage: $0 [amd64|arm64|both]" + exit 1 + ;; +esac + +echo "========================================" +echo "Building ICE native image for $BUILD_ARCH" +echo "Platform: $PLATFORM" +echo "========================================" + +# Build the Docker image +docker build \ + --platform="$PLATFORM" \ + --build-arg ARCH="$BUILD_ARCH" \ + -f ice/Dockerfile.native-builder \ + -t ice-native-builder:"$BUILD_ARCH" \ + . + +# Extract the binary +CONTAINER_ID=$(docker create ice-native-builder:"$BUILD_ARCH") +docker cp "$CONTAINER_ID":/ice "./ice-$BUILD_ARCH" +docker rm "$CONTAINER_ID" + +echo "" +echo "✓ Native binary created: ./ice-$BUILD_ARCH" +echo "" +echo "Test it with:" +echo " ./ice-$BUILD_ARCH --help" + diff --git a/ice/Dockerfile.native b/ice/Dockerfile.native new file mode 100644 index 00000000..52caa1e3 --- /dev/null +++ b/ice/Dockerfile.native @@ -0,0 +1,52 @@ +# Multi-arch native image build for ice +# Supports: amd64 (with static musl), arm64 (dynamic) +ARG BASE_IMAGE_TAG="nonroot" +ARG VERSION="0.0.0-SNAPSHOT" +ARG TARGETARCH + +FROM --platform=$BUILDPLATFORM ghcr.io/graalvm/native-image-community:21.0.2 AS build + +WORKDIR /app + +# Install musl for static linking (amd64) +RUN microdnf install -y musl-devel || true + +# Cache maven dependencies for faster re-builds +COPY .mvn/ .mvn/ +COPY mvnw . +COPY pom.xml . +COPY ice/pom.xml ice/pom.xml +COPY ice-rest-catalog/pom.xml ice-rest-catalog/pom.xml +RUN ./mvnw -am -pl ice dependency:go-offline + +ARG VERSION +ARG TARGETARCH + +COPY . . + +RUN ./mvnw -am -pl ice versions:set -DnewVersion=${VERSION} + +# Build with appropriate profile based on architecture +RUN if [ "$TARGETARCH" = "amd64" ]; then \ + echo "Building static native image for amd64 with musl..."; \ + ./mvnw -Pno-check -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true; \ + elif [ "$TARGETARCH" = "arm64" ]; then \ + echo "Building native image for arm64..."; \ + ./mvnw -Pno-check -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true; \ + else \ + echo "Building native image for $TARGETARCH..."; \ + ./mvnw -Pno-check -Pnative -pl ice clean package -Dmaven.test.skip=true; \ + fi + +# Use scratch for amd64 (static), distroless for arm64 (dynamic) +FROM scratch AS final-amd64 +COPY --from=build /app/ice/target/ice /usr/local/bin/ice +ENTRYPOINT ["/usr/local/bin/ice"] + +FROM gcr.io/distroless/base-debian12:${BASE_IMAGE_TAG} AS final-arm64 +COPY --from=build /app/ice/target/ice /usr/local/bin/ice +ENTRYPOINT ["/usr/local/bin/ice"] + +# Select appropriate final stage based on architecture +FROM final-${TARGETARCH} AS final + diff --git a/ice/Dockerfile.native-amd64-static b/ice/Dockerfile.native-amd64-static new file mode 100644 index 00000000..dd0c2587 --- /dev/null +++ b/ice/Dockerfile.native-amd64-static @@ -0,0 +1,33 @@ +# Dockerfile for building ICE native image (amd64, static with musl) +# Usage: docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64-static . + +FROM ghcr.io/graalvm/native-image-community:21-muslib AS builder + +WORKDIR /workspace + +# Copy license header file (required by license-maven-plugin) +COPY apache-header.txt . + +# Copy Maven files for dependency resolution +COPY mvnw . +COPY .mvn .mvn +COPY pom.xml . +COPY ice/pom.xml ice/ +COPY ice-rest-catalog/pom.xml ice-rest-catalog/ + +# Download dependencies (cached layer) +RUN ./mvnw dependency:go-offline -pl ice || true + +# Copy source code +COPY ice/src ice/src + +# Build static native image with musl +RUN ./mvnw -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true + +# ============================================================================ +# Final stage: minimal scratch image (truly standalone binary) +# ============================================================================ +FROM scratch +COPY --from=builder /workspace/ice/target/ice /ice +ENTRYPOINT ["/ice"] + diff --git a/ice/Dockerfile.native-arm64 b/ice/Dockerfile.native-arm64 new file mode 100644 index 00000000..4d997ec1 --- /dev/null +++ b/ice/Dockerfile.native-arm64 @@ -0,0 +1,33 @@ +# Dockerfile for building ICE native image (arm64, dynamic linking) +# Usage: docker build -f ice/Dockerfile.native-arm64 -t ice-native:arm64 . + +FROM ghcr.io/graalvm/native-image-community:21 AS builder + +WORKDIR /workspace + +# Copy license header file (required by license-maven-plugin) +COPY apache-header.txt . + +# Copy Maven files for dependency resolution +COPY mvnw . +COPY .mvn .mvn +COPY pom.xml . +COPY ice/pom.xml ice/ +COPY ice-rest-catalog/pom.xml ice-rest-catalog/ + +# Download dependencies (cached layer) +RUN ./mvnw dependency:go-offline -pl ice || true + +# Copy source code +COPY ice/src ice/src + +# Build dynamic native image +RUN ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true + +# ============================================================================ +# Final stage: distroless base (includes minimal glibc runtime) +# ============================================================================ +FROM gcr.io/distroless/base-debian12:nonroot +COPY --from=builder /workspace/ice/target/ice /ice +ENTRYPOINT ["/ice"] + diff --git a/ice/Dockerfile.native-builder b/ice/Dockerfile.native-builder new file mode 100644 index 00000000..0a044e6d --- /dev/null +++ b/ice/Dockerfile.native-builder @@ -0,0 +1,91 @@ +# Multi-stage Dockerfile for building ICE native images +# Supports both amd64 (with static musl) and arm64 (dynamic) + +ARG ARCH=amd64 + +# ============================================================================ +# Stage 1: Build stage with all dependencies +# ============================================================================ +FROM ghcr.io/graalvm/native-image-community:21 AS builder + +# Install build dependencies +RUN microdnf install -y \ + findutils \ + tar \ + gzip \ + wget \ + && microdnf clean all + +# Detect architecture and install appropriate dependencies +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + echo "Installing musl toolchain and zlib for amd64 static builds..."; \ + # Download and install musl-gcc + wget -q https://musl.libc.org/releases/musl-1.2.5.tar.gz && \ + tar -xzf musl-1.2.5.tar.gz && \ + cd musl-1.2.5 && \ + ./configure --prefix=/usr/local/musl --disable-shared && \ + make -j$(nproc) && \ + make install && \ + cd .. && \ + rm -rf musl-1.2.5 musl-1.2.5.tar.gz && \ + # Download and install zlib for musl + wget -q https://zlib.net/zlib-1.3.1.tar.gz && \ + tar -xzf zlib-1.3.1.tar.gz && \ + cd zlib-1.3.1 && \ + CC=/usr/local/musl/bin/musl-gcc ./configure --prefix=/usr/local/musl --static && \ + make -j$(nproc) && \ + make install && \ + cd .. && \ + rm -rf zlib-1.3.1 zlib-1.3.1.tar.gz && \ + # Create symlink for native-image to find musl-gcc + ln -sf /usr/local/musl/bin/musl-gcc /usr/local/bin/x86_64-linux-musl-gcc; \ + else \ + echo "ARM64 detected - using dynamic linking (no musl required)"; \ + fi + +WORKDIR /workspace + +# Copy license header file (required by license-maven-plugin) +COPY apache-header.txt . + +# Copy Maven wrapper and pom files first (for better caching) +COPY mvnw . +COPY .mvn .mvn +COPY pom.xml . +COPY ice/pom.xml ice/ +COPY ice-rest-catalog/pom.xml ice-rest-catalog/ + +# Download dependencies (cached layer) +RUN ./mvnw dependency:go-offline -pl ice || true + +# Copy source code +COPY ice/src ice/src + +# Build native image based on architecture +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + echo "Building static native image for amd64 with musl..."; \ + export PATH="/usr/local/musl/bin:$PATH" && \ + ./mvnw -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true; \ + else \ + echo "Building dynamic native image for arm64..."; \ + ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true; \ + fi + +# ============================================================================ +# Stage 2: Runtime image (minimal) +# ============================================================================ +FROM scratch AS runtime-amd64 +COPY --from=builder /workspace/ice/target/ice /ice +ENTRYPOINT ["/ice"] + +FROM gcr.io/distroless/base-debian12:nonroot AS runtime-arm64 +COPY --from=builder /workspace/ice/target/ice /ice +ENTRYPOINT ["/ice"] + +# ============================================================================ +# Stage 3: Final stage (architecture-dependent) +# ============================================================================ +FROM runtime-${ARCH} AS final + From d0b8aafba2661fe7562c2a4c080106fd2e61af58 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sun, 23 Nov 2025 10:22:59 -0600 Subject: [PATCH 10/25] Remove autogenerated files. --- GITHUB_RELEASE_TEMPLATE.md | 34 -- build-native.sh | 95 ----- docker-build-native.sh | 55 --- .../docker-compose/test-ssl-verification.md | 186 ++++++++++ examples/scratch/output.json | 0 ice-rest-catalog/SCENARIO_TESTING.md | 344 ++++++++++++++++++ ice/Dockerfile.native | 52 --- ice/Dockerfile.native-amd64-static | 2 +- ice/Dockerfile.native-builder | 91 ----- 9 files changed, 531 insertions(+), 328 deletions(-) delete mode 100644 GITHUB_RELEASE_TEMPLATE.md delete mode 100755 build-native.sh delete mode 100755 docker-build-native.sh create mode 100644 examples/docker-compose/test-ssl-verification.md create mode 100644 examples/scratch/output.json create mode 100644 ice-rest-catalog/SCENARIO_TESTING.md delete mode 100644 ice/Dockerfile.native delete mode 100644 ice/Dockerfile.native-builder diff --git a/GITHUB_RELEASE_TEMPLATE.md b/GITHUB_RELEASE_TEMPLATE.md deleted file mode 100644 index fe7ff576..00000000 --- a/GITHUB_RELEASE_TEMPLATE.md +++ /dev/null @@ -1,34 +0,0 @@ -## Installation - -### ice - -```sh -curl -sSL https://github.com/altinity/ice/releases/download/REPLACE_WITH_TAG/ice-REPLACE_WITH_VER \ - -o ice && chmod a+x ice && sudo mv ice /usr/local/bin/ -``` - -#### Docker - - - -- `altinity/ice:REPLACE_WITH_VER` -- `altinity/ice:debug-REPLACE_WITH_VER` - -> `debug-*` images contain busybox shell. - -### ice-rest-catalog - -```sh -curl -sSL https://github.com/altinity/ice/releases/download/REPLACE_WITH_TAG/ice-rest-catalog-REPLACE_WITH_VER \ - -o ice-rest-catalog && chmod a+x ice-rest-catalog && sudo mv ice-rest-catalog /usr/local/bin/ -``` - -#### Docker - - - -- `altinity/ice-rest-catalog:REPLACE_WITH_VER` -- `altinity/ice-rest-catalog:debug-REPLACE_WITH_VER` -- `altinity/ice-rest-catalog:debug-with-ice-REPLACE_WITH_VER` - -> `debug-*` images contain busybox shell. diff --git a/build-native.sh b/build-native.sh deleted file mode 100755 index 1b6c26c0..00000000 --- a/build-native.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash -# Build native images for ice CLI -# Supports: amd64 (static with musl), arm64 (dynamic) - -set -e - -VERSION="${VERSION:-0.0.0-SNAPSHOT}" -ARCH="${ARCH:-$(uname -m)}" - -# Convert architecture names -case "$ARCH" in - x86_64|amd64) - ARCH="amd64" - PROFILE="native-amd64-static" - ;; - aarch64|arm64) - ARCH="arm64" - PROFILE="native-arm64" - ;; - *) - echo "Unsupported architecture: $ARCH" - echo "Supported: x86_64/amd64, aarch64/arm64" - exit 1 - ;; -esac - -echo "============================================" -echo "Building native ice binary" -echo "Architecture: $ARCH" -echo "Profile: $PROFILE" -echo "Version: $VERSION" -echo "============================================" -echo "" - -# Check for musl-gcc on amd64 builds -if [ "$ARCH" = "amd64" ]; then - if ! command -v x86_64-linux-musl-gcc &> /dev/null && ! command -v musl-gcc &> /dev/null; then - echo " WARNING: musl compiler not found!" - echo "" - echo "For static builds on amd64, you need musl-tools installed." - echo "" - echo "Install it with:" - echo " Ubuntu/Debian: sudo apt-get install musl-tools" - echo " Fedora/RHEL: sudo dnf install musl-gcc musl-libc-static" - echo " Alpine: apk add musl-dev gcc" - echo "" - echo "Or build without static linking using the 'native' profile:" - echo " mvn -Pnative -pl ice clean package -Dmaven.test.skip=true" - echo "" - read -p "Continue anyway? (y/N) " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 - fi - else - echo "✓ musl compiler found" - fi -fi -echo "" - -# Set version -./mvnw -am -pl ice versions:set -DnewVersion=${VERSION} - -# Build native image -echo "Building native image..." -./mvnw -Pno-check -P${PROFILE} -pl ice clean package -Dmaven.test.skip=true - -echo "" -echo "============================================" -echo "✓ Native binary built successfully!" -echo "============================================" -echo "" -echo "Binary location: ice/target/ice" -echo "" -echo "Test the binary:" -echo " ./ice/target/ice --version" -echo " ./ice/target/ice check" -echo "" - -# Show binary info -if [ -f "ice/target/ice" ]; then - ls -lh ice/target/ice - file ice/target/ice || true - - if [ "$ARCH" = "amd64" ]; then - echo "" - echo "Static binary (no dependencies):" - ldd ice/target/ice 2>&1 || echo " ✓ Statically linked (expected for amd64)" - else - echo "" - echo "Dynamic binary dependencies:" - ldd ice/target/ice || true - fi -fi - diff --git a/docker-build-native.sh b/docker-build-native.sh deleted file mode 100755 index f300e81c..00000000 --- a/docker-build-native.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -# Build ICE native images using Docker -# Usage: ./docker-build-native.sh [amd64|arm64|both] - -set -euo pipefail - -ARCH="${1:-$(uname -m)}" - -# Normalize architecture names -case "$ARCH" in - x86_64|amd64) - BUILD_ARCH="amd64" - PLATFORM="linux/amd64" - ;; - aarch64|arm64) - BUILD_ARCH="arm64" - PLATFORM="linux/arm64" - ;; - both) - echo "Building for both architectures..." - $0 amd64 - $0 arm64 - exit 0 - ;; - *) - echo "Unsupported architecture: $ARCH" - echo "Usage: $0 [amd64|arm64|both]" - exit 1 - ;; -esac - -echo "========================================" -echo "Building ICE native image for $BUILD_ARCH" -echo "Platform: $PLATFORM" -echo "========================================" - -# Build the Docker image -docker build \ - --platform="$PLATFORM" \ - --build-arg ARCH="$BUILD_ARCH" \ - -f ice/Dockerfile.native-builder \ - -t ice-native-builder:"$BUILD_ARCH" \ - . - -# Extract the binary -CONTAINER_ID=$(docker create ice-native-builder:"$BUILD_ARCH") -docker cp "$CONTAINER_ID":/ice "./ice-$BUILD_ARCH" -docker rm "$CONTAINER_ID" - -echo "" -echo "✓ Native binary created: ./ice-$BUILD_ARCH" -echo "" -echo "Test it with:" -echo " ./ice-$BUILD_ARCH --help" - diff --git a/examples/docker-compose/test-ssl-verification.md b/examples/docker-compose/test-ssl-verification.md new file mode 100644 index 00000000..72ca27ea --- /dev/null +++ b/examples/docker-compose/test-ssl-verification.md @@ -0,0 +1,186 @@ +# Testing SSL Certificate Verification Skip + +This guide shows how to test the `--insecure` / `--ssl-no-verify` flag with self-signed certificates. + +## Option 1: Quick Test with a Self-Signed HTTPS Server + +### 1. Generate a self-signed certificate + +```bash +# Generate a self-signed certificate for testing +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \ + -subj "/CN=localhost" \ + -addext "subjectAltName=DNS:localhost,IP:127.0.0.1" +``` + +### 2. Set up an HTTPS proxy to ice-rest-catalog + +Create a simple nginx config to add SSL in front of the catalog: + +**nginx-ssl.conf**: +```nginx +events { + worker_connections 1024; +} + +http { + server { + listen 5443 ssl; + server_name localhost; + + ssl_certificate /etc/nginx/cert.pem; + ssl_certificate_key /etc/nginx/key.pem; + + location / { + proxy_pass http://ice-rest-catalog:5000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } +} +``` + +**docker-compose.ssl-test.yaml**: +```yaml +services: + nginx-ssl: + image: nginx:alpine + ports: + - "5443:5443" + volumes: + - ./cert.pem:/etc/nginx/cert.pem:ro + - ./key.pem:/etc/nginx/key.pem:ro + - ./nginx-ssl.conf:/etc/nginx/nginx.conf:ro + depends_on: + - ice-rest-catalog +``` + +### 3. Start the services + +```bash +# Start the regular docker-compose setup +docker-compose up -d + +# Start the SSL proxy +docker-compose -f docker-compose.ssl-test.yaml up -d +``` + +### 4. Test the ice CLI + +First, format and build the code: +```bash +cd /home/kanthi/Documents/GITHUB/ALTINITY/ice +mvn com.spotify.fmt:fmt-maven-plugin:format -pl ice +mvn clean install -pl ice -am -DskipTests +``` + +Create a test config file `.ice-ssl-test.yaml`: +```yaml +uri: https://localhost:5443 +bearerToken: foo +warehouse: s3://bucket1 +sslVerify: false # Config file option +s3: + endpoint: http://localhost:8999 + pathStyleAccess: true + accessKeyID: miniouser + secretAccessKey: miniopassword + region: minio +``` + +**Test 1: Without --insecure flag (should fail with SSL error)**: +```bash +./ice/target/ice-jar -c .ice-ssl-test.yaml check +# Expected: SSL certificate verification error +``` + +**Test 2: With --insecure flag (should succeed)**: +```bash +./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure check +# Expected: OK +``` + +**Test 3: Using config file sslVerify option**: +With `sslVerify: false` in the config file: +```bash +./ice/target/ice-jar -c .ice-ssl-test.yaml check +# Expected: OK (with warning about disabled SSL verification) +``` + +**Test 4: Test other commands**: +```bash +# List namespaces +./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure describe + +# Create a namespace +./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure create-namespace test_ns + +# Create a table +./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure create-table test_ns.test_table \ + --schema '[{"name":"id","type":"int"},{"name":"name","type":"string"}]' +``` + +## Option 2: Test with Public Self-Signed Certificate Server + +You can also test against a public service with a self-signed certificate: + +```bash +# This will fail due to self-signed certificate +./ice/target/ice-jar -c config.yaml check + +# This will work with --insecure +./ice/target/ice-jar -c config.yaml --insecure check +``` + +## Option 3: Test with Internal CA Certificate + +If you have an internal CA, you can test the custom CA bundle feature: + +```yaml +uri: https://internal-catalog.company.local:5443 +caCrt: | + -----BEGIN CERTIFICATE----- + MIIDXTCCAkWgAwIBAgIJAKJ... + -----END CERTIFICATE----- +bearerToken: foo +``` + +This should work without `--insecure` because the CA certificate is provided. + +## Expected Behavior + +### Without SSL verification skip: +- ❌ Fails with certificate verification errors for self-signed certificates +- ✅ Works with valid certificates from trusted CAs +- ✅ Works when custom CA certificate is provided via `caCrt` + +### With SSL verification skip (`--insecure` or `sslVerify: false`): +- ⚠️ Displays warning: "SSL certificate verification is DISABLED. This is insecure and should only be used for development." +- ✅ Works with any certificate (self-signed, expired, wrong hostname, etc.) +- ⚠️ **INSECURE**: Should only be used for development/testing + +## Command-line Flags + +Two equivalent options: +- `--insecure` - Shorter, commonly used in tools like curl +- `--ssl-no-verify` - More explicit about what it does + +Both flags: +- Override the config file `sslVerify` setting +- Apply to all subcommands (check, describe, scan, insert, etc.) +- Display a warning message when SSL verification is disabled + +## Config File Option + +```yaml +sslVerify: false # Skip SSL certificate verification +``` + +Note: The command-line flag takes precedence over the config file option. + + + + + + diff --git a/examples/scratch/output.json b/examples/scratch/output.json new file mode 100644 index 00000000..e69de29b diff --git a/ice-rest-catalog/SCENARIO_TESTING.md b/ice-rest-catalog/SCENARIO_TESTING.md new file mode 100644 index 00000000..af54e58e --- /dev/null +++ b/ice-rest-catalog/SCENARIO_TESTING.md @@ -0,0 +1,344 @@ +# Scenario-Based Testing Framework + +This document describes the new scenario-based testing framework for ICE REST Catalog integration tests. + +## Overview + +The scenario-based testing framework provides a scalable, data-driven approach to integration testing. Instead of hardcoding test scenarios in Java test methods, each scenario is defined in its own directory with: + +- Configuration files (scenario.yaml) +- Input data (parquet files) +- Executable test scripts (run.sh.tmpl, verify.sh.tmpl) + +This approach makes it much easier to: +- Add new test scenarios without writing Java code +- Share test scenarios across teams +- Test complex workflows with multiple steps +- Provision cloud resources dynamically (future feature) + +## Directory Structure + +``` +ice-rest-catalog/src/test/resources/scenarios/ +├── README.md # Documentation for scenario structure +├── basic-operations/ # Example scenario +│ ├── scenario.yaml # Scenario configuration +│ ├── run.sh.tmpl # Main test script (templated) +│ └── verify.sh.tmpl # Optional verification script +├── insert-scan/ +│ ├── scenario.yaml +│ ├── run.sh.tmpl +│ ├── verify.sh.tmpl +│ └── input.parquet # Test data +└── insert-partitioned/ + ├── scenario.yaml + ├── run.sh.tmpl + ├── verify.sh.tmpl + └── input.parquet +``` + +## Key Components + +### 1. ScenarioConfig.java +Java class that represents the scenario.yaml configuration file. Supports: +- Scenario metadata (name, description) +- Catalog configuration overrides +- Environment variables for scripts +- Cloud resource specifications (for future provisioning) +- Test phases + +### 2. ScenarioTestRunner.java +Core test execution engine that: +- Discovers scenario directories +- Loads scenario configurations +- Processes template variables in scripts +- Executes scripts and captures output +- Reports results + +### 3. ScenarioBasedIT.java +TestNG parameterized test class that: +- Automatically discovers all scenarios +- Runs each scenario as a separate test case +- Provides test infrastructure (MinIO, REST catalog) +- Injects template variables (CLI config, endpoints, etc.) + +### 4. RESTCatalogTestBase.java (Updated) +Base test class that provides: +- MinIO container setup/teardown +- REST catalog server setup/teardown +- Helper methods for scenarios (getMinioEndpoint, getCatalogUri, etc.) + +## How It Works + +### 1. Test Discovery +When you run `mvn test -Dtest=ScenarioBasedIT`, the test framework: + +1. Scans `src/test/resources/scenarios/` for directories +2. Each directory is considered a scenario +3. Creates a parameterized test for each scenario + +### 2. Test Execution +For each scenario: + +1. **Setup Phase**: + - Start MinIO container + - Start ICE REST catalog server + - Create temporary CLI config file + - Build template variables + +2. **Execution Phase**: + - Load scenario.yaml configuration + - Process run.sh.tmpl with template variables + - Execute the processed script + - Capture stdout, stderr, and exit code + +3. **Verification Phase** (optional): + - Process verify.sh.tmpl with template variables + - Execute verification script + - Capture results + +4. **Teardown Phase**: + - Stop REST catalog server + - Stop MinIO container + - Clean up temporary files + +### 3. Template Processing +Scripts can use template variables in the format `{{VARIABLE_NAME}}`: + +```bash +# Available template variables: +# {{ICE_CLI}} - Path to ice CLI executable +# {{CLI_CONFIG}} - Path to temporary CLI config file +# {{MINIO_ENDPOINT}} - MinIO endpoint URL (e.g., http://localhost:9000) +# {{CATALOG_URI}} - REST catalog URI (e.g., http://localhost:8080) +# {{SCENARIO_DIR}} - Absolute path to scenario directory + +# Environment variables from scenario.yaml are also available +{{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME} +``` + +## Creating a New Scenario + +1. **Create scenario directory**: + ```bash + mkdir ice-rest-catalog/src/test/resources/scenarios/my-new-test + ``` + +2. **Create scenario.yaml**: + ```yaml + name: "My New Test" + description: "Description of what this test does" + + env: + NAMESPACE_NAME: "my_test_ns" + TABLE_NAME: "my_test_ns.my_table" + + cloudResources: + s3: + buckets: + - "test-bucket" + ``` + +3. **Create run.sh.tmpl**: + ```bash + #!/bin/bash + set -e + + echo "Running my test..." + + # Create namespace + {{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME} + + # ... more test steps ... + + # Cleanup + {{ICE_CLI}} --config {{CLI_CONFIG}} delete-namespace ${NAMESPACE_NAME} + + echo "Test completed successfully" + ``` + +4. **Add test data** (optional): + ```bash + cp example-data.parquet ice-rest-catalog/src/test/resources/scenarios/my-new-test/input.parquet + ``` + +5. **Run the test**: + ```bash + mvn test -Dtest=ScenarioBasedIT#testScenario[my-new-test] + ``` + +## Running Tests + +### Run all scenarios: +```bash +cd ice-rest-catalog +mvn test -Dtest=ScenarioBasedIT +``` + +### Run a specific scenario: +```bash +mvn test -Dtest=ScenarioBasedIT#testScenario[basic-operations] +``` + +### Run scenarios matching a pattern: +```bash +mvn test -Dtest=ScenarioBasedIT#testScenario[insert*] +``` + +## Benefits Over Previous Approach + +### Before (Hardcoded Java Tests): +```java +@Test +public void testScenario1() throws Exception { + File config = createTempCliConfig(); + new CommandLine(Main.class).execute("--config", config.getAbsolutePath(), + "create-namespace", "test_ns"); + new CommandLine(Main.class).execute("--config", config.getAbsolutePath(), + "delete-namespace", "test_ns"); + // ... repeat for each scenario +} + +@Test +public void testScenario2() throws Exception { + // ... duplicate setup code ... +} +``` + +**Problems**: +- Lots of duplicated code +- Hard to add new scenarios +- Difficult to test complex workflows +- No separation of test data and test logic +- Hard to share tests with non-Java developers + +### After (Scenario-Based Tests): +``` +scenarios/ + scenario1/ + scenario.yaml + run.sh.tmpl + scenario2/ + scenario.yaml + run.sh.tmpl + input.parquet +``` + +**Benefits**: +- ✅ No code duplication +- ✅ Easy to add new scenarios (just add a directory) +- ✅ Can test complex workflows with multiple steps +- ✅ Clear separation of test data and logic +- ✅ Scripts can be shared and run independently +- ✅ Can be used by QA engineers without Java knowledge +- ✅ Future: automatic cloud resource provisioning + +## Example Scenarios + +### 1. basic-operations +Tests fundamental catalog operations: +- Create namespace +- List namespaces +- Delete namespace + +### 2. insert-scan +Tests data insertion and retrieval: +- Create namespace +- Insert data from parquet file +- Scan table +- Verify data contents +- Cleanup + +### 3. insert-partitioned +Tests partitioned table creation: +- Create namespace +- Insert data with partition specification +- Verify table was created +- Cleanup + +## Future Enhancements + +1. **Cloud Resource Provisioning**: + - Automatically create S3 buckets, SQS queues, etc. based on scenario.yaml + - Use AWS CloudFormation or Terraform templates + - Clean up resources after test completion + +2. **Parallel Execution**: + - Run independent scenarios in parallel + - Speed up test suite execution + +3. **Test Data Generation**: + - Generate synthetic test data based on schema specifications + - Support for various data formats (Avro, ORC, etc.) + +4. **Scenario Composition**: + - Reuse common scenario steps + - Create scenario libraries + +5. **Performance Testing**: + - Add performance benchmarks to scenarios + - Track performance over time + +## Migration Guide + +To migrate existing hardcoded tests to scenarios: + +1. Identify the test scenario (e.g., "insert with partitioning") +2. Create a scenario directory +3. Extract configuration into scenario.yaml +4. Convert Java test code to bash script in run.sh.tmpl +5. Add test data files if needed +6. Delete the old Java test method + +Example migration: + +**Before** (RESTCatalogInsertIT.java): +```java +@Test +public void testInsertCommand() throws Exception { + File config = createTempCliConfig(); + String namespace = "test_insert"; + new CommandLine(Main.class).execute("--config", config, + "create-namespace", namespace); + // ... more code ... +} +``` + +**After** (scenarios/insert-scan/): +``` +scenario.yaml # Configuration +run.sh.tmpl # Test logic +input.parquet # Test data +``` + +## Troubleshooting + +### Scenario not discovered +- Ensure scenario directory is in `src/test/resources/scenarios/` +- Check that `scenario.yaml` exists in the directory +- Directory name should not start with `.` + +### Script execution fails +- Check script has correct shebang (`#!/bin/bash`) +- Verify template variables are correctly specified +- Check file paths are relative to {{SCENARIO_DIR}} +- Review script output in test logs + +### ICE CLI not found +- Ensure `ice/target/ice-jar` is built: `mvn -am -pl ice package` +- Or ensure `.bin/local-ice` script exists +- Check that ICE_CLI template variable is correctly set + +## Additional Resources + +- [Scenarios README](src/test/resources/scenarios/README.md) - Detailed scenario structure documentation +- [ICE CLI Documentation](../ice/README.md) - CLI command reference +- [TestNG Documentation](https://testng.org/doc/) - TestNG testing framework + + + + + + + + diff --git a/ice/Dockerfile.native b/ice/Dockerfile.native deleted file mode 100644 index 52caa1e3..00000000 --- a/ice/Dockerfile.native +++ /dev/null @@ -1,52 +0,0 @@ -# Multi-arch native image build for ice -# Supports: amd64 (with static musl), arm64 (dynamic) -ARG BASE_IMAGE_TAG="nonroot" -ARG VERSION="0.0.0-SNAPSHOT" -ARG TARGETARCH - -FROM --platform=$BUILDPLATFORM ghcr.io/graalvm/native-image-community:21.0.2 AS build - -WORKDIR /app - -# Install musl for static linking (amd64) -RUN microdnf install -y musl-devel || true - -# Cache maven dependencies for faster re-builds -COPY .mvn/ .mvn/ -COPY mvnw . -COPY pom.xml . -COPY ice/pom.xml ice/pom.xml -COPY ice-rest-catalog/pom.xml ice-rest-catalog/pom.xml -RUN ./mvnw -am -pl ice dependency:go-offline - -ARG VERSION -ARG TARGETARCH - -COPY . . - -RUN ./mvnw -am -pl ice versions:set -DnewVersion=${VERSION} - -# Build with appropriate profile based on architecture -RUN if [ "$TARGETARCH" = "amd64" ]; then \ - echo "Building static native image for amd64 with musl..."; \ - ./mvnw -Pno-check -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true; \ - elif [ "$TARGETARCH" = "arm64" ]; then \ - echo "Building native image for arm64..."; \ - ./mvnw -Pno-check -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true; \ - else \ - echo "Building native image for $TARGETARCH..."; \ - ./mvnw -Pno-check -Pnative -pl ice clean package -Dmaven.test.skip=true; \ - fi - -# Use scratch for amd64 (static), distroless for arm64 (dynamic) -FROM scratch AS final-amd64 -COPY --from=build /app/ice/target/ice /usr/local/bin/ice -ENTRYPOINT ["/usr/local/bin/ice"] - -FROM gcr.io/distroless/base-debian12:${BASE_IMAGE_TAG} AS final-arm64 -COPY --from=build /app/ice/target/ice /usr/local/bin/ice -ENTRYPOINT ["/usr/local/bin/ice"] - -# Select appropriate final stage based on architecture -FROM final-${TARGETARCH} AS final - diff --git a/ice/Dockerfile.native-amd64-static b/ice/Dockerfile.native-amd64-static index dd0c2587..e8b4f271 100644 --- a/ice/Dockerfile.native-amd64-static +++ b/ice/Dockerfile.native-amd64-static @@ -1,5 +1,5 @@ # Dockerfile for building ICE native image (amd64, static with musl) -# Usage: docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64-static . +# Usage: docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64 . FROM ghcr.io/graalvm/native-image-community:21-muslib AS builder diff --git a/ice/Dockerfile.native-builder b/ice/Dockerfile.native-builder deleted file mode 100644 index 0a044e6d..00000000 --- a/ice/Dockerfile.native-builder +++ /dev/null @@ -1,91 +0,0 @@ -# Multi-stage Dockerfile for building ICE native images -# Supports both amd64 (with static musl) and arm64 (dynamic) - -ARG ARCH=amd64 - -# ============================================================================ -# Stage 1: Build stage with all dependencies -# ============================================================================ -FROM ghcr.io/graalvm/native-image-community:21 AS builder - -# Install build dependencies -RUN microdnf install -y \ - findutils \ - tar \ - gzip \ - wget \ - && microdnf clean all - -# Detect architecture and install appropriate dependencies -RUN ARCH=$(uname -m) && \ - if [ "$ARCH" = "x86_64" ]; then \ - echo "Installing musl toolchain and zlib for amd64 static builds..."; \ - # Download and install musl-gcc - wget -q https://musl.libc.org/releases/musl-1.2.5.tar.gz && \ - tar -xzf musl-1.2.5.tar.gz && \ - cd musl-1.2.5 && \ - ./configure --prefix=/usr/local/musl --disable-shared && \ - make -j$(nproc) && \ - make install && \ - cd .. && \ - rm -rf musl-1.2.5 musl-1.2.5.tar.gz && \ - # Download and install zlib for musl - wget -q https://zlib.net/zlib-1.3.1.tar.gz && \ - tar -xzf zlib-1.3.1.tar.gz && \ - cd zlib-1.3.1 && \ - CC=/usr/local/musl/bin/musl-gcc ./configure --prefix=/usr/local/musl --static && \ - make -j$(nproc) && \ - make install && \ - cd .. && \ - rm -rf zlib-1.3.1 zlib-1.3.1.tar.gz && \ - # Create symlink for native-image to find musl-gcc - ln -sf /usr/local/musl/bin/musl-gcc /usr/local/bin/x86_64-linux-musl-gcc; \ - else \ - echo "ARM64 detected - using dynamic linking (no musl required)"; \ - fi - -WORKDIR /workspace - -# Copy license header file (required by license-maven-plugin) -COPY apache-header.txt . - -# Copy Maven wrapper and pom files first (for better caching) -COPY mvnw . -COPY .mvn .mvn -COPY pom.xml . -COPY ice/pom.xml ice/ -COPY ice-rest-catalog/pom.xml ice-rest-catalog/ - -# Download dependencies (cached layer) -RUN ./mvnw dependency:go-offline -pl ice || true - -# Copy source code -COPY ice/src ice/src - -# Build native image based on architecture -RUN ARCH=$(uname -m) && \ - if [ "$ARCH" = "x86_64" ]; then \ - echo "Building static native image for amd64 with musl..."; \ - export PATH="/usr/local/musl/bin:$PATH" && \ - ./mvnw -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true; \ - else \ - echo "Building dynamic native image for arm64..."; \ - ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true; \ - fi - -# ============================================================================ -# Stage 2: Runtime image (minimal) -# ============================================================================ -FROM scratch AS runtime-amd64 -COPY --from=builder /workspace/ice/target/ice /ice -ENTRYPOINT ["/ice"] - -FROM gcr.io/distroless/base-debian12:nonroot AS runtime-arm64 -COPY --from=builder /workspace/ice/target/ice /ice -ENTRYPOINT ["/ice"] - -# ============================================================================ -# Stage 3: Final stage (architecture-dependent) -# ============================================================================ -FROM runtime-${ARCH} AS final - From 48e0a04c467cae8c0141bd388eda8bc1945c54e6 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sun, 23 Nov 2025 10:27:48 -0600 Subject: [PATCH 11/25] Removed accidentally committed files. --- .../docker-compose/test-ssl-verification.md | 186 ---------- examples/scratch/output.json | 0 ice-rest-catalog/SCENARIO_TESTING.md | 344 ------------------ 3 files changed, 530 deletions(-) delete mode 100644 examples/docker-compose/test-ssl-verification.md delete mode 100644 examples/scratch/output.json delete mode 100644 ice-rest-catalog/SCENARIO_TESTING.md diff --git a/examples/docker-compose/test-ssl-verification.md b/examples/docker-compose/test-ssl-verification.md deleted file mode 100644 index 72ca27ea..00000000 --- a/examples/docker-compose/test-ssl-verification.md +++ /dev/null @@ -1,186 +0,0 @@ -# Testing SSL Certificate Verification Skip - -This guide shows how to test the `--insecure` / `--ssl-no-verify` flag with self-signed certificates. - -## Option 1: Quick Test with a Self-Signed HTTPS Server - -### 1. Generate a self-signed certificate - -```bash -# Generate a self-signed certificate for testing -openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \ - -subj "/CN=localhost" \ - -addext "subjectAltName=DNS:localhost,IP:127.0.0.1" -``` - -### 2. Set up an HTTPS proxy to ice-rest-catalog - -Create a simple nginx config to add SSL in front of the catalog: - -**nginx-ssl.conf**: -```nginx -events { - worker_connections 1024; -} - -http { - server { - listen 5443 ssl; - server_name localhost; - - ssl_certificate /etc/nginx/cert.pem; - ssl_certificate_key /etc/nginx/key.pem; - - location / { - proxy_pass http://ice-rest-catalog:5000; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } - } -} -``` - -**docker-compose.ssl-test.yaml**: -```yaml -services: - nginx-ssl: - image: nginx:alpine - ports: - - "5443:5443" - volumes: - - ./cert.pem:/etc/nginx/cert.pem:ro - - ./key.pem:/etc/nginx/key.pem:ro - - ./nginx-ssl.conf:/etc/nginx/nginx.conf:ro - depends_on: - - ice-rest-catalog -``` - -### 3. Start the services - -```bash -# Start the regular docker-compose setup -docker-compose up -d - -# Start the SSL proxy -docker-compose -f docker-compose.ssl-test.yaml up -d -``` - -### 4. Test the ice CLI - -First, format and build the code: -```bash -cd /home/kanthi/Documents/GITHUB/ALTINITY/ice -mvn com.spotify.fmt:fmt-maven-plugin:format -pl ice -mvn clean install -pl ice -am -DskipTests -``` - -Create a test config file `.ice-ssl-test.yaml`: -```yaml -uri: https://localhost:5443 -bearerToken: foo -warehouse: s3://bucket1 -sslVerify: false # Config file option -s3: - endpoint: http://localhost:8999 - pathStyleAccess: true - accessKeyID: miniouser - secretAccessKey: miniopassword - region: minio -``` - -**Test 1: Without --insecure flag (should fail with SSL error)**: -```bash -./ice/target/ice-jar -c .ice-ssl-test.yaml check -# Expected: SSL certificate verification error -``` - -**Test 2: With --insecure flag (should succeed)**: -```bash -./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure check -# Expected: OK -``` - -**Test 3: Using config file sslVerify option**: -With `sslVerify: false` in the config file: -```bash -./ice/target/ice-jar -c .ice-ssl-test.yaml check -# Expected: OK (with warning about disabled SSL verification) -``` - -**Test 4: Test other commands**: -```bash -# List namespaces -./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure describe - -# Create a namespace -./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure create-namespace test_ns - -# Create a table -./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure create-table test_ns.test_table \ - --schema '[{"name":"id","type":"int"},{"name":"name","type":"string"}]' -``` - -## Option 2: Test with Public Self-Signed Certificate Server - -You can also test against a public service with a self-signed certificate: - -```bash -# This will fail due to self-signed certificate -./ice/target/ice-jar -c config.yaml check - -# This will work with --insecure -./ice/target/ice-jar -c config.yaml --insecure check -``` - -## Option 3: Test with Internal CA Certificate - -If you have an internal CA, you can test the custom CA bundle feature: - -```yaml -uri: https://internal-catalog.company.local:5443 -caCrt: | - -----BEGIN CERTIFICATE----- - MIIDXTCCAkWgAwIBAgIJAKJ... - -----END CERTIFICATE----- -bearerToken: foo -``` - -This should work without `--insecure` because the CA certificate is provided. - -## Expected Behavior - -### Without SSL verification skip: -- ❌ Fails with certificate verification errors for self-signed certificates -- ✅ Works with valid certificates from trusted CAs -- ✅ Works when custom CA certificate is provided via `caCrt` - -### With SSL verification skip (`--insecure` or `sslVerify: false`): -- ⚠️ Displays warning: "SSL certificate verification is DISABLED. This is insecure and should only be used for development." -- ✅ Works with any certificate (self-signed, expired, wrong hostname, etc.) -- ⚠️ **INSECURE**: Should only be used for development/testing - -## Command-line Flags - -Two equivalent options: -- `--insecure` - Shorter, commonly used in tools like curl -- `--ssl-no-verify` - More explicit about what it does - -Both flags: -- Override the config file `sslVerify` setting -- Apply to all subcommands (check, describe, scan, insert, etc.) -- Display a warning message when SSL verification is disabled - -## Config File Option - -```yaml -sslVerify: false # Skip SSL certificate verification -``` - -Note: The command-line flag takes precedence over the config file option. - - - - - - diff --git a/examples/scratch/output.json b/examples/scratch/output.json deleted file mode 100644 index e69de29b..00000000 diff --git a/ice-rest-catalog/SCENARIO_TESTING.md b/ice-rest-catalog/SCENARIO_TESTING.md deleted file mode 100644 index af54e58e..00000000 --- a/ice-rest-catalog/SCENARIO_TESTING.md +++ /dev/null @@ -1,344 +0,0 @@ -# Scenario-Based Testing Framework - -This document describes the new scenario-based testing framework for ICE REST Catalog integration tests. - -## Overview - -The scenario-based testing framework provides a scalable, data-driven approach to integration testing. Instead of hardcoding test scenarios in Java test methods, each scenario is defined in its own directory with: - -- Configuration files (scenario.yaml) -- Input data (parquet files) -- Executable test scripts (run.sh.tmpl, verify.sh.tmpl) - -This approach makes it much easier to: -- Add new test scenarios without writing Java code -- Share test scenarios across teams -- Test complex workflows with multiple steps -- Provision cloud resources dynamically (future feature) - -## Directory Structure - -``` -ice-rest-catalog/src/test/resources/scenarios/ -├── README.md # Documentation for scenario structure -├── basic-operations/ # Example scenario -│ ├── scenario.yaml # Scenario configuration -│ ├── run.sh.tmpl # Main test script (templated) -│ └── verify.sh.tmpl # Optional verification script -├── insert-scan/ -│ ├── scenario.yaml -│ ├── run.sh.tmpl -│ ├── verify.sh.tmpl -│ └── input.parquet # Test data -└── insert-partitioned/ - ├── scenario.yaml - ├── run.sh.tmpl - ├── verify.sh.tmpl - └── input.parquet -``` - -## Key Components - -### 1. ScenarioConfig.java -Java class that represents the scenario.yaml configuration file. Supports: -- Scenario metadata (name, description) -- Catalog configuration overrides -- Environment variables for scripts -- Cloud resource specifications (for future provisioning) -- Test phases - -### 2. ScenarioTestRunner.java -Core test execution engine that: -- Discovers scenario directories -- Loads scenario configurations -- Processes template variables in scripts -- Executes scripts and captures output -- Reports results - -### 3. ScenarioBasedIT.java -TestNG parameterized test class that: -- Automatically discovers all scenarios -- Runs each scenario as a separate test case -- Provides test infrastructure (MinIO, REST catalog) -- Injects template variables (CLI config, endpoints, etc.) - -### 4. RESTCatalogTestBase.java (Updated) -Base test class that provides: -- MinIO container setup/teardown -- REST catalog server setup/teardown -- Helper methods for scenarios (getMinioEndpoint, getCatalogUri, etc.) - -## How It Works - -### 1. Test Discovery -When you run `mvn test -Dtest=ScenarioBasedIT`, the test framework: - -1. Scans `src/test/resources/scenarios/` for directories -2. Each directory is considered a scenario -3. Creates a parameterized test for each scenario - -### 2. Test Execution -For each scenario: - -1. **Setup Phase**: - - Start MinIO container - - Start ICE REST catalog server - - Create temporary CLI config file - - Build template variables - -2. **Execution Phase**: - - Load scenario.yaml configuration - - Process run.sh.tmpl with template variables - - Execute the processed script - - Capture stdout, stderr, and exit code - -3. **Verification Phase** (optional): - - Process verify.sh.tmpl with template variables - - Execute verification script - - Capture results - -4. **Teardown Phase**: - - Stop REST catalog server - - Stop MinIO container - - Clean up temporary files - -### 3. Template Processing -Scripts can use template variables in the format `{{VARIABLE_NAME}}`: - -```bash -# Available template variables: -# {{ICE_CLI}} - Path to ice CLI executable -# {{CLI_CONFIG}} - Path to temporary CLI config file -# {{MINIO_ENDPOINT}} - MinIO endpoint URL (e.g., http://localhost:9000) -# {{CATALOG_URI}} - REST catalog URI (e.g., http://localhost:8080) -# {{SCENARIO_DIR}} - Absolute path to scenario directory - -# Environment variables from scenario.yaml are also available -{{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME} -``` - -## Creating a New Scenario - -1. **Create scenario directory**: - ```bash - mkdir ice-rest-catalog/src/test/resources/scenarios/my-new-test - ``` - -2. **Create scenario.yaml**: - ```yaml - name: "My New Test" - description: "Description of what this test does" - - env: - NAMESPACE_NAME: "my_test_ns" - TABLE_NAME: "my_test_ns.my_table" - - cloudResources: - s3: - buckets: - - "test-bucket" - ``` - -3. **Create run.sh.tmpl**: - ```bash - #!/bin/bash - set -e - - echo "Running my test..." - - # Create namespace - {{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME} - - # ... more test steps ... - - # Cleanup - {{ICE_CLI}} --config {{CLI_CONFIG}} delete-namespace ${NAMESPACE_NAME} - - echo "Test completed successfully" - ``` - -4. **Add test data** (optional): - ```bash - cp example-data.parquet ice-rest-catalog/src/test/resources/scenarios/my-new-test/input.parquet - ``` - -5. **Run the test**: - ```bash - mvn test -Dtest=ScenarioBasedIT#testScenario[my-new-test] - ``` - -## Running Tests - -### Run all scenarios: -```bash -cd ice-rest-catalog -mvn test -Dtest=ScenarioBasedIT -``` - -### Run a specific scenario: -```bash -mvn test -Dtest=ScenarioBasedIT#testScenario[basic-operations] -``` - -### Run scenarios matching a pattern: -```bash -mvn test -Dtest=ScenarioBasedIT#testScenario[insert*] -``` - -## Benefits Over Previous Approach - -### Before (Hardcoded Java Tests): -```java -@Test -public void testScenario1() throws Exception { - File config = createTempCliConfig(); - new CommandLine(Main.class).execute("--config", config.getAbsolutePath(), - "create-namespace", "test_ns"); - new CommandLine(Main.class).execute("--config", config.getAbsolutePath(), - "delete-namespace", "test_ns"); - // ... repeat for each scenario -} - -@Test -public void testScenario2() throws Exception { - // ... duplicate setup code ... -} -``` - -**Problems**: -- Lots of duplicated code -- Hard to add new scenarios -- Difficult to test complex workflows -- No separation of test data and test logic -- Hard to share tests with non-Java developers - -### After (Scenario-Based Tests): -``` -scenarios/ - scenario1/ - scenario.yaml - run.sh.tmpl - scenario2/ - scenario.yaml - run.sh.tmpl - input.parquet -``` - -**Benefits**: -- ✅ No code duplication -- ✅ Easy to add new scenarios (just add a directory) -- ✅ Can test complex workflows with multiple steps -- ✅ Clear separation of test data and logic -- ✅ Scripts can be shared and run independently -- ✅ Can be used by QA engineers without Java knowledge -- ✅ Future: automatic cloud resource provisioning - -## Example Scenarios - -### 1. basic-operations -Tests fundamental catalog operations: -- Create namespace -- List namespaces -- Delete namespace - -### 2. insert-scan -Tests data insertion and retrieval: -- Create namespace -- Insert data from parquet file -- Scan table -- Verify data contents -- Cleanup - -### 3. insert-partitioned -Tests partitioned table creation: -- Create namespace -- Insert data with partition specification -- Verify table was created -- Cleanup - -## Future Enhancements - -1. **Cloud Resource Provisioning**: - - Automatically create S3 buckets, SQS queues, etc. based on scenario.yaml - - Use AWS CloudFormation or Terraform templates - - Clean up resources after test completion - -2. **Parallel Execution**: - - Run independent scenarios in parallel - - Speed up test suite execution - -3. **Test Data Generation**: - - Generate synthetic test data based on schema specifications - - Support for various data formats (Avro, ORC, etc.) - -4. **Scenario Composition**: - - Reuse common scenario steps - - Create scenario libraries - -5. **Performance Testing**: - - Add performance benchmarks to scenarios - - Track performance over time - -## Migration Guide - -To migrate existing hardcoded tests to scenarios: - -1. Identify the test scenario (e.g., "insert with partitioning") -2. Create a scenario directory -3. Extract configuration into scenario.yaml -4. Convert Java test code to bash script in run.sh.tmpl -5. Add test data files if needed -6. Delete the old Java test method - -Example migration: - -**Before** (RESTCatalogInsertIT.java): -```java -@Test -public void testInsertCommand() throws Exception { - File config = createTempCliConfig(); - String namespace = "test_insert"; - new CommandLine(Main.class).execute("--config", config, - "create-namespace", namespace); - // ... more code ... -} -``` - -**After** (scenarios/insert-scan/): -``` -scenario.yaml # Configuration -run.sh.tmpl # Test logic -input.parquet # Test data -``` - -## Troubleshooting - -### Scenario not discovered -- Ensure scenario directory is in `src/test/resources/scenarios/` -- Check that `scenario.yaml` exists in the directory -- Directory name should not start with `.` - -### Script execution fails -- Check script has correct shebang (`#!/bin/bash`) -- Verify template variables are correctly specified -- Check file paths are relative to {{SCENARIO_DIR}} -- Review script output in test logs - -### ICE CLI not found -- Ensure `ice/target/ice-jar` is built: `mvn -am -pl ice package` -- Or ensure `.bin/local-ice` script exists -- Check that ICE_CLI template variable is correctly set - -## Additional Resources - -- [Scenarios README](src/test/resources/scenarios/README.md) - Detailed scenario structure documentation -- [ICE CLI Documentation](../ice/README.md) - CLI command reference -- [TestNG Documentation](https://testng.org/doc/) - TestNG testing framework - - - - - - - - From 3b3ddbb64cdabc5182c5d63ac9d1688c9c325cd2 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sun, 23 Nov 2025 10:29:25 -0600 Subject: [PATCH 12/25] Added GITHUB_RELEASE_TEMPLATE.md --- GITHUB_RELEASE_TEMPLATE.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 GITHUB_RELEASE_TEMPLATE.md diff --git a/GITHUB_RELEASE_TEMPLATE.md b/GITHUB_RELEASE_TEMPLATE.md new file mode 100644 index 00000000..fe7ff576 --- /dev/null +++ b/GITHUB_RELEASE_TEMPLATE.md @@ -0,0 +1,34 @@ +## Installation + +### ice + +```sh +curl -sSL https://github.com/altinity/ice/releases/download/REPLACE_WITH_TAG/ice-REPLACE_WITH_VER \ + -o ice && chmod a+x ice && sudo mv ice /usr/local/bin/ +``` + +#### Docker + + + +- `altinity/ice:REPLACE_WITH_VER` +- `altinity/ice:debug-REPLACE_WITH_VER` + +> `debug-*` images contain busybox shell. + +### ice-rest-catalog + +```sh +curl -sSL https://github.com/altinity/ice/releases/download/REPLACE_WITH_TAG/ice-rest-catalog-REPLACE_WITH_VER \ + -o ice-rest-catalog && chmod a+x ice-rest-catalog && sudo mv ice-rest-catalog /usr/local/bin/ +``` + +#### Docker + + + +- `altinity/ice-rest-catalog:REPLACE_WITH_VER` +- `altinity/ice-rest-catalog:debug-REPLACE_WITH_VER` +- `altinity/ice-rest-catalog:debug-with-ice-REPLACE_WITH_VER` + +> `debug-*` images contain busybox shell. From 3bbcf76980d4c5640375357e3f029fd206c7d4e8 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sun, 23 Nov 2025 10:39:06 -0600 Subject: [PATCH 13/25] Updated README.md with instructions to build native image. --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e83f3fdf..d9f7f459 100644 --- a/README.md +++ b/README.md @@ -52,16 +52,14 @@ Build standalone native binaries with no Java dependency: sdk env # or ensure Java 21+ and GraalVM are available # For amd64 (static with musl - no dependencies) -./build-native.sh -# Produces: ice/target/ice (static binary) - -# Or use Maven directly mvn -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true +For arm64 +mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true -# For ARM64 (dynamic with glibc) -ARCH=arm64 ./build-native.sh -# Or: mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true +# Docker builds +docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64 . +docker build -f ice/Dockerfile.native-arm64 -t ice-native:arm64 . ## License From 50ac8e36c1d6bf436f1aaa049da5d080effc03ff Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Mon, 27 Apr 2026 17:32:18 -0400 Subject: [PATCH 14/25] Merge x86 and arm native builds into the same profile - Binary is static besides libc due to some libraries like zstd that require JNI - Use graalvm tracing agent to generate reachability metadata files - Update workflow to test native binaries --- .bin/agent-ice | 17 + .github/workflows/verify.yaml | 8 +- README.md | 13 +- ice-rest-catalog/pom.xml | 4 + .../ice/rest/catalog/ScenarioBasedIT.java | 26 +- ...kerfile.native-arm64 => Dockerfile.native} | 10 +- ice/Dockerfile.native-amd64-static | 33 - ice/pom.xml | 74 +- .../com.altinity/ice/jni-config.json | 30 + .../ice/predefined-classes-config.json | 8 + .../com.altinity/ice/proxy-config.json | 5 + .../com.altinity/ice/reflect-config.json | 980 ++++++++++++++++++ .../com.altinity/ice/resource-config.json | 109 ++ .../ice/serialization-config.json | 8 + ice/src/main/resources/reflection-config.json | 112 -- 15 files changed, 1195 insertions(+), 242 deletions(-) create mode 100755 .bin/agent-ice rename ice/{Dockerfile.native-arm64 => Dockerfile.native} (68%) delete mode 100644 ice/Dockerfile.native-amd64-static create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/jni-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/predefined-classes-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/proxy-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/serialization-config.json delete mode 100644 ice/src/main/resources/reflection-config.json diff --git a/.bin/agent-ice b/.bin/agent-ice new file mode 100755 index 00000000..e8d44971 --- /dev/null +++ b/.bin/agent-ice @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +PROJECT_ROOT=$(cd -- "$SCRIPT_DIR/.." && pwd) + +shopt -s nullglob +jars=("$PROJECT_ROOT"/ice/target/ice-*-shaded.jar) +shopt -u nullglob +if (( ${#jars[@]} == 0 )); then + echo "agent-ice: no ice-*-shaded.jar in $PROJECT_ROOT/ice/target/." >&2 + exit 1 +fi +jar=$(ls -t "${jars[@]}" | head -n1) + +exec "${JAVA_HOME:?JAVA_HOME not set — run inside direnv shell}/bin/java" \ +-agentlib:native-image-agent=config-merge-dir=$PROJECT_ROOT/ice/src/main/resources/META-INF/native-image/com.altinity/ice,experimental-class-loader-support \ +-jar "$jar" "$@" diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 099facc5..973c64d9 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -17,7 +17,6 @@ jobs: - run: ./mvnw clean verify - name: Install run: ./mvnw install - # TODO: check native-image can build ice - name: Run Scenario-Based Integration Tests run: ../mvnw test -Dtest=ScenarioBasedIT working-directory: ice-rest-catalog @@ -65,11 +64,9 @@ jobs: include: - arch: amd64 runner: ubuntu-24.04 - profile: native artifact: ice-native-amd64-dynamic - arch: arm64 runner: ubuntu-24.04-arm - profile: native-arm64 artifact: ice-native-arm64-dynamic steps: - uses: actions/checkout@v4 @@ -79,7 +76,10 @@ jobs: distribution: 'graalvm' cache: maven - name: Build native image (dynamic linking - no musl required) - run: ./mvnw -P${{ matrix.profile }} -pl ice clean package -Dmaven.test.skip=true + run: ./mvnw -Pnative -pl ice clean package + - name: Run Scenario-Based Integration Tests + run: ../mvnw test -Dtest=ScenarioBasedIT -Dice.native=true + working-directory: ice-rest-catalog - name: Upload native binary as artifact uses: actions/upload-artifact@v4 with: diff --git a/README.md b/README.md index d9f7f459..05b1860e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Pre-built binaries (+ links to Docker images for [ice](https://hub.docker.com/r/ 1. **Java-based binaries** - Require Java 21+ to run (available [here](https://adoptium.net/installation/)) 2. **Native binaries** - Standalone executables with no Java dependency - - `ice-native-amd64` - Static binary (musl) for x86_64 Linux (no dependencies) + - `ice-native-amd64` - Dynamic binary for x86_64 Linux (requires glibc) - `ice-native-arm64` - Dynamic binary for ARM64 Linux (requires glibc) ## Usage @@ -51,15 +51,14 @@ Build standalone native binaries with no Java dependency: # Install prerequisites sdk env # or ensure Java 21+ and GraalVM are available -# For amd64 (static with musl - no dependencies) -mvn -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true -For arm64 -mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true +# Build ice binary (both amd64 and arm64) +mvn -Pnative -pl ice clean package -Dmaven.test.skip=true # Docker builds -docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64 . +docker build -f ice/Dockerfile.native -t ice-native:amd64 . -docker build -f ice/Dockerfile.native-arm64 -t ice-native:arm64 . +docker build -f ice/Dockerfile.native -t ice-native:arm64 . +``` ## License diff --git a/ice-rest-catalog/pom.xml b/ice-rest-catalog/pom.xml index 38053fdb..f861254e 100644 --- a/ice-rest-catalog/pom.xml +++ b/ice-rest-catalog/pom.xml @@ -17,6 +17,7 @@ 0.8.5 1.70.0 1.21.4 + false @@ -562,6 +563,9 @@ org.apache.maven.plugins maven-failsafe-plugin + + ${ice.native} + **/DockerScenarioBasedIT.java diff --git a/ice-rest-catalog/src/test/java/com/altinity/ice/rest/catalog/ScenarioBasedIT.java b/ice-rest-catalog/src/test/java/com/altinity/ice/rest/catalog/ScenarioBasedIT.java index 24b098e7..c54a692d 100644 --- a/ice-rest-catalog/src/test/java/com/altinity/ice/rest/catalog/ScenarioBasedIT.java +++ b/ice-rest-catalog/src/test/java/com/altinity/ice/rest/catalog/ScenarioBasedIT.java @@ -23,6 +23,8 @@ */ public class ScenarioBasedIT extends RESTCatalogTestBase { + private static final boolean USE_NATIVE = Boolean.getBoolean("ice.native"); + @Override protected ScenarioTestRunner createScenarioRunner(String scenarioName) throws Exception { Path scenariosDir = getScenariosDirectory(); @@ -38,18 +40,24 @@ protected ScenarioTestRunner createScenarioRunner(String scenarioName) throws Ex // Try to find ice-jar in the build String projectRoot = Paths.get("").toAbsolutePath().getParent().toString(); - String iceJar = projectRoot + "/ice/target/ice-jar"; + String iceJar = + USE_NATIVE ? projectRoot + "/ice/target/ice" : projectRoot + "/ice/target/ice-jar"; File iceJarFile = new File(iceJar); - if (iceJarFile.exists() && iceJarFile.canExecute()) { - // Use pre-built ice-jar if available - templateVars.put("ICE_CLI", iceJar); - logger.info("Using ice-jar from: {}", iceJar); + String override = System.getenv("ICE_CLI_OVERRIDE"); + if (override != null) { + templateVars.put("ICE_CLI", override); } else { - // Fall back to using local-ice wrapper script - String localIce = projectRoot + "/.bin/local-ice"; - templateVars.put("ICE_CLI", localIce); - logger.info("Using local-ice script from: {}", localIce); + if (iceJarFile.exists() && iceJarFile.canExecute()) { + // Use pre-built ice-jar if available + templateVars.put("ICE_CLI", iceJar); + logger.info("Using ice-jar from: {}", iceJar); + } else { + // Fall back to using local-ice wrapper script + String localIce = projectRoot + "/.bin/local-ice"; + templateVars.put("ICE_CLI", localIce); + logger.info("Using local-ice script from: {}", localIce); + } } return new ScenarioTestRunner(scenariosDir, templateVars); diff --git a/ice/Dockerfile.native-arm64 b/ice/Dockerfile.native similarity index 68% rename from ice/Dockerfile.native-arm64 rename to ice/Dockerfile.native index 4d997ec1..10961656 100644 --- a/ice/Dockerfile.native-arm64 +++ b/ice/Dockerfile.native @@ -1,5 +1,6 @@ -# Dockerfile for building ICE native image (arm64, dynamic linking) -# Usage: docker build -f ice/Dockerfile.native-arm64 -t ice-native:arm64 . +# Dockerfile for building ICE native image (mostly-static with dynamic libc) +# Usage (amd64): docker build -f ice/Dockerfile.native -t ice-native:amd64 . +# Usage (arm64): docker build -f ice/Dockerfile.native -t ice-native:arm64 . FROM ghcr.io/graalvm/native-image-community:21 AS builder @@ -21,8 +22,8 @@ RUN ./mvnw dependency:go-offline -pl ice || true # Copy source code COPY ice/src ice/src -# Build dynamic native image -RUN ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true +# Build mostly-static native image (everything statically linked except libc) +RUN ./mvnw -Pnative -pl ice clean package -Dmaven.test.skip=true # ============================================================================ # Final stage: distroless base (includes minimal glibc runtime) @@ -30,4 +31,3 @@ RUN ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true FROM gcr.io/distroless/base-debian12:nonroot COPY --from=builder /workspace/ice/target/ice /ice ENTRYPOINT ["/ice"] - diff --git a/ice/Dockerfile.native-amd64-static b/ice/Dockerfile.native-amd64-static deleted file mode 100644 index e8b4f271..00000000 --- a/ice/Dockerfile.native-amd64-static +++ /dev/null @@ -1,33 +0,0 @@ -# Dockerfile for building ICE native image (amd64, static with musl) -# Usage: docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64 . - -FROM ghcr.io/graalvm/native-image-community:21-muslib AS builder - -WORKDIR /workspace - -# Copy license header file (required by license-maven-plugin) -COPY apache-header.txt . - -# Copy Maven files for dependency resolution -COPY mvnw . -COPY .mvn .mvn -COPY pom.xml . -COPY ice/pom.xml ice/ -COPY ice-rest-catalog/pom.xml ice-rest-catalog/ - -# Download dependencies (cached layer) -RUN ./mvnw dependency:go-offline -pl ice || true - -# Copy source code -COPY ice/src ice/src - -# Build static native image with musl -RUN ./mvnw -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true - -# ============================================================================ -# Final stage: minimal scratch image (truly standalone binary) -# ============================================================================ -FROM scratch -COPY --from=builder /workspace/ice/target/ice /ice -ENTRYPOINT ["/ice"] - diff --git a/ice/pom.xml b/ice/pom.xml index 3b1db9bf..61c5d41f 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -669,39 +669,6 @@ native - - - - org.graalvm.buildtools - native-maven-plugin - ${native.maven.plugin.version} - true - - - build-native - - compile-no-fork - - package - - - - ice - com.altinity.ice.cli.Main - - -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty - --initialize-at-run-time=ch.qos.logback - -H:+ReportExceptionStackTraces - - - - - - - - - native-amd64-static @@ -723,12 +690,10 @@ com.altinity.ice.cli.Main - -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json --initialize-at-run-time=io.netty --initialize-at-run-time=ch.qos.logback - - --static - --libc=musl + + -H:+StaticExecutableWithDynamicLibC -H:+RemoveUnusedSymbols -H:+ReportExceptionStackTraces @@ -738,40 +703,5 @@ - - native-arm64 - - - - org.graalvm.buildtools - native-maven-plugin - ${native.maven.plugin.version} - true - - - build-native - - compile-no-fork - - package - - - - ice - com.altinity.ice.cli.Main - - - -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty - --initialize-at-run-time=ch.qos.logback - - -H:+RemoveUnusedSymbols - -H:+ReportExceptionStackTraces - - - - - - diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/jni-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/jni-config.json new file mode 100644 index 00000000..c681d3ef --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/jni-config.json @@ -0,0 +1,30 @@ +[ +{ + "name":"com.github.luben.zstd.ZstdInputStreamNoFinalizer", + "fields":[{"name":"dstPos"}, {"name":"srcPos"}] +}, +{ + "name":"com.github.luben.zstd.ZstdOutputStreamNoFinalizer", + "fields":[{"name":"dstPos"}, {"name":"srcPos"}] +}, +{ + "name":"java.lang.Boolean", + "methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"org.jline.nativ.CLibrary", + "fields":[{"name":"TCSADRAIN"}, {"name":"TCSAFLUSH"}, {"name":"TCSANOW"}, {"name":"TIOCGWINSZ"}, {"name":"TIOCSWINSZ"}] +}, +{ + "name":"org.jline.nativ.CLibrary$Termios", + "fields":[{"name":"SIZEOF"}, {"name":"c_cc"}, {"name":"c_cflag"}, {"name":"c_iflag"}, {"name":"c_ispeed"}, {"name":"c_lflag"}, {"name":"c_oflag"}, {"name":"c_ospeed"}] +}, +{ + "name":"org.jline.nativ.CLibrary$WinSize", + "fields":[{"name":"SIZEOF"}, {"name":"ws_col"}, {"name":"ws_row"}, {"name":"ws_xpixel"}, {"name":"ws_ypixel"}] +}, +{ + "name":"sun.management.VMManagementImpl", + "fields":[{"name":"compTimeMonitoringSupport"}, {"name":"currentThreadCpuTimeSupport"}, {"name":"objectMonitorUsageSupport"}, {"name":"otherThreadCpuTimeSupport"}, {"name":"remoteDiagnosticCommandsSupport"}, {"name":"synchronizerUsageSupport"}, {"name":"threadAllocatedMemorySupport"}, {"name":"threadContentionMonitoringSupport"}] +} +] diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/predefined-classes-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/predefined-classes-config.json new file mode 100644 index 00000000..0e79b2c5 --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/predefined-classes-config.json @@ -0,0 +1,8 @@ +[ + { + "type":"agent-extracted", + "classes":[ + ] + } +] + diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/proxy-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/proxy-config.json new file mode 100644 index 00000000..4a9716c1 --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/proxy-config.json @@ -0,0 +1,5 @@ +[ + { + "interfaces":["sun.misc.SignalHandler"] + } +] diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json new file mode 100644 index 00000000..7b350ca9 --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -0,0 +1,980 @@ +[ +{ + "name":"[B" +}, +{ + "name":"[Lcom.altinity.ice.cli.Main$IcePartition;" +}, +{ + "name":"[Lcom.altinity.ice.cli.Main$IceSortOrder;" +}, +{ + "name":"[Lcom.altinity.ice.cli.Main$PartitionFilter;" +}, +{ + "name":"[Lcom.altinity.ice.cli.internal.cmd.AlterTable$Update;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.deser.BeanDeserializerModifier;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.deser.Deserializers;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.deser.KeyDeserializers;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.deser.ValueInstantiators;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.ser.BeanSerializerModifier;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.ser.Serializers;" +}, +{ + "name":"[Ljava.lang.String;" +}, +{ + "name":"[Ljava.util.List;" +}, +{ + "name":"[Ljava.util.Map$Entry;" +}, +{ + "name":"[Lorg.apache.avro.util.springframework.ConcurrentReferenceHashMap$Segment;" +}, +{ + "name":"[Lorg.apache.iceberg.Accessor;" +}, +{ + "name":"[Lorg.apache.iceberg.avro.ValueWriter;" +}, +{ + "name":"[Lorg.apache.iceberg.parquet.ParquetValueReader;" +}, +{ + "name":"[Lorg.apache.iceberg.parquet.ParquetValueWriter;" +}, +{ + "name":"[Lorg.apache.iceberg.parquet.TripleIterator;" +}, +{ + "name":"[Lorg.apache.iceberg.relocated.com.google.common.collect.ImmutableMapEntry;" +}, +{ + "name":"[Lsun.security.pkcs.SignerInfo;" +}, +{ + "name":"ch.qos.logback.classic.joran.SerializedModelConfigurator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.util.DefaultJoranConfigurator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.core.ConsoleAppender", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setTarget","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.Layout", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.OutputStreamAppender", + "methods":[{"name":"setEncoder","parameterTypes":["ch.qos.logback.core.encoder.Encoder"] }] +}, +{ + "name":"ch.qos.logback.core.encoder.Encoder", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.encoder.LayoutWrappingEncoder", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setLayout","parameterTypes":["ch.qos.logback.core.Layout"] }, {"name":"setParent","parameterTypes":["ch.qos.logback.core.spi.ContextAware"] }] +}, +{ + "name":"ch.qos.logback.core.pattern.PatternLayoutBase", + "methods":[{"name":"setPattern","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.spi.ContextAware", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.Main", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.Main$IcePartition", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.Main$IceSortOrder", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","boolean","boolean"] }] +}, +{ + "name":"com.altinity.ice.cli.Main$PartitionFilter", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.util.List"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$AddColumn", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$Update", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"data","parameterTypes":[] }, {"name":"error","parameterTypes":[] }, {"name":"kind","parameterTypes":[] }, {"name":"metadata","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Data", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"currentSnapshot","parameterTypes":[] }, {"name":"location","parameterTypes":[] }, {"name":"metrics","parameterTypes":[] }, {"name":"partitionSpecRaw","parameterTypes":[] }, {"name":"properties","parameterTypes":[] }, {"name":"schemaRaw","parameterTypes":[] }, {"name":"sortOrderRaw","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Error", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Metadata", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"id","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Snapshot", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"id","parameterTypes":[] }, {"name":"location","parameterTypes":[] }, {"name":"operation","parameterTypes":[] }, {"name":"parentID","parameterTypes":[] }, {"name":"sequenceNumber","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampISO","parameterTypes":[] }, {"name":"timestampISOLocal","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.ListNamespaces$Result", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"namespaces","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.ListPartitions$PartitionFieldInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"name","parameterTypes":[] }, {"name":"sourceColumn","parameterTypes":[] }, {"name":"transform","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.ListPartitions$Result", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"partitionSpec","parameterTypes":[] }, {"name":"partitions","parameterTypes":[] }, {"name":"table","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.config.Config", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean","java.lang.String","java.lang.String","java.lang.String","java.lang.String[]","com.altinity.ice.cli.internal.config.Config$S3","java.util.Map"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.config.Config$S3", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.internal.iceberg.io.SchemeFileIO", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.internal.logback.ColorAwarePatternLayout", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.internal.logback.ColorAwarePatternLayout$NoColorConverter", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.internal.picocli.VersionProvider", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.fasterxml.jackson.databind.ext.Java7SupportImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BBHeader$ReadAndWriteCounterRef", + "fields":[{"name":"writeCounter"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BBHeader$ReadCounterRef", + "fields":[{"name":"readCounter"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BLCHeader$DrainStatusRef", + "fields":[{"name":"drainStatus"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueColdProducerFields", + "fields":[{"name":"producerLimit"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueConsumerFields", + "fields":[{"name":"consumerIndex"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueProducerFields", + "fields":[{"name":"producerIndex"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BoundedLocalCache", + "fields":[{"name":"refreshes"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.CacheLoader", + "methods":[{"name":"loadAll","parameterTypes":["java.util.Set"] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.FD", + "fields":[{"name":"value"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.FDMS", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.FS", + "fields":[{"name":"key"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.PS", + "fields":[{"name":"key"}, {"name":"value"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.PSA", + "fields":[{"name":"accessTime"}], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.PW", + "fields":[{"name":"value"}], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.SI", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.SSA", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.SSLA", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.StripedBuffer", + "fields":[{"name":"tableBusy"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.UnboundedLocalCache", + "fields":[{"name":"refreshes"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.WILSMS", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.WS", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.WSL", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.sun.crypto.provider.AESCipher$General", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.ARCFOURCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DESCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DESedeCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DHParameters", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.GaloisCounterMode$AESGCM", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.TlsMasterSecretGenerator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"groovy.lang.Closure" +}, +{ + "name":"java.io.Console", + "methods":[{"name":"isTerminal","parameterTypes":[] }] +}, +{ + "name":"java.io.Serializable", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Class", + "methods":[{"name":"getRecordComponents","parameterTypes":[] }] +}, +{ + "name":"java.lang.Comparable", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Double", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"java.lang.Number", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Object", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Record", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.String" +}, +{ + "name":"java.lang.System", + "methods":[{"name":"console","parameterTypes":[] }] +}, +{ + "name":"java.lang.Thread", + "fields":[{"name":"threadLocalRandomProbe"}] +}, +{ + "name":"java.lang.constant.Constable", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.constant.ConstantDesc", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.reflect.Executable", + "methods":[{"name":"getParameters","parameterTypes":[] }] +}, +{ + "name":"java.lang.reflect.Method" +}, +{ + "name":"java.lang.reflect.Parameter", + "methods":[{"name":"getName","parameterTypes":[] }] +}, +{ + "name":"java.lang.reflect.RecordComponent", + "methods":[{"name":"getName","parameterTypes":[] }, {"name":"getType","parameterTypes":[] }] +}, +{ + "name":"java.nio.file.Path" +}, +{ + "name":"java.nio.file.Paths", + "methods":[{"name":"get","parameterTypes":["java.lang.String","java.lang.String[]"] }] +}, +{ + "name":"java.security.AlgorithmParametersSpi" +}, +{ + "name":"java.security.KeyStoreSpi" +}, +{ + "name":"java.security.SecureRandomParameters" +}, +{ + "name":"java.security.interfaces.ECPrivateKey" +}, +{ + "name":"java.security.interfaces.ECPublicKey" +}, +{ + "name":"java.security.interfaces.RSAPrivateKey" +}, +{ + "name":"java.security.interfaces.RSAPublicKey" +}, +{ + "name":"java.sql.Connection" +}, +{ + "name":"java.sql.Date" +}, +{ + "name":"java.sql.Driver" +}, +{ + "name":"java.sql.DriverManager", + "methods":[{"name":"getConnection","parameterTypes":["java.lang.String"] }, {"name":"getDriver","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.sql.Time", + "methods":[{"name":"","parameterTypes":["long"] }] +}, +{ + "name":"java.sql.Timestamp", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.time.Duration", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.Instant", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.LocalDate", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.LocalDateTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.LocalTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.MonthDay", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.OffsetDateTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.OffsetTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.Period", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.Year", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.YearMonth", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.ZoneId", + "methods":[{"name":"of","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.time.ZoneOffset", + "methods":[{"name":"of","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.time.ZonedDateTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.util.Date" +}, +{ + "name":"java.util.Map", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.util.concurrent.ForkJoinTask", + "fields":[{"name":"aux"}, {"name":"status"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicBoolean", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicMarkableReference", + "fields":[{"name":"pair"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicReference", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.Striped64", + "fields":[{"name":"base"}, {"name":"cellsBusy"}] +}, +{ + "name":"java.util.concurrent.atomic.Striped64$Cell", + "fields":[{"name":"value"}] +}, +{ + "name":"javax.security.auth.x500.X500Principal", + "fields":[{"name":"thisX500Name"}], + "methods":[{"name":"","parameterTypes":["sun.security.x509.X500Name"] }] +}, +{ + "name":"jdk.internal.misc.Unsafe" +}, +{ + "name":"kotlin.Unit" +}, +{ + "name":"manifest_entry" +}, +{ + "name":"org.apache.commons.logging.LogFactory" +}, +{ + "name":"org.apache.commons.logging.impl.Log4JLogger", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }, {"name":"setLogFactory","parameterTypes":["org.apache.commons.logging.LogFactory"] }] +}, +{ + "name":"org.apache.commons.logging.impl.LogFactoryImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.commons.logging.impl.WeakHashtable", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.hadoop.fs.FSDataInputStream" +}, +{ + "name":"org.apache.hadoop.mapred.JobConf" +}, +{ + "name":"org.apache.hadoop.mapred.JobConfigurable" +}, +{ + "name":"org.apache.hadoop.thirdparty.com.google.common.util.concurrent.AbstractFuture", + "fields":[{"name":"listeners"}, {"name":"value"}, {"name":"waiters"}] +}, +{ + "name":"org.apache.hadoop.thirdparty.com.google.common.util.concurrent.AbstractFuture$Waiter", + "fields":[{"name":"next"}, {"name":"thread"}] +}, +{ + "name":"org.apache.http.client.config.RequestConfig$Builder", + "methods":[{"name":"setNormalizeUri","parameterTypes":["boolean"] }] +}, +{ + "name":"org.apache.iceberg.GenericDataFile", + "methods":[{"name":"","parameterTypes":["org.apache.iceberg.types.Types$StructType"] }] +}, +{ + "name":"org.apache.iceberg.GenericManifestEntry", + "methods":[{"name":"","parameterTypes":["org.apache.iceberg.types.Types$StructType"] }] +}, +{ + "name":"org.apache.iceberg.GenericManifestFile", + "methods":[{"name":"","parameterTypes":["org.apache.avro.Schema"] }] +}, +{ + "name":"org.apache.iceberg.GenericPartitionFieldSummary", + "methods":[{"name":"","parameterTypes":["org.apache.avro.Schema"] }] +}, +{ + "name":"org.apache.iceberg.PartitionData", + "methods":[{"name":"","parameterTypes":["org.apache.iceberg.types.Types$StructType"] }] +}, +{ + "name":"org.apache.iceberg.aws.ApacheHttpClientConfigurations", + "methods":[{"name":"create","parameterTypes":["java.util.Map"] }] +}, +{ + "name":"org.apache.iceberg.aws.AwsClientFactories$DefaultAwsClientFactory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.aws.s3.S3FileIO", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.hadoop.HadoopMetricsContext", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.BiMap", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.ImmutableBiMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.RegularImmutableMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.SingletonImmutableBiMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"org.apache.iceberg.rest.RESTMessage", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.rest.RESTRequest", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.rest.RESTResponse", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.rest.requests.CreateNamespaceRequest", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"org.apache.iceberg.rest.requests.CreateTableRequest", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"org.apache.iceberg.rest.responses.CreateNamespaceResponse", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.rest.responses.ListNamespacesResponse", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.rest.responses.ListTablesResponse", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.util.Pair$1" +}, +{ + "name":"org.apache.log4j.Level", + "fields":[{"name":"TRACE"}] +}, +{ + "name":"org.apache.log4j.Priority" +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.ByteBitPackingBE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.ByteBitPackingForLongBE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.ByteBitPackingForLongLE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.ByteBitPackingLE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.LemireBitPackingBE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.LemireBitPackingLE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.hadoop.codec.SnappyCodec", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.parquet.hadoop.codec.ZstandardCodec", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.brotli.dec.BrotliInputStream" +}, +{ + "name":"org.jline.terminal.impl.exec.ExecTerminalProvider", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.jline.terminal.impl.ffm.FfmTerminalProvider" +}, +{ + "name":"org.jline.terminal.impl.jansi.JansiTerminalProvider", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.jline.terminal.impl.jna.JnaTerminalProvider", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.jline.terminal.impl.jni.JniTerminalProvider", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.osgi.framework.BundleEvent" +}, +{ + "name":"picocli.AutoComplete$GenerateCompletion", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"picocli.CommandLine$AutoHelpMixin", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"scala.util.Properties" +}, +{ + "name":"shaded.parquet.com.fasterxml.jackson.databind.ext.Java7SupportImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.misc.Signal", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }, {"name":"handle","parameterTypes":["sun.misc.Signal","sun.misc.SignalHandler"] }] +}, +{ + "name":"sun.misc.SignalHandler", + "fields":[{"name":"SIG_DFL"}] +}, +{ + "name":"sun.misc.Unsafe", + "allDeclaredFields":true, + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "name":"sun.security.pkcs12.PKCS12KeyStore", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.DSA$SHA224withDSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.DSA$SHA256withDSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.JavaKeyStore$DualFormatJKS", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.JavaKeyStore$JKS", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.NativePRNG", + "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] +}, +{ + "name":"sun.security.provider.SHA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA2$SHA224", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA2$SHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA5$SHA384", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA5$SHA512", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.X509Factory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.certpath.PKIXCertPathValidator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.PSSParameters", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSAKeyFactory$Legacy", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSAPSSSignature", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSASignature$SHA224withRSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSASignature$SHA256withRSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.KeyManagerFactoryImpl$SunX509", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.SSLContextImpl$DefaultSSLContext", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.SSLContextImpl$TLSContext", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.util.ObjectIdentifier" +}, +{ + "name":"sun.security.x509.AuthorityInfoAccessExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.AuthorityKeyIdentifierExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.BasicConstraintsExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.CRLDistributionPointsExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.CertificateExtensions" +}, +{ + "name":"sun.security.x509.CertificatePoliciesExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.ExtendedKeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.IssuerAlternativeNameExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.KeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.NetscapeCertTypeExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.PrivateKeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.SubjectAlternativeNameExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.SubjectKeyIdentifierExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +} +] diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json new file mode 100644 index 00000000..1912bec8 --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json @@ -0,0 +1,109 @@ +{ + "resources":{ + "includes":[{ + "pattern":"\\QMETA-INF/maven/org.jline/jline-native/pom.properties\\E" + }, { + "pattern":"\\QMETA-INF/maven/org.xerial.snappy/snappy-java/pom.properties\\E" + }, { + "pattern":"\\QMETA-INF/services/ch.qos.logback.classic.spi.Configurator\\E" + }, { + "pattern":"\\QMETA-INF/services/java.lang.System$LoggerFinder\\E" + }, { + "pattern":"\\QMETA-INF/services/java.net.spi.InetAddressResolverProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.net.spi.URLStreamHandlerProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.nio.channels.spi.SelectorProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.nio.charset.spi.CharsetProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.time.zone.ZoneRulesProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/javax.xml.parsers.SAXParserFactory\\E" + }, { + "pattern":"\\QMETA-INF/services/javax.xml.stream.XMLInputFactory\\E" + }, { + "pattern":"\\QMETA-INF/services/org.apache.avro.Conversion\\E" + }, { + "pattern":"\\QMETA-INF/services/org.apache.avro.LogicalTypes$LogicalTypeFactory\\E" + }, { + "pattern":"\\QMETA-INF/services/org.apache.commons.logging.LogFactory\\E" + }, { + "pattern":"\\QMETA-INF/services/org.slf4j.spi.SLF4JServiceProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/exec\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/ffm\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/jansi\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/jna\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/jni\\E" + }, { + "pattern":"\\QMETA-INF/services/software.amazon.awssdk.http.SdkHttpService\\E" + }, { + "pattern":"\\Qcommons-logging.properties\\E" + }, { + "pattern":"\\Qcore-default.xml\\E" + }, { + "pattern":"\\Qcore-site.xml\\E" + }, { + "pattern":"\\Qhadoop-site.xml\\E" + }, { + "pattern":"\\Qiceberg-build.properties\\E" + }, { + "pattern":"\\Qlinux/amd64/libzstd-jni-1.5.6-6.so\\E" + }, { + "pattern":"\\Qlogback-test.scmo\\E" + }, { + "pattern":"\\Qlogback-test.xml\\E" + }, { + "pattern":"\\Qlogback.scmo\\E" + }, { + "pattern":"\\Qlogback.xml\\E" + }, { + "pattern":"\\Qmapred-default.xml\\E" + }, { + "pattern":"\\Qmapred-site.xml\\E" + }, { + "pattern":"\\Qmozilla/public-suffix-list.txt\\E" + }, { + "pattern":"\\Qorg-xerial-snappy.properties\\E" + }, { + "pattern":"\\Qorg/apache/hc/client5/version.properties\\E" + }, { + "pattern":"\\Qorg/jline/nativ/Linux/x86_64/libjlinenative.so\\E" + }, { + "pattern":"\\Qorg/jline/utils/capabilities.txt\\E" + }, { + "pattern":"\\Qorg/jline/utils/xterm-256color.caps\\E" + }, { + "pattern":"\\Qorg/publicsuffix/list/effective_tld_names.dat\\E" + }, { + "pattern":"\\Qorg/xerial/snappy/VERSION\\E" + }, { + "pattern":"\\Qorg/xerial/snappy/native/Linux/x86_64/libsnappyjava.so\\E" + }, { + "pattern":"\\Qsoftware/amazon/awssdk/core/util/mime.types\\E" + }, { + "pattern":"\\Qsoftware/amazon/awssdk/global/handlers/execution.interceptors\\E" + }, { + "pattern":"\\Qsoftware/amazon/awssdk/global/partitions.json\\E" + }, { + "pattern":"\\Qsoftware/amazon/awssdk/services/s3/execution.interceptors\\E" + }, { + "pattern":"\\Qyarn-default.xml\\E" + }, { + "pattern":"\\Qyarn-site.xml\\E" + }, { + "pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt72b/nfkc.nrm\\E" + }, { + "pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt72b/uprops.icu\\E" + }, { + "pattern":"java.base:\\Qsun/net/idn/uidna.spp\\E" + }, { + "pattern":"java.base:\\Qsun/text/resources/LineBreakIteratorData\\E" + }]}, + "bundles":[] +} diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/serialization-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/serialization-config.json new file mode 100644 index 00000000..f3d7e06e --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/serialization-config.json @@ -0,0 +1,8 @@ +{ + "types":[ + ], + "lambdaCapturingTypes":[ + ], + "proxies":[ + ] +} diff --git a/ice/src/main/resources/reflection-config.json b/ice/src/main/resources/reflection-config.json deleted file mode 100644 index 15a1a7b5..00000000 --- a/ice/src/main/resources/reflection-config.json +++ /dev/null @@ -1,112 +0,0 @@ -[ - { - "name": "ch.qos.logback.classic.AsyncAppender", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.DateConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.LevelConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.LineSeparatorConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.LoggerConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.MessageConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.ThreadConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.core.ConsoleAppender", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.core.FileAppender", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - } -] From 96405eebb19cb4d36c699853b97134fd020562d0 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Mon, 27 Apr 2026 17:50:11 -0400 Subject: [PATCH 15/25] Fix verify workflow --- .github/workflows/verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 973c64d9..ce998778 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -76,7 +76,7 @@ jobs: distribution: 'graalvm' cache: maven - name: Build native image (dynamic linking - no musl required) - run: ./mvnw -Pnative -pl ice clean package + run: ./mvnw -Pnative -pl ice clean install -Dmaven.test.skip=true - name: Run Scenario-Based Integration Tests run: ../mvnw test -Dtest=ScenarioBasedIT -Dice.native=true working-directory: ice-rest-catalog From ed93d9081f3b3e79700ed668c3ca3e24350519f7 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Thu, 30 Apr 2026 11:55:25 -0400 Subject: [PATCH 16/25] Try fix workflow --- .github/workflows/verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index ce998778..1cae0e24 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -76,7 +76,7 @@ jobs: distribution: 'graalvm' cache: maven - name: Build native image (dynamic linking - no musl required) - run: ./mvnw -Pnative -pl ice clean install -Dmaven.test.skip=true + run: ./mvnw -Pnative clean install -Dmaven.test.skip=true - name: Run Scenario-Based Integration Tests run: ../mvnw test -Dtest=ScenarioBasedIT -Dice.native=true working-directory: ice-rest-catalog From 4dd6346b41a4d72e33e4cdb97d8fe9ba24813eba Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Thu, 30 Apr 2026 12:24:35 -0400 Subject: [PATCH 17/25] Update reflect-config.json --- .../com.altinity/ice/reflect-config.json | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 7b350ca9..707ca319 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -107,7 +107,7 @@ "name":"com.altinity.ice.cli.Main", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] + "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.Main$IcePartition", @@ -135,7 +135,7 @@ "allDeclaredFields":true, "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true, - "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }] + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean"] }] }, { "name":"com.altinity.ice.cli.internal.cmd.AlterTable$Update", @@ -177,6 +177,45 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"id","parameterTypes":[] }, {"name":"location","parameterTypes":[] }, {"name":"operation","parameterTypes":[] }, {"name":"parentID","parameterTypes":[] }, {"name":"sequenceNumber","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampISO","parameterTypes":[] }, {"name":"timestampISOLocal","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$DataFileInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columnSizes","parameterTypes":[] }, {"name":"fileSizeInBytes","parameterTypes":[] }, {"name":"format","parameterTypes":[] }, {"name":"lowerBounds","parameterTypes":[] }, {"name":"nullValueCounts","parameterTypes":[] }, {"name":"partition","parameterTypes":[] }, {"name":"path","parameterTypes":[] }, {"name":"recordCount","parameterTypes":[] }, {"name":"upperBounds","parameterTypes":[] }, {"name":"valueCounts","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$HistoryInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$ManifestInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"addedFilesCount","parameterTypes":[] }, {"name":"dataFiles","parameterTypes":[] }, {"name":"deletedFilesCount","parameterTypes":[] }, {"name":"existingFilesCount","parameterTypes":[] }, {"name":"partitionSpecId","parameterTypes":[] }, {"name":"path","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$MetadataInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"history","parameterTypes":[] }, {"name":"manifests","parameterTypes":[] }, {"name":"schema","parameterTypes":[] }, {"name":"snapshots","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SchemaInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$Summary", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, { "name":"com.altinity.ice.cli.internal.cmd.ListNamespaces$Result", "allDeclaredFields":true, @@ -198,6 +237,13 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"partitionSpec","parameterTypes":[] }, {"name":"partitions","parameterTypes":[] }, {"name":"table","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.ListTables$Result", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"namespace","parameterTypes":[] }, {"name":"tables","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.config.Config", "allDeclaredFields":true, @@ -209,7 +255,8 @@ "name":"com.altinity.ice.cli.internal.config.Config$S3", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }] }, { "name":"com.altinity.ice.internal.iceberg.io.SchemeFileIO", @@ -545,6 +592,12 @@ "name":"java.time.ZonedDateTime", "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] }, +{ + "name":"java.util.Collections$UnmodifiableMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, { "name":"java.util.Date" }, From b98ee644239bc67841ebcbb1bbb15d2760a45a92 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Thu, 30 Apr 2026 13:14:38 -0400 Subject: [PATCH 18/25] Add aarch64 paths to resource-config.json --- .../native-image/com.altinity/ice/resource-config.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json index 1912bec8..9b4619fb 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json @@ -54,6 +54,8 @@ "pattern":"\\Qiceberg-build.properties\\E" }, { "pattern":"\\Qlinux/amd64/libzstd-jni-1.5.6-6.so\\E" + }, { + "pattern":"\\Qlinux/aarch64/libzstd-jni-1.5.6-6.so\\E" }, { "pattern":"\\Qlogback-test.scmo\\E" }, { @@ -74,6 +76,8 @@ "pattern":"\\Qorg/apache/hc/client5/version.properties\\E" }, { "pattern":"\\Qorg/jline/nativ/Linux/x86_64/libjlinenative.so\\E" + }, { + "pattern":"\\Qorg/jline/nativ/Linux/aarch64/libjlinenative.so\\E" }, { "pattern":"\\Qorg/jline/utils/capabilities.txt\\E" }, { @@ -84,6 +88,8 @@ "pattern":"\\Qorg/xerial/snappy/VERSION\\E" }, { "pattern":"\\Qorg/xerial/snappy/native/Linux/x86_64/libsnappyjava.so\\E" + }, { + "pattern":"\\Qorg/xerial/snappy/native/Linux/aarch64/libsnappyjava.so\\E" }, { "pattern":"\\Qsoftware/amazon/awssdk/core/util/mime.types\\E" }, { From 1348f73c8521ade5d007f7423bc58dad27436839 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Thu, 7 May 2026 13:17:48 -0400 Subject: [PATCH 19/25] Add describe-parquet test --- examples/scratch/README.md | 2 +- .../scenarios/basic-operations/run.sh.tmpl | 4 + .../scenarios/describe-parquet/input.parquet | Bin 0 -> 2446 bytes .../scenarios/describe-parquet/run.sh.tmpl | 151 ++++++++++++++++++ .../scenarios/describe-parquet/scenario.yaml | 10 ++ .../com.altinity/ice/reflect-config.json | 44 ++++- .../com.altinity/ice/resource-config.json | 12 +- 7 files changed, 215 insertions(+), 8 deletions(-) create mode 100644 ice-rest-catalog/src/test/resources/scenarios/describe-parquet/input.parquet create mode 100644 ice-rest-catalog/src/test/resources/scenarios/describe-parquet/run.sh.tmpl create mode 100644 ice-rest-catalog/src/test/resources/scenarios/describe-parquet/scenario.yaml diff --git a/examples/scratch/README.md b/examples/scratch/README.md index 011fd715..179eba38 100644 --- a/examples/scratch/README.md +++ b/examples/scratch/README.md @@ -37,7 +37,7 @@ ice insert nyc.taxis_p_by_day -p \ # delete partition ice delete nyc.taxis_p_by_day \ - --partition '[{"name": "tpep_pickup_datetime", "values": ["2024-12-31T23:51:20"]}]' --dry-run=false + --partition '[{"name": "tpep_pickup_datetime_day", "values": ["2024-12-31"]}]' --dry-run=false # insert data ordered by tpep_pickup_datetime column ice insert nyc.taxis_s_by_day -p \ diff --git a/ice-rest-catalog/src/test/resources/scenarios/basic-operations/run.sh.tmpl b/ice-rest-catalog/src/test/resources/scenarios/basic-operations/run.sh.tmpl index de9184a2..178d17fa 100644 --- a/ice-rest-catalog/src/test/resources/scenarios/basic-operations/run.sh.tmpl +++ b/ice-rest-catalog/src/test/resources/scenarios/basic-operations/run.sh.tmpl @@ -30,6 +30,10 @@ echo "OK list-namespaces listed ${NAMESPACE_NAME}" {{ICE_CLI}} --config {{CLI_CONFIG}} describe echo "OK Listed namespaces" +# Check configuration +{{ICE_CLI}} --config {{CLI_CONFIG}} check +echo "OK checked configuration" + # Insert from file (like README: ice insert flowers.iris -p file://...) {{ICE_CLI}} --config {{CLI_CONFIG}} insert ${TABLE_IRIS} -p "file://${INPUT_PATH}" echo "Inserted from file into ${TABLE_IRIS}" diff --git a/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/input.parquet b/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/input.parquet new file mode 100644 index 0000000000000000000000000000000000000000..028c64cf9f7d9ea46bfeeaf940482aaee90a1b54 GIT binary patch literal 2446 zcmZ`*L1-Ii7JgDj^8efVlXj z+h~)tReRFWhaP+iY7a$+Qgkq^*-PEa;-d=<2zpU(g6+Yl#l^)qB!vBb$#tBx9gt_{ z{qO(gz4v|Z{Vu=u=TMXW->5#yzNoj-c+To9(buwYj)=C>skKZhHy(ZdSt^wqi|&7y zN?D^(=3;JbG@?w3J<{(uM64qj3mr{oQZ#l|z@TipsH&9LfvnNEcG%`J+fs0g##Ncd zbUX7exWy$nkLrLEd4Po?Zml3GL2Z)^amx`evS2yK8Lb3r>3ybuE+Fm-Q=hc3= zNd<)4#fLqv(M9da4o6rocpN%8X>h^1rgkZHk(+Rj{l-b2p`%XBV1fC_E;2_-tzKG(RB zxnWH|)LsdNuF!!t4fhz?K0wudcULwRJSzEwmaEg@e2aLSeYTC_Yuo}$M_1AGM>@{zU?#KLo&SQ`ZEz>>IwEsSoA>Df=};m6B7Ba zYPh`*Hwha|&mO5BWFjo18v1$OCRwHj$n`+`nLnXJ50r-ichGNo)XJZ@VbL)d_zA^& zgo(2W(^`t(p^AoQy!rplOZJpnJOxz=gF0Hp^ypT|-Ly+QQoK(kQ1y)Z&I9Jjbf985Lr!D=ae)}z)e`vso zO&o&sm({zs?ko@E>94D|@2p?Hb@SG3Y2Mav-&lWt{rWOyZ9#kegVP=yoag^|!e@Gg zR#Gczopx`&49To~aQ*Kq?_Ildy}J63Wj#!Kcp~lO?yT09Z@zSM_5B-ns{_->!1U4j z$}g5&ZT0T6P6N}4Qw~T&A1>csU%mVB1W|q~?H1g>P2%Vob~O&ur@o@oSkK=Z%YQL6 zDPDEN;MBMrIbynhag-}9|3F6rxPXRw2n*3_$6p?|5J?1)tc-D%QCx}lac?$W} z(B!|*pF&9H>%5SA6e=JPiD-;}gstG4MkWHTQ+21e&5i48iNkM-0b*SR?d74NQmGPh0{{e!n B/dev/null 2>&1; then + echo "FAIL describe-parquet should fail on missing file" + exit 1 +fi +echo "OK Missing file rejected" + +echo "Describe-parquet test completed successfully" diff --git a/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/scenario.yaml b/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/scenario.yaml new file mode 100644 index 00000000..8e878c9c --- /dev/null +++ b/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/scenario.yaml @@ -0,0 +1,10 @@ +name: "Describe parquet metadata" +description: "Tests describe-parquet against a local iris parquet file across all option flags and both YAML and JSON output formats" + +catalogConfig: + warehouse: "s3://test-bucket/warehouse" + +env: + INPUT_FILE: "input.parquet" + EXPECTED_ROWS: "150" + EXPECTED_COLUMN_COUNT: "5" diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 707ca319..094000f9 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -107,7 +107,7 @@ "name":"com.altinity.ice.cli.Main", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] + "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeParquet","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","java.lang.String","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.Main$IcePartition", @@ -216,6 +216,48 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true }, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$Column", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"logicalType","parameterTypes":[] }, {"name":"name","parameterTypes":[] }, {"name":"repetition","parameterTypes":[] }, {"name":"type","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$ColumnChunk", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"codec","parameterTypes":[] }, {"name":"encodings","parameterTypes":[] }, {"name":"path","parameterTypes":[] }, {"name":"stats","parameterTypes":[] }, {"name":"totalSize","parameterTypes":[] }, {"name":"type","parameterTypes":[] }, {"name":"uncompressedSize","parameterTypes":[] }, {"name":"valueCount","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$ColumnStats", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"max","parameterTypes":[] }, {"name":"min","parameterTypes":[] }, {"name":"nulls","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$ParquetInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columns","parameterTypes":[] }, {"name":"rowGroups","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$RowGroup", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columns","parameterTypes":[] }, {"name":"compressedSize","parameterTypes":[] }, {"name":"index","parameterTypes":[] }, {"name":"rowCount","parameterTypes":[] }, {"name":"startingPos","parameterTypes":[] }, {"name":"totalSize","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$Summary", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columnCount","parameterTypes":[] }, {"name":"compressedSize","parameterTypes":[] }, {"name":"createdBy","parameterTypes":[] }, {"name":"rowGroups","parameterTypes":[] }, {"name":"rows","parameterTypes":[] }, {"name":"uncompressedSize","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.ListNamespaces$Result", "allDeclaredFields":true, diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json index 9b4619fb..ad082462 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json @@ -52,10 +52,10 @@ "pattern":"\\Qhadoop-site.xml\\E" }, { "pattern":"\\Qiceberg-build.properties\\E" - }, { - "pattern":"\\Qlinux/amd64/libzstd-jni-1.5.6-6.so\\E" }, { "pattern":"\\Qlinux/aarch64/libzstd-jni-1.5.6-6.so\\E" + }, { + "pattern":"\\Qlinux/amd64/libzstd-jni-1.5.6-6.so\\E" }, { "pattern":"\\Qlogback-test.scmo\\E" }, { @@ -74,10 +74,10 @@ "pattern":"\\Qorg-xerial-snappy.properties\\E" }, { "pattern":"\\Qorg/apache/hc/client5/version.properties\\E" - }, { - "pattern":"\\Qorg/jline/nativ/Linux/x86_64/libjlinenative.so\\E" }, { "pattern":"\\Qorg/jline/nativ/Linux/aarch64/libjlinenative.so\\E" + }, { + "pattern":"\\Qorg/jline/nativ/Linux/x86_64/libjlinenative.so\\E" }, { "pattern":"\\Qorg/jline/utils/capabilities.txt\\E" }, { @@ -86,10 +86,10 @@ "pattern":"\\Qorg/publicsuffix/list/effective_tld_names.dat\\E" }, { "pattern":"\\Qorg/xerial/snappy/VERSION\\E" - }, { - "pattern":"\\Qorg/xerial/snappy/native/Linux/x86_64/libsnappyjava.so\\E" }, { "pattern":"\\Qorg/xerial/snappy/native/Linux/aarch64/libsnappyjava.so\\E" + }, { + "pattern":"\\Qorg/xerial/snappy/native/Linux/x86_64/libsnappyjava.so\\E" }, { "pattern":"\\Qsoftware/amazon/awssdk/core/util/mime.types\\E" }, { From 321c38aef676ed8b50ebf56aa5f99df24ed8c8ef Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Fri, 8 May 2026 13:55:35 -0400 Subject: [PATCH 20/25] Add more cases to schema-evolution scenario --- .../scenarios/schema-evolution/run.sh.tmpl | 105 ++++++++++++++ .../scenarios/schema-evolution/scenario.yaml | 4 +- .../com.altinity/ice/reflect-config.json | 132 +++++++++++++++++- 3 files changed, 237 insertions(+), 4 deletions(-) diff --git a/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/run.sh.tmpl b/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/run.sh.tmpl index 4a076deb..e4fde013 100644 --- a/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/run.sh.tmpl +++ b/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/run.sh.tmpl @@ -45,9 +45,114 @@ if [ "${SECOND_LINES}" -le "${FIRST_LINES}" ]; then fi echo "OK Second scan: ${SECOND_LINES} lines (rows inserted)" +# alter_column: add an int column then widen to long +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"add_column","name":"an_int","type":"int"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/schema_ev_int.txt +if ! grep -qF 'an_int: optional int' /tmp/schema_ev_int.txt; then + echo "FAIL add_column an_int as int not visible" + cat /tmp/schema_ev_int.txt + exit 1 +fi +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"alter_column","name":"an_int","type":"long"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/schema_ev_long.txt +if ! grep -qF 'an_int: optional long' /tmp/schema_ev_long.txt; then + echo "FAIL alter_column int->long not applied" + cat /tmp/schema_ev_long.txt + exit 1 +fi +echo "OK alter_column promoted int to long" + +# rename_column an_int -> a_long +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"rename_column","name":"an_int","new_name":"a_long"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/schema_ev_rename.txt +if grep -qF ' an_int:' /tmp/schema_ev_rename.txt; then + echo "FAIL rename_column: old name 'an_int' still present" + cat /tmp/schema_ev_rename.txt + exit 1 +fi +if ! grep -qF 'a_long: optional long' /tmp/schema_ev_rename.txt; then + echo "FAIL rename_column: new name 'a_long' not visible" + cat /tmp/schema_ev_rename.txt + exit 1 +fi +echo "OK rename_column an_int -> a_long" + +# drop_column 'extra' +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"drop_column","name":"extra"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/schema_ev_drop.txt +if grep -qF ' extra:' /tmp/schema_ev_drop.txt; then + echo "FAIL drop_column: 'extra' still present" + cat /tmp/schema_ev_drop.txt + exit 1 +fi +echo "OK drop_column 'extra' removed" + +# set_tblproperty: set then remove (value=null) +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"set_tblproperty","key":"owner","value":"qa"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -p ${TABLE_NAME} > /tmp/schema_ev_props_set.txt +if ! grep -qF 'owner: qa' /tmp/schema_ev_props_set.txt; then + echo "FAIL set_tblproperty owner=qa not visible in describe -p" + cat /tmp/schema_ev_props_set.txt + exit 1 +fi +echo "OK set_tblproperty owner=qa" + +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"set_tblproperty","key":"owner","value":null}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -p ${TABLE_NAME} > /tmp/schema_ev_props_unset.txt +if grep -qF 'owner: qa' /tmp/schema_ev_props_unset.txt; then + echo "FAIL set_tblproperty value=null did not remove 'owner'" + cat /tmp/schema_ev_props_unset.txt + exit 1 +fi +echo "OK set_tblproperty value=null removed 'owner'" + +# rename_to: ensure new name appears and old name disappears +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} "[{\"op\":\"rename_to\",\"new_name\":\"${TABLE_RENAMED}\"}]" +{{ICE_CLI}} --config {{CLI_CONFIG}} list-tables ${NAMESPACE_NAME} > /tmp/schema_ev_rename_to.txt +LISTED_NAMES=$(awk '/^- /{sub(/^- */,""); print}' /tmp/schema_ev_rename_to.txt) +if grep -qFx "${TABLE_NAME}" <<<"${LISTED_NAMES}"; then + echo "FAIL rename_to: original table ${TABLE_NAME} still listed" + cat /tmp/schema_ev_rename_to.txt + exit 1 +fi +if ! grep -qFx "${TABLE_RENAMED}" <<<"${LISTED_NAMES}"; then + echo "FAIL rename_to: renamed table ${TABLE_RENAMED} not listed" + cat /tmp/schema_ev_rename_to.txt + exit 1 +fi +echo "OK rename_to ${TABLE_RENAMED}" + +# Rename back so the existing cleanup path still works +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_RENAMED} "[{\"op\":\"rename_to\",\"new_name\":\"${TABLE_NAME}\"}]" + +# drop_partition_field: needs a partitioned table +{{ICE_CLI}} --config {{CLI_CONFIG}} insert --create-table ${TABLE_PARTITIONED} "file://${INPUT_PATH}" \ + --partition='[{"column":"variety","transform":"identity"}]' +PART_BEFORE=$({{ICE_CLI}} --config {{CLI_CONFIG}} list-partitions ${TABLE_PARTITIONED}) +if ! grep -q "variety=" <<<"${PART_BEFORE}"; then + echo "FAIL partitioned table missing 'variety=' partition entries before drop" + printf '%s\n' "${PART_BEFORE}" + exit 1 +fi +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_PARTITIONED} $'[{"op":"drop_partition_field","name":"variety"}]' +DESCRIBE_PART=$({{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_PARTITIONED}) +# After dropping, the partition spec should no longer reference 'variety' as an active field. +# Iceberg renders dropped fields as "void()" in the spec; an active identity partition shows as "identity(variety)". +if grep -qE "identity\(variety\)" <<<"${DESCRIBE_PART}"; then + echo "FAIL drop_partition_field: identity(variety) still active in spec" + printf '%s\n' "${DESCRIBE_PART}" + exit 1 +fi +echo "OK drop_partition_field 'variety'" + # Cleanup {{ICE_CLI}} --config {{CLI_CONFIG}} delete-table ${TABLE_NAME} +{{ICE_CLI}} --config {{CLI_CONFIG}} delete-table ${TABLE_PARTITIONED} {{ICE_CLI}} --config {{CLI_CONFIG}} delete-namespace ${NAMESPACE_NAME} +rm -f /tmp/schema_ev_describe.txt /tmp/schema_ev_scan1.txt /tmp/schema_ev_scan2.txt \ + /tmp/schema_ev_int.txt /tmp/schema_ev_long.txt /tmp/schema_ev_rename.txt \ + /tmp/schema_ev_drop.txt /tmp/schema_ev_props_set.txt /tmp/schema_ev_props_unset.txt \ + /tmp/schema_ev_rename_to.txt echo "OK Cleanup done" echo "Schema evolution test completed successfully" diff --git a/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/scenario.yaml b/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/scenario.yaml index 8a753b63..684274be 100644 --- a/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/scenario.yaml +++ b/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/scenario.yaml @@ -1,5 +1,5 @@ name: "Schema evolution (add, drop, rename)" -description: "Tests alter-table: add column, drop column, rename column" +description: "Tests alter-table: add_column, alter_column, rename_column, drop_column, set_tblproperty, rename_to, drop_partition_field" catalogConfig: warehouse: "s3://test-bucket/warehouse" @@ -7,3 +7,5 @@ catalogConfig: env: NAMESPACE_NAME: "test_schema_ev" TABLE_NAME: "test_schema_ev.t1" + TABLE_RENAMED: "test_schema_ev.t1_renamed" + TABLE_PARTITIONED: "test_schema_ev.t_part" diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 094000f9..70a02591 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -14,6 +14,9 @@ { "name":"[Lcom.altinity.ice.cli.internal.cmd.AlterTable$Update;" }, +{ + "name":"[Lcom.altinity.ice.cli.internal.cmd.DescribeMetadata$ManifestInfo;" +}, { "name":"[Lcom.fasterxml.jackson.databind.deser.BeanDeserializerModifier;" }, @@ -32,6 +35,9 @@ { "name":"[Lcom.fasterxml.jackson.databind.ser.Serializers;" }, +{ + "name":"[Ljava.lang.Object;" +}, { "name":"[Ljava.lang.String;" }, @@ -137,6 +143,48 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean"] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$AlterColumn", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$DropColumn", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$DropPartitionField", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$RenameColumn", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$RenameTo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$SetTblProperty", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.AlterTable$Update", "allDeclaredFields":true, @@ -184,11 +232,19 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"columnSizes","parameterTypes":[] }, {"name":"fileSizeInBytes","parameterTypes":[] }, {"name":"format","parameterTypes":[] }, {"name":"lowerBounds","parameterTypes":[] }, {"name":"nullValueCounts","parameterTypes":[] }, {"name":"partition","parameterTypes":[] }, {"name":"path","parameterTypes":[] }, {"name":"recordCount","parameterTypes":[] }, {"name":"upperBounds","parameterTypes":[] }, {"name":"valueCounts","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$FieldInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"fieldId","parameterTypes":[] }, {"name":"name","parameterTypes":[] }, {"name":"required","parameterTypes":[] }, {"name":"type","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$HistoryInfo", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"metadataLog","parameterTypes":[] }, {"name":"snapshotLog","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$ManifestInfo", @@ -204,17 +260,40 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"history","parameterTypes":[] }, {"name":"manifests","parameterTypes":[] }, {"name":"schema","parameterTypes":[] }, {"name":"snapshots","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$MetadataLogEntry", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"file","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampMillis","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SchemaInfo", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"fields","parameterTypes":[] }, {"name":"schemaId","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SnapshotInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"manifestListLocation","parameterTypes":[] }, {"name":"operation","parameterTypes":[] }, {"name":"parentId","parameterTypes":[] }, {"name":"sequenceNumber","parameterTypes":[] }, {"name":"snapshotId","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampMillis","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SnapshotLogEntry", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"snapshotId","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampMillis","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$Summary", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"currentSnapshotId","parameterTypes":[] }, {"name":"formatVersion","parameterTypes":[] }, {"name":"lastUpdated","parameterTypes":[] }, {"name":"lastUpdatedMillis","parameterTypes":[] }, {"name":"location","parameterTypes":[] }, {"name":"numSnapshots","parameterTypes":[] }, {"name":"partitionSpec","parameterTypes":[] }, {"name":"properties","parameterTypes":[] }, {"name":"sortOrder","parameterTypes":[] }, {"name":"uuid","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$Column", @@ -480,6 +559,10 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true }, +{ + "name":"java.lang.Iterable", + "queryAllDeclaredMethods":true +}, { "name":"java.lang.Number", "allDeclaredFields":true, @@ -634,6 +717,15 @@ "name":"java.time.ZonedDateTime", "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] }, +{ + "name":"java.util.AbstractCollection", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.util.Collection", + "queryAllDeclaredMethods":true +}, { "name":"java.util.Collections$UnmodifiableMap", "allDeclaredFields":true, @@ -643,10 +735,34 @@ { "name":"java.util.Date" }, +{ + "name":"java.util.ImmutableCollections$AbstractImmutableCollection", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.util.ImmutableCollections$AbstractImmutableList", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.util.ImmutableCollections$ListN", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"java.util.List", + "queryAllDeclaredMethods":true +}, { "name":"java.util.Map", "queryAllDeclaredMethods":true }, +{ + "name":"java.util.RandomAccess", + "queryAllDeclaredMethods":true +}, { "name":"java.util.concurrent.ForkJoinTask", "fields":[{"name":"aux"}, {"name":"status"}] @@ -807,6 +923,12 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true }, +{ + "name":"org.apache.iceberg.rest.requests.RenameTableRequest", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, { "name":"org.apache.iceberg.rest.responses.CreateNamespaceResponse", "allDeclaredFields":true, @@ -950,6 +1072,10 @@ "name":"sun.security.provider.JavaKeyStore$JKS", "methods":[{"name":"","parameterTypes":[] }] }, +{ + "name":"sun.security.provider.MD5", + "methods":[{"name":"","parameterTypes":[] }] +}, { "name":"sun.security.provider.NativePRNG", "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] From 85e6f1018b79c1e06be85cfc1b301399745d752a Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Mon, 18 May 2026 11:30:53 -0400 Subject: [PATCH 21/25] Update reflect-config.json --- .../native-image/com.altinity/ice/reflect-config.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 70a02591..cc78b9ac 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -113,7 +113,7 @@ "name":"com.altinity.ice.cli.Main", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeParquet","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","java.lang.String","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] + "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeParquet","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","java.lang.String","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","int","long","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listSnapshots","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.Main$IcePartition", @@ -279,7 +279,7 @@ "allDeclaredFields":true, "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true, - "methods":[{"name":"manifestListLocation","parameterTypes":[] }, {"name":"operation","parameterTypes":[] }, {"name":"parentId","parameterTypes":[] }, {"name":"sequenceNumber","parameterTypes":[] }, {"name":"snapshotId","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampMillis","parameterTypes":[] }] + "methods":[{"name":"current","parameterTypes":[] }, {"name":"manifestListLocation","parameterTypes":[] }, {"name":"operation","parameterTypes":[] }, {"name":"parentId","parameterTypes":[] }, {"name":"sequenceNumber","parameterTypes":[] }, {"name":"snapshotId","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampMillis","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SnapshotLogEntry", @@ -393,6 +393,10 @@ "queryAllPublicMethods":true, "methods":[{"name":"","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.internal.logback.ProcessIdClassicConverter", + "methods":[{"name":"","parameterTypes":[] }] +}, { "name":"com.altinity.ice.internal.picocli.VersionProvider", "allDeclaredFields":true, From ce54649ed8cea4f37d2b1b972daf73fcee528a26 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Mon, 18 May 2026 17:02:23 -0400 Subject: [PATCH 22/25] Update reflect-config.json --- .../com.altinity/ice/reflect-config.json | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index cc78b9ac..67bdd053 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -198,6 +198,13 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"data","parameterTypes":[] }, {"name":"error","parameterTypes":[] }, {"name":"kind","parameterTypes":[] }, {"name":"metadata","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$ColumnMetrics", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"lowerBound","parameterTypes":[] }, {"name":"name","parameterTypes":[] }, {"name":"nested","parameterTypes":[] }, {"name":"nullCount","parameterTypes":[] }, {"name":"upperBound","parameterTypes":[] }, {"name":"valueCount","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Data", "allDeclaredFields":true, @@ -209,7 +216,8 @@ "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Error", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"message","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Metadata", @@ -218,6 +226,13 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"id","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Metrics", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columns","parameterTypes":[] }, {"name":"file","parameterTypes":[] }, {"name":"recordCount","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Snapshot", "allDeclaredFields":true, @@ -530,6 +545,10 @@ "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", "methods":[{"name":"","parameterTypes":[] }] }, +{ + "name":"com.sun.crypto.provider.HmacCore$HmacSHA384", + "methods":[{"name":"","parameterTypes":[] }] +}, { "name":"com.sun.crypto.provider.TlsMasterSecretGenerator", "methods":[{"name":"","parameterTypes":[] }] @@ -1132,6 +1151,10 @@ "name":"sun.security.rsa.RSASignature$SHA256withRSA", "methods":[{"name":"","parameterTypes":[] }] }, +{ + "name":"sun.security.rsa.RSASignature$SHA384withRSA", + "methods":[{"name":"","parameterTypes":[] }] +}, { "name":"sun.security.ssl.KeyManagerFactoryImpl$SunX509", "methods":[{"name":"","parameterTypes":[] }] From 6be1df897744fae04f442d9ba98df79701cc0fc7 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Tue, 26 May 2026 14:49:43 -0400 Subject: [PATCH 23/25] Support catalog-export and catalog-import for native --- README.md | 2 ++ .../com.altinity/ice/reflect-config.json | 30 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 05b1860e..719579d4 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ sdk env # or ensure Java 21+ and GraalVM are available # Build ice binary (both amd64 and arm64) mvn -Pnative -pl ice clean package -Dmaven.test.skip=true +# The output binary is at ice/target/ice + # Docker builds docker build -f ice/Dockerfile.native -t ice-native:amd64 . diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 67bdd053..7f793c0b 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -113,7 +113,7 @@ "name":"com.altinity.ice.cli.Main", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeParquet","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","java.lang.String","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","int","long","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listSnapshots","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] + "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"catalogExport","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"catalogImport","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeParquet","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","java.lang.String","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","int","long","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listSnapshots","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.Main$IcePartition", @@ -136,6 +136,34 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"","parameterTypes":["java.lang.String","java.util.List"] }] }, +{ + "name":"com.altinity.ice.cli.internal.catalog.AdminCatalogSnapshot", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["int","java.lang.String","java.lang.String","java.util.List","java.util.List"] }, {"name":"catalogName","parameterTypes":[] }, {"name":"exportedAt","parameterTypes":[] }, {"name":"namespaces","parameterTypes":[] }, {"name":"tables","parameterTypes":[] }, {"name":"version","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.catalog.AdminCatalogSnapshot$NamespaceEntry", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.util.Map"] }, {"name":"key","parameterTypes":[] }, {"name":"value","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.catalog.AdminCatalogSnapshot$TableEntry", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.util.Map"] }, {"name":"key","parameterTypes":[] }, {"name":"value","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.catalog.AdminImportResult", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["int","int","int","java.lang.String","java.lang.String"] }, {"name":"catalogName","parameterTypes":[] }, {"name":"created","parameterTypes":[] }, {"name":"exportedAt","parameterTypes":[] }, {"name":"overwritten","parameterTypes":[] }, {"name":"skipped","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.AlterTable$AddColumn", "allDeclaredFields":true, From 11cc445dad101022c89f618bb73c20abe347a216 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Wed, 10 Jun 2026 10:11:52 -0400 Subject: [PATCH 24/25] Update reflect-config.json --- .../com.altinity/ice/reflect-config.json | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 7f793c0b..7510a6f6 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -169,7 +169,7 @@ "allDeclaredFields":true, "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true, - "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean"] }] + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean","java.lang.Boolean","java.lang.String"] }] }, { "name":"com.altinity.ice.cli.internal.cmd.AlterTable$AlterColumn", @@ -898,11 +898,15 @@ }, { "name":"org.apache.iceberg.GenericManifestFile", - "methods":[{"name":"","parameterTypes":["org.apache.avro.Schema"] }] + "methods":[{"name":"","parameterTypes":["org.apache.avro.Schema"] }, {"name":"","parameterTypes":["org.apache.iceberg.types.Types$StructType"] }] }, { "name":"org.apache.iceberg.GenericPartitionFieldSummary", - "methods":[{"name":"","parameterTypes":["org.apache.avro.Schema"] }] + "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["org.apache.avro.Schema"] }, {"name":"","parameterTypes":["org.apache.iceberg.types.Types$StructType"] }] +}, +{ + "name":"org.apache.iceberg.InternalParquet", + "methods":[{"name":"register","parameterTypes":[] }] }, { "name":"org.apache.iceberg.PartitionData", @@ -962,6 +966,10 @@ "name":"org.apache.iceberg.rest.RESTResponse", "queryAllDeclaredMethods":true }, +{ + "name":"org.apache.iceberg.rest.auth.NoopAuthManager", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, { "name":"org.apache.iceberg.rest.requests.CreateNamespaceRequest", "allDeclaredFields":true, From 739af2161bc1d2b4723d65d355f274a410fc92eb Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Wed, 10 Jun 2026 10:49:07 -0400 Subject: [PATCH 25/25] Update pyarrow dependency --- .../src/test/pyiceberg/pyproject.toml | 2 +- ice-rest-catalog/src/test/pyiceberg/uv.lock | 65 ++++++++++++------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/ice-rest-catalog/src/test/pyiceberg/pyproject.toml b/ice-rest-catalog/src/test/pyiceberg/pyproject.toml index 61dfc655..d9ec2064 100644 --- a/ice-rest-catalog/src/test/pyiceberg/pyproject.toml +++ b/ice-rest-catalog/src/test/pyiceberg/pyproject.toml @@ -6,7 +6,7 @@ readme = "README.md" requires-python = ">=3.12" dependencies = [ "httpx>=0.28.1", - "pyarrow>=19.0.1", + "pyarrow>=23.0.1", "pyiceberg[pyarrow]>=0.11.1", ] diff --git a/ice-rest-catalog/src/test/pyiceberg/uv.lock b/ice-rest-catalog/src/test/pyiceberg/uv.lock index 3df73846..37a544a0 100644 --- a/ice-rest-catalog/src/test/pyiceberg/uv.lock +++ b/ice-rest-catalog/src/test/pyiceberg/uv.lock @@ -163,7 +163,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "httpx", specifier = ">=0.28.1" }, - { name = "pyarrow", specifier = ">=19.0.1" }, + { name = "pyarrow", specifier = ">=23.0.1" }, { name = "pyiceberg", extras = ["pyarrow"], specifier = ">=0.11.1" }, ] @@ -242,30 +242,45 @@ wheels = [ [[package]] name = "pyarrow" -version = "19.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7f/09/a9046344212690f0632b9c709f9bf18506522feb333c894d0de81d62341a/pyarrow-19.0.1.tar.gz", hash = "sha256:3bf266b485df66a400f282ac0b6d1b500b9d2ae73314a153dbe97d6d5cc8a99e", size = 1129437, upload-time = "2025-02-18T18:55:57.027Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b4/94e828704b050e723f67d67c3535cf7076c7432cd4cf046e4bb3b96a9c9d/pyarrow-19.0.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:80b2ad2b193e7d19e81008a96e313fbd53157945c7be9ac65f44f8937a55427b", size = 30670749, upload-time = "2025-02-18T18:53:00.062Z" }, - { url = "https://files.pythonhosted.org/packages/7e/3b/4692965e04bb1df55e2c314c4296f1eb12b4f3052d4cf43d29e076aedf66/pyarrow-19.0.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:ee8dec072569f43835932a3b10c55973593abc00936c202707a4ad06af7cb294", size = 32128007, upload-time = "2025-02-18T18:53:06.581Z" }, - { url = "https://files.pythonhosted.org/packages/22/f7/2239af706252c6582a5635c35caa17cb4d401cd74a87821ef702e3888957/pyarrow-19.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d5d1ec7ec5324b98887bdc006f4d2ce534e10e60f7ad995e7875ffa0ff9cb14", size = 41144566, upload-time = "2025-02-18T18:53:11.958Z" }, - { url = "https://files.pythonhosted.org/packages/fb/e3/c9661b2b2849cfefddd9fd65b64e093594b231b472de08ff658f76c732b2/pyarrow-19.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ad4c0eb4e2a9aeb990af6c09e6fa0b195c8c0e7b272ecc8d4d2b6574809d34", size = 42202991, upload-time = "2025-02-18T18:53:17.678Z" }, - { url = "https://files.pythonhosted.org/packages/fe/4f/a2c0ed309167ef436674782dfee4a124570ba64299c551e38d3fdaf0a17b/pyarrow-19.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:d383591f3dcbe545f6cc62daaef9c7cdfe0dff0fb9e1c8121101cabe9098cfa6", size = 40507986, upload-time = "2025-02-18T18:53:26.263Z" }, - { url = "https://files.pythonhosted.org/packages/27/2e/29bb28a7102a6f71026a9d70d1d61df926887e36ec797f2e6acfd2dd3867/pyarrow-19.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b4c4156a625f1e35d6c0b2132635a237708944eb41df5fbe7d50f20d20c17832", size = 42087026, upload-time = "2025-02-18T18:53:33.063Z" }, - { url = "https://files.pythonhosted.org/packages/16/33/2a67c0f783251106aeeee516f4806161e7b481f7d744d0d643d2f30230a5/pyarrow-19.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:5bd1618ae5e5476b7654c7b55a6364ae87686d4724538c24185bbb2952679960", size = 25250108, upload-time = "2025-02-18T18:53:38.462Z" }, - { url = "https://files.pythonhosted.org/packages/2b/8d/275c58d4b00781bd36579501a259eacc5c6dfb369be4ddeb672ceb551d2d/pyarrow-19.0.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e45274b20e524ae5c39d7fc1ca2aa923aab494776d2d4b316b49ec7572ca324c", size = 30653552, upload-time = "2025-02-18T18:53:44.357Z" }, - { url = "https://files.pythonhosted.org/packages/a0/9e/e6aca5cc4ef0c7aec5f8db93feb0bde08dbad8c56b9014216205d271101b/pyarrow-19.0.1-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:d9dedeaf19097a143ed6da37f04f4051aba353c95ef507764d344229b2b740ae", size = 32103413, upload-time = "2025-02-18T18:53:52.971Z" }, - { url = "https://files.pythonhosted.org/packages/6a/fa/a7033f66e5d4f1308c7eb0dfcd2ccd70f881724eb6fd1776657fdf65458f/pyarrow-19.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ebfb5171bb5f4a52319344ebbbecc731af3f021e49318c74f33d520d31ae0c4", size = 41134869, upload-time = "2025-02-18T18:53:59.471Z" }, - { url = "https://files.pythonhosted.org/packages/2d/92/34d2569be8e7abdc9d145c98dc410db0071ac579b92ebc30da35f500d630/pyarrow-19.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a21d39fbdb948857f67eacb5bbaaf36802de044ec36fbef7a1c8f0dd3a4ab2", size = 42192626, upload-time = "2025-02-18T18:54:06.062Z" }, - { url = "https://files.pythonhosted.org/packages/0a/1f/80c617b1084fc833804dc3309aa9d8daacd46f9ec8d736df733f15aebe2c/pyarrow-19.0.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:99bc1bec6d234359743b01e70d4310d0ab240c3d6b0da7e2a93663b0158616f6", size = 40496708, upload-time = "2025-02-18T18:54:12.347Z" }, - { url = "https://files.pythonhosted.org/packages/e6/90/83698fcecf939a611c8d9a78e38e7fed7792dcc4317e29e72cf8135526fb/pyarrow-19.0.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1b93ef2c93e77c442c979b0d596af45e4665d8b96da598db145b0fec014b9136", size = 42075728, upload-time = "2025-02-18T18:54:19.364Z" }, - { url = "https://files.pythonhosted.org/packages/40/49/2325f5c9e7a1c125c01ba0c509d400b152c972a47958768e4e35e04d13d8/pyarrow-19.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:d9d46e06846a41ba906ab25302cf0fd522f81aa2a85a71021826f34639ad31ef", size = 25242568, upload-time = "2025-02-18T18:54:25.846Z" }, - { url = "https://files.pythonhosted.org/packages/3f/72/135088d995a759d4d916ec4824cb19e066585b4909ebad4ab196177aa825/pyarrow-19.0.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:c0fe3dbbf054a00d1f162fda94ce236a899ca01123a798c561ba307ca38af5f0", size = 30702371, upload-time = "2025-02-18T18:54:30.665Z" }, - { url = "https://files.pythonhosted.org/packages/2e/01/00beeebd33d6bac701f20816a29d2018eba463616bbc07397fdf99ac4ce3/pyarrow-19.0.1-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:96606c3ba57944d128e8a8399da4812f56c7f61de8c647e3470b417f795d0ef9", size = 32116046, upload-time = "2025-02-18T18:54:35.995Z" }, - { url = "https://files.pythonhosted.org/packages/1f/c9/23b1ea718dfe967cbd986d16cf2a31fe59d015874258baae16d7ea0ccabc/pyarrow-19.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f04d49a6b64cf24719c080b3c2029a3a5b16417fd5fd7c4041f94233af732f3", size = 41091183, upload-time = "2025-02-18T18:54:42.662Z" }, - { url = "https://files.pythonhosted.org/packages/3a/d4/b4a3aa781a2c715520aa8ab4fe2e7fa49d33a1d4e71c8fc6ab7b5de7a3f8/pyarrow-19.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a9137cf7e1640dce4c190551ee69d478f7121b5c6f323553b319cac936395f6", size = 42171896, upload-time = "2025-02-18T18:54:49.808Z" }, - { url = "https://files.pythonhosted.org/packages/23/1b/716d4cd5a3cbc387c6e6745d2704c4b46654ba2668260d25c402626c5ddb/pyarrow-19.0.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:7c1bca1897c28013db5e4c83944a2ab53231f541b9e0c3f4791206d0c0de389a", size = 40464851, upload-time = "2025-02-18T18:54:57.073Z" }, - { url = "https://files.pythonhosted.org/packages/ed/bd/54907846383dcc7ee28772d7e646f6c34276a17da740002a5cefe90f04f7/pyarrow-19.0.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:58d9397b2e273ef76264b45531e9d552d8ec8a6688b7390b5be44c02a37aade8", size = 42085744, upload-time = "2025-02-18T18:55:08.562Z" }, +version = "24.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/13/13e1069b351bdc3881266e11147ffccf687505dbb0ea74036237f5d454a5/pyarrow-24.0.0.tar.gz", hash = "sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83", size = 1180261, upload-time = "2026-04-21T10:51:25.837Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/a9/9686d9f07837f91f775e8932659192e02c74f9d8920524b480b85212cc68/pyarrow-24.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:6233c9ed9ab9d1db47de57d9753256d9dcffbf42db341576099f0fd9f6bf4810", size = 34981559, upload-time = "2026-04-21T10:47:22.17Z" }, + { url = "https://files.pythonhosted.org/packages/80/b6/0ddf0e9b6ead3474ab087ae598c76b031fc45532bf6a63f3a553440fb258/pyarrow-24.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:f7616236ec1bc2b15bfdec22a71ab38851c86f8f05ff64f379e1278cf20c634a", size = 36663654, upload-time = "2026-04-21T10:47:28.315Z" }, + { url = "https://files.pythonhosted.org/packages/7c/3b/926382efe8ce27ba729071d3566ade6dfb86bdf112f366000196b2f5780a/pyarrow-24.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:1617043b99bd33e5318ae18eb2919af09c71322ef1ca46566cdafc6e6712fb66", size = 45679394, upload-time = "2026-04-21T10:47:34.821Z" }, + { url = "https://files.pythonhosted.org/packages/b3/7a/829f7d9dfd37c207206081d6dad474d81dde29952401f07f2ba507814818/pyarrow-24.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6165461f55ef6314f026de6638d661188e3455d3ec49834556a0ebbdbace18bb", size = 48863122, upload-time = "2026-04-21T10:47:42.056Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e8/f88ce625fe8babaae64e8db2d417c7653adb3019b08aae85c5ed787dc816/pyarrow-24.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b13dedfe76a0ad2d1d859b0811b53827a4e9d93a0bcb05cf59333ab4980cc7e", size = 49376032, upload-time = "2026-04-21T10:47:48.967Z" }, + { url = "https://files.pythonhosted.org/packages/36/7a/82c363caa145fff88fb475da50d3bf52bb024f61917be5424c3392eaf878/pyarrow-24.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:25ea65d868eb04015cd18e6df2fbe98f07e5bda2abefabcb88fce39a947716f6", size = 51929490, upload-time = "2026-04-21T10:47:55.981Z" }, + { url = "https://files.pythonhosted.org/packages/66/1c/e3e72c8014ad2743ca64a701652c733cc5cbcee15c0463a32a8c55518d9e/pyarrow-24.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:295f0a7f2e242dabd513737cf076007dc5b2d59237e3eca37b05c0c6446f3826", size = 27355660, upload-time = "2026-04-21T10:48:01.718Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d3/a1abf004482026ddc17f4503db227787fa3cfe41ec5091ff20e4fea55e57/pyarrow-24.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:02b001b3ed4723caa44f6cd1af2d5c86aa2cf9971dacc2ffa55b21237713dfba", size = 34976759, upload-time = "2026-04-21T10:48:07.258Z" }, + { url = "https://files.pythonhosted.org/packages/4f/4a/34f0a36d28a2dd32225301b79daad44e243dc1a2bb77d43b60749be255c4/pyarrow-24.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:04920d6a71aabd08a0417709efce97d45ea8e6fb733d9ca9ecffb13c67839f68", size = 36658471, upload-time = "2026-04-21T10:48:13.347Z" }, + { url = "https://files.pythonhosted.org/packages/1f/78/543b94712ae8bb1a6023bcc1acf1a740fbff8286747c289cd9468fced2a5/pyarrow-24.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:a964266397740257f16f7bb2e4f08a0c81454004beab8ff59dd531b73610e9f2", size = 45675981, upload-time = "2026-04-21T10:48:20.201Z" }, + { url = "https://files.pythonhosted.org/packages/84/9f/8fb7c222b100d314137fa40ec050de56cd8c6d957d1cfff685ce72f15b17/pyarrow-24.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:6f066b179d68c413374294bc1735f68475457c933258df594443bb9d88ddc2a0", size = 48859172, upload-time = "2026-04-21T10:48:27.541Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d3/1ea72538e6c8b3b475ed78d1049a2c518e655761ea50fe1171fc855fcab7/pyarrow-24.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1183baeb14c5f587b1ec52831e665718ce632caab84b7cd6b85fd44f96114495", size = 49385733, upload-time = "2026-04-21T10:48:34.7Z" }, + { url = "https://files.pythonhosted.org/packages/c3/be/c3d8b06a1ba35f2260f8e1f771abbee7d5e345c0937aab90675706b1690a/pyarrow-24.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:806f24b4085453c197a5078218d1ee08783ebbba271badd153d1ae22a3ee804f", size = 51934335, upload-time = "2026-04-21T10:48:42.099Z" }, + { url = "https://files.pythonhosted.org/packages/9c/62/89e07a1e7329d2cde3e3c6994ba0839a24977a2beda8be6005ea3d860b99/pyarrow-24.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:e4505fc6583f7b05ab854934896bcac8253b04ac1171a77dfb73efef92076d91", size = 27271748, upload-time = "2026-04-21T10:49:42.532Z" }, + { url = "https://files.pythonhosted.org/packages/17/1a/cff3a59f80b5b1658549d46611b67163f65e0664431c076ad728bf9d5af4/pyarrow-24.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:1a4e45017efbf115032e4475ee876d525e0e36c742214fbe405332480ecd6275", size = 35238554, upload-time = "2026-04-21T10:48:48.526Z" }, + { url = "https://files.pythonhosted.org/packages/a8/99/cce0f42a327bfef2c420fb6078a3eb834826e5d6697bf3009fe11d2ad051/pyarrow-24.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:7986f1fa71cee060ad00758bcc79d3a93bab8559bf978fab9e53472a2e25a17b", size = 36782301, upload-time = "2026-04-21T10:48:55.181Z" }, + { url = "https://files.pythonhosted.org/packages/2a/66/8e560d5ff6793ca29aca213c53eec0dd482dd46cb93b2819e5aab52e4252/pyarrow-24.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:d3e0b61e8efb24ed38898e5cdc5fffa9124be480008d401a1f8071500494ae42", size = 45721929, upload-time = "2026-04-21T10:49:03.676Z" }, + { url = "https://files.pythonhosted.org/packages/27/0c/a26e25505d030716e078d9f16eb74973cbf0b33b672884e9f9da1c83b871/pyarrow-24.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:55a3bc1e3df3b5567b7d27ef551b2283f0c68a5e86f1cd56abc569da4f31335b", size = 48825365, upload-time = "2026-04-21T10:49:11.714Z" }, + { url = "https://files.pythonhosted.org/packages/5f/eb/771f9ecb0c65e73fe9dccdd1717901b9594f08c4515d000c7c62df573811/pyarrow-24.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:641f795b361874ac9da5294f8f443dfdbee355cf2bd9e3b8d97aaac2306b9b37", size = 49451819, upload-time = "2026-04-21T10:49:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/48/da/61ae89a88732f5a785646f3ec6125dbb640fa98a540eb2b9889caa561403/pyarrow-24.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8adc8e6ce5fccf5dc707046ae4914fd537def529709cc0d285d37a7f9cd442ca", size = 51909252, upload-time = "2026-04-21T10:49:31.164Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1a/8dd5cafab7b66573fa91c03d06d213356ad4edd71813aa75e08ce2b3a844/pyarrow-24.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:9b18371ad2f44044b81a8d23bc2d8a9b6a6226dca775e8e16cfee640473d6c5d", size = 27388127, upload-time = "2026-04-21T10:49:37.334Z" }, + { url = "https://files.pythonhosted.org/packages/ad/80/d022a34ff05d2cbedd8ccf841fc1f532ecfa9eb5ed1711b56d0e0ea71fc9/pyarrow-24.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838", size = 35007997, upload-time = "2026-04-21T10:49:48.796Z" }, + { url = "https://files.pythonhosted.org/packages/1a/ff/f01485fda6f4e5d441afb8dd5e7681e4db18826c1e271852f5d3957d6a80/pyarrow-24.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b", size = 36678720, upload-time = "2026-04-21T10:49:55.858Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c2/2d2d5fea814237923f71b36495211f20b43a1576f9a4d6da7e751a64ec6f/pyarrow-24.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795", size = 45741852, upload-time = "2026-04-21T10:50:04.624Z" }, + { url = "https://files.pythonhosted.org/packages/8e/3a/28ba9c1c1ebdbb5f1b94dfebb46f207e52e6a554b7fe4132540fde29a3a0/pyarrow-24.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26", size = 48889852, upload-time = "2026-04-21T10:50:12.293Z" }, + { url = "https://files.pythonhosted.org/packages/df/51/4a389acfd31dca009f8fb82d7f510bb4130f2b3a8e18cf00194d0687d8ac/pyarrow-24.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde", size = 49445207, upload-time = "2026-04-21T10:50:20.677Z" }, + { url = "https://files.pythonhosted.org/packages/19/4b/0bab2b23d2ae901b1b9a03c0efd4b2d070256f8ce3fc43f6e58c167b2081/pyarrow-24.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76", size = 51954117, upload-time = "2026-04-21T10:50:29.14Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/f4e9145da0417b3d2c12035a8492b35ff4a3dbc653e614fcfb51d9dedb38/pyarrow-24.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e", size = 28001155, upload-time = "2026-04-21T10:51:22.337Z" }, + { url = "https://files.pythonhosted.org/packages/79/4f/46a49a63f43526da895b1a45bbb51d5baf8e4d77159f8528fc3e5490007f/pyarrow-24.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05", size = 35250387, upload-time = "2026-04-21T10:50:35.552Z" }, + { url = "https://files.pythonhosted.org/packages/a0/da/d5e0cd5ef00796922404806d5f00325cdadc3441ce2c13fe7115f2df9a64/pyarrow-24.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a", size = 36797102, upload-time = "2026-04-21T10:50:42.417Z" }, + { url = "https://files.pythonhosted.org/packages/34/c7/5904145b0a593a05236c882933d439b5720f0a145381179063722fbfc123/pyarrow-24.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072", size = 45745118, upload-time = "2026-04-21T10:50:49.324Z" }, + { url = "https://files.pythonhosted.org/packages/13/d3/cca42fe166d1c6e4d5b80e530b7949104d10e17508a90ae202dac205ce2a/pyarrow-24.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931", size = 48844765, upload-time = "2026-04-21T10:50:55.579Z" }, + { url = "https://files.pythonhosted.org/packages/b0/49/942c3b79878ba928324d1e17c274ed84581db8c0a749b24bcf4cbdf15bd3/pyarrow-24.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699", size = 49471890, upload-time = "2026-04-21T10:51:02.439Z" }, + { url = "https://files.pythonhosted.org/packages/76/97/ff71431000a75d84135a1ace5ca4ba11726a231a8007bbb320a4c54075d5/pyarrow-24.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136", size = 51932250, upload-time = "2026-04-21T10:51:10.576Z" }, + { url = "https://files.pythonhosted.org/packages/51/be/6f79d55816d5c22557cf27533543d5d70dfe692adfbee4b99f2760674f38/pyarrow-24.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19", size = 28131282, upload-time = "2026-04-21T10:51:16.815Z" }, ] [[package]]