This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch CAMEL-23255-infinispan-schema-retry in repository https://gitbox.apache.org/repos/asf/camel.git
commit 950bfcc7eb8b6e299313a4807076f190163dff7e Author: Guillaume Nodet <[email protected]> AuthorDate: Thu Mar 26 11:06:13 2026 +0100 CAMEL-23255: Retry schema registration on IllegalLifecycleStateException When Camel and a remote Infinispan server start concurrently (e.g., in Kubernetes), the server's internal ___protobuf_metadata cache may not be ready yet, causing schema registration to fail with RemoteIllegalLifecycleStateException. Add retry logic using Camel's ForegroundTask with a configurable timeout (embeddingStoreSchemaRegistrationTimeout, default 60s). Only RemoteIllegalLifecycleStateException triggers retries; other errors (bad credentials, invalid schema, network issues) fail immediately. Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../InfinispanRemoteComponentConfigurer.java | 6 ++ .../remote/InfinispanRemoteEndpointConfigurer.java | 6 ++ .../remote/InfinispanRemoteEndpointUriFactory.java | 3 +- .../component/infinispan/remote/infinispan.json | 66 +++++++++++----------- .../remote/InfinispanRemoteConfiguration.java | 18 ++++++ .../infinispan/remote/InfinispanRemoteManager.java | 41 +++++++++++++- 6 files changed, 106 insertions(+), 34 deletions(-) diff --git a/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteComponentConfigurer.java b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteComponentConfigurer.java index 0e5b80bd5c9b..75d6b4a61974 100644 --- a/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteComponentConfigurer.java +++ b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteComponentConfigurer.java @@ -55,6 +55,8 @@ public class InfinispanRemoteComponentConfigurer extends PropertyConfigurerSuppo case "embeddingStoreEnabled": getOrCreateConfiguration(target).setEmbeddingStoreEnabled(property(camelContext, boolean.class, value)); return true; case "embeddingstoreregisterschema": case "embeddingStoreRegisterSchema": getOrCreateConfiguration(target).setEmbeddingStoreRegisterSchema(property(camelContext, boolean.class, value)); return true; + case "embeddingstoreschemaregistrationtimeout": + case "embeddingStoreSchemaRegistrationTimeout": getOrCreateConfiguration(target).setEmbeddingStoreSchemaRegistrationTimeout(property(camelContext, java.time.Duration.class, value)); return true; case "embeddingstoretypename": case "embeddingStoreTypeName": getOrCreateConfiguration(target).setEmbeddingStoreTypeName(property(camelContext, java.lang.String.class, value)); return true; case "embeddingstorevectorsimilarity": @@ -122,6 +124,8 @@ public class InfinispanRemoteComponentConfigurer extends PropertyConfigurerSuppo case "embeddingStoreEnabled": return boolean.class; case "embeddingstoreregisterschema": case "embeddingStoreRegisterSchema": return boolean.class; + case "embeddingstoreschemaregistrationtimeout": + case "embeddingStoreSchemaRegistrationTimeout": return java.time.Duration.class; case "embeddingstoretypename": case "embeddingStoreTypeName": return java.lang.String.class; case "embeddingstorevectorsimilarity": @@ -185,6 +189,8 @@ public class InfinispanRemoteComponentConfigurer extends PropertyConfigurerSuppo case "embeddingStoreEnabled": return getOrCreateConfiguration(target).isEmbeddingStoreEnabled(); case "embeddingstoreregisterschema": case "embeddingStoreRegisterSchema": return getOrCreateConfiguration(target).isEmbeddingStoreRegisterSchema(); + case "embeddingstoreschemaregistrationtimeout": + case "embeddingStoreSchemaRegistrationTimeout": return getOrCreateConfiguration(target).getEmbeddingStoreSchemaRegistrationTimeout(); case "embeddingstoretypename": case "embeddingStoreTypeName": return getOrCreateConfiguration(target).getEmbeddingStoreTypeName(); case "embeddingstorevectorsimilarity": diff --git a/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteEndpointConfigurer.java b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteEndpointConfigurer.java index 89f89820cd62..f2d81c1b19c8 100644 --- a/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteEndpointConfigurer.java +++ b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteEndpointConfigurer.java @@ -45,6 +45,8 @@ public class InfinispanRemoteEndpointConfigurer extends PropertyConfigurerSuppor case "embeddingStoreEnabled": target.getConfiguration().setEmbeddingStoreEnabled(property(camelContext, boolean.class, value)); return true; case "embeddingstoreregisterschema": case "embeddingStoreRegisterSchema": target.getConfiguration().setEmbeddingStoreRegisterSchema(property(camelContext, boolean.class, value)); return true; + case "embeddingstoreschemaregistrationtimeout": + case "embeddingStoreSchemaRegistrationTimeout": target.getConfiguration().setEmbeddingStoreSchemaRegistrationTimeout(property(camelContext, java.time.Duration.class, value)); return true; case "embeddingstoretypename": case "embeddingStoreTypeName": target.getConfiguration().setEmbeddingStoreTypeName(property(camelContext, java.lang.String.class, value)); return true; case "embeddingstorevectorsimilarity": @@ -113,6 +115,8 @@ public class InfinispanRemoteEndpointConfigurer extends PropertyConfigurerSuppor case "embeddingStoreEnabled": return boolean.class; case "embeddingstoreregisterschema": case "embeddingStoreRegisterSchema": return boolean.class; + case "embeddingstoreschemaregistrationtimeout": + case "embeddingStoreSchemaRegistrationTimeout": return java.time.Duration.class; case "embeddingstoretypename": case "embeddingStoreTypeName": return java.lang.String.class; case "embeddingstorevectorsimilarity": @@ -177,6 +181,8 @@ public class InfinispanRemoteEndpointConfigurer extends PropertyConfigurerSuppor case "embeddingStoreEnabled": return target.getConfiguration().isEmbeddingStoreEnabled(); case "embeddingstoreregisterschema": case "embeddingStoreRegisterSchema": return target.getConfiguration().isEmbeddingStoreRegisterSchema(); + case "embeddingstoreschemaregistrationtimeout": + case "embeddingStoreSchemaRegistrationTimeout": return target.getConfiguration().getEmbeddingStoreSchemaRegistrationTimeout(); case "embeddingstoretypename": case "embeddingStoreTypeName": return target.getConfiguration().getEmbeddingStoreTypeName(); case "embeddingstorevectorsimilarity": diff --git a/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteEndpointUriFactory.java b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteEndpointUriFactory.java index 60a09b3899bd..7323219dda3e 100644 --- a/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteEndpointUriFactory.java +++ b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteEndpointUriFactory.java @@ -23,7 +23,7 @@ public class InfinispanRemoteEndpointUriFactory extends org.apache.camel.support private static final Set<String> SECRET_PROPERTY_NAMES; private static final Map<String, String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(33); + Set<String> props = new HashSet<>(34); props.add("bridgeErrorHandler"); props.add("cacheContainer"); props.add("cacheContainerConfiguration"); @@ -36,6 +36,7 @@ public class InfinispanRemoteEndpointUriFactory extends org.apache.camel.support props.add("embeddingStoreDistance"); props.add("embeddingStoreEnabled"); props.add("embeddingStoreRegisterSchema"); + props.add("embeddingStoreSchemaRegistrationTimeout"); props.add("embeddingStoreTypeName"); props.add("embeddingStoreVectorSimilarity"); props.add("eventTypes"); diff --git a/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/org/apache/camel/component/infinispan/remote/infinispan.json b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/org/apache/camel/component/infinispan/remote/infinispan.json index d8578d7a476c..a86475d95bf5 100644 --- a/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/org/apache/camel/component/infinispan/remote/infinispan.json +++ b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/org/apache/camel/component/infinispan/remote/infinispan.json @@ -40,22 +40,23 @@ "embeddingStoreDistance": { "index": 13, "kind": "property", "displayName": "Embedding Store Distance", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 3, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "The distance to use for kNN searc [...] "embeddingStoreEnabled": { "index": 14, "kind": "property", "displayName": "Embedding Store Enabled", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Whether to enable the embedd [...] "embeddingStoreRegisterSchema": { "index": 15, "kind": "property", "displayName": "Embedding Store Register Schema", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Whether to au [...] - "embeddingStoreTypeName": { "index": 16, "kind": "property", "displayName": "Embedding Store Type Name", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "The name of the type used to store embe [...] - "embeddingStoreVectorSimilarity": { "index": 17, "kind": "property", "displayName": "Embedding Store Vector Similarity", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "enum", "javaType": "org.infinispan.api.annotations.indexing.option.VectorSimilarity", "enum": [ "L2", "INNER_PRODUCT", "MAX_INNER_PRODUCT", "COSINE" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "COSINE", "configurationClass": "org.apache.camel.c [...] - "autowiredEnabled": { "index": 18, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching [...] - "cacheContainer": { "index": 19, "kind": "property", "displayName": "Cache Container", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.infinispan.client.hotrod.RemoteCacheManager", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Specifies the cache Cont [...] - "cacheContainerConfiguration": { "index": 20, "kind": "property", "displayName": "Cache Container Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.infinispan.client.hotrod.configuration.Configuration", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "des [...] - "configurationProperties": { "index": 21, "kind": "property", "displayName": "Configuration Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Implementation specific pr [...] - "configurationUri": { "index": 22, "kind": "property", "displayName": "Configuration Uri", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "An implementation sp [...] - "flags": { "index": 23, "kind": "property", "displayName": "Flags", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "A comma separated list of org.infinispan.client.hotrod.Flag to be applied by default on each cac [...] - "remappingFunction": { "index": 24, "kind": "property", "displayName": "Remapping Function", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.function.BiFunction", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Set a specific remappingFunction to use in a compute opera [...] - "resultHeader": { "index": 25, "kind": "property", "displayName": "Result Header", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Store the operation result in a header instead of the message body. By default, r [...] - "password": { "index": 26, "kind": "property", "displayName": "Password", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the password to access the infinispan instance" }, - "saslMechanism": { "index": 27, "kind": "property", "displayName": "Sasl Mechanism", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the SASL Mechanism to access the infinispan instance" }, - "secure": { "index": 28, "kind": "property", "displayName": "Secure", "group": "security", "label": "common,security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define if we are connecting to a secured Infinispan instance" }, - "securityRealm": { "index": 29, "kind": "property", "displayName": "Security Realm", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the security realm to access the infinispan instance" }, - "securityServerName": { "index": 30, "kind": "property", "displayName": "Security Server Name", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the security server name to access the infinispan inst [...] - "username": { "index": 31, "kind": "property", "displayName": "Username", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the username to access the infinispan instance" } + "embeddingStoreSchemaRegistrationTimeout": { "index": 16, "kind": "property", "displayName": "Embedding Store Schema Registration Timeout", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "duration", "javaType": "java.time.Duration", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "60s", "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configura [...] + "embeddingStoreTypeName": { "index": 17, "kind": "property", "displayName": "Embedding Store Type Name", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "The name of the type used to store embe [...] + "embeddingStoreVectorSimilarity": { "index": 18, "kind": "property", "displayName": "Embedding Store Vector Similarity", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "enum", "javaType": "org.infinispan.api.annotations.indexing.option.VectorSimilarity", "enum": [ "L2", "INNER_PRODUCT", "MAX_INNER_PRODUCT", "COSINE" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "COSINE", "configurationClass": "org.apache.camel.c [...] + "autowiredEnabled": { "index": 19, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching [...] + "cacheContainer": { "index": 20, "kind": "property", "displayName": "Cache Container", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.infinispan.client.hotrod.RemoteCacheManager", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Specifies the cache Cont [...] + "cacheContainerConfiguration": { "index": 21, "kind": "property", "displayName": "Cache Container Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.infinispan.client.hotrod.configuration.Configuration", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "des [...] + "configurationProperties": { "index": 22, "kind": "property", "displayName": "Configuration Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Implementation specific pr [...] + "configurationUri": { "index": 23, "kind": "property", "displayName": "Configuration Uri", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "An implementation sp [...] + "flags": { "index": 24, "kind": "property", "displayName": "Flags", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "A comma separated list of org.infinispan.client.hotrod.Flag to be applied by default on each cac [...] + "remappingFunction": { "index": 25, "kind": "property", "displayName": "Remapping Function", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.function.BiFunction", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Set a specific remappingFunction to use in a compute opera [...] + "resultHeader": { "index": 26, "kind": "property", "displayName": "Result Header", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Store the operation result in a header instead of the message body. By default, r [...] + "password": { "index": 27, "kind": "property", "displayName": "Password", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the password to access the infinispan instance" }, + "saslMechanism": { "index": 28, "kind": "property", "displayName": "Sasl Mechanism", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the SASL Mechanism to access the infinispan instance" }, + "secure": { "index": 29, "kind": "property", "displayName": "Secure", "group": "security", "label": "common,security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define if we are connecting to a secured Infinispan instance" }, + "securityRealm": { "index": 30, "kind": "property", "displayName": "Security Realm", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the security realm to access the infinispan instance" }, + "securityServerName": { "index": 31, "kind": "property", "displayName": "Security Server Name", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the security server name to access the infinispan inst [...] + "username": { "index": 32, "kind": "property", "displayName": "Username", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the username to access the infinispan instance" } }, "headers": { "CamelInfinispanEventType": { "index": 0, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The type of the received event.", "constantName": "org.apache.camel.component.infinispan.InfinispanConstants#EVENT_TYPE" }, @@ -95,21 +96,22 @@ "embeddingStoreDistance": { "index": 14, "kind": "parameter", "displayName": "Embedding Store Distance", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 3, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "The distance to use for kNN sear [...] "embeddingStoreEnabled": { "index": 15, "kind": "parameter", "displayName": "Embedding Store Enabled", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Whether to enable the embed [...] "embeddingStoreRegisterSchema": { "index": 16, "kind": "parameter", "displayName": "Embedding Store Register Schema", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Whether to a [...] - "embeddingStoreTypeName": { "index": 17, "kind": "parameter", "displayName": "Embedding Store Type Name", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "The name of the type used to store emb [...] - "embeddingStoreVectorSimilarity": { "index": 18, "kind": "parameter", "displayName": "Embedding Store Vector Similarity", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "enum", "javaType": "org.infinispan.api.annotations.indexing.option.VectorSimilarity", "enum": [ "L2", "INNER_PRODUCT", "MAX_INNER_PRODUCT", "COSINE" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "COSINE", "configurationClass": "org.apache.camel. [...] - "lazyStartProducer": { "index": 19, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...] - "cacheContainer": { "index": 20, "kind": "parameter", "displayName": "Cache Container", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.infinispan.client.hotrod.RemoteCacheManager", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Specifies the cache Con [...] - "cacheContainerConfiguration": { "index": 21, "kind": "parameter", "displayName": "Cache Container Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.infinispan.client.hotrod.configuration.Configuration", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "de [...] - "configurationProperties": { "index": 22, "kind": "parameter", "displayName": "Configuration Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Implementation specific p [...] - "configurationUri": { "index": 23, "kind": "parameter", "displayName": "Configuration Uri", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "An implementation s [...] - "flags": { "index": 24, "kind": "parameter", "displayName": "Flags", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "A comma separated list of org.infinispan.client.hotrod.Flag to be applied by default on each ca [...] - "remappingFunction": { "index": 25, "kind": "parameter", "displayName": "Remapping Function", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.function.BiFunction", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Set a specific remappingFunction to use in a compute oper [...] - "resultHeader": { "index": 26, "kind": "parameter", "displayName": "Result Header", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Store the operation result in a header instead of the message body. By default, [...] - "password": { "index": 27, "kind": "parameter", "displayName": "Password", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the password to access the infinispan instance" }, - "saslMechanism": { "index": 28, "kind": "parameter", "displayName": "Sasl Mechanism", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the SASL Mechanism to access the infinispan instance" }, - "secure": { "index": 29, "kind": "parameter", "displayName": "Secure", "group": "security", "label": "common,security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define if we are connecting to a secured Infinispan instance" }, - "securityRealm": { "index": 30, "kind": "parameter", "displayName": "Security Realm", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the security realm to access the infinispan instance" }, - "securityServerName": { "index": 31, "kind": "parameter", "displayName": "Security Server Name", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the security server name to access the infinispan ins [...] - "username": { "index": 32, "kind": "parameter", "displayName": "Username", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the username to access the infinispan instance" } + "embeddingStoreSchemaRegistrationTimeout": { "index": 17, "kind": "parameter", "displayName": "Embedding Store Schema Registration Timeout", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "duration", "javaType": "java.time.Duration", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "60s", "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configur [...] + "embeddingStoreTypeName": { "index": 18, "kind": "parameter", "displayName": "Embedding Store Type Name", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "The name of the type used to store emb [...] + "embeddingStoreVectorSimilarity": { "index": 19, "kind": "parameter", "displayName": "Embedding Store Vector Similarity", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "enum", "javaType": "org.infinispan.api.annotations.indexing.option.VectorSimilarity", "enum": [ "L2", "INNER_PRODUCT", "MAX_INNER_PRODUCT", "COSINE" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "COSINE", "configurationClass": "org.apache.camel. [...] + "lazyStartProducer": { "index": 20, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...] + "cacheContainer": { "index": 21, "kind": "parameter", "displayName": "Cache Container", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.infinispan.client.hotrod.RemoteCacheManager", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Specifies the cache Con [...] + "cacheContainerConfiguration": { "index": 22, "kind": "parameter", "displayName": "Cache Container Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.infinispan.client.hotrod.configuration.Configuration", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "de [...] + "configurationProperties": { "index": 23, "kind": "parameter", "displayName": "Configuration Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Implementation specific p [...] + "configurationUri": { "index": 24, "kind": "parameter", "displayName": "Configuration Uri", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "An implementation s [...] + "flags": { "index": 25, "kind": "parameter", "displayName": "Flags", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "A comma separated list of org.infinispan.client.hotrod.Flag to be applied by default on each ca [...] + "remappingFunction": { "index": 26, "kind": "parameter", "displayName": "Remapping Function", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.function.BiFunction", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Set a specific remappingFunction to use in a compute oper [...] + "resultHeader": { "index": 27, "kind": "parameter", "displayName": "Result Header", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Store the operation result in a header instead of the message body. By default, [...] + "password": { "index": 28, "kind": "parameter", "displayName": "Password", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the password to access the infinispan instance" }, + "saslMechanism": { "index": 29, "kind": "parameter", "displayName": "Sasl Mechanism", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the SASL Mechanism to access the infinispan instance" }, + "secure": { "index": 30, "kind": "parameter", "displayName": "Secure", "group": "security", "label": "common,security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define if we are connecting to a secured Infinispan instance" }, + "securityRealm": { "index": 31, "kind": "parameter", "displayName": "Security Realm", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the security realm to access the infinispan instance" }, + "securityServerName": { "index": 32, "kind": "parameter", "displayName": "Security Server Name", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the security server name to access the infinispan ins [...] + "username": { "index": 33, "kind": "parameter", "displayName": "Username", "group": "security", "label": "common,security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration", "configurationField": "configuration", "description": "Define the username to access the infinispan instance" } } } diff --git a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteConfiguration.java b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteConfiguration.java index 8daacb553a33..483de83d4851 100644 --- a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteConfiguration.java +++ b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteConfiguration.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.infinispan.remote; +import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -71,6 +72,10 @@ public class InfinispanRemoteConfiguration extends InfinispanConfiguration imple private int embeddingStoreDistance = 3; @UriParam(label = "producer,advanced") private String embeddingStoreTypeName; + @UriParam(label = "producer,advanced", defaultValue = "60s", javaType = "java.time.Duration", + description = "Maximum time to wait for the Infinispan server to be ready when registering the embedding store schema." + + " This handles the case where Camel and the Infinispan server start concurrently.") + private Duration embeddingStoreSchemaRegistrationTimeout = Duration.ofSeconds(60); public Configuration getCacheContainerConfiguration() { return cacheContainerConfiguration; @@ -316,6 +321,19 @@ public class InfinispanRemoteConfiguration extends InfinispanConfiguration imple return embeddingStoreTypeName; } + public Duration getEmbeddingStoreSchemaRegistrationTimeout() { + return embeddingStoreSchemaRegistrationTimeout; + } + + /** + * Maximum time to wait for the Infinispan server to be ready when registering the embedding store schema. This + * handles the case where Camel and the Infinispan server start concurrently (e.g., in Kubernetes). The server's + * internal protobuf metadata cache may not be available immediately. + */ + public void setEmbeddingStoreSchemaRegistrationTimeout(Duration embeddingStoreSchemaRegistrationTimeout) { + this.embeddingStoreSchemaRegistrationTimeout = embeddingStoreSchemaRegistrationTimeout; + } + @Override public InfinispanRemoteConfiguration clone() { try { diff --git a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteManager.java b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteManager.java index dc87c45ad31e..6aba0401fa2d 100644 --- a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteManager.java +++ b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteManager.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.infinispan.remote; +import java.time.Duration; import java.util.Properties; import java.util.Set; @@ -24,16 +25,24 @@ import org.apache.camel.component.infinispan.InfinispanManager; import org.apache.camel.component.infinispan.InfinispanUtil; import org.apache.camel.component.infinispan.remote.embeddingstore.EmbeddingStoreUtil; import org.apache.camel.support.service.ServiceSupport; +import org.apache.camel.support.task.ForegroundTask; +import org.apache.camel.support.task.Tasks; +import org.apache.camel.support.task.budget.Budgets; import org.apache.camel.util.ObjectHelper; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.configuration.Configuration; import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; +import org.infinispan.client.hotrod.exceptions.RemoteIllegalLifecycleStateException; import org.infinispan.commons.api.BasicCache; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.apache.camel.component.infinispan.InfinispanConstants.CACHE_MANAGER_CURRENT; public class InfinispanRemoteManager extends ServiceSupport implements InfinispanManager<RemoteCacheManager> { + private static final Logger LOG = LoggerFactory.getLogger(InfinispanRemoteManager.class); + private final InfinispanRemoteConfiguration configuration; private CamelContext camelContext; private RemoteCacheManager cacheContainer; @@ -127,7 +136,37 @@ public class InfinispanRemoteManager extends ServiceSupport implements Infinispa } if (embeddingStoreEnabled && configuration.isEmbeddingStoreRegisterSchema()) { - EmbeddingStoreUtil.registerSchema(configuration, cacheContainer); + registerSchemaWithRetry(); + } + } + + /** + * Registers the embedding store schema with retry logic to handle the case where Camel and the remote Infinispan + * server start up concurrently (e.g., in Kubernetes). The server's internal {@code ___protobuf_metadata} cache may + * not be ready yet, causing a {@link RemoteIllegalLifecycleStateException}. + */ + private void registerSchemaWithRetry() throws Exception { + Duration timeout = configuration.getEmbeddingStoreSchemaRegistrationTimeout(); + ForegroundTask task = Tasks.foregroundTask() + .withBudget(Budgets.iterationTimeBudget() + .withInterval(Duration.ofSeconds(1)) + .withMaxDuration(timeout) + .build()) + .build(); + + boolean registered = task.run(null, () -> { + try { + EmbeddingStoreUtil.registerSchema(configuration, cacheContainer); + return true; + } catch (RemoteIllegalLifecycleStateException e) { + LOG.debug("Schema registration failed (server not ready), retrying: {}", e.getMessage()); + return false; + } + }); + + if (!registered) { + throw new IllegalStateException( + "Failed to register Infinispan schema after retries. The server may not be fully started."); } }
