<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Extreme Pattern: Show Me the OSGi Bundles </title>
    <link>http://blog.extremepattern.com/articles/2006/11/23/show-me-the-osgi-bundles</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>enjoy</description>
    <item>
      <title>Show Me the OSGi Bundles </title>
      <description>&lt;h3&gt;源起&lt;/h3&gt;


	&lt;p&gt;想要從 web/http 介面看到 OSGi 平台的 bundle 狀態，進一步也可以做 start/stop/update 控制。&lt;/p&gt;


	&lt;h3&gt;&lt;span class="caps"&gt;JMX&lt;/span&gt; ?&lt;/h3&gt;


	&lt;p&gt;一開始想到 &lt;span class="caps"&gt;JMX&lt;/span&gt; 轉 Http 的實做，既然用 equinox 就考慮 Resource Monitoring 專案看看，
該案目前還在孕育階段，牽涉的包非常多，請參閱下面連結。&lt;/p&gt;


	&lt;p&gt;http://www.eclipse.org/equinox/incubator/monitoring/index.php&lt;/p&gt;


	&lt;p&gt;目前只有小小意圖，簡單的秀出狀態的話，要調整並安裝這些包似乎太麻煩。於是自己來個小包，用 spring-osgi/spring-mvc 支援，實做一個 controller ，支援注入 BundleContext 的 BundleContextAware 介面，然後簡單秀出來看。&lt;/p&gt;


	&lt;p&gt;為了重複使用方便，將之前練習的 haha.hello.jetty 改為 haha.osgi.jetty。&lt;/p&gt;


	&lt;h3&gt;haha.osgi.webconsole&lt;/h3&gt;


	&lt;p&gt;使用之前做的 haha.osgi.jetty.HttpService ，只要設定根目錄，會自行找到 
&lt;span class="caps"&gt;WEN&lt;/span&gt;-INF/web.xml 並啟動需要的 controller，所以這裡不寫註冊 Servlet 的程式，
改回原來習慣的 web.xml 方式。&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;META&lt;/span&gt;-INF/MANIFEST.MF&lt;/p&gt;


&lt;pre&gt;
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
&lt;/pre&gt;

	&lt;p&gt;&lt;span class="caps"&gt;META&lt;/span&gt;-INF/spring/webconsole-beans.xml&lt;/p&gt;


&lt;pre&gt;
&amp;lt;osgi:reference id="httpService" 
  interface="haha.osgi.jetty.HttpService" /&amp;gt;

&amp;lt;bean id="register" 
  class="haha.osgi.jetty.Register" init-method="init" 
  destroy-method="destroy"&amp;gt;
  &amp;lt;property name="httpService" ref="httpService" /&amp;gt;
  &amp;lt;property name="webappDir" value="webapp" /&amp;gt;
  &amp;lt;property name="contextPath" value="/osgi" /&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;

webapp/WEB-INF/web.xml
&lt;pre&gt;
&amp;lt;servlet&amp;gt;
&amp;lt;servlet-name&amp;gt;status&amp;lt;/servlet-name&amp;gt;
&amp;lt;servlet-class&amp;gt;
  org.springframework.web.servlet.DispatcherServlet
&amp;lt;/servlet-class&amp;gt;
&amp;lt;init-param&amp;gt;
  &amp;lt;param-name&amp;gt;contextClass&amp;lt;/param-name&amp;gt;
  &amp;lt;param-value&amp;gt;
  org.springframework.osgi.context.support.OsgiWebApplicationContext
  &amp;lt;/param-value&amp;gt;
&amp;lt;/init-param&amp;gt;
&amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
&amp;lt;/servlet&amp;gt;

&amp;lt;servlet-mapping&amp;gt;
&amp;lt;servlet-name&amp;gt;status&amp;lt;/servlet-name&amp;gt;
&amp;lt;url-pattern&amp;gt;/status&amp;lt;/url-pattern&amp;gt;
&amp;lt;/servlet-mapping&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;webapp/WEB-INF/status-servlet.xml&lt;/p&gt;


&lt;pre&gt;
&amp;lt;bean
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&amp;gt;
&amp;lt;property name="mappings"&amp;gt;
  &amp;lt;value&amp;gt;/*=statusController&amp;lt;/value&amp;gt;
&amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;
&amp;lt;bean id="statusController" 
  class="haha.osgi.webconsole.StatusController"&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;haha.osgi.webconsole.StatusController&lt;/p&gt;


&lt;pre&gt;
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]
&lt;/pre&gt;

	&lt;h3&gt;結果&lt;/h3&gt;


	&lt;p&gt;http://127.0.0.1/osgi/status&lt;/p&gt;


&lt;pre&gt;
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
&lt;/pre&gt;

	&lt;h3&gt;觀察&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;簡單使用 BundleContext 秀狀態，可以進一步做控制的實做&lt;/li&gt;
		&lt;li&gt;這類應用要設定三個 &lt;span class="caps"&gt;XML&lt;/span&gt; 似乎過於複雜，沒用到 spring-mvc 的功能，只是簡單 controller 其實可以用 servlet 代替。&lt;/li&gt;
		&lt;li&gt;轉換成 &lt;span class="caps"&gt;JSTL&lt;/span&gt; view 發生找不到 tld 的問題，變成要自帶 &lt;span class="caps"&gt;WEB&lt;/span&gt;-INF/c.tld 並改 uri 的做法，採用 eclipse buddy 機制也許也有用。主要是找不到放在別的包中的 &lt;span class="caps"&gt;META&lt;/span&gt;-INF 目錄下的 c.tld 等檔案。&lt;/li&gt;
	&lt;/ol&gt;</description>
      <pubDate>Thu, 23 Nov 2006 23:27:00 -0800</pubDate>
      <guid isPermaLink="false">urn:uuid:c93a989f-8918-4614-8d8c-f69acd017b4a</guid>
      <author>LIN</author>
      <link>http://blog.extremepattern.com/articles/2006/11/23/show-me-the-osgi-bundles</link>
      <category>eclipse</category>
      <category>java</category>
    </item>
  </channel>
</rss>
