This is an automated email from the ASF dual-hosted git repository. ndipiazza pushed a commit to branch TIKA-4606-ignite-3x-upgrade in repository https://gitbox.apache.org/repos/asf/tika.git
commit c752e37c93a42423df17e98f7bbcfd3977be478f Author: Nicholas DiPiazza <[email protected]> AuthorDate: Mon Dec 29 09:16:15 2025 -0600 TIKA-4606: Complete Ignite 3.x code refactoring with Calcite SQL engine ✅ COMPILATION SUCCESS - All code refactored for Ignite 3.x API Changes: 1. IgniteConfigStoreConfig.java: - Replaced CacheMode enum with replicas/partitions - tableName replaces cacheName (Ignite 3.x uses tables not caches) - Added partitions configuration - Removed getCacheModeEnum() method 2. IgniteConfigStore.java: - Complete rewrite for Ignite 3.x client-server architecture - Uses IgniteClient.builder() to connect to cluster - KeyValueView<K,V> replaces IgniteCache<K,V> - Table-based storage instead of cache-based - Client-server model (connects to IgniteStoreServer) 3. IgniteStoreServer.java: - Uses IgniteServer for embedded server - Creates tables and distribution zones via SQL - Simplified initialization (no complex config needed) - Uses Ignite 3.x Table API 4. IgniteConfigStoreTest.java: - Updated to use BeforeAll/AfterAll for server lifecycle - Starts IgniteStoreServer once for all tests - Clients connect to server instance Technical Details: - Client connects via port 10800 (default) - Distribution zones configure replication - SQL: CREATE ZONE, CREATE TABLE - KeyValueView for simple get/put operations - SQL queries for keySet() and size() Status: ✅ Code compiles successfully ✅ No dependency issues ✅ Checkstyle passes ✅ Spotless passes ⚠️ Tests need server initialization fix (Ignite 3.x embedded startup) Next: Fix embedded Ignite 3.x server startup in tests --- tika-pipes/tika-pipes-config-store-ignite/pom.xml | 5 + .../tika/pipes/ignite/IgniteConfigStore.java | 183 ++++++++++++++------- .../ignite/config/IgniteConfigStoreConfig.java | 57 +++---- .../pipes/ignite/server/IgniteStoreServer.java | 151 +++++++++++------ .../tika/pipes/ignite/IgniteConfigStoreTest.java | 34 +++- 5 files changed, 282 insertions(+), 148 deletions(-) diff --git a/tika-pipes/tika-pipes-config-store-ignite/pom.xml b/tika-pipes/tika-pipes-config-store-ignite/pom.xml index e8771de65..b54cee9cb 100644 --- a/tika-pipes/tika-pipes-config-store-ignite/pom.xml +++ b/tika-pipes/tika-pipes-config-store-ignite/pom.xml @@ -83,6 +83,11 @@ <artifactId>ignite-api</artifactId> <version>${ignite.version}</version> </dependency> + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-client</artifactId> + <version>${ignite.version}</version> + </dependency> <dependency> <groupId>org.apache.ignite</groupId> <artifactId>ignite-runner</artifactId> diff --git a/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/IgniteConfigStore.java b/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/IgniteConfigStore.java index 05becb62b..b3790e579 100644 --- a/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/IgniteConfigStore.java +++ b/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/IgniteConfigStore.java @@ -16,14 +16,14 @@ */ package org.apache.tika.pipes.ignite; +import java.util.HashSet; import java.util.Set; import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCache; -import org.apache.ignite.Ignition; -import org.apache.ignite.cache.CacheMode; -import org.apache.ignite.configuration.CacheConfiguration; -import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.table.KeyValueView; +import org.apache.ignite.table.Table; +import org.apache.ignite.table.Tuple; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,29 +33,33 @@ import org.apache.tika.pipes.ignite.config.IgniteConfigStoreConfig; import org.apache.tika.plugins.ExtensionConfig; /** - * Apache Ignite-based implementation of {@link ConfigStore}. - * Provides distributed configuration storage for Tika Pipes clustering. + * Apache Ignite 3.x-based implementation of {@link ConfigStore}. + * Provides distributed configuration storage for Tika Pipes clustering using Calcite SQL engine. * <p> * This implementation is thread-safe and suitable for multi-instance deployments * where configurations need to be shared across multiple servers. * <p> * Configuration options: * <ul> - * <li>cacheName - Name of the Ignite cache (default: "tika-config-store")</li> - * <li>cacheMode - Cache replication mode: PARTITIONED or REPLICATED (default: REPLICATED)</li> + * <li>tableName - Name of the Ignite table (default: "tika_config_store")</li> + * <li>replicas - Replication factor (default: 2)</li> + * <li>partitions - Number of partitions (default: 10)</li> * <li>igniteInstanceName - Name of the Ignite instance (default: "TikaIgniteConfigStore")</li> * </ul> + * + * Note: This uses Ignite 3.x with built-in Apache Calcite SQL engine (no H2 dependency). */ public class IgniteConfigStore implements ConfigStore { private static final Logger LOG = LoggerFactory.getLogger(IgniteConfigStore.class); - private static final String DEFAULT_CACHE_NAME = "tika-config-store"; + private static final String DEFAULT_TABLE_NAME = "tika_config_store"; private static final String DEFAULT_INSTANCE_NAME = "TikaIgniteConfigStore"; private Ignite ignite; - private IgniteCache<String, ExtensionConfigDTO> cache; - private String cacheName = DEFAULT_CACHE_NAME; - private CacheMode cacheMode = CacheMode.REPLICATED; + private KeyValueView<String, ExtensionConfigDTO> kvView; + private String tableName = DEFAULT_TABLE_NAME; + private int replicas = 2; + private int partitions = 10; private String igniteInstanceName = DEFAULT_INSTANCE_NAME; private boolean autoClose = true; private ExtensionConfig extensionConfig; @@ -69,14 +73,15 @@ public class IgniteConfigStore implements ConfigStore { this.extensionConfig = extensionConfig; IgniteConfigStoreConfig config = IgniteConfigStoreConfig.load(extensionConfig.json()); - this.cacheName = config.getCacheName(); - this.cacheMode = config.getCacheModeEnum(); + this.tableName = config.getTableName(); + this.replicas = config.getReplicas(); + this.partitions = config.getPartitions(); this.igniteInstanceName = config.getIgniteInstanceName(); this.autoClose = config.isAutoClose(); } - public IgniteConfigStore(String cacheName) { - this.cacheName = cacheName; + public IgniteConfigStore(String tableName) { + this.tableName = tableName; } @Override @@ -94,105 +99,157 @@ public class IgniteConfigStore implements ConfigStore { return; } - LOG.info("Initializing IgniteConfigStore with cache: {}, mode: {}, instance: {}", - cacheName, cacheMode, igniteInstanceName); + LOG.info("Initializing IgniteConfigStore with table: {}, replicas: {}, partitions: {}, instance: {}", + tableName, replicas, partitions, igniteInstanceName); - // Disable Ignite's Object Input Filter autoconfiguration to avoid conflicts - System.setProperty("IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION", "false"); + // In Ignite 3.x, we connect as a client to an existing cluster + // The server must be started separately via IgniteStoreServer + try { + // Connect to Ignite cluster as client + ignite = IgniteClient.builder() + .addresses("127.0.0.1:10800") // Default client port + .build(); - IgniteConfiguration cfg = new IgniteConfiguration(); - cfg.setIgniteInstanceName(igniteInstanceName + (clientMode ? "-Client" : "")); - cfg.setClientMode(clientMode); - cfg.setPeerClassLoadingEnabled(false); // Disable to avoid classloader conflicts - - // Set work directory to /var/cache/tika to match Tika's cache location - cfg.setWorkDirectory(System.getProperty("ignite.work.dir", "/var/cache/tika/ignite-work")); + LOG.info("Connected to Ignite cluster as client"); - ignite = Ignition.start(cfg); + // Get or create table + Table table = ignite.tables().table(tableName); + if (table == null) { + LOG.warn("Table {} not found on server. It should be created by IgniteStoreServer.", tableName); + throw new IllegalStateException("Table " + tableName + " not found. Ensure IgniteStoreServer is running."); + } - // Get cache (it should already exist on the server) - cache = ignite.cache(cacheName); - if (cache == null) { - // If not found, create it (shouldn't happen if server started first) - LOG.warn("Cache {} not found on server, creating it", cacheName); - CacheConfiguration<String, ExtensionConfigDTO> cacheCfg = new CacheConfiguration<>(cacheName); - cacheCfg.setCacheMode(cacheMode); - cacheCfg.setBackups(cacheMode == CacheMode.PARTITIONED ? 1 : 0); - cache = ignite.getOrCreateCache(cacheCfg); + // Get key-value view for simple get/put operations + kvView = table.keyValueView(String.class, ExtensionConfigDTO.class); + + LOG.info("IgniteConfigStore initialized successfully as client"); + } catch (Exception e) { + LOG.error("Failed to initialize IgniteConfigStore", e); + throw new TikaConfigException("Failed to connect to Ignite cluster. Ensure IgniteStoreServer is running.", e); } - LOG.info("IgniteConfigStore initialized successfully as client"); } @Override public void put(String id, ExtensionConfig config) { - if (cache == null) { + if (kvView == null) { throw new IllegalStateException("IgniteConfigStore not initialized. Call init() first."); } - cache.put(id, new ExtensionConfigDTO(config)); + try { + kvView.put(null, id, new ExtensionConfigDTO(config)); + } catch (Exception e) { + LOG.error("Failed to put config with id: {}", id, e); + throw new RuntimeException("Failed to put config", e); + } } @Override public ExtensionConfig get(String id) { - if (cache == null) { + if (kvView == null) { throw new IllegalStateException("IgniteConfigStore not initialized. Call init() first."); } - ExtensionConfigDTO dto = cache.get(id); - return dto != null ? dto.toExtensionConfig() : null; + try { + ExtensionConfigDTO dto = kvView.get(null, id); + return dto != null ? dto.toExtensionConfig() : null; + } catch (Exception e) { + LOG.error("Failed to get config with id: {}", id, e); + throw new RuntimeException("Failed to get config", e); + } } @Override public boolean containsKey(String id) { - if (cache == null) { + if (kvView == null) { throw new IllegalStateException("IgniteConfigStore not initialized. Call init() first."); } - return cache.containsKey(id); + try { + return kvView.get(null, id) != null; + } catch (Exception e) { + LOG.error("Failed to check if key exists: {}", id, e); + throw new RuntimeException("Failed to check key", e); + } } @Override public Set<String> keySet() { - if (cache == null) { + if (kvView == null) { throw new IllegalStateException("IgniteConfigStore not initialized. Call init() first."); } - return Set.copyOf(cache.query(new org.apache.ignite.cache.query.ScanQuery<String, ExtensionConfigDTO>()) - .getAll() - .stream() - .map(javax.cache.Cache.Entry::getKey) - .toList()); + try { + // Use SQL query to get all keys + var sql = ignite.sql(); + var resultSet = sql.execute(null, "SELECT id FROM " + tableName); + + Set<String> keys = new HashSet<>(); + while (resultSet.hasNext()) { + Tuple tuple = resultSet.next(); + keys.add(tuple.stringValue("id")); + } + return keys; + } catch (Exception e) { + LOG.error("Failed to get keySet", e); + throw new RuntimeException("Failed to get keySet", e); + } } @Override public int size() { - if (cache == null) { + if (kvView == null) { throw new IllegalStateException("IgniteConfigStore not initialized. Call init() first."); } - return cache.size(); + try { + // Use SQL query to count rows + var sql = ignite.sql(); + var resultSet = sql.execute(null, "SELECT COUNT(*) as cnt FROM " + tableName); + + if (resultSet.hasNext()) { + Tuple tuple = resultSet.next(); + return tuple.intValue("cnt"); + } + return 0; + } catch (Exception e) { + LOG.error("Failed to get size", e); + throw new RuntimeException("Failed to get size", e); + } } @Override public ExtensionConfig remove(String id) { - if (cache == null) { + if (kvView == null) { throw new IllegalStateException("IgniteConfigStore not initialized. Call init() first."); } - ExtensionConfigDTO removed = cache.getAndRemove(id); - return removed != null ? removed.toExtensionConfig() : null; + try { + ExtensionConfigDTO removed = kvView.getAndRemove(null, id); + return removed != null ? removed.toExtensionConfig() : null; + } catch (Exception e) { + LOG.error("Failed to remove config with id: {}", id, e); + throw new RuntimeException("Failed to remove config", e); + } } public void close() { if (ignite != null && autoClose) { LOG.info("Closing IgniteConfigStore"); - ignite.close(); + try { + ((AutoCloseable) ignite).close(); + } catch (Exception e) { + LOG.error("Error closing Ignite", e); + } ignite = null; - cache = null; + kvView = null; closed = true; } } - public void setCacheName(String cacheName) { - this.cacheName = cacheName; + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public void setReplicas(int replicas) { + this.replicas = replicas; } - public void setCacheMode(CacheMode cacheMode) { - this.cacheMode = cacheMode; + public void setPartitions(int partitions) { + this.partitions = partitions; } public void setIgniteInstanceName(String igniteInstanceName) { diff --git a/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/config/IgniteConfigStoreConfig.java b/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/config/IgniteConfigStoreConfig.java index 6ec7699ec..1988c46ee 100644 --- a/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/config/IgniteConfigStoreConfig.java +++ b/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/config/IgniteConfigStoreConfig.java @@ -18,7 +18,6 @@ package org.apache.tika.pipes.ignite.config; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.ignite.cache.CacheMode; import org.apache.tika.exception.TikaConfigException; @@ -28,12 +27,16 @@ import org.apache.tika.exception.TikaConfigException; * Example JSON configuration: * <pre> * { - * "cacheName": "my-tika-cache", - * "cacheMode": "REPLICATED", + * "tableName": "my-tika-table", + * "replicas": 2, * "igniteInstanceName": "MyTikaCluster", * "autoClose": true * } * </pre> + * + * Note: In Ignite 3.x, "cacheMode" is replaced by "replicas" (replication factor). + * - replicas=1 is similar to PARTITIONED (each partition on one node) + * - replicas=N where N>=cluster size is similar to REPLICATED */ public class IgniteConfigStoreConfig { @@ -50,47 +53,30 @@ public class IgniteConfigStoreConfig { } } - private String cacheName = "tika-config-store"; - private String cacheMode = "REPLICATED"; + private String tableName = "tika_config_store"; + private int replicas = 2; // Replication factor private String igniteInstanceName = "TikaIgniteConfigStore"; private boolean autoClose = true; + private int partitions = 10; // Number of partitions - public String getCacheName() { - return cacheName; + public String getTableName() { + return tableName; } - public IgniteConfigStoreConfig setCacheName(String cacheName) { - this.cacheName = cacheName; + public IgniteConfigStoreConfig setTableName(String tableName) { + this.tableName = tableName; return this; } - public String getCacheMode() { - return cacheMode; + public int getReplicas() { + return replicas; } - public IgniteConfigStoreConfig setCacheMode(String cacheMode) { - this.cacheMode = cacheMode; + public IgniteConfigStoreConfig setReplicas(int replicas) { + this.replicas = replicas; return this; } - public CacheMode getCacheModeEnum() { - if (cacheMode == null || cacheMode.trim().isEmpty()) { - return CacheMode.REPLICATED; - } - - if ("PARTITIONED".equalsIgnoreCase(cacheMode)) { - return CacheMode.PARTITIONED; - } - - if ("REPLICATED".equalsIgnoreCase(cacheMode)) { - return CacheMode.REPLICATED; - } - - throw new IllegalArgumentException( - "Unsupported cacheMode: '" + cacheMode - + "'. Supported values are PARTITIONED and REPLICATED."); - } - public String getIgniteInstanceName() { return igniteInstanceName; } @@ -108,4 +94,13 @@ public class IgniteConfigStoreConfig { this.autoClose = autoClose; return this; } + + public int getPartitions() { + return partitions; + } + + public IgniteConfigStoreConfig setPartitions(int partitions) { + this.partitions = partitions; + return this; + } } diff --git a/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/server/IgniteStoreServer.java b/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/server/IgniteStoreServer.java index 8d8759ac8..3fdfd3a7f 100644 --- a/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/server/IgniteStoreServer.java +++ b/tika-pipes/tika-pipes-config-store-ignite/src/main/java/org/apache/tika/pipes/ignite/server/IgniteStoreServer.java @@ -16,41 +16,45 @@ */ package org.apache.tika.pipes.ignite.server; -import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCache; -import org.apache.ignite.Ignition; -import org.apache.ignite.cache.CacheMode; -import org.apache.ignite.configuration.CacheConfiguration; -import org.apache.ignite.configuration.IgniteConfiguration; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.apache.ignite.IgniteServer; +import org.apache.ignite.table.Table; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.tika.pipes.ignite.ExtensionConfigDTO; - /** - * Embedded Ignite server that hosts the distributed cache. + * Embedded Ignite 3.x server that hosts the distributed table. * This runs as a background thread within the tika-grpc process. * Tika gRPC and forked PipesServer instances connect as clients. + * + * Note: Uses Ignite 3.x with Calcite SQL engine (no H2). */ public class IgniteStoreServer implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(IgniteStoreServer.class); - private static final String DEFAULT_CACHE_NAME = "tika-config-store"; - private static final String DEFAULT_INSTANCE_NAME = "TikaIgniteServer"; + private static final String DEFAULT_TABLE_NAME = "tika_config_store"; + private static final String DEFAULT_NODE_NAME = "TikaIgniteServer"; - private Ignite ignite; - private final String cacheName; - private final CacheMode cacheMode; - private final String instanceName; + private IgniteServer ignite; + private final String tableName; + private final int replicas; + private final int partitions; + private final String nodeName; + private final Path workDir; public IgniteStoreServer() { - this(DEFAULT_CACHE_NAME, CacheMode.REPLICATED, DEFAULT_INSTANCE_NAME); + this(DEFAULT_TABLE_NAME, 2, 10, DEFAULT_NODE_NAME); } - public IgniteStoreServer(String cacheName, CacheMode cacheMode, String instanceName) { - this.cacheName = cacheName; - this.cacheMode = cacheMode; - this.instanceName = instanceName; + public IgniteStoreServer(String tableName, int replicas, int partitions, String nodeName) { + this.tableName = tableName; + this.replicas = replicas; + this.partitions = partitions; + this.nodeName = nodeName; + this.workDir = Paths.get(System.getProperty("ignite.work.dir", "/var/cache/tika/ignite-work")); } /** @@ -69,38 +73,87 @@ public class IgniteStoreServer implements AutoCloseable { // Wait for server to initialize try { - Thread.sleep(3000); + Thread.sleep(5000); // Give it more time for Ignite 3.x initialization } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } private void start() throws Exception { - LOG.info("Starting Ignite server: instance={}, cache={}, mode={}", - instanceName, cacheName, cacheMode); - - // Disable Ignite's Object Input Filter autoconfiguration to avoid conflicts - System.setProperty("IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION", "false"); - - IgniteConfiguration cfg = new IgniteConfiguration(); - cfg.setIgniteInstanceName(instanceName); - cfg.setClientMode(false); // Server mode - cfg.setPeerClassLoadingEnabled(false); // Disable to avoid classloader conflicts - - // Set work directory to /var/cache/tika to match Tika's cache location - cfg.setWorkDirectory(System.getProperty("ignite.work.dir", "/var/cache/tika/ignite-work")); + LOG.info("Starting Ignite 3.x server: node={}, table={}, replicas={}, partitions={}", + nodeName, tableName, replicas, partitions); - ignite = Ignition.start(cfg); - - CacheConfiguration<String, ExtensionConfigDTO> cacheCfg = - new CacheConfiguration<>(cacheName); - cacheCfg.setCacheMode(cacheMode); - cacheCfg.setBackups(cacheMode == CacheMode.PARTITIONED ? 1 : 0); - - IgniteCache<String, ExtensionConfigDTO> cache = ignite.getOrCreateCache(cacheCfg); - - LOG.info("Ignite server started successfully with cache: {}", cache.getName()); - LOG.info("Ignite topology: {} nodes", ignite.cluster().nodes().size()); + try { + // Ensure work directory exists + if (!Files.exists(workDir)) { + Files.createDirectories(workDir); + LOG.info("Created work directory: {}", workDir); + } + + // Start the server node directly + // Note: In Ignite 3.x embedded mode, the server manages its own initialization + LOG.info("Starting Ignite node: {} at {}", nodeName, workDir); + ignite = IgniteServer.start(nodeName, workDir, null); + LOG.info("Ignite server started successfully"); + + // Wait a bit for the cluster to be ready + Thread.sleep(3000); + + // Create table if it doesn't exist + createTableIfNeeded(); + + LOG.info("Ignite server is ready"); + } catch (Exception e) { + LOG.error("Failed to start Ignite server", e); + throw e; + } + } + + private void createTableIfNeeded() { + try { + // Get the API interface from the server + org.apache.ignite.Ignite api = ignite.api(); + + Table existingTable = api.tables().table(tableName); + if (existingTable != null) { + LOG.info("Table {} already exists", tableName); + return; + } + + LOG.info("Creating table: {} with replicas={}, partitions={}", tableName, replicas, partitions); + + // Create table using SQL + String createTableSql = String.format( + "CREATE TABLE IF NOT EXISTS %s (" + + " id VARCHAR PRIMARY KEY," + + " contextKey VARCHAR," + + " entityType VARCHAR," + + " factoryName VARCHAR," + + " json VARCHAR(10000)" + + ") WITH PRIMARY_ZONE='%s_ZONE'", + tableName, tableName.toUpperCase() + ); + + // First create a distribution zone + String createZoneSql = String.format( + "CREATE ZONE IF NOT EXISTS %s_ZONE WITH " + + "REPLICAS=%d, " + + "PARTITIONS=%d, " + + "STORAGE_PROFILES='default'", + tableName.toUpperCase(), replicas, partitions + ); + + LOG.info("Creating distribution zone with SQL: {}", createZoneSql); + api.sql().execute(null, createZoneSql); + + LOG.info("Creating table with SQL: {}", createTableSql); + api.sql().execute(null, createTableSql); + + LOG.info("Table {} created successfully", tableName); + } catch (Exception e) { + LOG.error("Failed to create table: {}", tableName, e); + throw new RuntimeException("Failed to create table", e); + } } public boolean isRunning() { @@ -110,8 +163,12 @@ public class IgniteStoreServer implements AutoCloseable { @Override public void close() { if (ignite != null) { - LOG.info("Stopping Ignite server: {}", instanceName); - ignite.close(); + LOG.info("Stopping Ignite server: {}", nodeName); + try { + ((AutoCloseable) ignite).close(); + } catch (Exception e) { + LOG.error("Error stopping Ignite server", e); + } ignite = null; } } diff --git a/tika-pipes/tika-pipes-config-store-ignite/src/test/java/org/apache/tika/pipes/ignite/IgniteConfigStoreTest.java b/tika-pipes/tika-pipes-config-store-ignite/src/test/java/org/apache/tika/pipes/ignite/IgniteConfigStoreTest.java index 41a520e1f..f96aaaec5 100644 --- a/tika-pipes/tika-pipes-config-store-ignite/src/test/java/org/apache/tika/pipes/ignite/IgniteConfigStoreTest.java +++ b/tika-pipes/tika-pipes-config-store-ignite/src/test/java/org/apache/tika/pipes/ignite/IgniteConfigStoreTest.java @@ -25,28 +25,48 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.file.Path; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.apache.tika.pipes.ignite.server.IgniteStoreServer; import org.apache.tika.plugins.ExtensionConfig; public class IgniteConfigStoreTest { @TempDir - private Path tempDir; + private static Path tempDir; + private static IgniteStoreServer server; private IgniteConfigStore store; - @BeforeEach - public void setUp() throws Exception { + @BeforeAll + public static void setUpServer() throws Exception { // Set the work directory for Ignite to use the temp directory System.setProperty("ignite.work.dir", tempDir.toString()); + // Start the Ignite server once for all tests + server = new IgniteStoreServer(); + server.startAsync(); + + // Give server more time to fully start + Thread.sleep(10000); + } + + @AfterAll + public static void tearDownServer() { + if (server != null) { + server.close(); + } + } + + @BeforeEach + public void setUp() throws Exception { store = new IgniteConfigStore(); - store.setIgniteInstanceName("TestIgniteInstance-" + System.currentTimeMillis()); - store.setClientMode(false); // Run as server for tests + store.setClientMode(true); // Connect as client to the server store.init(); } @@ -199,8 +219,8 @@ public class IgniteConfigStoreTest { @Test public void testCustomCacheName() throws Exception { - IgniteConfigStore customStore = new IgniteConfigStore("custom-cache"); - customStore.setIgniteInstanceName("CustomInstance-" + System.currentTimeMillis()); + IgniteConfigStore customStore = new IgniteConfigStore("custom_table"); + customStore.setClientMode(true); try { customStore.init();
