jboss fuse 教程_JBoss Fuse –使用MVEL将您的静态配置转换为动态模板
jboss fuse 教程
最近,我重新發現了我已經忘記的JBoss Fuse功能,并且我認為其他人可能會從此提醒中受益 。
這篇文章將重點放在JBoss Fuse和Fabric8上,但所有正在尋找最小侵入性方法來為其靜態配置文件添加一定程度的動態支持的開發人員也可能會感興趣。
在OSGi和Fabric8中進行動態配置的想法
OSGi框架因其類加載行為而經常被人們記住。 但其中一部分還定義了框架必須實現的其他概念和功能。 其中之一是ConfigAdmin 。
ConfigAdmin是一項服務,用于定義邏輯上綁定到部署單元的一組外部化的屬性文件。
此外部屬性文件的生命周期與OSGi捆綁軟件生命周期鏈接: 如果您修改外部屬性文件,則將通知您的捆綁軟件 。 根據您對捆綁軟件進行編碼的方式,您可以決定對通知做出React,并以編程方式或通過不同的幫助程序框架(例如,藍圖) 來調用使用新配置的代碼。
這種機制既方便又強大,并且所有使用OSGi的開發人員都熟悉它。
Fabric8以ConfigAdmin的思想為基礎,并對其進行了擴展 。
Fabric8通過其配置功能定義了概要文件的概念,該概要文件封裝了部署單元和配置。 它在普通OSGi的基礎上增加了一層功能,并且允許管理任何種類的部署單元,不僅包括OSGi捆綁軟件,還包括任何種類的配置或靜態文件。
如果查看官方文檔,則會找到Fabric8層提供的“擴展”列表,并且您會發現它們主要分為兩類: Url Handlers和Property Resolvers 。
我建議對本技術感興趣的每個人都仔細閱讀本文檔。 但是要提供一個簡短的摘要和一個簡短的示例,請假設您的Fabric概要文件具有使用特定占位符在運行時解析某些值的功能。 例如
# 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}開箱即用有多個處理程序,涵蓋了開發人員認為最常見的用例:Zookeeper,配置文件,藍圖,Spring,系統屬性,受管端口等。
而且,您可能還想擴展定義自己的擴展的機制:例如,您可能想對存儲在某個系統上的性能指標作出React,您可以編寫一個擴展,并使用其語法約定從系統中注入值。
所有這些功能的限制:靜態配置文件
我上面介紹的功能令人興奮且強大,但是它們有一個隱含的限制 : 它們僅適用于.properties文件或Fabric可以識別的文件 。
這意味著,如果您必須管理Fabric Profile,OSGi屬性或與之交互的其他特定技術(例如Camel),則這些功能可用,但是對于Fabric-Unaware而言 , 它們未啟用任何功能 。
假設您有讀取.xml配置文件的自定義代碼。 并想象您的代碼沒有引用任何Fabric對象或服務。
您的代碼將按原樣處理該.xml文件。 標記或路徑不會有任何魔術替代,因為盡管您在Fabric內部運行,但您并未使用任何直接支持的技術,也未在通知Fabric時可能需要其服務。
要解決此問題,您有3種選擇 :
什么是MVEL?
MVEL實際上是一種編程語言 : https : //en.wikipedia.org/wiki/MVEL 。 特別是,它也是腳本語言 ,您可以從源代碼直接運行而跳過編譯步驟。
實際上,它具有多個特定的特性,可能使其很有趣地嵌入到另一個應用程序中,并在運行時用于定義新的行為。 例如,由于所有這些原因,它也是JBoss Drools項目支持的語言之一,可與您可能希望在運行時定義或修改的業務規則一起使用。
為什么對我們有用? 主要有兩個原因:
模板語言
模板語言是那些語言家族(通常是領域特定語言),您可以在其中更改按原樣閱讀的文本的靜態部分和將在解析時處理的動態指令 。 我可能以更復雜的方式說出了我上面已經介紹過的相同想法:您可以在文本中包含標記,這些標記將按照特定的約定進行翻譯。
這聽起來完全像我們上面介紹的處理程序所提供的功能。 有一個重要的區別:盡管那些是上下文特定的處理程序,但MVEL是一種通用技術。 因此,不要指望它對Zookeeper或Fabric概要文件有任何了解,而是希望它能夠支持通用編程語言概念,例如循環,代碼調用,反射等。
面料支持它!
可以在以下位置找到對Fabric中支持的參考: http : //fabric8.io/gitbook/urlHandlers.html
但是,讓我添加一個實現該功能的原始代碼的一段,因為即使在JBoss Fuse的上下文之外,這也是您可能會發現這種方法很有趣的部分: 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()); }這里發生了什么事?
首先,由于未在代碼段中顯示,因此請記住這是一個網址處理程序。 這意味著針對通過特定uri引用的文件觸發了行為獲取。 在這種情況下,它就是mvel: 例如,有效路徑可能是mvel:jetty.xml 。
另一個有趣且相對簡單的注意事項是與MVEL解釋器的交互。 像大多數模板技術一樣,即使是您可以自己實現的最簡單的技術,也通常具有:
- 引擎/編譯器,這里是TemplateCompiler
- 包含模板的變量,這里是url
- 代表上下文的變量,即您要向引擎公開的一組變量,此處為data
將它們放在一起,要求引擎完成它的工作,在這里使用TemplateRuntime.execute(...) ,您在輸出中得到的是一個靜態String。 不再使用模板指令,而是應用了模板定義的所有邏輯,并最終從上下文中獲取了一些附加的輸入值。
一個例子
我希望我的解釋足夠簡單,但是可能有一個例子是表達這一概念的最佳方法。
讓我們使用JBoss Fuse default.profile包含的jetty.xml ,它是JBoss Fuse不會作為任何特殊文件處理的靜態資源,因此它不提供任何替代功能。
我將在這里展示MVEL集成的兩個方面:從上下文變量中讀取一些值,并展示如何使用編程邏輯(這里只是2個整數的和):
<Property name="jetty.port" default="@{ Integer.valueOf( profile.configurations['org.ops4j.pax.web']['org.osgi.service.http.port'] ) + 10 }"/>我們正在修改Jetty端口的默認值,其初始值來自“配置文件”上下文變量,該變量是可識別結構的對象,可以訪問其余配置:
profile.configurations['org.ops4j.pax.web']['org.osgi.service.http.port']
我們將其從String顯式轉換為Integer:
Integer.valueOf( ... )
并將靜態值10添加到返回值中:
.. + 10
讓我們保存文件,停止我們的fuse實例。 重新啟動它并重新創建測試結構:
# in Fuse CLI shell shutdown -f# in bash shell rm -rf data instancesbin/fuse# in Fuse CLI shell fabric:create --wait-for-provisioning只需等待并監視日志,然后…… 呃。 一個錯誤! 發生了什么?
這是錯誤:
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如果您注意到此錯誤消息,則說明我們的模板片段無法轉換為Number 。
為什么我們的模板代碼片段會在第一個實例中顯示? 模板引擎應該完成其工作的一部分,并給我們返回一個靜態String,而無需任何對模板指令的引用!
我已經故意向您顯示此錯誤,以堅持我上面描述的概念,但是在初審中可能不會被理解。
Fabric中對MVEL的支持是作為url處理程序實現的。
到目前為止, 我們只是修改了靜態資源文件的內容,但沒有向Fabric提供任何暗示,我們希望將該文件作為mvel模板進行處理。
怎么做?
只是使用正確的uri引用同一文件即可。
因此,修改文件default.profile/org.ops4j.pax.web.properties ,該文件位于默認Fabric Profile中,您可以在其中定義哪個靜態文件包含Jetty配置:
# change it from org.ops4j.pax.web.config.url=profile:jetty.xml to org.ops4j.pax.web.config.url=mvel:profile:jetty.xml現在,再次停止實例,刪除Fabric配置文件,重新創建Fabric,并注意您的Jetty實例如何正確運行。
我們可以通過以下方式進行檢查:
JBossFuse:karaf@root> config:list | grep org.osgi.service.http.portorg.osgi.service.http.port = 8181從瀏覽器中,您可以驗證是否可以通過端口8191訪問部署在Jetty頂部的JBoss Fuse Web控制臺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 教程
總結
以上是生活随笔為你收集整理的jboss fuse 教程_JBoss Fuse –使用MVEL将您的静态配置转换为动态模板的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云防ddos攻击价格(阿里防ddos
- 下一篇: 无食品备案证罚款(无食品备案证)