Keep It Simple, Stupid

简单 快乐 追求

Karaf应用中配置数据源

| Comments

我厂主要系统采用模块化开发以来,就遇到诸多的问题,不过都还可以解决。模块化我们选用了karaf这个集成组件。

开发中遇到数据源的配置问题。主要表现在每一位开发的数据库都是分开的,线上产品的数据库也是分开,线上数据库通过CMDB工具可以取到相应配置。

要解决以上需求,我们将开发和线上的datasource分成了两个独立的模块,开发对应模块xx-datasource-dev,那么线上对应的就是xx-datasource-production. 为什么要分成两个项目? 很明显,我们开发环境中没有CMDB这样工具来集中管理开发人员的数据库,目前还是开发自己在玩自己的数据库。

这样我们的开发数据库基本上依赖maven来构建。

线上的依赖CMDB在初始化客户系统的时候,创建好数据源。看起来一切很ok,但是没法重启。(因为部署的时候消息触发来取CMDB的配置信息, 重启只是重启整个karaf)

我们考虑到了,需要将线上初始化取到的CMBD配置进行持久化(写文件)。 那么在karaf环境下如何写文件和读文件呢?

我们参考了karaf官方手册的介绍。

实例

首先需要写一个POJO来处理datasource的基础属性,我们这里简单处理只设置driver | url | username | password 4个属性。

程序代码参见DatasourceConfiguration

定义一个读配置的service,可以在datasource bundle激活器被触发时候来设置数据源并进行服务注册。

程序代码参见DatasourceConfigurationQuery

程序很简单,关键是配置,目前karaf默认配置应用的是blueprint

配置代码参见datasourceConfiguration.xml

以上配置是比较关键的。在整个bundle加载的时候会将karaf的/etc/datasource.prop.cfg文件对应起来,并可以通过config命令进行写入值,也可以读取值。

对于在发布该bundle的时候,需要将对应的文件也写入到指定的文件目录:

代码参见features.xml

另外要考虑的如何才能符合上述的格式进行安装(configfile).

需要在编译安装的时候进行生成,在pom.xml需要用到插件。

代码参见pom.xml

这样写好后,只需要在karaf里面安装该bundle,然后去指定文件目录确定该文件是否生成。生成后,就可以用karaf提供的config命令来进行设置值了。

在后续的datasource bundle的激活器中进行存储和获取。 存取方式分为2种:

  1. config:list | config:edit
  2. 应用ConfigurationAdmin 程序实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private ConfigurationAdmin configAdmin;

private void updateDatasourceProp(final DatasourceProp datasourceProp) {
        try {
            Configuration configuration = configAdmin.getConfiguration(DatasourceProp.PID);
            Dictionary<String,Object> props = new Hashtable<String,Object>();
            props.put(DatasourceProp.URL_KEY, datasourceProp.getUrl());
            props.put(DatasourceProp.USERNAME_KEY, datasourceProp.getUsername());
            props.put(DatasourceProp.PASSWORD_KEY, datasourceProp.getPassword());
            props.put(DatasourceProp.MIGRATION_KEY, datasourceProp.getMigration());
            configuration.setBundleLocation(null);
            configuration.update(props);
        } catch (final Exception e) {
            logger.error("reason : datasourceProp update failure", e);
            throw new ExceptionInInitializerError(e);
        }
    }
    
<reference id="configAdmin" interface="org.osgi.service.cm.ConfigurationAdmin"/>

Comments