Как пройти валидационный запрос для сервера sql в среде fuse osgi - PullRequest
0 голосов
/ 24 января 2019

Как передать свойства запроса проверки, testonborrow, validationQueryTimeout источнику данных sqlserver в среде Fuse Osgi?Мы используем сервис osgi для предоставления источника данных Microsoft SQLServer.Прямо сейчас мы передаем имя источника данных, пользователя, пароль, номер_порта и имя_сервера как свойства для создания экземпляра SQLServerDataSource.Как мы можем передать свойства запроса проверки, testonborrow, testWhileIdle, testOnBorrow и т. Д., Аналогичные Apache commons dbcp?Мы наблюдаем проблемы с подключением, и мы решили их, передавая запрос проверки и т. Д. В dbcp общего доступа, и хотели сделать то же самое с источником данных SQLServer.Цените любую помощь?Вот пример того, как мы создаем экземпляр источника данных SQLServer и предоставляем его в качестве службы OSGI.

 <bean id="abcd" class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
        <property name="databaseName" value="datasourcename" />
        <property name="user" value="user" />
        <property name="password" value="password" />
        <property name="portNumber" value="portNumber" />
        <property name="serverName" value="serverName" />
 </bean>
<!-- Opening Datasource as osgi service -->
<service interface="javax.sql.DataSource" ref="abcd">
        <service-properties>
            <entry key="osgi.jndi.service.name" value="jdbc/abcd" />
        </service-properties>
</service>

1 Ответ

0 голосов
/ 24 января 2019

Вот своего рода канонический пример, который использует источник данных не XA, который вы настроили с помощью com.microsoft.sqlserver.jdbc.SQLServerDataSource:

<?xml version="1.0"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">

    <!--
        This Blueprint XML shows the _deployment_ method for data source configuration.
        With this method, it is not required to use pax-jdbc bundles at all. Instead both database-specific
        and generic data sources are declared as Blueprint beans.
        We need:
         - SQL Server driver bundle
         - mvn:org.apache.commons/commons-pool2/2.5.0 bundle
         - mvn:org.apache.commons/commons-dbcp2/2.1.1 bundle

        This Blueprint XML can be directly dropped to ${karaf.home}/deploy or archived in typical /OSGI-INF/blueprint
        directory and installed as normal bundle.
    -->

    <!--
        Database-specific, non-pooling, non-enlisting javax.sql.XADataSource
    -->
    <bean id="sqlServerDS" class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
        <property name="databaseName" value="datasourcename" />
        <property name="user" value="user" />
        <property name="password" value="password" />
        <property name="portNumber" value="portNumber" />
        <property name="serverName" value="serverName" />
    </bean>

    <!--
        Non database-specific, generic, pooling, non-XA factory for javax.sql.DataSource instances
    -->
    <bean id="dataSourceConnectionFactory" class="org.apache.commons.dbcp2.DataSourceConnectionFactory">
        <!-- pass database-specific javax.sql.DataSource -->
        <argument ref="sqlServerDS" />
    </bean>

    <!--
        Non database-specific factory for org.apache.commons.dbcp2.PoolableConnection objects
    -->
    <bean id="poolableConnectionFactory" class="org.apache.commons.dbcp2.PoolableConnectionFactory">
        <argument index="0" ref="dataSourceConnectionFactory" />
        <!-- JMX Name - not needed -->
        <argument index="1">
            <null />
        </argument>
        <property name="maxConnLifetimeMillis" value="30000" />
        <!-- set your validation query here: -->
        <property name="validationQuery" value="select schema_name, schema_owner from information_schema.schemata" />
        <!-- in seconds -->
        <property name="validationQueryTimeout" value="2" />
    </bean>

    <!--
        Pooling configuration
    -->
    <bean id="poolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
        <property name="minIdle" value="2" />
        <property name="maxTotal" value="10" />
        <property name="testOnBorrow" value="true" />
    </bean>

    <!--
        Non database-specific pool of objects provided by PoolableConnectionFactory
    -->
    <bean id="pool" class="org.apache.commons.pool2.impl.GenericObjectPool">
        <argument index="0" ref="poolableConnectionFactory" />
        <argument index="1" ref="poolConfig" />
    </bean>

    <!--
        And findally non database-specific, generic, pooling javax.sql.DataSource
    -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.PoolingDataSource">
        <argument ref="pool" />
    </bean>

    <!--
        Expose datasource to use by application code (like Camel, Spring, ...)
    -->
    <service interface="javax.sql.DataSource" ref="dataSource">
        <service-properties>
            <entry key="osgi.jndi.service.name" value="jdbc/ds" />
        </service-properties>
    </service>

