Karaf教程第2部分使用Configuration Admin服务
原文地址? http://blog.csdn.net/wusandi/article/details/78172920
????
? 在Karaf教程的第1部分,我們學(xué)習(xí)了如何使用maven和blueprint提供和使用pojo服務(wù),如何使用http服務(wù)發(fā)布servlet。
????在第2部分,我們集中精力關(guān)注OSGi bundle的配置。不像servlet容器,OSGi容器包含一個(gè)非常好的配置規(guī)范:來自企業(yè)級(jí)規(guī)范的Config Admin服務(wù)。在本教程中,我們將在純OSGi和blueprint中使用Config Admin服務(wù),學(xué)習(xí)如何在bundle中自動(dòng)部署配置文件。
????這個(gè)教程的練習(xí)可以在github上找到:https://github.com/cschneider/Karaf-Tutorial/tree/master/configadmin。
2.1 Configuration?Admin服務(wù)規(guī)范
我們首先快速概覽一下Configuration Admin服務(wù)規(guī)范。對(duì)于我們來說,主要有兩個(gè)接口可以使用:
1、ConfigurationAdmin:允許獲取和改變配置。這個(gè)服務(wù)由Config Admin服務(wù)實(shí)現(xiàn)提供。
2、ManagedService:允許對(duì)配置改變產(chǎn)生影響。必須實(shí)現(xiàn)這個(gè)接口,并將它注冊(cè)給要被通知的服務(wù)。
????所以,基本上在Config Admin服務(wù)中的配置是一個(gè)字典,這個(gè)字典包含了屬性和他們的值。字典由持久性標(biāo)識(shí)PID標(biāo)識(shí)。PID就是一個(gè)簡(jiǎn)單的字符串,它唯一標(biāo)識(shí)了配置。
2.2 如何處理配置?
????雖然你可以使用ConfigurationAdmin.getConfiguration接口獲取配置,但是我不推薦你這么做。OSGi是動(dòng)態(tài)的,所以有可能發(fā)生bundle在Config Admin服務(wù)之前啟動(dòng)或者Config Admin服務(wù)還沒有讀取這個(gè)bundle的配置。所以有時(shí)候你獲取的配置可能為null。
????所以,推薦的方式是使用ManagedService,并對(duì)更新做出反應(yīng)。如果你的bundle沒有配置無法啟動(dòng),那么在收到第一個(gè)更新時(shí)創(chuàng)建一個(gè)要被配置的pojo類是個(gè)好主意。
2.3 介紹要被配置的非常簡(jiǎn)單的類
????由于我們想要實(shí)現(xiàn)一個(gè)整潔風(fēng)格的配置,那么要被配置的類應(yīng)該是純pojo。雖然可以簡(jiǎn)單的實(shí)現(xiàn)ManagedService接口,直接使用Dictionary,但這將使你依賴于OSGi和當(dāng)前的Config Admin規(guī)范。所以,替代做法是我們使用一個(gè)具有title熟悉的簡(jiǎn)單的bean類。另外,我增加了一個(gè)刷新方法,當(dāng)配置發(fā)生改變的時(shí)候來調(diào)用刷新方法。
[java]?view plaincopy
所以我們的目標(biāo)就是當(dāng)配置發(fā)生改變時(shí),配置title,然后調(diào)用refresh方法。我們將在純OSGi和blueprint中做這件事。
2.4 練習(xí)一下:使用純OSGi接口處理配置
????本教程的第1個(gè)練習(xí)演示如何只用OSGi接口使用Config Admin服務(wù)。雖然這可能不是你以后使用的方式,但這種方式可以幫助你理解更深層次的東西。
????你可以在子目錄configapp中找到實(shí)現(xiàn):(https://github.com/cschneider/Karaf-Tutorial/tree/master/configadmin/configapp)。
????所以首先我們需要一個(gè)pom文件用于maven構(gòu)建。你最好從configapp示例程序的pom文件開始。如果你新建了新的工程,你必須是使用maven-bundle-plugin插件使你的工程成為一個(gè)bundle,你需要添加兩個(gè)依賴:
[html]?view plaincopy?
????第一個(gè)依賴用于獲取config admin服務(wù)接口,第二個(gè)依賴用于創(chuàng)建Activator,它包含基本的OSGi接口。
????現(xiàn)在,我們關(guān)心如何更新MyApp類。下面這個(gè)類解決了這個(gè)問題。我們實(shí)現(xiàn)了ManagedService接口,來與Config Admin服務(wù)交互。所以無論什么時(shí)候,配置發(fā)生改變,我們的方法都會(huì)被調(diào)用。第一件事是檢查是否為null,當(dāng)config被移除時(shí)這是有可能發(fā)生的。這時(shí)我們可以停止MyApp,但為了簡(jiǎn)單起見,我們只是忽略它。下一步是創(chuàng)建MyApp類。通常你可能會(huì)在Activator中實(shí)例化它,但是你不得不處理空配置,這是我們不希望的。最后是簡(jiǎn)單地用從config中獲取的值調(diào)用setter方法,在所有的設(shè)置完成后再調(diào)用refresh方法。
[java]?view plaincopy
????當(dāng)然,這還是什么事情都沒做。最后一步就是在Activator.start方法中注冊(cè)ConfigUpdater。我們簡(jiǎn)單地使用registerService方法,就像每一個(gè)其他的服務(wù)一樣。唯一特殊的地方是你必須設(shè)置SERVICE_PID為config pid,這樣Config Admin服務(wù)就知道你想要監(jiān)視的配置了。
[java]?view plaincopy
2.5 運(yùn)行這個(gè)簡(jiǎn)單的示例
?用mvn install命令構(gòu)建這個(gè)工程
?啟動(dòng)一個(gè)全新的karaf實(shí)例
?將configapp.jar從target目錄復(fù)制到Karaf的deploy目錄
????現(xiàn)在我們注意到似乎沒有發(fā)生任何事情。在Karaf控制臺(tái)調(diào)用list,你會(huì)看到這個(gè)bundle確實(shí)已經(jīng)啟動(dòng)了,但是它沒有任何輸出,因?yàn)樗€沒有配置。我們?nèi)匀恍枰獎(jiǎng)?chuàng)建配置文件,并設(shè)置title。
?復(fù)制已有的文件/configadmin-features/src/main/resources/ConfigApp.cfg到Karaf的/etc目錄
????這里重要的部分是文件名必須是<pid>.cfg。這樣config admin服務(wù)才能找到它。
????現(xiàn)在fileinstall bundle會(huì)在etc目錄檢測(cè)到新的文件。由于文件結(jié)尾是.cfg,它認(rèn)為這是一個(gè)config admin資源,創(chuàng)建或更新由文件名確定的pid的Config Admin服務(wù)配置。
所以現(xiàn)在在Karaf控制臺(tái)你應(yīng)該能看到下面的打印。這個(gè)打印顯示了配置改變被正確地檢測(cè)和轉(zhuǎn)發(fā)。如果你現(xiàn)在用編輯器改變了這個(gè)文件并保存,那么這個(gè)變化也會(huì)被傳播。
?
2.6 使用Karaf config命令探究配置
在Karaf控制臺(tái)鍵入如下命令:
?
在其他的配置中,你應(yīng)該找到上面的配置"ConfigApp"。這個(gè)配置顯示它從哪兒加載的,pid,當(dāng)然還有在文件中設(shè)置的所有屬性。
我們也可以改變這個(gè)配置:
?
我們看到這個(gè)修改直接傳播到了我們的bundle。如果你看看etc下面的配置文件,你會(huì)發(fā)現(xiàn)這個(gè)改變已經(jīng)持久化到了這個(gè)文件。所以如果我們重啟了Karaf,修改還是生效的。
2.7 使用Blueprint配置
????在純OSGi環(huán)境中處理了Config Admin服務(wù)之后,現(xiàn)在我們將看一看如何在Blueprint中實(shí)現(xiàn)同樣的功能。幸運(yùn)地是,這是相當(dāng)容易,就Blueprint為我們做的大多數(shù)的工作一樣。
????我們僅僅定義了一個(gè)cm:property-placeholder元素。這個(gè)處理文件的屬性占位符的功能很相似,但是這里是處理Config Admin服務(wù)。我們需要提供一個(gè)配置的PID和更新策略。更新策略我們選擇“reload”。這意味著在配置改變之后,blueprint上下文會(huì)被重新加載或反射改變。我們也設(shè)置了默認(rèn)的屬性,當(dāng)配置的PID找不到或者屬性不存在的時(shí)候,就會(huì)使用這些默認(rèn)值。
????集成我們的bean類通常是一個(gè)簡(jiǎn)單的bean定義。在這個(gè)類中我們定義了title熟悉,分配一個(gè)占位符,這個(gè)占位符會(huì)使用config admin服務(wù)進(jìn)行解析。唯一特別的是初始化方法。這個(gè)給了我們機(jī)會(huì)以便對(duì)配置改變之后做出反應(yīng),就像純OSGi示例中一樣。
對(duì)于bluenprint來說,我們不需要任何maven的依賴,因?yàn)槲覀兊?/span>Java代碼是純Java bean。只要將Blueprint上下文放在OSGI-INF/blueprint目錄中并且blueprint extender加載了,那么blueprint上下文就被會(huì)簡(jiǎn)單地激活。由于As blueprint總是在Karaf中被加載,所以我們什么都不需要做。
[html]?view plaincopy2.8 Deploying config files
在我們成功地使用了Config Admin服務(wù)之后,剩下要做的唯一一件事就是部署帶默認(rèn)配置的bundle。這可以使用Karaf feature文件實(shí)現(xiàn)。我們定義一個(gè)feature,帶有它需要的bundle,簡(jiǎn)單地添加一個(gè)configfile元素。這使得Karaf部署給定的文件到Karaf安裝位置的etc目錄。如果這個(gè)文件已經(jīng)存在,那么它不會(huì)被覆蓋。
[html]?view plaincopy
這樣,最后一個(gè)問題是如何將配置部署到maven,讓configfileonfig元素能夠找到它。這好像屬于Karaf中的the build-helper-maven-plugin的特性。請(qǐng)參見pom文件了解使用細(xì)節(jié)。
?
2.9 Summing it up and a look into the future
????在本教程中,我們學(xué)習(xí)了如何使用Config Admin服務(wù)以及如何在純OSGi和blueprint中使用該服務(wù)。我們也看到了如何構(gòu)建和部署我們的工程。
????雖然這已經(jīng)很有用了,但在我看來,有一點(diǎn)點(diǎn)小問題。第一個(gè)問題是configfile似乎看起來與config admin不一致。實(shí)際上,Karaf不使用config admin服務(wù)部署文件。所以我想要看到的是已經(jīng)存在的config元素不僅僅是為了寫入配置,而且還用于持久化。幸運(yùn)地是,我的同事Jean Baptiste正在研究這個(gè)問題。參見https://issues.apache.org/jira/browse/KARAF-888。
????另一個(gè)問題是對(duì)于企業(yè)級(jí)環(huán)境,需要具有附加特性的config admin服務(wù)。一件是要可能在整個(gè)服務(wù)器網(wǎng)絡(luò)中進(jìn)行配置,具有配置的中心源和友好的UI。另一件事是你不僅想要部署默認(rèn)的配置,而且要部署管理員真正想要為系統(tǒng)進(jìn)行的配置。所以,我想你能夠定義一個(gè)部署計(jì)劃,不僅要安裝bundle和feature,還需要配置的改變。如果這個(gè)正確的完成,將允許部署、配置改變的良好檢查,也允許管理員一旦在出錯(cuò)的情況下回滾配置的變化。我希望我們可以在下一個(gè)Talend ESB EE發(fā)布版中提供這樣的計(jì)劃。
總結(jié)
以上是生活随笔為你收集整理的Karaf教程第2部分使用Configuration Admin服务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小李子日记。
- 下一篇: Prometheus 实战于源码分析之s