1、OSGi依赖、接口相关的基本知识
http://www.blogjava.net/aoxj/archive/2010/05/25/321844.html
http://felix.apache.org/site/apache-felix-osgi-tutorial.html
http://felix.apache.org/site/apache-felix-dependency-manager-getting-started.html
http://felix.apache.org/site/dependency-manager-usage.html
http://felix.apache.org/开源源代码可以从这里下载
2、关键类分析
ComponentActivatorAbstractBase是SAL核心的一个类,这个类可以看出各个bundle之间、Componet之间、全局和容器Container之间的依赖和调用关系。
注意:这里的容器指OpenDaylight中的Container,当然OSGi实现felix-osgi本身就是一个大容器,它管理着各个bundle。
ComponentActivatorAbstractBase:bundle的抽象基类,完成该bundle相关的各种Componet的管理,子类覆盖相关钩子方法实现定制 |
|
关键方法 |
功能说明 |
Public void containerCreate(String containerName) |
根据getImplementations()获取容器相关的服务,每个实现和容器的Name为关键字通过DependencyManager(依赖管理,以Componet的形势管理依赖)创建一个Componet(这里每个Component就是一个服务,里面说明了导出的接口和依赖的接口),然后增加该服务的生命周期的监听器,从代码可知,服务在状态转变的时候会调用实现类Implementation的started()、stopping(),接着配置这个Componet,主要是指定导出接口和依赖的接口、实现接口。紧接着设置Componet的属性containerName。最后将这个Componet放到DependencyManager和缓存(并发Map:dbInstances)中。 |
public void start(BundleContext context) |
先根据OSGi上下文信息,生成bundle对应的DependencyManager对象(这里看来肯定先是生成bundle对象然后再生成容器对象),再根据getGlobalImplementations ()获取全局相关的服务,每个实现关键字通过DependencyManager创建一个Componet,接着配置这个Componet,主要是指定导出接口和依赖的接口、实现接口。然后将这个Componet放到DependencyManager和缓存(并发Map:dbGlobalInstances)中。接着向OSGi容器注册IContainerAware接口以便容器的生命周期转换点调用。最后调用bunndle的钩子函数init()。该函数的功能代码的注释已经概括的很明确。 |
protected ServiceDependency createServiceDependency() |
生成服务依赖对象,需要被子类调用,在配置Componet的依赖关系的时候需要用到。 |
|
|
以OpenFlow的南向Bundle为例说明Bundle如何实现ComponentActivatorAbstractBase,
org.opendaylight.controller.protocol_plugin.openflow.internal.Activator:继承ComponentActivatorAbstractBase,管理全局和容器相关的服务,当然bundle本身就是一个大服务 |
|
关键方法 |
功能说明 |
Object[] getImplementations() |
返回容器相关的这四个服务的实现 TopologyServices.class, DataPacketServices.class, InventoryService.class, ReadService.class, FlowProgrammerNotifier.class |
void configureInstance(Component c, Object imp, String containerName) |
覆盖方法,根据各个服务的实现,配置容器相关的Componet,主要是指定接口和实现类以及依赖的接口 |
Object[] getGlobalImplementations() |
返回全局的服务实现,Controller.class, OFStatisticsManager.class, FlowProgrammerService.class, ReadServiceFilter.class, DiscoveryService.class, DataPacketMuxDemux.class, InventoryService.class, InventoryServiceShim.class, TopologyServiceShim.class |
configureGlobalInstance(Component c, Object imp) |
覆盖方法,根据各个服务的实现,配置全局的Componet,主要是指定接口和实现类以及依赖的接口 |
3、Bundle之间的关系分析
接口导出和功能概览可以看下面链接:
https://wiki.opendaylight.org/view/Controller_Project%27s_Modules/Bundles_and_Interfaces
以南向的openflow plungin为例:
org.opendaylight.controller.protocol_plugin.openflow.internal.Activator |
||
导出接口(Component) |
依赖接口 |
说明 |
IPluginInTopologyService ITopologyServiceShimListener(plungin) |
IPluginOutTopologyService IRefreshInternalProvider (plungin) |
|
IPluginInInventoryService IInventoryShimInternalListener(plungin) IInventoryProvider(plungin) |
IController(plungin) IPluginOutInventoryService |
|
IPluginInDataPacketService |
IController(plungin) IDataPacketMux(plungin) IPluginOutDataPacketService IPluginOutConnectionService |
|
IReadFilterInternalListener(plungin) IPluginInReadService |
IReadServiceFilter(plungin)
IPluginOutReadService IPluginOutConnectionService |
|
IFlowProgrammerNotifier(plungin) |
IPluginOutFlowProgrammerService IPluginOutConnectionService |
|
全局接口…… |
…… |
|
主要的接口导出和依赖关系的类示意图见,分析代码过程可以参考这些图顺藤摸瓜,研究里面的机制
http://download.csdn.net/detail/ictcamera/6860635
4、理解
Container和Componet的关系呢?
每个具体的接口实现和容器的Container为关键字通过DependencyManager(依赖管理)创建一个Componet,这里每个Component就是一个服务,里面说明了导出的接口和依赖的接口,DependencyManager以Component的形式来管理依赖。见源代码中的ContainerManager.Java。
Container和Cluster关系?
Container是OpenDaylight中的一个网络域,默认是default,北向bound提供的API可以增加、删除、修改Container,查询Container中的信息(有很多链接信息、整个域网络信息)。Cluster管理模块也管理集群Controllers(OpenDaylight)中的所有Container信息。