我们正在开发一个网络应用程序(我们称之为图像库),我们已经确定了以下需求:
问题:我们是应该在标准的OSGi框架上构建它还是我们更好地使用其中一个新兴的应用程序框架(Virgo,Aries或即将推出的OSGi标准)?
更多背景和一些初步想法:
我们正在构建一个网络应用程序,我们预计很快会有数百个客户(公司),每个用户数量达到数百名(员工),否则为什么会这么麻烦;)。我们希望使其模块化,因此OSGi。在未来,客户自己可能会开发和插入组件到他们的应用程序,因此我们需要客户隔离。我们也可能希望不同的客户获得不同的功能集。
当不同的客户端共享相同的捆绑包时,为应用程序的不同客户端提供不同的服务实现的“正确”方法是什么?
我们可以使用app-server方法(我们看过Virgo)并将每个客户的每个包加载到他们自己的“app”中。然而,它不喜欢拥抱OSGi。我们没有托管多个应用程序,99%的服务将共享相同的impl。为所有客户。我们还想将应用程序(配置,监控等)作为一个来管理。
每个服务都可以为每个客户注册(正确配置)一次,以及一些“客户令牌”属性。它有点乱,需要使用扩展模式或ManagedServiceFactory来处理?在为客户A注册服务之前,还需要获取每个服务器的A版本。
每个请求都会知道“当前”客户,并且可以绑定到该线程。每次搜索服务时都必须提供客户令牌,这有点乱。这使得很难使用蓝图等组件框架。为了解决这个问题,我们可以使用服务挂钩代理每个注册的服务类型,并让代理根据当前客户(线程)调度到正确的实例。
通过实施上述解决方法(hack?)开始我们整个OSGi体验真的感觉就像是我们走错了路。那我们该怎么办?回到处女座?尝试类似于上面概述的内容?完全不同的东西?!
PS。感谢您一直在这里阅读! ;)
答案 0 :(得分:5)
解决方案有几个方面:
首先,您需要找到一种方法来配置您拥有的不同客户。在ConfigurationAdmin之上构建解决方案在这里是有意义的,因为那样您就可以尽可能地利用现有的OSGi标准。您可能希望在顶部构建内容的原因是ConfigurationAdmin允许您配置每个单独的服务,但您可能希望在顶部添加一个层,以便您可以一次性更方便地配置整个应用程序(捆绑包的组合)。然后可以将这种配置转换为服务的各个配置。
向具有客户特定实现的服务添加属性非常有意义。您可以使用ManagedServiceFactory进行设置,该属性可以使用过滤器轻松地为正确的客户查找服务。您甚至可以定义一个回退场景,您可以在其中查找客户特定服务或通用服务(因为并非所有服务都可能是客户特定的)。由于您需要向依赖项明确添加此类过滤器,因此我建议您使用现有的依赖项管理解决方案并针对您的特定用例进行扩展,以便依赖项自动添加正确的客户特定过滤器,而无需手动指定。我意识到我可能需要在这里详细介绍,让我知道......
接下来的问题是,如何在应用程序中跟踪客户“上下文”。传统上这里只有几个选项,线程本地上下文是最常用的选项。将线程绑定到客户确实会在实现选项方面限制您,因为通常它可能意味着您必须禁止开发人员自己创建线程,并且很难将某些任务卸载到工作线程池中。如果您决定使用远程服务,情况会更糟,因为这意味着您将完全松开上下文。
因此,为了将客户身份从一个组件传递到另一个组件,我个人更喜欢以下解决方案:
答案 1 :(得分:1)
我已经考虑了同样的问题(我认为)已有一段时间了,并且希望您对以下类比提出意见。
考虑一系列Web应用程序,您可以使用单点登录(SSO)基础结构提供访问控制。用户使用SSO服务器进行一次身份验证,并且 - 当请求进入时 - 目标Web应用程序向SSO服务器询问用户是否(仍然)进行了身份验证,并确定用户是否已获得授权。授权信息也可能由SSO服务器提供。
现在将您的应用程序包视为迷你应用程序。虽然它们不是Web应用程序,但使用SSO技术进行身份验证和提供授权信息的某种SSO捆绑包仍然没有意义吗?必须开发或配置每个应用程序包以使用SSO包来验证身份验证(SSO令牌),并通过询问SSO包是否允许用户访问此应用程序包来验证授权。
SSO包维护某种会话存储库,并且还提供用户属性,例如用于标识此用户的数据存储库(某种类型)的信息。这样,您也不会通过(有意义的)客户服务令牌#34;而是通过SSO捆绑提供和管理的神秘SSO令牌。
答案 2 :(得分:1)
请注意,Virgo是基于Equinox的OSGi容器,所以如果你不想使用一些Virgo特有的功能,你不必这样做。但是,如果您使用Virgo,即使是基本的OSGi应用程序,也会获得大量benefits。听起来,就像你想要网络支持一样,它与Virgo网络服务器开箱即用,可以省去你自己拼凑它的麻烦。
完全披露:我领导处女座项目。