Karaf教程之Config Admin服务的使用
2017-12-20 13:26
204 查看
目录
摘要配置管理服务规范
如何使配置生效
引入简单的可配置类
动手实践。使用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 = ConfigApp felix.fileinstall.filename = file:/C:/java/apache-karaf-2.2.3/etc/ConfigApp.cfg title = my Title
在配置列表中你应该能够找到配置ConfigApp。这个配置显示配置文件从哪里加载的,pid标识符和在文件中设置的所有属性。
我们也可以修改配置:
> config:edit ConfigApp > config:propset title "A better title" > config:proplist service.pid = ConfigApp felix.fileinstall.filename = file:/C:/java/apache-karaf-2.2.3/etc/ConfigApp.cfg title = 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教程第3部分 使用OSGi Metatype服务和Felix Webconsole改善配置编辑
- 微软TFS云端服务TFSPreview.com使用教程
- 完美图解教程 Linux环境VNC服务安装、配置与使用 分类: B3_LINUX 2012-11-26 18:35 419人阅读 评论(0) 收藏
- 完美图解教程 Linux环境VNC服务安装、配置与使用
- 完美图解教程 Linux环境VNC服务安装、配置与使用
- SQL Server SQL Agent服务使用教程小结
- google 服务利器 HOST 使用教程
- Unity中使用WCF服务小教程
- 开源IT服务管理系统-OTRS安装使用教程
- 使用ASP.NET WEB API构建基于REST风格的服务实战系列教程(一)——使用EF6构建数据库及模型
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【二】——使用Repository模式构建数据库访问层
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【三】——Web Api入门
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【开篇】【持续更新中。。。】
- WebService服务和ajax使用教程
- WebService服务和ajax使用教程
- [教程]使用google code在线代码托管服务管理你的项目源码
- 完美图解教程 Linux环境VNC服务安装、配置与使用
- JNDI目录服务及LDAP服务器使用入门教程
- Dojo1.8系列教程四 ---- Dojo的配置(dojoConfig的使用)
- 使用.NET创建Windows系统服务及安装完全教程(收藏)