How to provide OSGi services to a client

We are developing a web application (we call it the image bank), for which we have identified the following needs:

  • The application serves customers, which consist of a set of users.
  • A new client can be created dynamically, and the client manages it.
  • Clients have different sets of functions that can be dynamically changed.
  • Customers can develop their own functions and deploy them.
  • The application is homogeneous and has the current version, but access to client versions can still be processed individually.
  • The application must be managed as a whole, and customers share resources that must be easily scalable.

Question:. Should we build it on the standard OSGi platform or will we better use one of the new application frameworks (Virgo, Aries or the upcoming OSGi standard)?

More background and some initial thoughts:

We are creating a web application that, we assume, will soon have hundreds of customers (companies) with hundreds of users (employees), otherwise why bother;). We want to make it modular, therefore, OSGi. In the future, customers themselves can develop and connect components to their application so that we need customer isolation. We may also want different clients to have different feature sets.

What is the “right” way to provide different service implementations for different application clients when different clients use the same packages?

We could use the app-server approach (we looked at Virgo) and download each set once for each client in our “application”. However, he does not want to hug OSGi. We do not have many applications, 99% of which will use the same. for all customers. We also want to manage (configure, control, etc.) the Application as one.

Each service can be registered (correctly configured) once for each client, along with some client-token property. Is this a bit dirty and will need to handle the expander pattern, or perhaps a ManagedServiceFactory? In addition, before registering services for client A, you will need to purchase an A-version of each of these dependencies.

The "current" client will be known to each request and can be tied to a thread. This is a bit of a mess that should supply a customer token every time you look for a service. This makes it difficult to use components such as a plan. To get around this problem, we could use service hooks to proxy each registered type of service and allow the proxy to be sent to the desired instance in accordance with the current client (stream).

The beginning of our entire OSGi experience by implementing a workaround (hack?) Above really seems like an indication that we're wrong. so what do we do? Return to Virgo? Try something similar to the one described above? Something completely different ?!

ps. Thank you for reading everything here!;)

+7
source share
3 answers

There are several aspects to the solution:

First of all, you need to find a way to configure the various clients that you have. Creating a solution on top of ConfigurationAdmin makes sense here, because then you can make the most of the existing OSGi standard. The reason you might want to create something on top is because ConfigurationAdmin allows you to configure each individual service, but you may need to add a layer on top so you can more conveniently configure your entire application (bundle assembly) for once. This configuration can then be translated into individual service configurations.

Adding properties to services that have customer-specific implementations makes a lot of sense. You can configure them using ManagedServiceFactory, and the property makes it easy to find the service for the right client using a filter. You can even define a fallback scenario in which you are either looking for a client service or general (since not all services are likely to be client specific). Since you need to explicitly add such filters to your dependencies, I would recommend using an existing dependency management solution and expanding it for your specific use case so that the dependencies automatically add the correct filters for a specific client, without manually specifying. I understand that I may have to stop here in more detail, just let me know ...

The next question is how to track the "context" of the client in your application. Traditionally, there are only a few options, with the most commonly used local thread context. Binding threads to clients tends to limit you in terms of implementation options, although this usually means that you should prevent developers from creating threads themselves, and it’s hard to disable certain tasks for workflow pools. This gets even worse if you ever decide to use remote services, as it means that you completely lose context.

So, to transfer client identification from one component to another, I personally prefer a solution where:

  • As soon as the request arrives (for example, in your HTTP servlet), the client identifier is somehow determined.
  • Pass this identifier explicitly through the service dependency chain.
  • Use only solutions such as using thread locales within the boundaries of one package, if, for example, you use a third-party library inside your package that needs this to track the client.
+5
source

I’ve been thinking about the same problem (I think) for some time now and would like your opinion on the following analogy.

Consider a series of web applications in which you provide access control using a single sign-on (SSO) infrastructure. The user authenticates once using the SSO server, and when the request arrives, the target web application asks the SSO server whether the user is (still) authenticated and determines whether the user is allowed. Authorization information may also be provided by the SSO server.

Now think of your app bundles as gadgets. Although they are not web applications, does it make sense to have some kind of SSO kit using SSO methods for authentication and providing authorization information? Each application package must be designed or configured to use the SSO package for authentication (SSO token) and authorization by requesting an SSO package if the user is allowed access to this application package.

The SSO suite supports some kind of session repository, and also provides custom properties, for example. information to identify the data warehouse (a kind of) of this user. That way, you would also not miss the (meaningful) customer service token, but rather the critical SSO token that is supplied and managed by the SSO package.

+1
source

Please, not that Virgo is an Equinox-based OSGi container, so if you don’t want to use some Virgo-specific feature, you don’t have to. However, you will get many benefits if you use Virgo, even for the underlying OSGi application. It sounds like you want the web support that comes out of the box with the Virgo web server to save you the trouble of combining it yourself.

Full disclosure: I am leading the Virgo project.

+1
source

All Articles