[tx-control] Improvements for the Local and XA JDBC ResourceProviders:
* Add Metatypes
* Avoid publishing "." properties
* Ensure that tracked services are DataSourceFactories
git-svn-id: https://svn.apache.org/repos/asf/aries/trunk/tx-control@1751615 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/tx-control-provider-jdbc-local/pom.xml b/tx-control-provider-jdbc-local/pom.xml
index 4e84990..07b0b31 100644
--- a/tx-control-provider-jdbc-local/pom.xml
+++ b/tx-control-provider-jdbc-local/pom.xml
@@ -79,6 +79,10 @@
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.jdbc</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.service.metatype.annotations</artifactId>
+ </dependency>
<!-- Hikari CP dependency -->
<dependency>
diff --git a/tx-control-provider-jdbc-local/src/main/java/org/apache/aries/tx/control/jdbc/local/impl/Config.java b/tx-control-provider-jdbc-local/src/main/java/org/apache/aries/tx/control/jdbc/local/impl/Config.java
new file mode 100644
index 0000000..c3e5c32
--- /dev/null
+++ b/tx-control-provider-jdbc-local/src/main/java/org/apache/aries/tx/control/jdbc/local/impl/Config.java
@@ -0,0 +1,90 @@
+package org.apache.aries.tx.control.jdbc.local.impl;
+
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DATABASE_NAME;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DATASOURCE_NAME;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DESCRIPTION;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_NETWORK_PROTOCOL;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_PASSWORD;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_PORT_NUMBER;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_ROLE_NAME;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_SERVER_NAME;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_URL;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_USER;
+
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.AttributeType;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+@ObjectClassDefinition(factoryPid="org.apache.aries.tx.control.jdbc.local", description="Aries Transaction Control Factory for Local JDBCResourceProvider Services")
+public @interface Config {
+
+ // Most commonly used properties declared first so that they go into the metatype first
+
+ @AttributeDefinition(required=false,
+ description="The name of the driver class for the DataSourceFactory service. This property need not be defined if aries.dsf.target.filter is defined.")
+ String osgi_jdbc_driver_class();
+
+ @AttributeDefinition(required=false, description="The JDBC URL to pass to the DataSourceFactory")
+ String url();
+
+ @AttributeDefinition(required=false, description="The userid to pass to the DataSourceFactory")
+ String user();
+
+ @AttributeDefinition(type=AttributeType.PASSWORD, required=false,
+ description="The password to pass to the DataSourceFactory (not visible as a service property)")
+ String password();
+
+ // Pool configuration properties
+
+ @AttributeDefinition(required=false, description="Is connection pooling enabled for this JDBCResourceProvider")
+ boolean osgi_connection_pooling_enabled() default true;
+
+ @AttributeDefinition(required=false, description="The maximum number of connections in the pool")
+ int osgi_connection_max() default 10;
+
+ @AttributeDefinition(required=false, description="The minimum number of connections in the pool")
+ int osgi_connection_min() default 10;
+
+ @AttributeDefinition(required=false, description="The maximum time (in ms) that the pool will wait for a connection before failing")
+ long osgi_connection_timeout() default 30000;
+
+ @AttributeDefinition(required=false, description="The minimum time (in ms) a connection will be idle before being reclaimed by the pool")
+ long osgi_idle_timeout() default 180000;
+
+ @AttributeDefinition(required=false, description="The maximum time (in ms) that a connection will stay in the pool before being discarded")
+ long osgi_connection_lifetime() default 10800000;
+
+ // Detailed Configuration
+
+ @AttributeDefinition(required=false, description="The filter to use when finding the DataSourceFactory service. This property need not be defined if osgi.jdbc.driver.class is defined.")
+ String aries_dsf_target_filter();
+
+ @AttributeDefinition(required=false, description="The names of the properties from this configuration that should be passed to the DataSourceFactory")
+ String[] aries_jdbc_property_names() default {JDBC_DATABASE_NAME, JDBC_DATASOURCE_NAME,
+ JDBC_DESCRIPTION, JDBC_NETWORK_PROTOCOL, JDBC_PASSWORD, JDBC_PORT_NUMBER, JDBC_ROLE_NAME, JDBC_SERVER_NAME,
+ JDBC_URL, JDBC_USER};
+
+
+ //Raw JDBC configuration
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String databaseName();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String dataSourceName();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String description();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String networkProtocol();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ int portNumber();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String roleName();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String serverName();
+}
diff --git a/tx-control-provider-jdbc-local/src/main/java/org/apache/aries/tx/control/jdbc/local/impl/ManagedServiceFactoryImpl.java b/tx-control-provider-jdbc-local/src/main/java/org/apache/aries/tx/control/jdbc/local/impl/ManagedServiceFactoryImpl.java
index 007a2d7..db09ac2 100644
--- a/tx-control-provider-jdbc-local/src/main/java/org/apache/aries/tx/control/jdbc/local/impl/ManagedServiceFactoryImpl.java
+++ b/tx-control-provider-jdbc-local/src/main/java/org/apache/aries/tx/control/jdbc/local/impl/ManagedServiceFactoryImpl.java
@@ -166,7 +166,7 @@
throw new ConfigurationException(OSGI_JDBC_DRIVER_CLASS,
"The configuration must specify either a target filter or a JDBC driver class");
}
- targetFilter = "(" + OSGI_JDBC_DRIVER_CLASS + "=" + driver + ")";
+ targetFilter = "(&(" + OBJECTCLASS + "=" + DataSourceFactory.class.getName() + ")(" + OSGI_JDBC_DRIVER_CLASS + "=" + driver + "))";
}
targetFilter = "(&(" + OBJECTCLASS + "=" + DataSourceFactory.class.getName() + ")" + targetFilter + ")";
@@ -214,7 +214,9 @@
private Dictionary<String, ?> getServiceProperties() {
Hashtable<String, Object> props = new Hashtable<>();
- providerProperties.keySet().stream().filter(s -> !JDBC_PASSWORD.equals(s))
+ providerProperties.keySet().stream()
+ .filter(s -> !s.startsWith("."))
+ .filter(s -> !JDBC_PASSWORD.equals(s))
.forEach(s -> props.put(s, providerProperties.get(s)));
return props;
}
diff --git a/tx-control-provider-jdbc-xa/pom.xml b/tx-control-provider-jdbc-xa/pom.xml
index 8cd493c..2d42086 100644
--- a/tx-control-provider-jdbc-xa/pom.xml
+++ b/tx-control-provider-jdbc-xa/pom.xml
@@ -78,6 +78,10 @@
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.jdbc</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.service.metatype.annotations</artifactId>
+ </dependency>
<!-- Hikari CP dependency -->
<dependency>
diff --git a/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/Config.java b/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/Config.java
new file mode 100644
index 0000000..cb71589
--- /dev/null
+++ b/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/Config.java
@@ -0,0 +1,98 @@
+package org.apache.aries.tx.control.jdbc.xa.impl;
+
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DATABASE_NAME;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DATASOURCE_NAME;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_DESCRIPTION;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_NETWORK_PROTOCOL;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_PASSWORD;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_PORT_NUMBER;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_ROLE_NAME;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_SERVER_NAME;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_URL;
+import static org.osgi.service.jdbc.DataSourceFactory.JDBC_USER;
+
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.AttributeType;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+@ObjectClassDefinition(factoryPid="org.apache.aries.tx.control.jdbc.xa", description="Aries Transaction Control Factory for XA enabled JDBCResourceProvider Services")
+public @interface Config {
+
+ // Most commonly used properties declared first so that they go into the metatype first
+
+ @AttributeDefinition(required=false,
+ description="The name of the driver class for the DataSourceFactory service. This property need not be defined if aries.dsf.target.filter is defined.")
+ String osgi_jdbc_driver_class();
+
+ @AttributeDefinition(required=false, description="The JDBC URL to pass to the DataSourceFactory")
+ String url();
+
+ @AttributeDefinition(required=false, description="The userid to pass to the DataSourceFactory")
+ String user();
+
+ @AttributeDefinition(type=AttributeType.PASSWORD, required=false,
+ description="The password to pass to the DataSourceFactory (not visible as a service property)")
+ String password();
+
+ // Pool configuration properties
+
+ @AttributeDefinition(required=false, description="Is connection pooling enabled for this JDBCResourceProvider")
+ boolean osgi_connection_pooling_enabled() default true;
+
+ @AttributeDefinition(required=false, description="The maximum number of connections in the pool")
+ int osgi_connection_max() default 10;
+
+ @AttributeDefinition(required=false, description="The minimum number of connections in the pool")
+ int osgi_connection_min() default 10;
+
+ @AttributeDefinition(required=false, description="The maximum time (in ms) that the pool will wait for a connection before failing")
+ long osgi_connection_timeout() default 30000;
+
+ @AttributeDefinition(required=false, description="The minimum time (in ms) a connection will be idle before being reclaimed by the pool")
+ long osgi_idle_timeout() default 180000;
+
+ @AttributeDefinition(required=false, description="The maximum time (in ms) that a connection will stay in the pool before being discarded")
+ long osgi_connection_lifetime() default 10800000;
+
+ // Transaction integration configuration
+
+ @AttributeDefinition(required=false, description="Should this Resource participate in transactions using XA")
+ boolean osgi_xa_enabled() default true;
+
+ @AttributeDefinition(required=false, description="Should this Resource participate as a Local Resource if XA is not available")
+ boolean osgi_local_enabled() default true;
+
+ // Detailed Configuration
+
+ @AttributeDefinition(required=false, description="The filter to use when finding the DataSourceFactory service. This property need not be defined if osgi.jdbc.driver.class is defined.")
+ String aries_dsf_target_filter();
+
+ @AttributeDefinition(required=false, description="The names of the properties from this configuration that should be passed to the DataSourceFactory")
+ String[] aries_jdbc_property_names() default {JDBC_DATABASE_NAME, JDBC_DATASOURCE_NAME,
+ JDBC_DESCRIPTION, JDBC_NETWORK_PROTOCOL, JDBC_PASSWORD, JDBC_PORT_NUMBER, JDBC_ROLE_NAME, JDBC_SERVER_NAME,
+ JDBC_URL, JDBC_USER};
+
+
+ //Raw JDBC configuration
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String databaseName();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String dataSourceName();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String description();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String networkProtocol();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ int portNumber();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String roleName();
+
+ @AttributeDefinition(required=false, description="JDBC configuration property")
+ String serverName();
+}
diff --git a/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/ManagedServiceFactoryImpl.java b/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/ManagedServiceFactoryImpl.java
index 28c9f16..ee18aa1 100644
--- a/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/ManagedServiceFactoryImpl.java
+++ b/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/impl/ManagedServiceFactoryImpl.java
@@ -166,7 +166,7 @@
throw new ConfigurationException(OSGI_JDBC_DRIVER_CLASS,
"The configuration must specify either a target filter or a JDBC driver class");
}
- targetFilter = "(" + OSGI_JDBC_DRIVER_CLASS + "=" + driver + ")";
+ targetFilter = "(&(" + OBJECTCLASS + "=" + DataSourceFactory.class.getName() + ")(" + OSGI_JDBC_DRIVER_CLASS + "=" + driver + "))";
}
targetFilter = "(&(" + OBJECTCLASS + "=" + DataSourceFactory.class.getName() + ")" + targetFilter + ")";
@@ -214,7 +214,9 @@
private Dictionary<String, ?> getServiceProperties() {
Hashtable<String, Object> props = new Hashtable<>();
- providerProperties.keySet().stream().filter(s -> !JDBC_PASSWORD.equals(s))
+ providerProperties.keySet().stream()
+ .filter(s -> !s.startsWith("."))
+ .filter(s -> !JDBC_PASSWORD.equals(s))
.forEach(s -> props.put(s, providerProperties.get(s)));
return props;
}