如何过滤 OSGi 服务可见性?
OSGi 采用面向服务的体系结构:捆绑包注册其他捆绑包使用的服务对象。 服务发布和绑定由框架管理。 这将服务提供者与服务用户完全解耦(除了需要就服务接口达成一致之外)。
有没有办法(通过配置)限制哪些服务对哪些捆绑包可见?
例如,如果我有一个 HttpService,那么所有愿意这样做的包都可以将 servlet 安装到其中。 我想让 HttpService 对选择性捆绑包不可见。
额外积分:除了过滤服务注册之外,还能够修改注册属性。 因此,即使捆绑包使用 alias=/admin
注册了 Servlet,我也可以将其更改为 alias=/somethingelse
供 Pax Web Extender Whiteboard 使用。
OSGi employs a service-oriented architecture: Bundles register service objects, that other bundles consume. Service publishing and binding is managed by the framework. This decouples service providers from service users completely (except for the need to agree on a service interface).
Is there a way to limit (by configuration) what services are visible to what bundles ?
For example, if I have an HttpService, all bundles that feel like doing so can install servlets into it. I would like to make the HttpService not visible to selective bundles.
For extra credits: In addition to just filtering service registrations, the ability to modify registration properties. So that even if a bundle registers a Servlet with alias=/admin
, I can change that to alias=/somethingelse
for consumption by Pax Web Extender Whiteboard.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如您所知,可以过滤服务属性,尽管这可能无法提供您所要求的控制:服务对于框架中部署的其他包仍然可见。
在 SpringSource 的 dm Server(一个开源、模块化、基于 OSGi 的 Java 应用程序服务器)中,应用程序在部署时可以限定范围。 这允许您部署多个应用程序(在不同的范围内),这些应用程序可能包含不一致版本的依赖包,同时仍然允许共享公共包(通过将它们部署在范围之外 - 在所谓的全局范围内)。
如果某个范围内的应用程序/捆绑包注册了 OSGi 服务,则该服务仅可供同一范围内的捆绑包使用。 (服务也有“作用域”。)
这并不神奇:服务器包装了 OSGi 服务接口,并使用“幕后”服务属性来即时执行所需的过滤。
我认为这会给你带来你正在寻找的那种分离。
有关 dm Server 的信息(不要与 Spring DM 混淆)请访问 SpringSource.org dmServer 页面。
史蒂夫·鲍威尔
SpringSource; dm服务器开发
As you are aware, it is possible to filter on service properties, though this probably doesn't give the sort of control you are asking for: the services are still visible to other bundles deployed in the framework.
In SpringSource's dm Server (an open-source, modular, OSGi-based Java application server) an application can be Scoped when it is deployed. This allows you to deploy multiple applications (in separate scopes) that might include inconsistent versions of dependent bundles, while still allowing common bundles to be shared (by deploying them outside of a scope—in the so-called global scope).
If a scoped application/bundle registers an OSGi service it is only available to the bundles in the same scope. (The services are 'scoped' as well.)
This is not magic: the server wraps the OSGi services interfaces and uses service properties 'under the covers' to perform the filtering required on-the-fly.
I think this would give you the sort of separation you are looking for.
For information about dm Server (not to be confused with Spring DM) go to the SpringSource.org dmServer page.
Steve Powell
SpringSource; dm Server Development
即将推出的 OSGi 规范 R4.2 定义了一个名为 Find Hook 的组件,它允许:
“检查返回的服务引用集并可选择缩小返回的服务集”
请参阅
http://www.osgi.org/download/ r4-v4.2-core-draft-20090310.pdf 第 12.5 节
请注意,R4.2 还不是最终版本,但我仍然相信主要的 OSGi 实现(Felix 和 Equinox)已经具有此附加功能的代码在他们的后备箱里
The upcoming R4.2 of the OSGi specification define a component called Find Hook that allows exactly to:
"inspect the returned set of service references and optionally shrink the set of returned services"
See
http://www.osgi.org/download/r4-v4.2-core-draft-20090310.pdf section 12.5
Please note that R4.2 is not final yet, still I believe the major OSGi implementations (Felix and Equinox) already have the code for this additional functionality in their trunk
使用服务属性无法做到这一点。 您可以定义自己的服务属性,指定哪些捆绑包应该使用您正在导出的服务,但无法阻止其他捆绑包也使用它。
嗯……这很难。 您可以定义自己的 Servlet 接口“MyServlet”并使用该接口导出您的 Servlet。 然后,另一个包可以使用这些 MyServlet 并将它们重新导出为具有修改后的服务属性的 Servlet。
除此之外……不知道。
There is no way to do that using service properties. You could define your own service property that specifies which bundles should consume the service you are exporting, but there is no way to prevent other bundles from consuming it as well.
Well... that's a tough one. You could define your own Servlet interface "MyServlet" and export your Servlets using that interface. Then, another bundle could consume those MyServlets and re-export them as Servlets with modified service properties.
Other than that ... no idea.
我还没有尝试过这个,但似乎它可能对您有帮助...
在 OSGi R4 组件规范中描述了“配置管理服务”,从 5 分钟的检查来看,它似乎能够动态更改服务。
最终,我认为您将根据一些商定的配置值来控制对服务的访问
I haven't tried this, but seems like it may help you...
In the OSGi R4 Component Spec describes the "Configuration Admin Service" which, from a 5 minutes inspection, appears to be able to alter services dynamically.
Ultimately I think it will be up to you to control access to the services based on some agreed upon configuration values
使用 iPOJO 您可以非常简单地更改公开服务的属性。 它还有许多其他功能,对于经常使用 OSGi 的人来说可能会很有趣。
using iPOJO you can change properties of the exposed services pretty simple. It has bunch of other features, which could be interessting to someone using OSGi a lot.
如果您想限制服务的可见性,最好的选择是启用 OSGi 安全性。 它旨在限制哪些服务、包和其他内容对哪些捆绑包可见。 例如,您可以仅将特定服务提供给您签名的捆绑包(或使用各种其他标准)。
已经提到的另一个选项是使用 4.2 服务挂钩,它允许一种“自己动手”的安全机制。
第二个问题是更改注册服务的端点等属性,您可以通过注册服务时返回的 ServiceRegistration 来完成此操作。 可以通过成为托管服务并使用 ConfigurationAdmin 自行配置来触发更改。
If you want to limit the visibility of services, your best bet is to enable OSGi security. It is designed to limit what services, packages and other things are visible to what bundles. You can for example only make a certain service available to a bundle that is signed by you (or use various other criteria).
The other option, already mentioned, it to use the 4.2 service hooks, which allow a sort of "do it yourself" security mechanism.
The second question, changing properties like the endpoint under which a service is registered, is something you can do via the ServiceRegistration that you get back when registering your service. Changes can be triggered by becoming a ManagedService and use ConfigurationAdmin to configure yourself.