1. 程式人生 > >Karaf教程之Config Admin服務的使用

Karaf教程之Config Admin服務的使用

目錄

摘要
配置管理服務規範
如何使配置生效
引入簡單的可配置類
動手實踐。使用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發行版本提供一些相關功能。

參考文獻

myqrcode

相關推薦

Karaf教程Config Admin服務的使用

目錄 摘要 配置管理服務規範 如何使配置生效 引入簡單的可配置類 動手實踐。使用OSGi介面方式實現配置 例子執行 深入Karaf配置命令 使用Blueprint配置 部署配置檔案 總結和展望未來

開發者教程資料檢索服務系列 | 第一期:資料檢索在網約車行業的應用

為滿足開發者多樣性的地圖服務使用需求,百度地圖開放平臺對外開放了多類地圖API服務。在眾多的地圖API服務中,和地理資料檢索相關的服務是開發者使用次數最多,同時也是應用範圍最廣的服務,以此為代表的有地點檢索服務、逆地理編碼服務等。為了方便廣大開發者快速接入服務,滿足業務需求,

Discuz!論壇教程修改admin.php防止直接惡意訪問

開啟admin.php檔案 找到 $discuz->init(); 在下面加上程式碼: if(!$_G['uid'] || !getstatus($_G['member']['allowadmi

Axis2/C入門教程二(服務端實現詳細分析)

本文承接Axis2/C入門教程之一,詳細分析服務端程式碼hello_svc.c的實現。hello_svc.c程式碼如下:#include <axis2_svc_skeleton.h> #include <axutil_log_default.h> #i

Karaf教程第2部分 使用Configuration Admin服務

    在Karaf教程的第1部分,我們學習瞭如何使用maven和blueprint提供和使用pojo服務,如何使用http服務釋出servlet。     在第2部分,我們集中精力關注OSGi bundle的配置。不像servlet容器,OSGi容器包含一個非常好的配置

WCF系列教程WCF服務宿主

class ati 托管 系列 msm scm 打開 實例 部分 本文參考自http://www.cnblogs.com/wangweimutou/p/4377062.html,純屬讀書筆記,加深記憶。 一、簡介 任何一個程序的運行都需要依賴一個確定的進程中,WCF也不例外

WCF系列教程客戶端異步調用服務

1.5 void 添加引用 dsl idt pan important 配置 但是 本文參考自http://www.cnblogs.com/wangweimutou/p/4409227.html,純屬讀書筆記,加深記憶 一、簡介 在前面的隨筆中,詳細的介紹了WCF客戶端服務

WCF系列教程WCF服務協定

需要 通信 mes 配置 ace 交換 對象 web服務 程序 本文參考自:http://www.cnblogs.com/wangweimutou/p/4422883.html,純屬讀書筆記,加深記憶 一、服務協定簡介: 1、WCF所有的服務協定層裏面的服務接口,都有一個S

菜鳥教程工具使用(五)——JRebel與Windows服務的Tomcat集成

-m end 個人 再見 proc key pre 安裝 target 之前寫過一篇Tomcat借助JRebel支持熱部署的文章——《借助JRebel使Tomcat支持熱部署 》。介紹的是在開發、測試環境中的配置。可是正式的部署環境。我們不會通過命令行來啟動Tomcat,

Spring Boot 入門(四)微服務 Config Server 統一配置中心

bootstra pan pat 默認 star default client efault localhost 一、目錄結構 二、pom文件 <!-- 配置服務依賴 --> <dependency> &l

h5房卡牛牛源碼搭建架設教程微信端和電腦端服務器架構

超時 教程 80年 學生 服務器架構 通信 es2017 jpg 基礎上 類型1:卡牌、跑酷等弱交互服務端  卡牌跑酷類因為交互弱,玩家和玩家之間不需要實時面對面PK,打一下對方的離線數據,計算下排行榜,買賣下道具即可,所以實現往往使用簡單的 HTTP服務器:

【前端】CentOS 7 系列教程五: 安裝最新版 nginx 並設置 nginx 代理轉發 node 服務

con config get http ati sha cal 安裝 pre 轉載請註明出處:http://www.cnblogs.com/shamoyuu/p/linux_5.html 進入/usr/local目錄 cd /usr/local 下載最新

SpringCloud 教程 服務消費(Feign)

cat artifact 獲取 run println pac tro pro 應用程序 1、啟動服務註冊應用 可參考 SpringCloud 教程 之一 服務註冊與服務發現(Eureka) 創建 springcloud-eureka-server 服務註冊工程,並啟動

SpringCloud 教程 服務發現(Eureka Discovery Client + Ribbon)

1、啟動服務註冊中心 可參考 SpringCloud 教程 之一 服務註冊中心及服務註冊(Eureka Server + Eureka Client) 第1節 建立【服務註冊中心】工程,即 Eureka Server。建立並執行工程。 2、建立服務提供者工程 2.1、新建Spring Boot 工程 s

vue iview-admin使用教程路由配置 -- 齊梟飛-web前端架構

功執行iview-admin之後,您就可以開始動手修改它,將自己的內容替換進去了。 首先最基礎也是最重要的,應該說是路由配置,路由配置裡目前有三種類型的配置,對應三種頁面的展示 成功執行iview-admin之後,您就可以開始動手修改它,將自己的內容替換進去了。

OpenVPM系列圖文教程(一)—— Windows下搭建服務端、客戶端配置

背景:公司移動APP需要使用吶網服務,就順便研究了一下各種搭建方式,廢話不說看教程! 本文測試環境 雲香港 ECS 1 核 1GB (新人2折) Windows server 2012 R2 Datacenter Intel® Xeon® CPU

服務入門教程<環境搭建>:Springboot+mybatis+themleaf+zookeeper+dubbo

首先說明下我這裡用的環境是:Springboot+mybatis+themleaf;Linxu下安裝Ubuntu,JDK1.8,zookeeper,dubbo 沒有用Docker,其實可以用Docker拉取這些映象,只不過我嫌麻煩,就先用這個了,其實只要掌握了Docker如何拉取映象,設定固定IP之後,用法

OpenVPN 系列圖文教程(一)—— Windows下搭建VPN服務端、客戶端配置

背景:公司移動APP需要使用VPN服務,就順便研究了一下各種VPN的搭建,突然發現買個阿里雲香港伺服器自己用也是不錯的選擇哈哈,廢話不說看教程! 本文測試環境 阿里雲香港 ECS 1 核 1GB(簡約型 t1, ecs.t1.small) 領取優惠

Spring Cloud入門教程服務消費者 Feign(三)(Finchley版本+Boot2.0)

什麼是Feign?         Feign是受到Retrofit,JAXRS-2.0和WebSocket的影響,它是一個java的到http客戶端繫結的開源專案。 Feign的主要目標是將Java Http 客戶端變得簡單。 推薦部落格: 常見錯誤:

nginx負載均衡教程從不用root編譯開始! + flask + uwsgi 部署高併發網路服務

編譯使用nginx without root! 之前閱讀了很過國內的部落格,對nginx在linux下的使用都是一筆帶過,這個給後面的使用造成了很大的麻煩!尤其是在不用root怎麼安裝這塊!本部分詳細的講解,供新人使用!此處參考了一個國外人的[wiki