</blueprint>

Я не уверен, реализует ли com.microsoft.sqlserver.jdbc.SQLServerDataSource javax.sql.XADataSource - в данном случае этобыло бы проще, так как вы могли бы использовать org.apache.commons.dbcp2.managed.BasicManagedDataSource и просто настроить его так, как вам нужно:

<bean id="pool" class="org.apache.commons.dbcp2.managed.BasicManagedDataSource">
    <property name="xaDataSourceInstance" ref="sqlServerDS" />
    <property name="transactionManager" ref="tm" />
    <property name="minIdle" value="3" />
    <property name="maxTotal" value="10" />
    <property name="validationQuery" value="select schema_name, schema_owner from information_schema.schemata" />
</bean>

Но в этом случае sqlServerDS должен быть экземпляром javax.sql.XADataSource.

РЕДАКТИРОВАТЬ: я вижу, что есть еще проблемы, описанные здесь: https://issues.apache.org/jira/browse/ARIES-960

Лично лучше создать объект, как это (извините за использование PostgreSQL):

package com.example;

import javax.sql.DataSource;

public class DataSourceFactory {

    public DataSource create() {

        // Database-specific, non-pooling, non-enlisting javax.sql.XADataSource
        org.postgresql.ds.PGSimpleDataSource postgresqlDs = new org.postgresql.ds.PGSimpleDataSource();
        postgresqlDs.setUrl("jdbc:postgresql://localhost:5432/db");
        postgresqlDs.setUser("user");
        postgresqlDs.setPassword("password");
        postgresqlDs.setCurrentSchema("schema");
        postgresqlDs.setConnectTimeout(5);

        // Non database-specific, generic, pooling, non-XA factory for javax.sql.DataSource instances
        org.apache.commons.dbcp2.DataSourceConnectionFactory dataSourceConnectionFactory
                = new org.apache.commons.dbcp2.DataSourceConnectionFactory(postgresqlDs);

        // Non database-specific factory for org.apache.commons.dbcp2.PoolableConnection objects
        org.apache.commons.dbcp2.PoolableConnectionFactory poolableConnectionFactory
                = new org.apache.commons.dbcp2.PoolableConnectionFactory(dataSourceConnectionFactory, null);
        poolableConnectionFactory.setMaxConnLifetimeMillis(30000);
        poolableConnectionFactory.setValidationQuery("select schema_name, schema_owner from information_schema.schemata");
        poolableConnectionFactory.setValidationQueryTimeout(2);

        // Pooling configuration
        org.apache.commons.pool2.impl.GenericObjectPoolConfig poolConfig
                = new org.apache.commons.pool2.impl.GenericObjectPoolConfig();
        poolConfig.setMinIdle(2);
        poolConfig.setMaxTotal(10);
        poolConfig.setTestOnBorrow(true);

        // Non database-specific pool of objects provided by PoolableConnectionFactory
        org.apache.commons.pool2.impl.GenericObjectPool<org.apache.commons.dbcp2.PoolableConnection> pool
                = new org.apache.commons.pool2.impl.GenericObjectPool<>(poolableConnectionFactory, poolConfig);

        // And finally non database-specific, generic, pooling javax.sql.DataSource
        org.apache.commons.dbcp2.PoolingDataSource<org.apache.commons.dbcp2.PoolableConnection> dataSource
                = new org.apache.commons.dbcp2.PoolingDataSource<>(pool);

        return dataSource;
    }

}

И использовать более простой план, как это:

<bean id="factory" class="com.example.DataSourceFactory">
    <!-- You can configure properties for your factory here -->
</bean>

<bean id="dataSource" factory-ref="factory" factory-method="create" />

<service interface="javax.sql.DataSource" ref="dataSource">
    <service-properties>
        <entry key="osgi.jndi.service.name" value="jdbc/ds" />
    </service-properties>
</service>
...