对于osgi bundle的集成测试研究

    由于OSGI技术优秀的模块化技术分离,在不同的bundle之间进行交互的方式有两种:一是包(package)的导出和导入,二是bundle向外部发布service。第二种方式是osgi中推荐的方式,同时这种方式具有SOA的特点。但是,这种模块化的组织方式,特别是通过服务在不同的bundle间进行交互,使得osgi环境中的测试,必须在osgi container中进行,增加了测试环境搭建的难度。    在spring dm中,提供了一种启动osgi container的方式,通过springdm、osgi container、junit的组合,进行osgi的集成的测试。但是这种方式的设置比较复杂,特别是对于每一个bundle到要在测试程序和pom中设置,容易引起错误。

    因此,基于对OSGI container的分析(主要是Felix和Equinox),可以通过在传统的程序中,嵌入(embedded)一个osgi的环境,可以利用Junit象测试普通的java程序一样测试bundle提供的service。

  一、建立一个OSGI的嵌入环境

    这里以建立Felix的嵌入式环境为例子进行解释,对于Equinox的环境,基本的建立方法相同。在建立Osgi环境过程中,关键的问题有两个:一是对于OSGI 环境配置文件的读取和处理,并把它设置到启动的嵌入式环境中;二是对于自动启动的bundle的读取和启动。工程的目录结构如图所示:

    首先是对于Felix配置文件的处理, 读取配置文件config.properties,并把读入的内容加载到Properties中。

    	InputStream input = null;
    	try {
			input = new FileInputStream("conf/config.properties");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

    	Properties props = new Properties();
    	try {
			props.load(input);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

 

其次是读取自动启动的bundles,放在工程的bundles目录下,子目录以数字命名,对应于Felix中bundle的启动级别,在Felix中,对于自动启动的bundle的设置属性为:"felix.auto.start",通过程序中读取这个目录下的bundle,设置到properties:

		File dir = new File("bundles");
		String[] list = dir.list();

		for(int i= 0;i< list.length;i++)
		{

			File jarDir = new File("bundles/"+list[i]);
			
			

			String runJars =  this.getFileName(" file:", jarDir);

			props.setProperty(AUTO_START_PROP+"."+list[i], runJars);
		}

   private String getFileName(String rootPath,File file)
    {
     String bundlesPath="";
     
     if(!file.getAbsolutePath().contains(".svn"))
     {
      if(file.isDirectory())
      {
       String[] files = file.list();
       
       for(int i=0;i<files.length;i++)
       {
        bundlesPath = bundlesPath+getFileName(rootPath,new File(file.getPath()+"/"+files[i]));
       }
       
      }
      else
      {
       bundlesPath=rootPath+file;
      }
     }
     return bundlesPath;
    }
  

最终,把完整的属性设置传给Felix,然后以嵌入式方式启动OSGI环境。完整的Felix Host代码如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.felix.framework.Felix;
import org.apache.felix.main.AutoProcessor;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;


public class FelixHostApplication
{
 //    private HostActivator m_activator = null;

    private static  Felix m_felix = null;
    private final String AUTO_START_PROP ="felix.auto.start";

    public Object getBunndleContext()
    {
    	return m_felix.getBundleContext();
    }
    
    private String getFileName(String rootPath,File file)
    {
    	String bundlesPath="";
    	
    	if(!file.getAbsolutePath().contains(".svn"))
    	{
	    	if(file.isDirectory())
	    	{
	    		String[] files = file.list();
	    		
	    		for(int i=0;i<files.length;i++)
	    		{
	    			bundlesPath = bundlesPath+getFileName(rootPath,new File(file.getPath()+"/"+files[i]));
	    		}
	    		
	    	}
	    	else
	    	{
	    		bundlesPath=rootPath+file;
	    	}
    	}
    	return bundlesPath;
    }
    

    public FelixHostApplication()
    {
    	InputStream input = null;
    	try {
			input = new FileInputStream("conf/config.properties");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

    	Properties props = new Properties();
    	try {
			props.load(input);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		File dir = new File("bundles");
		String[] list = dir.list();

		for(int i= 0;i< list.length;i++)
		{

			File jarDir = new File("bundles/"+list[i]);
			
			

			String runJars =  this.getFileName(" file:", jarDir);

			props.setProperty(AUTO_START_PROP+"."+list[i], runJars);
		}



        // Create a configuration property map.
        Map config = new HashMap(props);
        // Create host activator;
 /*       m_activator = new HostActivator();
        List list1 = new ArrayList();
        list1.add(m_activator);
        config.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list1);
*/

       try
        {
            // Now create an instance of the framework with
            // our configuration properties.
            m_felix = new Felix(config);

            m_felix.init();
            AutoProcessor.process(config, m_felix.getBundleContext());

 //          m_felix.getBundleContext().registerService(ShareInterface.class.getName(), new ShareImpl(), null);


           // Now start Felix instance.
            m_felix.start();

            Thread.sleep(10*1000);

            System.out.println("hello");

        }
        catch (Exception ex)
        {
            System.err.println("Could not create framework: " + ex);
            ex.printStackTrace();
        }
    }

  public Bundle[] getInstalledBundles()
    {
        // Use the system bundle activator to gain external
        // access to the set of installed bundles.
        return this.m_felix.getBundleContext().getBundles();
    }

    public void shutdownApplication()
    {
        // Shut down the felix framework when stopping the
        // host application.
        try {
			m_felix.stop();
		       m_felix.waitForStop(0);
		} catch (BundleException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
}

 

 二、在Junit Test Case中启动OSGI 环境

    建立一个Junit Test Case,重载它的setup方法,生成一个OSGI环境:

host = new FelixHostApplication();

 

然后通过反射的方法(见文《在osgi容器外应用osgi bundle提供的服务》),就可以获得注册的服务了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值