目录

摘要
配置管理服务规范
如何使配置生效
引入简单的可配置类
动手实践。使用OSGi接口方式实现配置
例子运行
深入Karaf配置命令
使用Blueprint配置
部署配置文件
总结和展望未来
参考文献

摘要

在Karaf教程的第一部分,我们学习了如何使用maven和blueprint提供和使用pojo服务,以及如何使用http服务发布一个servlet。
在第二部分,我们关注OSGi bundles的配置。和servlet容器不同,对于配置OSGi包含了一个非常好的规范:来自OSGi企业规范的配置管理服务。在该教程中,将涉及分别通过OSGi和blueprint方式来使用配置管理服务,以及如何使配置文件和bundles自动化部署。

教程的代码可以在github查阅,地址Here

配置管理服务规范

首先我们看下配置服务规范概览。这里使用到主要有以下两个接口:

  • ConfigurationAdmin -允许检索和改变配置。这个服务是配置管理服务实现提供的接口。

  • ManagedService -配置发生改变的时候,允许做出响应。你不得不实现这个接口,并且把它注册为一个服务来获取通告。

所以基本上在配置管理服务中的配置是一个字典,这个字典包含了属性和相应的值。字典被一个持久化标识符(persistent identifier (pid))标识.标识是一个简单的字符串,且唯一的标识该配置。

如何使配置生效

可以通过使用ConfigurationAdmin.getConfiguration接口检索一个配置,但不推荐这么做。OSGi是动态的以至于可能发生这样的情况,bundles在config admin服务或者config admin服务还没有读取配置之前启动了。所以有时可能获取到一个null配置。

因此推荐的方式是使用ManagedService服务来监听更新。如果因为没有配置bundle不能启动,则可在第一次更新消息被接收的时,通过创建一个可配置的pojo对象是一个不错的主意。

引入简单的可配置类

按照需求,可配置的类应该是pojo。虽然可以简单地实现ManagedService接口并直接使用Dictionary,这需要依赖于OSGi和当前的Config Admin Service规范。因此改用一个具有title属性的简单bean类。另外添加了一个刷新方法,在配置项被更改之后应该被调用。

public class MyApp {String title;public void setTitle(String title) {this.title = title;}public void refresh() {System.out.println("Configuration updated (title=" + title + ")");}
}

我们的目的是配置tilte,当配置改变的时候要调用refresh方法。我们将使用OSGi方式和blueprint两种方式实现。

动手实践。使用OSGi接口方式实现配置

