Karaf教程之Config Admin服务的使用
目錄
摘要
配置管理服務(wù)規(guī)范
如何使配置生效
引入簡單的可配置類
動手實踐。使用OSGi接口方式實現(xiàn)配置
例子運行
深入Karaf配置命令
使用Blueprint配置
部署配置文件
總結(jié)和展望未來
參考文獻
摘要
在Karaf教程的第一部分,我們學(xué)習了如何使用maven和blueprint提供和使用pojo服務(wù),以及如何使用http服務(wù)發(fā)布一個servlet。
在第二部分,我們關(guān)注OSGi bundles的配置。和servlet容器不同,對于配置OSGi包含了一個非常好的規(guī)范:來自O(shè)SGi企業(yè)規(guī)范的配置管理服務(wù)。在該教程中,將涉及分別通過OSGi和blueprint方式來使用配置管理服務(wù),以及如何使配置文件和bundles自動化部署。
教程的代碼可以在github查閱,地址Here
配置管理服務(wù)規(guī)范
首先我們看下配置服務(wù)規(guī)范概覽。這里使用到主要有以下兩個接口:
ConfigurationAdmin -允許檢索和改變配置。這個服務(wù)是配置管理服務(wù)實現(xiàn)提供的接口。
ManagedService -配置發(fā)生改變的時候,允許做出響應(yīng)。你不得不實現(xiàn)這個接口,并且把它注冊為一個服務(wù)來獲取通告。
所以基本上在配置管理服務(wù)中的配置是一個字典,這個字典包含了屬性和相應(yīng)的值。字典被一個持久化標識符(persistent identifier (pid))標識.標識是一個簡單的字符串,且唯一的標識該配置。
如何使配置生效
可以通過使用ConfigurationAdmin.getConfiguration接口檢索一個配置,但不推薦這么做。OSGi是動態(tài)的以至于可能發(fā)生這樣的情況,bundles在config admin服務(wù)或者config admin服務(wù)還沒有讀取配置之前啟動了。所以有時可能獲取到一個null配置。
因此推薦的方式是使用ManagedService服務(wù)來監(jiān)聽更新。如果因為沒有配置bundle不能啟動,則可在第一次更新消息被接收的時,通過創(chuàng)建一個可配置的pojo對象是一個不錯的主意。
引入簡單的可配置類
按照需求,可配置的類應(yīng)該是pojo。雖然可以簡單地實現(xiàn)ManagedService接口并直接使用Dictionary,這需要依賴于OSGi和當前的Config Admin Service規(guī)范。因此改用一個具有title屬性的簡單bean類。另外添加了一個刷新方法,在配置項被更改之后應(yīng)該被調(diào)用。
public class MyApp {String title;public void setTitle(String title) {this.title = title;}public void refresh() {System.out.println("Configuration updated (title=" + title + ")");} }我們的目的是配置tilte,當配置改變的時候要調(diào)用refresh方法。我們將使用OSGi方式和blueprint兩種方式實現(xiàn)。
動手實踐。使用OSGi接口方式實現(xiàn)配置
首先在本節(jié)展示通過使用OSGi接口如何使用config admin服務(wù)。然而這絕不可能是你以后要這么實現(xiàn)。這僅僅是幫助你理解在鉤子下發(fā)生了什么。
你可以在這個子目錄下configapp找到實現(xiàn)(https://github.com/cschneider/Karaf-Tutorial/tree/master/configadmin/configapp)
首先我們需要一個pom文件用于maven編譯。你最好從例子中configapp的pom開始看起。
如果你才剛開始,你將不得不使用maven-bundle-plugin編譯你的工程為一個OSGi bundle,且你需要添加兩個依賴:
第一個依賴是用于config admin服務(wù)相關(guān)接口,第二個依賴是用于創(chuàng)建Activator和包含基本的OSGi相關(guān)的接口。
現(xiàn)在我們將專注修訂MyApp類。下面的類達到了目的。我們實現(xiàn)了ManagedService接口用于和Config Admin服務(wù)交互。無論什么時候配置發(fā)生變化,ConfigUpdater都被調(diào)用。
第一件事是檢查是否為null,這個情況是可能發(fā)生的,當config被移除的時候。關(guān)于這個步驟我們可以停掉MyApp運行,但是為了保持簡單我們僅僅是忽略了這些問題。下一步是創(chuàng)建一個MyApp實例。
正常情況,你將在Activator完成這個步驟,但是你將不得不考慮空配置的情況,這種情況不是我們期望的。最后一步是簡單地從config獲取一個值傳入setter方法并調(diào)用,且在設(shè)置完所有配置后調(diào)用refresh方法。
當然這樣還沒有完成所有事情,最后一步是在Activator.start注冊ConfigUpdater。類似其他服務(wù)一樣我們簡單地使用了registerService。唯一特別的事情是你不得不設(shè)置屬性SERVICE_PID到你的配置pid,這樣Config Admin服務(wù)就知道你想要監(jiān)聽的是什么配置了。
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目錄復(fù)制configapp.jar bundle到Karaf deploy目錄
現(xiàn)在我們注意到好像什么事都沒發(fā)生。在Karaf控制臺調(diào)用list你應(yīng)該能夠看到bundle實際上是已經(jīng)啟動,但是卻沒有任何輸出,因為沒有配置。我們?nèi)匀恍枰獎?chuàng)建配置文件和設(shè)置tilte。
- 復(fù)制已經(jīng)存在的文件/configadmin-features/src/main/resources/ConfigApp.cfg 到Karaf實例中的/etc目錄
這里重要的部分是文件名必須是.cfg。這樣config admin服務(wù)能夠發(fā)現(xiàn)它。
現(xiàn)在fileinstall bundle將在etc目錄下偵測到新的文件。當以.cfg結(jié)尾的文件將被當作配置管理資源且根據(jù)文件名pid來創(chuàng)建或者更新對應(yīng)的Config Admin服務(wù)配置。
所以現(xiàn)在你應(yīng)該在Karaf控制臺能看到如下輸出。這顯示了配置的變化被檢測和轉(zhuǎn)發(fā)。如果你現(xiàn)在用編輯器修改文件內(nèi)容和保存修改,修改將被通告。
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在配置列表中你應(yīng)該能夠找到配置ConfigApp。這個配置顯示配置文件從哪里加載的,pid標識符和在文件中設(shè)置的所有屬性。
我們也可以修改配置:
> 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)我們發(fā)現(xiàn)修訂直接通告到bundle,如果你查看etc下配置文件,你可以發(fā)現(xiàn)修訂也被持久化到文件了。所以在重啟Karaf后修訂仍然生效。
使用Blueprint配置
繼我們用OSGi實現(xiàn)和Config Admin服務(wù)交互后,現(xiàn)在我們將看下使用Blueprint怎么實現(xiàn)相同的功能。幸運地是這種方式十分的簡單,Blueprint做了大部分的事情。
簡單的定義一個cm:property-placeholder元素。類似文件中的屬性占位符但是這個是和Config Admin服務(wù)起作用。我們需要提供config PID和更新策略。當我們選擇reload策略,這意味著一個修訂發(fā)生,blueprint的上下文環(huán)境會重新加載反映這個修訂。當config PID沒有找到或者屬性不存在,將設(shè)置為默認屬性值。
和bean類集成通常是一個簡單的bean定義,這個bean是定義了title屬性和分配了一個占位符。通過使用config admin服務(wù)解析這個占位符。唯一特別是的事情是init-method。
這被用于在配置修訂后,我們機會去做相應(yīng)的事情。例如上面的OSGi例子。
因為blueprint我們不需要任何maven依賴,因此java代碼僅是一個Java bean時。通過把它放在OSGI-INF/blueprintblueprint目錄和blueprint extender被加載,環(huán)境很容易被激活。因為在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解析錯誤的影響。
部署配置文件
在我們已經(jīng)成功地使用Config Admin服務(wù)后,進入產(chǎn)品環(huán)境唯一的事情就是部署bundle和一個默認配置。這個可以通過使用一個Karaf的feature文件來完成。我們根據(jù)需要的bunldes定義一個feature,和簡單添加一個configfile元素。這個使得Karaf部署指定文件到karaf安裝的etc目錄下。如果文件已經(jīng)存在,它不會被覆蓋。
<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能夠發(fā)現(xiàn)它。這個有點類似feature和build-helper-maven-plugin關(guān)系,詳情請看pom文件怎么使用它。
總結(jié)和展望未來
在這個教程中,我們已經(jīng)學(xué)習了Config Admin服務(wù)是怎么工作的以及如何使用OSGi和blueprint。我們也明白了如何編譯及如何把文檔和我們的工程部署在一起。
然而這里還是有一些非常有用的小細節(jié)沒有涉及到。第一個細節(jié)是configfile不總是和config admin服務(wù)一致。實事上Karaf沒有使用config admin服務(wù)去部署文件。我們所看到的是,已經(jīng)存在的config元素不僅寫配置到config admin服務(wù)中,而且持久化了它。幸運的是我的同事Jean Baptiste已經(jīng)在研究這方面相關(guān)的,請訪問Here
另外一個細節(jié)是對于企業(yè)環(huán)境,第一,需要定制化的config admin服務(wù)。例如需要在整網(wǎng)集中的地方設(shè)置配置和友好的UI界面。第二,是你不僅僅想要部署默認配置,而是部署對于系統(tǒng)管理確實需要的配置。所以針對安裝的bunldes和feature和必要配置的修訂,我認為你應(yīng)該定一個部署計劃。如果這個被正確的完成。將有利于部署和配置修訂的檢查,同時也有利于在某些配置錯誤的情況下去回滾修訂。我希望我們可以在下一個Talend ESB EE發(fā)行版本提供一些相關(guān)功能。
參考文獻
Using the Configuration Admin Service
總結(jié)
以上是生活随笔為你收集整理的Karaf教程之Config Admin服务的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tikz作图教程:说说图形颜色填充那些事
- 下一篇: ps – report process