OSGi 系列(十三)之 Configuration Admin Service

OSGi 系列(十三)之 Configuration Admin Service

OSGi 的 CM 就是 Configuration Admin Service,是用于管理 Bundle 属性、并在属性发生变更时通知相应的 Service,这是保持 OSGi 动态性的很关键的一个服务。

1. ConfigurationAdmin

用于管理配置数据的服务,主要有两个作用:

  • 获取配置数据
  • 更新配置数据
public class ConfigurationAdminDemo {
    private ConfigurationAdmin configurationAdmin;

    public void init() {
        try {
            Configuration conf = configurationAdmin.getConfiguration("jdbc.mysql");
            Dictionary<String, Object> dict = conf.getProperties();
            System.out.println(dict);
            
            Dictionary<String, String> properties = new Hashtable<>();
            properties.put("username", "root");
            properties.put("password", "123456");
            conf.update(properties);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public ConfigurationAdmin getConfigurationAdmin() {
        return configurationAdmin;
    }

    public void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
        this.configurationAdmin = configurationAdmin;
    }
}

blueprint.xml 配制文件:

<reference id="configurationAdmin" interface="org.osgi.service.cm.ConfigurationAdmin" />
<bean class="com.edu.osgi.cm.ConfigurationAdminDemo" init-method="init">
    <property name="configurationAdmin" ref="configurationAdmin" />
</bean> 

结果如下:

图13.1 ConfigurationAdmin结果

2. ManagedService

用来关联和操作单个配置文件的服务当相关联的配置文件发生变化的时候,会通知到相应的服务。

public class DBConfigManagedService implements ManagedService {
    public void updated(Dictionary<String, ?> properties) throws ConfigurationException {
        System.out.println("======updated======");
        System.out.println(properties);
    }
}

blueprint.xml 配制文件:

<service interface="org.osgi.service.cm.ManagedService">
    <service-properties>
        <entry key="service.pid" value="jdbc.mysql" />
    </service-properties>
    <bean class="com.edu.osgi.cm.DBConfigManagedService" />
</service>

手动修改 jdbc.mysql.cfg 文件后,结果如下:

图13.2 ManagedService结果

3. blueprint 中 cm 的使用

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
           http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd">

    <cm:property-placeholder persistent-id="jdbc.mysql.conf" update-strategy="reload"/>
    <bean class="com.edu.osgi.cm.MysqlConfig" init-method="display">    
        <property name="className" value="${className}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
    </bean>
</blueprint>

4. karaf 中 cm 命令

  • config:list "(service.pid=jdbc.mysql)" 列出 jdbc.mysql 配制文件

    图13.3 config:list

  • config:edit 编辑属性

    config:edit jdbc.mysql
    config:property-set name join
    config:update
    

5. ManagedServiceFactory

用来关联和操作多个配置文件的服务,当多个相关联的配置文件发生变化的时候,都会通知到相应的服务。

(1) 环境准备

<dependency>
    <groupId>org.osgi</groupId>
    <artifactId>org.osgi.core</artifactId>
    <version>5.0.0</version>
</dependency>
<dependency>
    <groupId>org.osgi</groupId>
    <artifactId>org.osgi.compendium</artifactId>
    <version>5.0.0</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.1.1</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.38</version>
</dependency>

(2) 实现 ManagedServiceFactory 接口

public class DataSourceServiceFactory implements ManagedServiceFactory {

    private BundleContext bundleContext;
    private Map<String, ServiceRegistration<?>> serviceMap = new ConcurrentHashMap<>();
    
    public String getName() {
        return "DataSourceServiceFactory";
    }

    // 更新配置文件
    public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
        System.out.println("============updated============");
        System.out.println(pid);
        System.out.println(properties);
        BasicDataSource bds = new BasicDataSource();
        bds.setDriverClassName(properties.get("driverClassName").toString());
        bds.setUrl(properties.get("url").toString());
        bds.setUsername(properties.get("username").toString());
        bds.setPassword(properties.get("password").toString());

        Dictionary<String, String> props = new Hashtable<>();
        props.put("instance", properties.get("instance").toString());
        
        ServiceRegistration<?> sr = bundleContext.registerService(DataSource.class.getName(), bds, props);
        System.out.println("------------");
        serviceMap.put(pid, sr);
    }

    // 删除配置文件
    public void deleted(String pid) {
        System.out.println("============deleted============");
        System.out.println(pid);
        ServiceRegistration<?> sr = serviceMap.get(pid);
        sr.unregister();
        serviceMap.remove(pid);
    }

    public void setBundleContext(BundleContext bundleContext) {
        this.bundleContext = bundleContext;
    }
}

(3) blueprint.xml

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
           http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd">

    <service interface="org.osgi.service.cm.ManagedServiceFactory">
        <service-properties>
            <entry key="service.pid" value="jdbc.datasource"/>
        </service-properties>
        <bean class="com.edu.osgi.cm.DataSourceServiceFactory">
            <property name="bundleContext" ref="blueprintBundleContext" />
        </bean>
    </service>
    
    <!--<reference interface="javax.sql.DataSource" filter="(instance=test)"/>-->
</blueprint>

(4) 测试

# 安装事务
feature:install transaction
install -s mvn:org.apache.commons/commons-pool2/2.4.2
install -s mvn:org.apache.commons/commons-dbcp2/2.1.1
install -s mvn:mysql/mysql-connector-java/5.1.18

在 deploy 目录下新建二个文件 jdbc.datasource-dev.cfg、jdbc.datasource-test.cfg(注意:文件要以 jdbc.datasource 开头,"-" 分隔)

jdbc.datasource-dev.cfg

instance=dev
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///dev
username=root
password=root

jdbc.datasource-test.cfg

instance=test
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///test
username=root
password=root

图13.4 ManagedServiceFactory测试结果

posted on 2018-03-16 19:58  binarylei  阅读(1146)  评论(0编辑  收藏  举报

导航