This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch ra in repository https://gitbox.apache.org/repos/asf/camel.git
commit 997301263623320f230f833fe48e71038bb4e8b1 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Tue May 28 12:08:06 2024 +0200 CAMEL-20798: Add RemoteAddress to endpoints so they can tell the url/hostname etc for the system it connects. This is needed for better monitoring, tracing and management. Add this information into camel-tracer as tags. --- .../camel/catalog/components/sql-stored.json | 3 +- .../org/apache/camel/catalog/components/sql.json | 7 +- .../component/sql/SqlComponentConfigurer.java | 6 ++ .../sql/stored/SqlStoredComponentConfigurer.java | 6 ++ .../org/apache/camel/component/sql/sql.json | 7 +- .../camel/component/sql/stored/sql-stored.json | 3 +- .../camel/component/sql/DefaultSqlEndpoint.java | 71 ++++++++++++------ .../apache/camel/component/sql/SqlComponent.java | 20 +++++ .../component/sql/SqlServiceLocationHelper.java | 85 ++++++++++++++++++++++ .../component/sql/stored/SqlStoredComponent.java | 21 +++++- .../component/sql/stored/SqlStoredEndpoint.java | 36 +++++++++ .../dsl/Activemq6ComponentBuilderFactory.java | 21 ++++++ .../dsl/ActivemqComponentBuilderFactory.java | 21 ++++++ .../component/dsl/AmqpComponentBuilderFactory.java | 21 ++++++ .../component/dsl/JmsComponentBuilderFactory.java | 21 ++++++ .../component/dsl/SqlComponentBuilderFactory.java | 21 ++++++ .../dsl/SqlStoredComponentBuilderFactory.java | 21 ++++++ 17 files changed, 361 insertions(+), 30 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json index 866019e7eb5..22439195b22 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json @@ -25,7 +25,8 @@ "componentProperties": { "dataSource": { "index": 0, "kind": "property", "displayName": "Data Source", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "javax.sql.DataSource", "deprecated": false, "autowired": true, "secret": false, "description": "Sets the DataSource to use to communicate with the database." }, "lazyStartProducer": { "index": 1, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "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 producer may otherwise fail [...] - "autowiredEnabled": { "index": 2, "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 t [...] + "autowiredEnabled": { "index": 2, "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 t [...] + "serviceLocationEnabled": { "index": 3, "kind": "property", "displayName": "Service Location Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to detect the network address location of the JMS broker on startup. This information is gathered via reflection on the ConnectionFactory, and is vendor specific. This option can [...] }, "headers": { "CamelSqlStoredTemplate": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The template", "constantName": "org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_TEMPLATE" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json index f075feac521..91905276c79 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json @@ -28,9 +28,10 @@ "lazyStartProducer": { "index": 2, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "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 producer may otherwise fail [...] "autowiredEnabled": { "index": 3, "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 t [...] "rowMapperFactory": { "index": 4, "kind": "property", "displayName": "Row Mapper Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.sql.RowMapperFactory", "deprecated": false, "autowired": true, "secret": false, "description": "Factory for creating RowMapper" }, - "usePlaceholder": { "index": 5, "kind": "property", "displayName": "Use Placeholder", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to use placeholder and replace all placeholder characters with sign in the SQL queries. This option is default true" }, - "healthCheckConsumerEnabled": { "index": 6, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, - "healthCheckProducerEnabled": { "index": 7, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on producer [...] + "serviceLocationEnabled": { "index": 5, "kind": "property", "displayName": "Service Location Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to detect the network address location of the JMS broker on startup. This information is gathered via reflection on the ConnectionFactory, and is vendor specific. This option can [...] + "usePlaceholder": { "index": 6, "kind": "property", "displayName": "Use Placeholder", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to use placeholder and replace all placeholder characters with sign in the SQL queries. This option is default true" }, + "healthCheckConsumerEnabled": { "index": 7, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, + "healthCheckProducerEnabled": { "index": 8, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on producer [...] }, "headers": { "CamelSqlQuery": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Query to execute. This query takes precedence over the query specified in the endpoint URI. Note that query parameters in the header _are_ represented by a instead of a pass:# symbol", "constantName": "org.apache.camel.component.sql.SqlCons [...] diff --git a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlComponentConfigurer.java b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlComponentConfigurer.java index 1943c610d87..1f9d62383c0 100644 --- a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlComponentConfigurer.java +++ b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/SqlComponentConfigurer.java @@ -37,6 +37,8 @@ public class SqlComponentConfigurer extends PropertyConfigurerSupport implements case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; case "rowmapperfactory": case "rowMapperFactory": target.setRowMapperFactory(property(camelContext, org.apache.camel.component.sql.RowMapperFactory.class, value)); return true; + case "servicelocationenabled": + case "serviceLocationEnabled": target.setServiceLocationEnabled(property(camelContext, boolean.class, value)); return true; case "useplaceholder": case "usePlaceholder": target.setUsePlaceholder(property(camelContext, boolean.class, value)); return true; default: return false; @@ -65,6 +67,8 @@ public class SqlComponentConfigurer extends PropertyConfigurerSupport implements case "lazyStartProducer": return boolean.class; case "rowmapperfactory": case "rowMapperFactory": return org.apache.camel.component.sql.RowMapperFactory.class; + case "servicelocationenabled": + case "serviceLocationEnabled": return boolean.class; case "useplaceholder": case "usePlaceholder": return boolean.class; default: return null; @@ -89,6 +93,8 @@ public class SqlComponentConfigurer extends PropertyConfigurerSupport implements case "lazyStartProducer": return target.isLazyStartProducer(); case "rowmapperfactory": case "rowMapperFactory": return target.getRowMapperFactory(); + case "servicelocationenabled": + case "serviceLocationEnabled": return target.isServiceLocationEnabled(); case "useplaceholder": case "usePlaceholder": return target.isUsePlaceholder(); default: return null; diff --git a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/stored/SqlStoredComponentConfigurer.java b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/stored/SqlStoredComponentConfigurer.java index feb4d7dd565..5e853b26b96 100644 --- a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/stored/SqlStoredComponentConfigurer.java +++ b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/stored/SqlStoredComponentConfigurer.java @@ -29,6 +29,8 @@ public class SqlStoredComponentConfigurer extends PropertyConfigurerSupport impl case "dataSource": target.setDataSource(property(camelContext, javax.sql.DataSource.class, value)); return true; case "lazystartproducer": case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; + case "servicelocationenabled": + case "serviceLocationEnabled": target.setServiceLocationEnabled(property(camelContext, boolean.class, value)); return true; default: return false; } } @@ -47,6 +49,8 @@ public class SqlStoredComponentConfigurer extends PropertyConfigurerSupport impl case "dataSource": return javax.sql.DataSource.class; case "lazystartproducer": case "lazyStartProducer": return boolean.class; + case "servicelocationenabled": + case "serviceLocationEnabled": return boolean.class; default: return null; } } @@ -61,6 +65,8 @@ public class SqlStoredComponentConfigurer extends PropertyConfigurerSupport impl case "dataSource": return target.getDataSource(); case "lazystartproducer": case "lazyStartProducer": return target.isLazyStartProducer(); + case "servicelocationenabled": + case "serviceLocationEnabled": return target.isServiceLocationEnabled(); default: return null; } } diff --git a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/sql.json b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/sql.json index f075feac521..91905276c79 100644 --- a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/sql.json +++ b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/sql.json @@ -28,9 +28,10 @@ "lazyStartProducer": { "index": 2, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "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 producer may otherwise fail [...] "autowiredEnabled": { "index": 3, "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 t [...] "rowMapperFactory": { "index": 4, "kind": "property", "displayName": "Row Mapper Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.sql.RowMapperFactory", "deprecated": false, "autowired": true, "secret": false, "description": "Factory for creating RowMapper" }, - "usePlaceholder": { "index": 5, "kind": "property", "displayName": "Use Placeholder", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to use placeholder and replace all placeholder characters with sign in the SQL queries. This option is default true" }, - "healthCheckConsumerEnabled": { "index": 6, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, - "healthCheckProducerEnabled": { "index": 7, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on producer [...] + "serviceLocationEnabled": { "index": 5, "kind": "property", "displayName": "Service Location Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to detect the network address location of the JMS broker on startup. This information is gathered via reflection on the ConnectionFactory, and is vendor specific. This option can [...] + "usePlaceholder": { "index": 6, "kind": "property", "displayName": "Use Placeholder", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to use placeholder and replace all placeholder characters with sign in the SQL queries. This option is default true" }, + "healthCheckConsumerEnabled": { "index": 7, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, + "healthCheckProducerEnabled": { "index": 8, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on producer [...] }, "headers": { "CamelSqlQuery": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Query to execute. This query takes precedence over the query specified in the endpoint URI. Note that query parameters in the header _are_ represented by a instead of a pass:# symbol", "constantName": "org.apache.camel.component.sql.SqlCons [...] diff --git a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json index 866019e7eb5..22439195b22 100644 --- a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json +++ b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json @@ -25,7 +25,8 @@ "componentProperties": { "dataSource": { "index": 0, "kind": "property", "displayName": "Data Source", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "javax.sql.DataSource", "deprecated": false, "autowired": true, "secret": false, "description": "Sets the DataSource to use to communicate with the database." }, "lazyStartProducer": { "index": 1, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "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 producer may otherwise fail [...] - "autowiredEnabled": { "index": 2, "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 t [...] + "autowiredEnabled": { "index": 2, "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 t [...] + "serviceLocationEnabled": { "index": 3, "kind": "property", "displayName": "Service Location Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to detect the network address location of the JMS broker on startup. This information is gathered via reflection on the ConnectionFactory, and is vendor specific. This option can [...] }, "headers": { "CamelSqlStoredTemplate": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The template", "constantName": "org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_TEMPLATE" }, diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java index 31c5ae5f60f..7ba81bc6c12 100644 --- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java +++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java @@ -21,20 +21,22 @@ import java.sql.ResultSet; import java.sql.SQLDataException; import java.sql.SQLException; import java.sql.Statement; +import java.util.HashMap; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.apache.camel.Component; +import org.apache.camel.spi.BeanIntrospection; import org.apache.camel.spi.EndpointServiceLocation; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriParam; import org.apache.camel.support.DefaultPollingEndpoint; +import org.apache.camel.support.PluginHelper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapperResultSetExtractor; -import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource; /** * Base class for SQL endpoints. @@ -42,6 +44,10 @@ import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource; public abstract class DefaultSqlEndpoint extends DefaultPollingEndpoint implements EndpointServiceLocation { private JdbcTemplate jdbcTemplate; + private boolean serviceLocationEnabled; + private String serviceUrl; + private Map<String, String> serviceMetadata; + @Metadata(autowired = true) @UriParam(description = "Sets the DataSource to use to communicate with the database at endpoint level.") private DataSource dataSource; @@ -138,28 +144,16 @@ public abstract class DefaultSqlEndpoint extends DefaultPollingEndpoint implemen super(endpointUri, component); } - @Override - public String getServiceUrl() { - if (dataSource != null && dataSource instanceof AbstractDriverBasedDataSource ads) { - return ads.getUrl(); - } - return null; - } - - @Override - public String getServiceProtocol() { - return "jdbc"; + public boolean isServiceLocationEnabled() { + return serviceLocationEnabled; } - @Override - public Map<String, String> getServiceMetadata() { - if (dataSource != null && dataSource instanceof AbstractDriverBasedDataSource ads) { - String u = ads.getUsername(); - if (u != null) { - return Map.of("username", u); - } - } - return null; + /** + * Whether to detect the network address location of the JMS broker on startup. This information is gathered via + * reflection on the ConnectionFactory, and is vendor specific. This option can be used to turn this off. + */ + public void setServiceLocationEnabled(boolean serviceLocationEnabled) { + this.serviceLocationEnabled = serviceLocationEnabled; } public JdbcTemplate getJdbcTemplate() { @@ -556,4 +550,39 @@ public abstract class DefaultSqlEndpoint extends DefaultPollingEndpoint implemen rowMapperFactory = new DefaultRowMapperFactory(); } } + + @Override + protected void doStart() throws Exception { + if (isServiceLocationEnabled()) { + // we need to use reflection to find the URL to the database, so do this once on startup + BeanIntrospection bi = PluginHelper.getBeanIntrospection(getCamelContext()); + DataSource ds = getDataSource(); + serviceUrl = SqlServiceLocationHelper.getJDBCURLFromDataSource(bi, ds); + + serviceMetadata = new HashMap<>(); + String user = SqlServiceLocationHelper.getUsernameFromConnectionFactory(bi, ds); + if (user != null) { + serviceMetadata.put("username", user); + } + } + } + + @Override + public String getServiceUrl() { + return serviceUrl; + } + + @Override + public String getServiceProtocol() { + return "jdbc"; + } + + @Override + public Map<String, String> getServiceMetadata() { + if (serviceMetadata != null && !serviceMetadata.isEmpty()) { + return serviceMetadata; + } + return null; + } + } diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java index 6519caff21c..66d2d2f4e32 100644 --- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java +++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlComponent.java @@ -42,6 +42,12 @@ public class SqlComponent extends HealthCheckComponent { private boolean usePlaceholder = true; @Metadata(label = "advanced", autowired = true) private RowMapperFactory rowMapperFactory; + @Metadata(label = "advanced", + description = "Whether to detect the network address location of the JMS broker on startup." + + " This information is gathered via reflection on the ConnectionFactory, and is vendor specific." + + " This option can be used to turn this off.", + defaultValue = "true") + private boolean serviceLocationEnabled = true; public SqlComponent() { } @@ -94,6 +100,7 @@ public class SqlComponent extends HealthCheckComponent { // create endpoint SqlEndpoint endpoint = new SqlEndpoint(uri, this); + endpoint.setServiceLocationEnabled(serviceLocationEnabled); endpoint.setQuery(query); endpoint.setPlaceholder(parameterPlaceholderSubstitute); endpoint.setUsePlaceholder(isUsePlaceholder()); @@ -159,4 +166,17 @@ public class SqlComponent extends HealthCheckComponent { public void setRowMapperFactory(RowMapperFactory rowMapperFactory) { this.rowMapperFactory = rowMapperFactory; } + + public boolean isServiceLocationEnabled() { + return serviceLocationEnabled; + } + + /** + * Whether to detect the network address location of the JMS broker on startup. This information is gathered via + * reflection on the ConnectionFactory, and is vendor specific. This option can be used to turn this off. + */ + public void setServiceLocationEnabled(boolean serviceLocationEnabled) { + this.serviceLocationEnabled = serviceLocationEnabled; + } + } diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlServiceLocationHelper.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlServiceLocationHelper.java new file mode 100644 index 00000000000..7080156b950 --- /dev/null +++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlServiceLocationHelper.java @@ -0,0 +1,85 @@ +/* + * 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.camel.component.sql; + +import java.util.HashMap; +import java.util.Map; + +import javax.sql.DataSource; + +import org.apache.camel.spi.BeanIntrospection; +import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource; + +public class SqlServiceLocationHelper { + + public static String getJDBCURLFromDataSource(BeanIntrospection bi, DataSource ds) { + if (ds == null) { + return null; + } + if (ds instanceof AbstractDriverBasedDataSource ads) { + return ads.getUrl(); + } + + Map<String, Object> props = new HashMap<>(); + bi.getProperties(ds, props, null, false); + Object url = props.get("url"); + if (url == null) { + url = props.get("jdbcUrl"); + } + if (url != null) { + return url.toString(); + } else { + // nested which can be wrapped in connection pooling + DataSource ncf = (DataSource) props.get("dataSource"); + if (ncf != null) { + return getJDBCURLFromDataSource(bi, ncf); + } + } + return null; + } + + public static String getUsernameFromConnectionFactory(BeanIntrospection bi, DataSource ds) { + if (ds == null) { + return null; + } + + if (ds instanceof AbstractDriverBasedDataSource ads) { + return ads.getUsername(); + } + + Map<String, Object> props = new HashMap<>(); + bi.getProperties(ds, props, null, false); + Object user = props.get("user"); + if (user == null) { + user = props.get("username"); + } + if (user == null) { + user = props.get("userName"); + } + if (user != null) { + return user.toString(); + } else { + // nested which can be wrapped in connection pooling + DataSource ncf = (DataSource) props.get("dataSource"); + if (ncf != null) { + return getUsernameFromConnectionFactory(bi, ncf); + } + } + return null; + } + +} diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredComponent.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredComponent.java index fea5a377605..4915ed148de 100644 --- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredComponent.java +++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredComponent.java @@ -33,11 +33,17 @@ public class SqlStoredComponent extends DefaultComponent { @Metadata(autowired = true) private DataSource dataSource; + @Metadata(label = "advanced", + description = "Whether to detect the network address location of the JMS broker on startup." + + " This information is gathered via reflection on the ConnectionFactory, and is vendor specific." + + " This option can be used to turn this off.", + defaultValue = "true") + private boolean serviceLocationEnabled = true; @Override protected Endpoint createEndpoint(String uri, String template, Map<String, Object> parameters) throws Exception { - SqlStoredEndpoint endpoint = new SqlStoredEndpoint(uri, this); + endpoint.setServiceLocationEnabled(serviceLocationEnabled); endpoint.setTemplate(template); setProperties(endpoint, parameters); @@ -73,4 +79,17 @@ public class SqlStoredComponent extends DefaultComponent { public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } + + public boolean isServiceLocationEnabled() { + return serviceLocationEnabled; + } + + /** + * Whether to detect the network address location of the JMS broker on startup. This information is gathered via + * reflection on the ConnectionFactory, and is vendor specific. This option can be used to turn this off. + */ + public void setServiceLocationEnabled(boolean serviceLocationEnabled) { + this.serviceLocationEnabled = serviceLocationEnabled; + } + } diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java index cbcb3bef458..da9dd136310 100644 --- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java +++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.sql.stored; +import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; @@ -24,12 +25,15 @@ import org.apache.camel.Category; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.component.sql.SqlServiceLocationHelper; import org.apache.camel.component.sql.stored.template.TemplateParser; +import org.apache.camel.spi.BeanIntrospection; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.PluginHelper; import org.apache.camel.util.UnsafeUriCharactersEncoder; import org.springframework.jdbc.core.JdbcTemplate; @@ -43,6 +47,10 @@ public class SqlStoredEndpoint extends DefaultEndpoint { private CallableStatementWrapperFactory wrapperFactory; private JdbcTemplate jdbcTemplate; + private boolean serviceLocationEnabled; + private String serviceUrl; + private Map<String, String> serviceMetadata; + @UriPath(description = "Sets the stored procedure template to perform. You can externalize the template by using file: or classpath: as prefix and specify the location of the file.") @Metadata(required = true, supportFileReference = true, largeInput = true, inputLanguage = "sql") private String template; @@ -73,6 +81,18 @@ public class SqlStoredEndpoint extends DefaultEndpoint { setJdbcTemplate(jdbcTemplate); } + public boolean isServiceLocationEnabled() { + return serviceLocationEnabled; + } + + /** + * Whether to detect the network address location of the JMS broker on startup. This information is gathered via + * reflection on the ConnectionFactory, and is vendor specific. This option can be used to turn this off. + */ + public void setServiceLocationEnabled(boolean serviceLocationEnabled) { + this.serviceLocationEnabled = serviceLocationEnabled; + } + @Override public Producer createProducer() throws Exception { return new SqlStoredProducer(this); @@ -100,6 +120,22 @@ public class SqlStoredEndpoint extends DefaultEndpoint { jdbcTemplate, new TemplateParser(getCamelContext().getClassResolver()), isFunction()); } + @Override + protected void doStart() throws Exception { + if (isServiceLocationEnabled()) { + // we need to use reflection to find the URL to the database, so do this once on startup + BeanIntrospection bi = PluginHelper.getBeanIntrospection(getCamelContext()); + DataSource ds = getDataSource(); + serviceUrl = SqlServiceLocationHelper.getJDBCURLFromDataSource(bi, ds); + + serviceMetadata = new HashMap<>(); + String user = SqlServiceLocationHelper.getUsernameFromConnectionFactory(bi, ds); + if (user != null) { + serviceMetadata.put("username", user); + } + } + } + @Override protected void doStop() throws Exception { super.doStop(); diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Activemq6ComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Activemq6ComponentBuilderFactory.java index 76fc4e795cf..07d82bd0ab4 100644 --- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Activemq6ComponentBuilderFactory.java +++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Activemq6ComponentBuilderFactory.java @@ -1811,6 +1811,26 @@ public interface Activemq6ComponentBuilderFactory { } + /** + * Whether to detect the network address location of the JMS broker on + * startup. This information is gathered via reflection on the + * ConnectionFactory, and is vendor specific. This option can be used to + * turn this off. + * + * The option is a: <code>boolean</code> type. + * + * Default: true + * Group: advanced + * + * @param serviceLocationEnabled the value to set + * @return the dsl builder + */ + default Activemq6ComponentBuilder serviceLocationEnabled(boolean serviceLocationEnabled) { + doSetProperty("serviceLocationEnabled", serviceLocationEnabled); + return this; + } + + /** * Sets whether synchronous processing should be strictly used. * @@ -2327,6 +2347,7 @@ public interface Activemq6ComponentBuilderFactory { case "receiveTimeout": getOrCreateConfiguration((ActiveMQComponent) component).setReceiveTimeout((long) value); return true; case "recoveryInterval": getOrCreateConfiguration((ActiveMQComponent) component).setRecoveryInterval((long) value); return true; case "requestTimeoutCheckerInterval": getOrCreateConfiguration((ActiveMQComponent) component).setRequestTimeoutCheckerInterval((long) value); return true; + case "serviceLocationEnabled": ((ActiveMQComponent) component).setServiceLocationEnabled((boolean) value); return true; case "synchronous": getOrCreateConfiguration((ActiveMQComponent) component).setSynchronous((boolean) value); return true; case "temporaryQueueResolver": getOrCreateConfiguration((ActiveMQComponent) component).setTemporaryQueueResolver((org.apache.camel.component.jms.TemporaryQueueResolver) value); return true; case "transferException": getOrCreateConfiguration((ActiveMQComponent) component).setTransferException((boolean) value); return true; diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ActivemqComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ActivemqComponentBuilderFactory.java index 691ba6eb224..db57143d20d 100644 --- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ActivemqComponentBuilderFactory.java +++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ActivemqComponentBuilderFactory.java @@ -1811,6 +1811,26 @@ public interface ActivemqComponentBuilderFactory { } + /** + * Whether to detect the network address location of the JMS broker on + * startup. This information is gathered via reflection on the + * ConnectionFactory, and is vendor specific. This option can be used to + * turn this off. + * + * The option is a: <code>boolean</code> type. + * + * Default: true + * Group: advanced + * + * @param serviceLocationEnabled the value to set + * @return the dsl builder + */ + default ActivemqComponentBuilder serviceLocationEnabled(boolean serviceLocationEnabled) { + doSetProperty("serviceLocationEnabled", serviceLocationEnabled); + return this; + } + + /** * Sets whether synchronous processing should be strictly used. * @@ -2327,6 +2347,7 @@ public interface ActivemqComponentBuilderFactory { case "receiveTimeout": getOrCreateConfiguration((ActiveMQComponent) component).setReceiveTimeout((long) value); return true; case "recoveryInterval": getOrCreateConfiguration((ActiveMQComponent) component).setRecoveryInterval((long) value); return true; case "requestTimeoutCheckerInterval": getOrCreateConfiguration((ActiveMQComponent) component).setRequestTimeoutCheckerInterval((long) value); return true; + case "serviceLocationEnabled": ((ActiveMQComponent) component).setServiceLocationEnabled((boolean) value); return true; case "synchronous": getOrCreateConfiguration((ActiveMQComponent) component).setSynchronous((boolean) value); return true; case "temporaryQueueResolver": getOrCreateConfiguration((ActiveMQComponent) component).setTemporaryQueueResolver((org.apache.camel.component.jms.TemporaryQueueResolver) value); return true; case "transferException": getOrCreateConfiguration((ActiveMQComponent) component).setTransferException((boolean) value); return true; diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AmqpComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AmqpComponentBuilderFactory.java index f3f71fd6971..94f8be22d74 100644 --- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AmqpComponentBuilderFactory.java +++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AmqpComponentBuilderFactory.java @@ -1748,6 +1748,26 @@ public interface AmqpComponentBuilderFactory { } + /** + * Whether to detect the network address location of the JMS broker on + * startup. This information is gathered via reflection on the + * ConnectionFactory, and is vendor specific. This option can be used to + * turn this off. + * + * The option is a: <code>boolean</code> type. + * + * Default: true + * Group: advanced + * + * @param serviceLocationEnabled the value to set + * @return the dsl builder + */ + default AmqpComponentBuilder serviceLocationEnabled(boolean serviceLocationEnabled) { + doSetProperty("serviceLocationEnabled", serviceLocationEnabled); + return this; + } + + /** * Sets whether synchronous processing should be strictly used. * @@ -2241,6 +2261,7 @@ public interface AmqpComponentBuilderFactory { case "receiveTimeout": getOrCreateConfiguration((AMQPComponent) component).setReceiveTimeout((long) value); return true; case "recoveryInterval": getOrCreateConfiguration((AMQPComponent) component).setRecoveryInterval((long) value); return true; case "requestTimeoutCheckerInterval": getOrCreateConfiguration((AMQPComponent) component).setRequestTimeoutCheckerInterval((long) value); return true; + case "serviceLocationEnabled": ((AMQPComponent) component).setServiceLocationEnabled((boolean) value); return true; case "synchronous": getOrCreateConfiguration((AMQPComponent) component).setSynchronous((boolean) value); return true; case "temporaryQueueResolver": getOrCreateConfiguration((AMQPComponent) component).setTemporaryQueueResolver((org.apache.camel.component.jms.TemporaryQueueResolver) value); return true; case "transferException": getOrCreateConfiguration((AMQPComponent) component).setTransferException((boolean) value); return true; diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/JmsComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/JmsComponentBuilderFactory.java index 0d6bf56c12c..6bcbc6ddd3c 100644 --- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/JmsComponentBuilderFactory.java +++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/JmsComponentBuilderFactory.java @@ -1728,6 +1728,26 @@ public interface JmsComponentBuilderFactory { } + /** + * Whether to detect the network address location of the JMS broker on + * startup. This information is gathered via reflection on the + * ConnectionFactory, and is vendor specific. This option can be used to + * turn this off. + * + * The option is a: <code>boolean</code> type. + * + * Default: true + * Group: advanced + * + * @param serviceLocationEnabled the value to set + * @return the dsl builder + */ + default JmsComponentBuilder serviceLocationEnabled(boolean serviceLocationEnabled) { + doSetProperty("serviceLocationEnabled", serviceLocationEnabled); + return this; + } + + /** * Sets whether synchronous processing should be strictly used. * @@ -2220,6 +2240,7 @@ public interface JmsComponentBuilderFactory { case "receiveTimeout": getOrCreateConfiguration((JmsComponent) component).setReceiveTimeout((long) value); return true; case "recoveryInterval": getOrCreateConfiguration((JmsComponent) component).setRecoveryInterval((long) value); return true; case "requestTimeoutCheckerInterval": getOrCreateConfiguration((JmsComponent) component).setRequestTimeoutCheckerInterval((long) value); return true; + case "serviceLocationEnabled": ((JmsComponent) component).setServiceLocationEnabled((boolean) value); return true; case "synchronous": getOrCreateConfiguration((JmsComponent) component).setSynchronous((boolean) value); return true; case "temporaryQueueResolver": getOrCreateConfiguration((JmsComponent) component).setTemporaryQueueResolver((org.apache.camel.component.jms.TemporaryQueueResolver) value); return true; case "transferException": getOrCreateConfiguration((JmsComponent) component).setTransferException((boolean) value); return true; diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SqlComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SqlComponentBuilderFactory.java index f0f0a4a1a82..2a9f78c6800 100644 --- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SqlComponentBuilderFactory.java +++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SqlComponentBuilderFactory.java @@ -157,6 +157,26 @@ public interface SqlComponentBuilderFactory { } + /** + * Whether to detect the network address location of the JMS broker on + * startup. This information is gathered via reflection on the + * ConnectionFactory, and is vendor specific. This option can be used to + * turn this off. + * + * The option is a: <code>boolean</code> type. + * + * Default: true + * Group: advanced + * + * @param serviceLocationEnabled the value to set + * @return the dsl builder + */ + default SqlComponentBuilder serviceLocationEnabled(boolean serviceLocationEnabled) { + doSetProperty("serviceLocationEnabled", serviceLocationEnabled); + return this; + } + + /** * Sets whether to use placeholder and replace all placeholder * characters with sign in the SQL queries. This option is default true. @@ -231,6 +251,7 @@ public interface SqlComponentBuilderFactory { case "lazyStartProducer": ((SqlComponent) component).setLazyStartProducer((boolean) value); return true; case "autowiredEnabled": ((SqlComponent) component).setAutowiredEnabled((boolean) value); return true; case "rowMapperFactory": ((SqlComponent) component).setRowMapperFactory((org.apache.camel.component.sql.RowMapperFactory) value); return true; + case "serviceLocationEnabled": ((SqlComponent) component).setServiceLocationEnabled((boolean) value); return true; case "usePlaceholder": ((SqlComponent) component).setUsePlaceholder((boolean) value); return true; case "healthCheckConsumerEnabled": ((SqlComponent) component).setHealthCheckConsumerEnabled((boolean) value); return true; case "healthCheckProducerEnabled": ((SqlComponent) component).setHealthCheckProducerEnabled((boolean) value); return true; diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SqlStoredComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SqlStoredComponentBuilderFactory.java index 9ef34e7c6c5..737a641b57a 100644 --- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SqlStoredComponentBuilderFactory.java +++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SqlStoredComponentBuilderFactory.java @@ -111,6 +111,26 @@ public interface SqlStoredComponentBuilderFactory { doSetProperty("autowiredEnabled", autowiredEnabled); return this; } + + + /** + * Whether to detect the network address location of the JMS broker on + * startup. This information is gathered via reflection on the + * ConnectionFactory, and is vendor specific. This option can be used to + * turn this off. + * + * The option is a: <code>boolean</code> type. + * + * Default: true + * Group: advanced + * + * @param serviceLocationEnabled the value to set + * @return the dsl builder + */ + default SqlStoredComponentBuilder serviceLocationEnabled(boolean serviceLocationEnabled) { + doSetProperty("serviceLocationEnabled", serviceLocationEnabled); + return this; + } } class SqlStoredComponentBuilderImpl @@ -129,6 +149,7 @@ public interface SqlStoredComponentBuilderFactory { case "dataSource": ((SqlStoredComponent) component).setDataSource((javax.sql.DataSource) value); return true; case "lazyStartProducer": ((SqlStoredComponent) component).setLazyStartProducer((boolean) value); return true; case "autowiredEnabled": ((SqlStoredComponent) component).setAutowiredEnabled((boolean) value); return true; + case "serviceLocationEnabled": ((SqlStoredComponent) component).setServiceLocationEnabled((boolean) value); return true; default: return false; } }