hello osgi servlet

0

源起

在 OSGi 原始的 R1 時代,Framework/Http/Log/Device Access 的部份就已經上場,這裡將試做 Http/Log 的部份,並使用 R4 的 Declarative Services 規格 org.osgi.service.component 來試驗。

規格書的 R4 Compendium V4.0.1 Specification 中 102 Http Service Specification 指的就是 org.osgi.service.http 這個部份,該部分實做可以參考 org.eclipse.equinox.http.HttpService。

如何用 Http Service

這裡建議使用 eclipse 來做,先建立一個空白標準 OSGi 專案,然後需要動到三個檔案,因為 eclipse PDE 尚未支援 Service-Component 的標籤,所以要自行到 MANIFEST 去填寫。

  1. META-INF/MANIFEST.MF (修改檔案 Service-Component point to component.xml)
  2. OSGI-INF/component.xml (新增檔案 implementation point to Component.java)
  3. Component.java (新增檔案 activate and deactivate methods)

META-INF/MANIFEST.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloHttp Plug-in
Bundle-SymbolicName: HelloHttp
Bundle-Version: 1.0.0
Bundle-Localization: plugin
Import-Package: javax.servlet;version="2.3.0",
 javax.servlet.http;version="2.3.0",
 org.osgi.framework;version="1.3.0",
 org.osgi.service.component;version="1.0.0",
 org.osgi.service.http;version="1.2.0",
 org.osgi.service.log;version="1.3.0" 
Service-Component: OSGI-INF/component.xml

OSGI-INF/component.xml

<?xml version="1.0" encoding="UTF-8"?>
<component name="hello.component">
  <implementation class="hello.Component"/>
  <reference name="LOG" 
    interface="org.osgi.service.log.LogService" 
    cardinality="1..1" 
    policy="static"/>
  <reference name="HTTP" 
    interface="org.osgi.service.http.HttpService" 
    cardinality="0..1" 
    policy="dynamic" 
    bind="setHttp" 
    unbind="unsetHttp"/>
</component>

hello/Component.java

package hello;

import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.osgi.service.log.LogService;