首先在本节展示通过使用OSGi接口如何使用config admin服务。然而这绝不可能是你以后要这么实现。这仅仅是帮助你理解在钩子下发生了什么。
你可以在这个子目录下configapp找到实现(https://github.com/cschneider/Karaf-Tutorial/tree/master/configadmin/configapp)
首先我们需要一个pom文件用于maven编译。你最好从例子中configapp的pom开始看起。
如果你才刚开始,你将不得不使用maven-bundle-plugin编译你的工程为一个OSGi bundle,且你需要添加两个依赖:

<dependency><groupId>org.osgi</groupId><artifactId>org.osgi.compendium</artifactId><version>4.2.0</version>
</dependency>
<dependency><groupId>org.osgi</groupId><artifactId>org.osgi.core</artifactId><version>4.2.0</version>
</dependency>

第一个依赖是用于config admin服务相关接口,第二个依赖是用于创建Activator和包含基本的OSGi相关的接口。

现在我们将专注修订MyApp类。下面的类达到了目的。我们实现了ManagedService接口用于和Config Admin服务交互。无论什么时候配置发生变化,ConfigUpdater都被调用。
第一件事是检查是否为null,这个情况是可能发生的,当config被移除的时候。关于这个步骤我们可以停掉MyApp运行,但是为了保持简单我们仅仅是忽略了这些问题。下一步是创建一个MyApp实例。
正常情况,你将在Activator完成这个步骤,但是你将不得不考虑空配置的情况,这种情况不是我们期望的。最后一步是简单地从config获取一个值传入setter方法并调用,且在设置完所有配置后调用refresh方法。

private final class ConfigUpdater implements ManagedService {public void updated(Dictionary config) throws ConfigurationException {if (config == null) {return;}if (app == null) {app = new MyApp();}app.setTitle((String)config.get("title"));app.refresh();}
}

当然这样还没有完成所有事情,最后一步是在Activator.start注册ConfigUpdater。类似其他服务一样我们简单地使用了registerService。唯一特别的事情是你不得不设置属性SERVICE_PID到你的配置pid,这样Config Admin服务就知道你想要监听的是什么配置了。

Hashtable<String, Object> properties = new Hashtable<String, Object>();
properties.put(Constants.SERVICE_PID, CONFIG_PID);
serviceReg = context.registerService(ManagedService.class.getName(), new ConfigUpdater() , properties);

例子运行

  • 运行mvn install编译工程.
  • 启动一个新的Karaf实例
  • 从target目录复制configapp.jar bundle到Karaf deploy目录

现在我们注意到好像什么事都没发生。在Karaf控制台调用list你应该能够看到bundle实际上是已经启动,但是却没有任何输出,因为没有配置。我们仍然需要创建配置文件和设置tilte。
- 复制已经存在的文件/configadmin-features/src/main/resources/ConfigApp.cfg 到Karaf实例中的/etc目录

这里重要的部分是文件名必须是.cfg。这样config admin服务能够发现它。

现在fileinstall bundle将在etc目录下侦测到新的文件。当以.cfg结尾的文件将被当作配置管理资源且根据文件名pid来创建或者更新对应的Config Admin服务配置。

所以现在你应该在Karaf控制台能看到如下输出。这显示了配置的变化被检测和转发。如果你现在用编辑器修改文件内容和保存修改,修改将被通告。

Configuration updated (title=" + title + ")

深入Karaf配置命令

在Karaf控制台输入如下:

> config:list
Pid:            ConfigApp
BundleLocation: file:/C:/java/apache-karaf-2.2.3/deploy/configapp.jar
Properties:service.pid = ConfigAppfelix.fileinstall.filename = file:/C:/java/apache-karaf-2.2.3/etc/ConfigApp.cfgtitle = my Title

在配置列表中你应该能够找到配置ConfigApp。这个配置显示配置文件从哪里加载的,pid标识符和在文件中设置的所有属性。

我们也可以修改配置:

> config:edit ConfigApp
> config:propset title "A better title"
> config:proplistservice.pid = ConfigAppfelix.fileinstall.filename = file:/C:/java/apache-karaf-2.2.3/etc/ConfigApp.cfgtitle = A better title
> config:update
Configuration updated (title=A better title)

我们发现修订直接通告到bundle,如果你查看etc下配置文件,你可以发现修订也被持久化到文件了。所以在重启Karaf后修订仍然生效。

使用Blueprint配置

继我们用OSGi实现和Config Admin服务交互后,现在我们将看下使用Blueprint怎么实现相同的功能。幸运地是这种方式十分的简单,Blueprint做了大部分的事情。

简单的定义一个cm:property-placeholder元素。类似文件中的属性占位符但是这个是和Config Admin服务起作用。我们需要提供config PID和更新策略。当我们选择reload策略,这意味着一个修订发生,blueprint的上下文环境会重新加载反映这个修订。当config PID没有找到或者属性不存在,将设置为默认属性值。

和bean类集成通常是一个简单的bean定义,这个bean是定义了title属性和分配了一个占位符。通过使用config admin服务解析这个占位符。唯一特别是的事情是init-method。
这被用于在配置修订后,我们机会去做相应的事情。例如上面的OSGi例子。

因为blueprint我们不需要任何maven依赖,因此java代码仅是一个Java bean时。通过把它放在OSGI-INF/blueprintblueprint目录和blueprint extender被加载,环境很容易被激活。因为在Karaf中blueprint总是被加载,所以我们不需要做其他事情。

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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://svn.apache.org/repos/asf/aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd]
">
<cm:property-placeholder persistent-id="ConfigApp" update-strategy="reload" >
<cm:default-properties>
<cm:property name="title" value="Default Title"/>
</cm:default-properties>
</cm:property-placeholder><bean id="myApp" init-method="refresh">
<property name="title" value="$\{title\}"></property>
</bean>
</blueprint>

上面xml请删除title附近的反斜杠。这个仅仅是了避免当wiki macro解析错误的影响。

部署配置文件

在我们已经成功地使用Config Admin服务后,进入产品环境唯一的事情就是部署bundle和一个默认配置。这个可以通过使用一个Karaf的feature文件来完成。我们根据需要的bunldes定义一个feature,和简单添加一个configfile元素。这个使得Karaf部署指定文件到karaf安装的etc目录下。如果文件已经存在,它不会被覆盖。

<feature name="tutorial-configadmin" version="${pom.version}">
<bundle>mvn:net.lr.tutorial.configadmin/configapp/${pom.version}</bundle>
<bundle>mvn:net.lr.tutorial.configadmin/configapp-blueprint/${pom.version}</bundle>
<configfile finalname="/etc/ConfigApp.cfg">mvn:net.lr.tutorial.configadmin/configadmin-features/${pom.version}/cfg</configfile>
</feature>

最后一个问题是怎么部署配置到maven使得configfile能够发现它。这个有点类似feature和build-helper-maven-plugin关系,详情请看pom文件怎么使用它。

总结和展望未来

在这个教程中,我们已经学习了Config Admin服务是怎么工作的以及如何使用OSGi和blueprint。我们也明白了如何编译及如何把文档和我们的工程部署在一起。

然而这里还是有一些非常有用的小细节没有涉及到。第一个细节是configfile不总是和config admin服务一致。实事上Karaf没有使用config admin服务去部署文件。我们所看到的是,已经存在的config元素不仅写配置到config admin服务中,而且持久化了它。幸运的是我的同事Jean Baptiste已经在研究这方面相关的,请访问Here

另外一个细节是对于企业环境,第一,需要定制化的config admin服务。例如需要在整网集中的地方设置配置和友好的UI界面。第二,是你不仅仅想要部署默认配置,而是部署对于系统管理确实需要的配置。所以针对安装的bunldes和feature和必要配置的修订,我认为你应该定一个部署计划。如果这个被正确的完成。将有利于部署和配置修订的检查,同时也有利于在某些配置错误的情况下去回滚修订。我希望我们可以在下一个Talend ESB EE发行版本提供一些相关功能。

参考文献

Using the Configuration Admin Service


Karaf教程之Config Admin服务的使用相关推荐

  1. 【SAP PO】SAP PO 接口配置完整教程之二REST服务对接

    SAP PO 接口配置完整教程之二REST服务对接 1.了解服务协议 1.1.服务通讯协议 1.2.具体接口协议 1.3.接口服务测试 2.PO端接口配置 2.1.PO端ESR配置 2.2.PO端IB ...

  2. Karaf教程第2部分使用Configuration Admin服务

    原文地址  http://blog.csdn.net/wusandi/article/details/78172920 在Karaf教程的第1部分,我们学习了如何使用maven和blueprint提供 ...

  3. Nmap扫描教程之DNS服务类

    Nmap扫描教程之DNS服务类 Nmap DNS服务类 DNS(Domain Name System,域名系统)的作用就是将主机名解析为对应IP地址的过程.通常主机域名的一般结构为:主机名.三级域名. ...

  4. dSploitzANTI渗透教程之HTTP服务重定向地址

    dSploitzANTI渗透教程之HTTP服务重定向地址 HTTP服务 HTTP服务主要用于重定向地址的.当用户创建一个钓鱼网站时,可以通过使用HTTP服务指定,并通过实施中间人攻击,使客户端访问该钓 ...

  5. DNS域欺骗攻击详细教程之Windows篇

    一.DNS域欺骗攻击原理 DNS欺骗即域名信息欺骗是最常见的DNS安全问题.当一个DNS服务器掉入陷阱,使用了来自一个恶意DNS服务器的错误信息,那么该DNS服务器就被欺骗了.DNS欺骗会使那些易受攻 ...

  6. Kail Linux渗透测试教程之在Metasploit中扫描

    Kail Linux渗透测试教程之在Metasploit中扫描 在Metasploit中扫描 在Metasploit中,附带了大量的内置扫描器.使用这些扫描器可以搜索并获得来自一台计算机或一个完整网络 ...

  7. ECSHOP模板堂教程之:目录结构

    2016 ecshop模板堂教程之:目录结构网站:知识库来源:网络收集----------- -------- ---------- ------------ ------ ------------- ...

  8. Wireshark数据抓包教程之Wireshark的基础知识

    Wireshark数据抓包教程之Wireshark的基础知识 Wireshark的基础知识 在这个网络信息时代里,计算机安全始终是一个让人揪心的问题,网络安全则有过之而无不及.Wireshark作为国 ...

  9. thymeleaf加载不了js引用_web前端教程之js中的模块化一

    web前端教程之js中的模块化一:我们知道最常见的模块化方案有CommonJS.AMD.CMD.ES6,AMD规范一般用于浏览器,异步的,因为模块加载是异步的,js解释是同步的,所以有时候导致依赖还没 ...

最新文章

  1. dubbo web工程示例_dubbo实战之二:与SpringBoot集成
  2. 聚类(序)——监督学习与无监督学习
  3. 利用gcc的__attribute__编译属性section子项构建初始化函数表【转】
  4. 学习Python最好的途径——激发自己的学习兴趣!
  5. Andorid之华为手机开发模式不打印日志
  6. 排位重要还是媳妇儿重要?
  7. linux 终端调用MATLAB程序
  8. hdu 3530 Subsequence 单调队列
  9. php多表查询 例子,thinkphp学习笔记之多表查询
  10. SLF4J: The requested version 1.5.8 by your slf4j
  11. 手机计算机音乐软件,“自从拥有了这三款软件,我把电脑、手机上的音乐播放器全部卸载了”...
  12. stm32万年历流程图_基于 STM32 RTC的万年历
  13. 计算机专业表情包图片,各个专业表情包盘点 | 你的专业也有自己专属表情包吗?...
  14. ES--highlight(高亮)查询
  15. JAVA访问控制权限
  16. 高中辍学,三年间做遍各种零工,转行程序员改变人生
  17. github问题之Unable to retrieve your user info from the server
  18. 全国大学生数学建模竞赛2012A题葡萄酒的评价MATLAB程序
  19. BSD维基百科,自由的百科全书
  20. 三国记系列游戏,第二部《三国记-乱世群雄》发布

热门文章

  1. 网易100天---26、What Is Artificial Intelligence (AI)?
  2. 如何提高公司部门间协作效率
  3. 计算机管理控制台损坏,电脑开机提示“WINDOWSSYSTEM32CONFIGSYSTEM文件损坏”
  4. Pyinstaller 4.4官方手册 3# Pyinstaller是什么?是如何工作的?
  5. canvas上纯JS实现可滑动时间刻度轴
  6. 2019中国爱分析数据智能高峰论坛(北京)
  7. 面对元宇宙算力瓶颈,AI算力专家宁畅开出三大秘方
  8. 【Go】超详细Go入门
  9. 一环(令牌)将它们全部统治
  10. 烟台市副高职称英语计算机考试试题,山东省烟台市2015年度全国职称外语等级考试科目、级别及题型...