Show Me the OSGi Bundles
23
Nov
Nov
0
源起
想要從 web/http 介面看到 OSGi 平台的 bundle 狀態,進一步也可以做 start/stop/update 控制。
JMX ?
一開始想到 JMX 轉 Http 的實做,既然用 equinox 就考慮 Resource Monitoring 專案看看, 該案目前還在孕育階段,牽涉的包非常多,請參閱下面連結。
http://www.eclipse.org/equinox/incubator/monitoring/index.php
目前只有小小意圖,簡單的秀出狀態的話,要調整並安裝這些包似乎太麻煩。於是自己來個小包,用 spring-osgi/spring-mvc 支援,實做一個 controller ,支援注入 BundleContext 的 BundleContextAware 介面,然後簡單秀出來看。
為了重複使用方便,將之前練習的 haha.hello.jetty 改為 haha.osgi.jetty。
haha.osgi.webconsole
使用之前做的 haha.osgi.jetty.HttpService ,只要設定根目錄,會自行找到 WEN-INF/web.xml 並啟動需要的 controller,所以這裡不寫註冊 Servlet 的程式, 改回原來習慣的 web.xml 方式。
META-INF/MANIFEST.MF
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: haha.osgi.webconsole Bundle-SymbolicName: haha.osgi.webconsole Bundle-Version: 1.0.0 Bundle-Localization: plugin Import-Package: javax.servlet;version="2.4.0", javax.servlet.http;version="2.4.0", org.osgi.framework;version="1.3.0" Require-Bundle: haha.remix.spring, haha.osgi.jetty
META-INF/spring/webconsole-beans.xml
<osgi:reference id="httpService" interface="haha.osgi.jetty.HttpService" /> <bean id="register" class="haha.osgi.jetty.Register" init-method="init" destroy-method="destroy"> <property name="httpService" ref="httpService" /> <property name="webappDir" value="webapp" /> <property name="contextPath" value="/osgi" /> </bean>webapp/WEB-INF/web.xml
<servlet> <servlet-name>status</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextClass</param-name> <param-value> org.springframework.osgi.context.support.OsgiWebApplicationContext </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>status</servlet-name> <url-pattern>/status</url-pattern> </servlet-mapping>
webapp/WEB-INF/status-servlet.xml
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <value>/*=statusController</value> </property> </bean> <bean id="statusController" class="haha.osgi.webconsole.StatusController"> </bean>
haha.osgi.webconsole.StatusController
public class StatusController extends AbstractController
implements BundleContextAware {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest req,
HttpServletResponse res) throws Exception {
res.setContentType("text/plain; charset=UTF-8");
PrintWriter out = res.getWriter();
Bundle[] bundles = bundleContext.getBundles();
for (Bundle bundle : bundles) {
int state = bundle.getState();
String status = "ACTIVE";
switch (state) {
case Bundle.INSTALLED:
status = "INSTALLED";
break;
[SKIP]
結果
http://127.0.0.1/osgi/status
Bundle 0 / system.bundle / ACTIVE Bundle 1 / haha.remix.jetty / ACTIVE Bundle 2 / haha.remix.spring / ACTIVE Bundle 5 / org.apache.commons.logging / ACTIVE Bundle 6 / org.eclipse.equinox.common / ACTIVE Bundle 7 / org.eclipse.osgi.services / ACTIVE Bundle 14 / haha.osgi.webconsole / ACTIVE Bundle 16 / org.eclipse.equinox.log / ACTIVE Bundle 18 / haha.osgi.jetty / ACTIVE
觀察
- 簡單使用 BundleContext 秀狀態,可以進一步做控制的實做
- 這類應用要設定三個 XML 似乎過於複雜,沒用到 spring-mvc 的功能,只是簡單 controller 其實可以用 servlet 代替。
- 轉換成 JSTL view 發生找不到 tld 的問題,變成要自帶 WEB-INF/c.tld 並改 uri 的做法,採用 eclipse buddy 機制也許也有用。主要是找不到放在別的包中的 META-INF 目錄下的 c.tld 等檔案。