public class Component {
    LogService log;
    HttpService http;
    protected void activate(ComponentContext context) {
        log = (LogService) context.locateService("LOG");
        log.log(LogService.LOG_INFO, "#### Hello World");
    }
    protected void deactivate(ComponentContext context) {
        log.log(LogService.LOG_INFO, "#### Goodbye World");
    }
    protected void setHttp(HttpService h) {
        this.http = h;
        this.registerServlet();
    }
    protected void unsetHttp(HttpService h) {
        this.http.unregister("/haha");
        this.http = null;
    }
    private void registerServlet() {

        Hashtable initparams = new Hashtable();
        initparams.put("name", "value");

        Servlet myServlet = new HttpServlet() {

            String name = "foo";

            public void init(ServletConfig config) {
                this.name = (String) config.getInitParameter("name");
            }

            public void doGet(HttpServletRequest req, HttpServletResponse rsp)
                    throws IOException {
                String foo = req.getParameter("foo");
                rsp.setContentType("text/html;charset=UTF-8");
                StringBuilder sb = new StringBuilder();
                sb.append("The init parameter : " + this.name);
                sb.append("<BR/>");
                sb.append("The foo parameter : " + foo);
                sb.append("<BR/>");
                sb.append("日期 : " + new Date());
                sb.append("<BR/>");

                // servlet 2.3 only
                //Locale reqLocal = req.getLocale();
                //sb.append("The country is :" + reqLocal.getCountry()).append("<BR/>");
                //sb.append("The language is :" + reqLocal.getLanguage());    
                rsp.getWriter().println(sb.toString());

            }
        };

        try {

            http.registerServlet("/haha", myServlet, initparams,null);

        } catch (ServletException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NamespaceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

測試

先看看 bundle 以及 log 服務是否運作。 然後開 http://127.0.0.1/haha?foo=abc 看看,之後再關掉 http service。

osgi> ss

Framework is launched.

id    State       Bundle
0    ACTIVE      system.bundle_3.3.0.v20060919
2    ACTIVE      org.eclipse.equinox.ds_1.0.0.v20060828
4    ACTIVE      org.eclipse.equinox.log_1.0.100.v20060717
6    ACTIVE      org.eclipse.osgi.services_3.1.100.v20060918
12    ACTIVE      HelloHttp_1.0.0
13    ACTIVE      org.eclipse.equinox.http_1.0.100.v20060821
14    ACTIVE      org.eclipse.equinox.servlet.api_1.0.0.v20060717

osgi> log
>Info [4] Log created; Log Size=100; Log Threshold=4 initial@reference:file:org.eclipse.equinox.log_1.0.100.v20060717.jar/
>Info [4] ServiceEvent REGISTERED {service.id=21}
>Info [4] ServiceEvent REGISTERED {service.id=22}
>Info [4] ServiceEvent REGISTERED {service.id=23}
>Info [4] BundleEvent STARTED initial@reference:file:org.eclipse.equinox.log_1.0.100.v20060717.jar/
>Info [6] BundleEvent STARTED initial@reference:file:org.eclipse.osgi.services_3.1.100.v20060918.jar/
>Info [12] #### Hello World initial@reference:file:../HelloLog/
>Info [12] BundleEvent STARTED initial@reference:file:../HelloLog/
>Info [13] ServiceEvent REGISTERED {service.id=24}
>Info [13] ServiceEvent REGISTERED {service.id=25}
>Info [13] ServiceEvent REGISTERED {service.id=26}
>Info [13] BundleEvent STARTED initial@reference:file:org.eclipse.equinox.http_1.0.100.v20060821.jar/
>Info [14] BundleEvent STARTED initial@reference:file:org.eclipse.equinox.servlet.api_1.0.0.v20060717.jar/
>Info [0] FrameworkEvent STARTLEVEL CHANGED System Bundle

osgi> stop 13

osgi> log

>Info [13] ServiceEvent UNREGISTERING {service.id=25}
>Info [13] ServiceEvent UNREGISTERING {service.id=26}
>Info [13] ServiceEvent UNREGISTERING {service.id=24}
>Info [13] BundleEvent STOPPED initial@reference:file:org.eclipse.equinox.http_1.0.100.v20060821.jar/

網路上找個新的 Http Service 來換。

osgi> install http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
Bundle id is 15

osgi> ss

Framework is launched.

id    State       Bundle
0    ACTIVE      system.bundle_3.3.0.v20060919
2    ACTIVE      org.eclipse.equinox.ds_1.0.0.v20060828
4    ACTIVE      org.eclipse.equinox.log_1.0.100.v20060717
6    ACTIVE      org.eclipse.osgi.services_3.1.100.v20060918
12    ACTIVE      HelloHttp_1.0.0
13    RESOLVED    org.eclipse.equinox.http_1.0.100.v20060821
14    ACTIVE      org.eclipse.equinox.servlet.api_1.0.0.v20060717
15    INSTALLED   org.knopflerfish.bundle.http_2.0.0

osgi> start 15

osgi> ss

Framework is launched.

id    State       Bundle
0    ACTIVE      system.bundle_3.3.0.v20060919
2    ACTIVE      org.eclipse.equinox.ds_1.0.0.v20060828
4    ACTIVE      org.eclipse.equinox.log_1.0.100.v20060717
6    ACTIVE      org.eclipse.osgi.services_3.1.100.v20060918
12    ACTIVE      HelloHttp_1.0.0
13    RESOLVED    org.eclipse.equinox.http_1.0.100.v20060821
14    ACTIVE      org.eclipse.equinox.servlet.api_1.0.0.v20060717
15    ACTIVE   org.knopflerfish.bundle.http_2.0.0

osgi> log
>Info [15] BundleEvent INSTALLED http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
>Info [15] BundleEvent RESOLVED http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
>Info [15] ServiceEvent REGISTERED {service.id=27}
>Info [15] No CM present, using default configuration http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
>Debug [15] Updated pid=org.knopflerfish.bundle.http.factory.HttpServer.default http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
>Debug [15] create pid=org.knopflerfish.bundle.http.factory.HttpServer.default http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
>Debug [15] Creating socket http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
>Info [15] HTTP server started on port 8080 http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
>Info [15] ServiceEvent REGISTERED {service.id=28}
>Info [15] BundleEvent STARTED http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar
>Debug [15] Alias "/haha" was registered by bundle 12 http://www.knopflerfish.org/repo/jars/http/http_all-2.0.0.jar

再測一次看看。

Comments

(leave url/email »)

   Preview comment