jboss fuse 教程_JBoss Fuse –使用MVEL将您的静态配置转换为动态模板
jboss fuse 教程
最近,我重新發(fā)現(xiàn)了我已經(jīng)忘記的JBoss Fuse功能,并且我認(rèn)為其他人可能會(huì)從此提醒中受益 。
這篇文章將重點(diǎn)放在JBoss Fuse和Fabric8上,但所有正在尋找最小侵入性方法來(lái)為其靜態(tài)配置文件添加一定程度的動(dòng)態(tài)支持的開(kāi)發(fā)人員也可能會(huì)感興趣。
在OSGi和Fabric8中進(jìn)行動(dòng)態(tài)配置的想法
OSGi框架因其類加載行為而經(jīng)常被人們記住。 但其中一部分還定義了框架必須實(shí)現(xiàn)的其他概念和功能。 其中之一是ConfigAdmin 。
ConfigAdmin是一項(xiàng)服務(wù),用于定義邏輯上綁定到部署單元的一組外部化的屬性文件。
此外部屬性文件的生命周期與OSGi捆綁軟件生命周期鏈接: 如果您修改外部屬性文件,則將通知您的捆綁軟件 。 根據(jù)您對(duì)捆綁軟件進(jìn)行編碼的方式,您可以決定對(duì)通知做出React,并以編程方式或通過(guò)不同的幫助程序框架(例如,藍(lán)圖) 來(lái)調(diào)用使用新配置的代碼。
這種機(jī)制既方便又強(qiáng)大,并且所有使用OSGi的開(kāi)發(fā)人員都熟悉它。
Fabric8以ConfigAdmin的思想為基礎(chǔ),并對(duì)其進(jìn)行了擴(kuò)展 。
Fabric8通過(guò)其配置功能定義了概要文件的概念,該概要文件封裝了部署單元和配置。 它在普通OSGi的基礎(chǔ)上增加了一層功能,并且允許管理任何種類的部署單元,不僅包括OSGi捆綁軟件,還包括任何種類的配置或靜態(tài)文件。
如果查看官方文檔,則會(huì)找到Fabric8層提供的“擴(kuò)展”列表,并且您會(huì)發(fā)現(xiàn)它們主要分為兩類: Url Handlers和Property Resolvers 。
我建議對(duì)本技術(shù)感興趣的每個(gè)人都仔細(xì)閱讀本文檔。 但是要提供一個(gè)簡(jiǎn)短的摘要和一個(gè)簡(jiǎn)短的示例,請(qǐng)假設(shè)您的Fabric概要文件具有使用特定占位符在運(yùn)行時(shí)解析某些值的功能。 例如
# sample url handler usage, ResourceName is a filename relative to the namespace of the containing Profile: profile:ResourceName# sample property handler, the value is read at deploy time, from the Apache Zookeeper distributed registry that is published when you run JBoss Fuse ${zk:/fabric/registry/containers/config/ContainerName/Property}開(kāi)箱即用有多個(gè)處理程序,涵蓋了開(kāi)發(fā)人員認(rèn)為最常見(jiàn)的用例:Zookeeper,配置文件,藍(lán)圖,Spring,系統(tǒng)屬性,受管端口等。
而且,您可能還想擴(kuò)展定義自己的擴(kuò)展的機(jī)制:例如,您可能想對(duì)存儲(chǔ)在某個(gè)系統(tǒng)上的性能指標(biāo)作出React,您可以編寫(xiě)一個(gè)擴(kuò)展,并使用其語(yǔ)法約定從系統(tǒng)中注入值。
所有這些功能的限制:靜態(tài)配置文件
我上面介紹的功能令人興奮且強(qiáng)大,但是它們有一個(gè)隱含的限制 : 它們僅適用于.properties文件或Fabric可以識(shí)別的文件 。
這意味著,如果您必須管理Fabric Profile,OSGi屬性或與之交互的其他特定技術(shù)(例如Camel),則這些功能可用,但是對(duì)于Fabric-Unaware而言 , 它們未啟用任何功能 。
假設(shè)您有讀取.xml配置文件的自定義代碼。 并想象您的代碼沒(méi)有引用任何Fabric對(duì)象或服務(wù)。
您的代碼將按原樣處理該.xml文件。 標(biāo)記或路徑不會(huì)有任何魔術(shù)替代,因?yàn)楸M管您在Fabric內(nèi)部運(yùn)行,但您并未使用任何直接支持的技術(shù),也未在通知Fabric時(shí)可能需要其服務(wù)。
要解決此問(wèn)題,您有3種選擇 :
什么是MVEL?
MVEL實(shí)際上是一種編程語(yǔ)言 : https : //en.wikipedia.org/wiki/MVEL 。 特別是,它也是腳本語(yǔ)言 ,您可以從源代碼直接運(yùn)行而跳過(guò)編譯步驟。
實(shí)際上,它具有多個(gè)特定的特性,可能使其很有趣地嵌入到另一個(gè)應(yīng)用程序中,并在運(yùn)行時(shí)用于定義新的行為。 例如,由于所有這些原因,它也是JBoss Drools項(xiàng)目支持的語(yǔ)言之一,可與您可能希望在運(yùn)行時(shí)定義或修改的業(yè)務(wù)規(guī)則一起使用。
為什么對(duì)我們有用? 主要有兩個(gè)原因:
模板語(yǔ)言
模板語(yǔ)言是那些語(yǔ)言家族(通常是領(lǐng)域特定語(yǔ)言),您可以在其中更改按原樣閱讀的文本的靜態(tài)部分和將在解析時(shí)處理的動(dòng)態(tài)指令 。 我可能以更復(fù)雜的方式說(shuō)出了我上面已經(jīng)介紹過(guò)的相同想法:您可以在文本中包含標(biāo)記,這些標(biāo)記將按照特定的約定進(jìn)行翻譯。
這聽(tīng)起來(lái)完全像我們上面介紹的處理程序所提供的功能。 有一個(gè)重要的區(qū)別:盡管那些是上下文特定的處理程序,但MVEL是一種通用技術(shù)。 因此,不要指望它對(duì)Zookeeper或Fabric概要文件有任何了解,而是希望它能夠支持通用編程語(yǔ)言概念,例如循環(huán),代碼調(diào)用,反射等。
面料支持它!
可以在以下位置找到對(duì)Fabric中支持的參考: http : //fabric8.io/gitbook/urlHandlers.html
但是,讓我添加一個(gè)實(shí)現(xiàn)該功能的原始代碼的一段,因?yàn)榧词乖贘Boss Fuse的上下文之外,這也是您可能會(huì)發(fā)現(xiàn)這種方法很有趣的部分: https : //github.com/fabric8io/fabric8/blob/1 .x / fabric / fabric-core / src / main / java / io / fabric8 / service / MvelUrlHandler.java#L115-L126
public InputStream getInputStream() throws IOException {assertValid();String path = url.getPath();URL url = new URL(path);CompiledTemplate compiledTemplate = TemplateCompiler.compileTemplate(url.openStream());Map<String, Object> data = new HashMap<String, Object>();Profile overlayProfile = fabricService.get().getCurrentContainer().getOverlayProfile();data.put(“profile”, Profiles.getEffectiveProfile(fabricService.get(), overlayProfile));data.put(“runtime”, runtimeProperties.get());String content = TemplateRuntime.execute(compiledTemplate, data).toString();return new ByteArrayInputStream(content.getBytes()); }這里發(fā)生了什么事?
首先,由于未在代碼段中顯示,因此請(qǐng)記住這是一個(gè)網(wǎng)址處理程序。 這意味著針對(duì)通過(guò)特定uri引用的文件觸發(fā)了行為獲取。 在這種情況下,它就是mvel: 例如,有效路徑可能是mvel:jetty.xml 。
另一個(gè)有趣且相對(duì)簡(jiǎn)單的注意事項(xiàng)是與MVEL解釋器的交互。 像大多數(shù)模板技術(shù)一樣,即使是您可以自己實(shí)現(xiàn)的最簡(jiǎn)單的技術(shù),也通常具有:
- 引擎/編譯器,這里是TemplateCompiler
- 包含模板的變量,這里是url
- 代表上下文的變量,即您要向引擎公開(kāi)的一組變量,此處為data
將它們放在一起,要求引擎完成它的工作,在這里使用TemplateRuntime.execute(...) ,您在輸出中得到的是一個(gè)靜態(tài)String。 不再使用模板指令,而是應(yīng)用了模板定義的所有邏輯,并最終從上下文中獲取了一些附加的輸入值。
一個(gè)例子
我希望我的解釋足夠簡(jiǎn)單,但是可能有一個(gè)例子是表達(dá)這一概念的最佳方法。
讓我們使用JBoss Fuse default.profile包含的jetty.xml ,它是JBoss Fuse不會(huì)作為任何特殊文件處理的靜態(tài)資源,因此它不提供任何替代功能。
我將在這里展示MVEL集成的兩個(gè)方面:從上下文變量中讀取一些值,并展示如何使用編程邏輯(這里只是2個(gè)整數(shù)的和):
<Property name="jetty.port" default="@{ Integer.valueOf( profile.configurations['org.ops4j.pax.web']['org.osgi.service.http.port'] ) + 10 }"/>我們正在修改Jetty端口的默認(rèn)值,其初始值來(lái)自“配置文件”上下文變量,該變量是可識(shí)別結(jié)構(gòu)的對(duì)象,可以訪問(wèn)其余配置:
profile.configurations['org.ops4j.pax.web']['org.osgi.service.http.port']
我們將其從String顯式轉(zhuǎn)換為Integer:
Integer.valueOf( ... )
并將靜態(tài)值10添加到返回值中:
.. + 10
讓我們保存文件,停止我們的fuse實(shí)例。 重新啟動(dòng)它并重新創(chuàng)建測(cè)試結(jié)構(gòu):
# in Fuse CLI shell shutdown -f# in bash shell rm -rf data instancesbin/fuse# in Fuse CLI shell fabric:create --wait-for-provisioning只需等待并監(jiān)視日志,然后…… 呃。 一個(gè)錯(cuò)誤! 發(fā)生了什么?
這是錯(cuò)誤:
2015-10-05 12:00:10,005 | ERROR | pool-7-thread-1 | Activator | 102 - org.ops4j.pax.web.pax-web-runtime - 3.2.5 | Unable to start pax web server: Exception while starting Jetty java.lang.RuntimeException: Exception while starting Jetty at org.ops4j.pax.web.service.jetty.internal.JettyServerImpl.start(JettyServerImpl.java:143)[103:org.ops4j.pax.web.pax-web-jetty:3.2.5] … Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)[:1.7.0_76] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)[:1.7.0_76] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)[:1.7.0_76] at java.lang.reflect.Constructor.newInstance(Constructor.java:526)[:1.7.0_76] at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.set(XmlConfiguration.java:572)[96:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415] at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:396)[96:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415] … Caused by: java.lang.NumberFormatException: For input string: “@{profile.configurations[’org.ops4j.pax.web'][‘org.osgi.service.http.port’] + 1}” at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)[:1.7.0_76] at java.lang.Integer.parseInt(Integer.java:492)[:1.7.0_76] at java.lang.Integer.<init>(Integer.java:677)[:1.7.0_76] … 29 more如果您注意到此錯(cuò)誤消息,則說(shuō)明我們的模板片段無(wú)法轉(zhuǎn)換為Number 。
為什么我們的模板代碼片段會(huì)在第一個(gè)實(shí)例中顯示? 模板引擎應(yīng)該完成其工作的一部分,并給我們返回一個(gè)靜態(tài)String,而無(wú)需任何對(duì)模板指令的引用!
我已經(jīng)故意向您顯示此錯(cuò)誤,以堅(jiān)持我上面描述的概念,但是在初審中可能不會(huì)被理解。
Fabric中對(duì)MVEL的支持是作為url處理程序?qū)崿F(xiàn)的。
到目前為止, 我們只是修改了靜態(tài)資源文件的內(nèi)容,但沒(méi)有向Fabric提供任何暗示,我們希望將該文件作為mvel模板進(jìn)行處理。
怎么做?
只是使用正確的uri引用同一文件即可。
因此,修改文件default.profile/org.ops4j.pax.web.properties ,該文件位于默認(rèn)Fabric Profile中,您可以在其中定義哪個(gè)靜態(tài)文件包含Jetty配置:
# change it from org.ops4j.pax.web.config.url=profile:jetty.xml to org.ops4j.pax.web.config.url=mvel:profile:jetty.xml現(xiàn)在,再次停止實(shí)例,刪除Fabric配置文件,重新創(chuàng)建Fabric,并注意您的Jetty實(shí)例如何正確運(yùn)行。
我們可以通過(guò)以下方式進(jìn)行檢查:
JBossFuse:karaf@root> config:list | grep org.osgi.service.http.portorg.osgi.service.http.port = 8181從瀏覽器中,您可以驗(yàn)證是否可以通過(guò)端口8191訪問(wèn)部署在Jetty頂部的JBoss Fuse Web控制臺(tái)Hawtio: http:// localhost:8191 / hawtio
翻譯自: https://www.javacodegeeks.com/2015/10/jboss-fuse-turn-your-static-config-into-dynamic-templates-with-mvel.html
jboss fuse 教程
總結(jié)
以上是生活随笔為你收集整理的jboss fuse 教程_JBoss Fuse –使用MVEL将您的静态配置转换为动态模板的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 阿里云防ddos攻击价格(阿里防ddos
- 下一篇: jboss7.0.2_红帽JBoss企业