This is an automated email from the ASF dual-hosted git repository. majin1102 pushed a commit to branch emr/initialize-network-integration in repository https://gitbox.apache.org/repos/asf/amoro.git
commit f049e009468b03176a1e6c80252cb8725693654f Author: majin.nathan <[email protected]> AuthorDate: Mon Aug 3 17:04:20 2026 +0800 feat: initialize LAS network integration --- amoro-ams/pom.xml | 24 +++ .../amoro/server/las/LasIntegrationConfig.java | 122 +++++++++++++ .../amoro/server/las/LasIntegrationContext.java | 191 +++++++++++++++++++++ .../apache/amoro/server/las/LasRestExtension.java | 123 +++++++++++++ .../org.apache.amoro.server.RestExtensionFactory | 1 + .../server/las/TestLasIntegrationContext.java | 86 ++++++++++ dist/src/main/amoro-bin/conf/config.yaml | 23 +++ .../amoro-bin/conf/plugins/rest-extensions.yaml | 4 + pom.xml | 11 ++ 9 files changed, 585 insertions(+) diff --git a/amoro-ams/pom.xml b/amoro-ams/pom.xml index af6fa6bb6..143d2c06f 100644 --- a/amoro-ams/pom.xml +++ b/amoro-ams/pom.xml @@ -64,6 +64,30 @@ <artifactId>kubernetes-client</artifactId> </dependency> + <!-- LAS/EMR network integrations. Concrete clients are initialized lazily by AMS. --> + <dependency> + <groupId>io.proton</groupId> + <artifactId>proton-hadoop3-bundle</artifactId> + <version>${proton.version}</version> + </dependency> + + <dependency> + <groupId>com.bytedance.las</groupId> + <artifactId>iam</artifactId> + <exclusions> + <exclusion> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>com.volcengine.emr.serverless</groupId> + <artifactId>serverless-sdk-query</artifactId> + <version>${serverless-sdk-query.version}</version> + </dependency> + <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_${scala.binary.version}</artifactId> diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/las/LasIntegrationConfig.java b/amoro-ams/src/main/java/org/apache/amoro/server/las/LasIntegrationConfig.java new file mode 100644 index 000000000..cd119ee09 --- /dev/null +++ b/amoro-ams/src/main/java/org/apache/amoro/server/las/LasIntegrationConfig.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.amoro.server.las; + +import org.apache.amoro.config.ConfigOption; +import org.apache.amoro.config.ConfigOptions; + +import java.time.Duration; + +/** Configuration used to connect AMS to services in the LAS/EMR network. */ +public final class LasIntegrationConfig { + + private static final String PREFIX = "las.integration."; + + public static final ConfigOption<Boolean> ENABLED = + ConfigOptions.key(PREFIX + "enabled") + .booleanType() + .defaultValue(false) + .withDescription("Whether the LAS/EMR integration is enabled."); + + public static final ConfigOption<String> HMS_URI = + ConfigOptions.key(PREFIX + "hms-uri") + .stringType() + .noDefaultValue() + .withDescription("HMS3 Thrift URI used as the metadata source of truth."); + + public static final ConfigOption<String> TOS_ENDPOINT = + ConfigOptions.key(PREFIX + "tos-endpoint") + .stringType() + .noDefaultValue() + .withDescription("TOS endpoint used by Proton file system clients."); + + public static final ConfigOption<String> IAM_ENDPOINT = + ConfigOptions.key(PREFIX + "iam-endpoint") + .stringType() + .noDefaultValue() + .withDescription("IAM endpoint used to obtain short-lived workload credentials."); + + public static final ConfigOption<String> EMR_SERVERLESS_ENDPOINT = + ConfigOptions.key(PREFIX + "emr-serverless-endpoint") + .stringType() + .noDefaultValue() + .withDescription("EMR Serverless endpoint used to submit maintenance executors."); + + public static final ConfigOption<String> EMR_SERVERLESS_SERVICE = + ConfigOptions.key(PREFIX + "emr-serverless-service") + .stringType() + .defaultValue("emr_serverless") + .withDescription("Service name used by the EMR Serverless client."); + + public static final ConfigOption<String> REGION = + ConfigOptions.key(PREFIX + "region") + .stringType() + .defaultValue("cn-beijing") + .withDescription("Cloud region containing the LAS/EMR services."); + + public static final ConfigOption<Duration> CONNECT_TIMEOUT = + ConfigOptions.key(PREFIX + "connect-timeout") + .durationType() + .defaultValue(Duration.ofSeconds(30)) + .withDescription("Connection timeout for LAS/EMR service clients."); + + public static final ConfigOption<Duration> READ_TIMEOUT = + ConfigOptions.key(PREFIX + "read-timeout") + .durationType() + .defaultValue(Duration.ofSeconds(30)) + .withDescription("Socket read timeout for LAS/EMR service clients."); + + public static final ConfigOption<String> OPTIMIZER_JAR_URI = + ConfigOptions.key(PREFIX + "optimizer-jar-uri") + .stringType() + .noDefaultValue() + .withDescription("URI of the optimizer jar submitted to EMR Serverless."); + + public static final ConfigOption<Boolean> CROSS_VPC_ENABLED = + ConfigOptions.key(PREFIX + "cross-vpc.enabled") + .booleanType() + .defaultValue(false) + .withDescription("Whether EMR Serverless cross-VPC access is enabled."); + + public static final ConfigOption<String> CROSS_VPC_ACCOUNT_ID = + ConfigOptions.key(PREFIX + "cross-vpc.account-id") + .stringType() + .noDefaultValue() + .withDescription("Account ID owning the VPC used by EMR Serverless."); + + public static final ConfigOption<String> CROSS_VPC_VPC_ID = + ConfigOptions.key(PREFIX + "cross-vpc.vpc-id") + .stringType() + .noDefaultValue() + .withDescription("VPC ID used by EMR Serverless."); + + public static final ConfigOption<String> CROSS_VPC_SUBNET_IDS = + ConfigOptions.key(PREFIX + "cross-vpc.subnet-ids") + .stringType() + .noDefaultValue() + .withDescription("Comma-separated subnet IDs used by EMR Serverless."); + + public static final ConfigOption<String> CROSS_VPC_SECURITY_GROUP_ID = + ConfigOptions.key(PREFIX + "cross-vpc.security-group-id") + .stringType() + .noDefaultValue() + .withDescription("Security group ID used by EMR Serverless."); + + private LasIntegrationConfig() {} +} diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/las/LasIntegrationContext.java b/amoro-ams/src/main/java/org/apache/amoro/server/las/LasIntegrationContext.java new file mode 100644 index 000000000..ca4c6f76c --- /dev/null +++ b/amoro-ams/src/main/java/org/apache/amoro/server/las/LasIntegrationContext.java @@ -0,0 +1,191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.amoro.server.las; + +import org.apache.amoro.config.ConfigOption; +import org.apache.amoro.config.Configurations; +import org.apache.amoro.hive.CachedHiveClientPool; +import org.apache.amoro.shade.guava32.com.google.common.collect.Maps; +import org.apache.amoro.table.TableMetaStore; +import org.apache.commons.lang3.StringUtils; +import org.apache.hadoop.conf.Configuration; + +import java.net.URI; +import java.net.URISyntaxException; +import java.time.Duration; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** Validated network configuration and client factories shared by future LAS OpenAPI handlers. */ +public final class LasIntegrationContext { + + private static final Set<String> HTTP_SCHEMES = new HashSet<>(Arrays.asList("http", "https")); + private static final Set<String> OPTIMIZER_JAR_SCHEMES = + new HashSet<>(Arrays.asList("tos", "http", "https")); + + private final boolean enabled; + private final URI hmsUri; + private final URI tosEndpoint; + private final URI iamEndpoint; + private final URI emrServerlessEndpoint; + private final URI optimizerJarUri; + private final String region; + private final String emrServerlessService; + private final Duration connectTimeout; + private final Duration readTimeout; + + private LasIntegrationContext(Configurations configurations) { + this.enabled = configurations.getBoolean(LasIntegrationConfig.ENABLED); + this.region = configurations.getString(LasIntegrationConfig.REGION); + this.emrServerlessService = + configurations.getString(LasIntegrationConfig.EMR_SERVERLESS_SERVICE); + this.connectTimeout = configurations.get(LasIntegrationConfig.CONNECT_TIMEOUT); + this.readTimeout = configurations.get(LasIntegrationConfig.READ_TIMEOUT); + + if (!enabled) { + this.hmsUri = null; + this.tosEndpoint = null; + this.iamEndpoint = null; + this.emrServerlessEndpoint = null; + this.optimizerJarUri = null; + return; + } + + this.hmsUri = + requiredUri(configurations, LasIntegrationConfig.HMS_URI, Collections.singleton("thrift")); + this.tosEndpoint = requiredUri(configurations, LasIntegrationConfig.TOS_ENDPOINT, HTTP_SCHEMES); + this.iamEndpoint = requiredUri(configurations, LasIntegrationConfig.IAM_ENDPOINT, HTTP_SCHEMES); + this.emrServerlessEndpoint = + requiredUri(configurations, LasIntegrationConfig.EMR_SERVERLESS_ENDPOINT, HTTP_SCHEMES); + this.optimizerJarUri = + requiredUri(configurations, LasIntegrationConfig.OPTIMIZER_JAR_URI, OPTIMIZER_JAR_SCHEMES); + requiredString(configurations, LasIntegrationConfig.REGION); + requiredString(configurations, LasIntegrationConfig.EMR_SERVERLESS_SERVICE); + positiveDuration(configurations, LasIntegrationConfig.CONNECT_TIMEOUT); + positiveDuration(configurations, LasIntegrationConfig.READ_TIMEOUT); + + if (configurations.getBoolean(LasIntegrationConfig.CROSS_VPC_ENABLED)) { + requiredString(configurations, LasIntegrationConfig.CROSS_VPC_ACCOUNT_ID); + requiredString(configurations, LasIntegrationConfig.CROSS_VPC_VPC_ID); + requiredString(configurations, LasIntegrationConfig.CROSS_VPC_SUBNET_IDS); + requiredString(configurations, LasIntegrationConfig.CROSS_VPC_SECURITY_GROUP_ID); + } + } + + public static LasIntegrationContext initialize(Configurations configurations) { + return new LasIntegrationContext(configurations); + } + + public boolean enabled() { + return enabled; + } + + public CachedHiveClientPool newHmsClientPool() { + ensureEnabled(); + Configuration configuration = new Configuration(); + configuration.set("hive.metastore.uris", hmsUri.toString()); + TableMetaStore metaStore = TableMetaStore.builder().withConfiguration(configuration).build(); + return new CachedHiveClientPool(metaStore, Maps.newHashMap()); + } + + public Configuration newTosConfiguration() { + ensureEnabled(); + Configuration configuration = new Configuration(false); + configuration.set("fs.AbstractFileSystem.tos.impl", "io.proton.fs.ProtonFS"); + configuration.set("fs.tos.impl", "io.proton.fs.ProtonFileSystem"); + configuration.set("fs.tos.endpoint", tosEndpoint.toString()); + return configuration; + } + + public URI hmsUri() { + ensureEnabled(); + return hmsUri; + } + + public URI iamEndpoint() { + ensureEnabled(); + return iamEndpoint; + } + + public URI emrServerlessEndpoint() { + ensureEnabled(); + return emrServerlessEndpoint; + } + + public URI optimizerJarUri() { + ensureEnabled(); + return optimizerJarUri; + } + + public String region() { + return region; + } + + public String emrServerlessService() { + return emrServerlessService; + } + + public Duration connectTimeout() { + return connectTimeout; + } + + public Duration readTimeout() { + return readTimeout; + } + + private void ensureEnabled() { + if (!enabled) { + throw new IllegalStateException("LAS/EMR integration is disabled"); + } + } + + private static URI requiredUri( + Configurations configurations, ConfigOption<String> option, Set<String> allowedSchemes) { + String value = requiredString(configurations, option); + try { + URI uri = new URI(value); + if (!allowedSchemes.contains(uri.getScheme()) || StringUtils.isBlank(uri.getHost())) { + throw new IllegalArgumentException( + String.format("%s must contain a supported scheme and host: %s", option.key(), value)); + } + return uri; + } catch (URISyntaxException e) { + throw new IllegalArgumentException(option.key() + " is not a valid URI: " + value, e); + } + } + + private static String requiredString(Configurations configurations, ConfigOption<String> option) { + String value = configurations.getString(option); + if (StringUtils.isBlank(value)) { + throw new IllegalArgumentException(option.key() + " must be configured"); + } + return value; + } + + private static Duration positiveDuration( + Configurations configurations, ConfigOption<Duration> option) { + Duration value = configurations.get(option); + if (value == null || value.isZero() || value.isNegative()) { + throw new IllegalArgumentException(option.key() + " must be greater than zero"); + } + return value; + } +} diff --git a/amoro-ams/src/main/java/org/apache/amoro/server/las/LasRestExtension.java b/amoro-ams/src/main/java/org/apache/amoro/server/las/LasRestExtension.java new file mode 100644 index 000000000..29676349f --- /dev/null +++ b/amoro-ams/src/main/java/org/apache/amoro/server/las/LasRestExtension.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.amoro.server.las; + +import io.javalin.apibuilder.EndpointGroup; +import io.javalin.http.Context; +import org.apache.amoro.config.Configurations; +import org.apache.amoro.server.RestExtension; +import org.apache.amoro.server.RestExtensionFactory; +import org.apache.amoro.server.catalog.CatalogManager; +import org.apache.amoro.server.table.TableManager; +import org.apache.amoro.shade.guava32.com.google.common.base.Preconditions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; + +/** Bootstrap extension for LAS/EMR network integration. */ +public class LasRestExtension implements RestExtension { + + private static final Logger LOG = LoggerFactory.getLogger(LasRestExtension.class); + + private final LasIntegrationContext integrationContext; + private final CatalogManager catalogManager; + private final TableManager tableManager; + + LasRestExtension( + LasIntegrationContext integrationContext, + CatalogManager catalogManager, + TableManager tableManager) { + this.integrationContext = integrationContext; + this.catalogManager = catalogManager; + this.tableManager = tableManager; + LOG.info("LAS/EMR integration initialized, enabled={}", integrationContext.enabled()); + } + + @Override + public EndpointGroup endpoints() { + return () -> { + // Intentionally empty. Add management-plane routes here under /api/ams/v1/las when the + // OpenAPI contract is ready. Controllers should receive integrationContext, catalogManager, + // and tableManager from this extension instead of constructing HMS, TOS, IAM, or EMR clients + // themselves. Routes registered here automatically pass through the existing AMS REST + // authentication filter; do not add management-plane routes to the URL whitelist. + }; + } + + @Override + public boolean needHandleException(Context ctx) { + return false; + } + + @Override + public void handleException(Exception e, Context ctx) { + throw new UnsupportedOperationException("LAS REST extension does not expose endpoints yet", e); + } + + /** Factory loaded by the AMS REST extension plugin manager. */ + public static class Factory implements RestExtensionFactory { + + private Configurations serviceConfig; + private CatalogManager catalogManager; + private TableManager tableManager; + + @Override + public RestExtensionFactory withServiceConfig(Configurations serviceConfig) { + this.serviceConfig = serviceConfig; + return this; + } + + @Override + public RestExtensionFactory withCatalogManager(CatalogManager catalogManager) { + this.catalogManager = catalogManager; + return this; + } + + @Override + public RestExtensionFactory withTableManager(TableManager tableManager) { + this.tableManager = tableManager; + return this; + } + + @Override + public RestExtension build() { + Preconditions.checkNotNull(serviceConfig, "serviceConfig is required"); + Preconditions.checkNotNull(catalogManager, "catalogManager is required"); + Preconditions.checkNotNull(tableManager, "tableManager is required"); + return new LasRestExtension( + LasIntegrationContext.initialize(serviceConfig), catalogManager, tableManager); + } + + @Override + public void open(Map<String, String> properties) { + LOG.info("Opening LAS/EMR integration extension"); + } + + @Override + public void close() { + LOG.info("Closing LAS/EMR integration extension"); + } + + @Override + public String name() { + return "las-integration"; + } + } +} diff --git a/amoro-ams/src/main/resources/META-INF/services/org.apache.amoro.server.RestExtensionFactory b/amoro-ams/src/main/resources/META-INF/services/org.apache.amoro.server.RestExtensionFactory index a0b5cf404..a3f310817 100644 --- a/amoro-ams/src/main/resources/META-INF/services/org.apache.amoro.server.RestExtensionFactory +++ b/amoro-ams/src/main/resources/META-INF/services/org.apache.amoro.server.RestExtensionFactory @@ -17,3 +17,4 @@ # org.apache.amoro.server.RestCatalogService$RestCatalogServiceFactory +org.apache.amoro.server.las.LasRestExtension$Factory diff --git a/amoro-ams/src/test/java/org/apache/amoro/server/las/TestLasIntegrationContext.java b/amoro-ams/src/test/java/org/apache/amoro/server/las/TestLasIntegrationContext.java new file mode 100644 index 000000000..fef97b5e8 --- /dev/null +++ b/amoro-ams/src/test/java/org/apache/amoro/server/las/TestLasIntegrationContext.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.amoro.server.las; + +import org.apache.amoro.config.Configurations; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +public class TestLasIntegrationContext { + + @Test + public void testDisabledByDefault() { + LasIntegrationContext context = LasIntegrationContext.initialize(new Configurations()); + + Assertions.assertFalse(context.enabled()); + Assertions.assertThrows(IllegalStateException.class, context::newHmsClientPool); + } + + @Test + public void testInitializeKubernetesServiceEndpoints() { + LasIntegrationContext context = LasIntegrationContext.initialize(validConfigurations()); + + Assertions.assertTrue(context.enabled()); + Assertions.assertEquals("thrift://hms-service:9083", context.hmsUri().toString()); + Assertions.assertEquals("https://iam.volcengineapi.com", context.iamEndpoint().toString()); + Assertions.assertEquals("https://emr-serverless", context.emrServerlessEndpoint().toString()); + Assertions.assertEquals("cn-beijing", context.region()); + Assertions.assertNotNull(context.newHmsClientPool()); + Assertions.assertEquals( + "https://tos-cn-beijing.volces.com", context.newTosConfiguration().get("fs.tos.endpoint")); + } + + @Test + public void testRejectMissingRequiredEndpoint() { + Configurations configurations = validConfigurations(); + configurations.setString(LasIntegrationConfig.HMS_URI, ""); + + IllegalArgumentException exception = + Assertions.assertThrows( + IllegalArgumentException.class, () -> LasIntegrationContext.initialize(configurations)); + Assertions.assertTrue(exception.getMessage().contains(LasIntegrationConfig.HMS_URI.key())); + } + + @Test + public void testCrossVpcConfigurationIsAtomic() { + Configurations configurations = validConfigurations(); + configurations.setBoolean(LasIntegrationConfig.CROSS_VPC_ENABLED, true); + + IllegalArgumentException exception = + Assertions.assertThrows( + IllegalArgumentException.class, () -> LasIntegrationContext.initialize(configurations)); + Assertions.assertTrue( + exception.getMessage().contains(LasIntegrationConfig.CROSS_VPC_ACCOUNT_ID.key())); + } + + private static Configurations validConfigurations() { + Map<String, String> values = new HashMap<>(); + values.put(LasIntegrationConfig.ENABLED.key(), "true"); + values.put(LasIntegrationConfig.HMS_URI.key(), "thrift://hms-service:9083"); + values.put(LasIntegrationConfig.TOS_ENDPOINT.key(), "https://tos-cn-beijing.volces.com"); + values.put(LasIntegrationConfig.IAM_ENDPOINT.key(), "https://iam.volcengineapi.com"); + values.put(LasIntegrationConfig.EMR_SERVERLESS_ENDPOINT.key(), "https://emr-serverless"); + values.put( + LasIntegrationConfig.OPTIMIZER_JAR_URI.key(), "tos://amoro-artifacts/amoro-optimizer.jar"); + return Configurations.fromMap(values); + } +} diff --git a/dist/src/main/amoro-bin/conf/config.yaml b/dist/src/main/amoro-bin/conf/config.yaml index f4cdaaac8..d505e3823 100644 --- a/dist/src/main/amoro-bin/conf/config.yaml +++ b/dist/src/main/amoro-bin/conf/config.yaml @@ -71,6 +71,29 @@ ams: # set default-role: VIEWER only when you intentionally want authenticated # users without a matched role mapping to receive read-only access. + # LAS/EMR integration bootstrap. The disabled default keeps existing deployments unchanged. + # Values may also be supplied through environment variables, for example: + # AMS_LAS_INTEGRATION_ENABLED=true + # AMS_LAS_INTEGRATION_HMS__URI=thrift://hms-service.<namespace>.svc.cluster.local:9083 + las: + integration: + enabled: false + # hms-uri: thrift://hms-service.<namespace>.svc.cluster.local:9083 + # tos-endpoint: https://tos-cn-beijing.volces.com + # iam-endpoint: https://iam.volcengineapi.com + # emr-serverless-endpoint: https://open.volcengineapi.com + # optimizer-jar-uri: tos://<bucket>/<path>/amoro-optimizer.jar + region: cn-beijing + emr-serverless-service: emr_serverless + connect-timeout: 30s + read-timeout: 30s + cross-vpc: + enabled: false + # account-id: <account-id> + # vpc-id: <vpc-id> + # subnet-ids: <subnet-id-1>,<subnet-id-2> + # security-group-id: <security-group-id> + refresh-external-catalogs: interval: 3min # 180000 thread-count: 10 diff --git a/dist/src/main/amoro-bin/conf/plugins/rest-extensions.yaml b/dist/src/main/amoro-bin/conf/plugins/rest-extensions.yaml index ff2729d81..1ceca25d0 100644 --- a/dist/src/main/amoro-bin/conf/plugins/rest-extensions.yaml +++ b/dist/src/main/amoro-bin/conf/plugins/rest-extensions.yaml @@ -20,3 +20,7 @@ rest-extensions: - name: iceberg-rest-catalog enabled: true + - name: las-integration + # This extension initializes the LAS/EMR integration context only. It intentionally exposes no + # HTTP endpoints until the management-plane API contract is implemented. + enabled: true diff --git a/pom.xml b/pom.xml index 40cc34ecb..edba971c8 100644 --- a/pom.xml +++ b/pom.xml @@ -168,6 +168,9 @@ <jcasbin.version>1.99.0</jcasbin.version> <fasterxml.jackson.version>2.14.2</fasterxml.jackson.version> <arrow.version>18.3.0</arrow.version> + <las-dependency.version>catalog-1.0.23-SNAPSHOT</las-dependency.version> + <proton.version>2.3.5</proton.version> + <serverless-sdk-query.version>1.0.2</serverless-sdk-query.version> <apache-directory-server.version>2.0.0-M15</apache-directory-server.version> <apache-directory-api-all.version>1.0.0-M20</apache-directory-api-all.version> <rocksdb-dependency-scope>compile</rocksdb-dependency-scope> @@ -1327,6 +1330,14 @@ <type>pom</type> <scope>import</scope> </dependency> + + <dependency> + <groupId>com.bytedance.las</groupId> + <artifactId>las-bom</artifactId> + <version>${las-dependency.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> </dependencies> </dependencyManagement>
