Possibility to intercept OSGi service resolving - java

I have rather big set of services registered with registerService. For simplicity let's assume they are lookup by some property name. So pair of invocation is straightforward (I use pseudocode for property spec):
context.registerService(
IMyService.getClass().getName(), myServiceInst, {"name"="a"})
After that on client side:
context.getServiceReferences(IMyService.getClass().getName(), {"name"="a"})
For some reason I cannot register all possible combinations of name. Is it possible to intercept all OSGi queries so I could create services on the fly when they are queried?
I would like have basic solution that works on all layers of OSGi - it mean that code above and code with (for example) Declarative Service will work the same way.

Take a look at Service Hooks in the core specification. They allow you to find out who is waiting for what services. Notice that this might imply parsing the filter if you're interested in what properties they're waiting for.

I think you have a couple of options:
Option 1:
If you need only one Service object by client bundle (where the client bundle identifies the key-value pairs) consider using http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/ServiceFactory.html. I think the javadoc is pretty self explaining and you can find easily usage samples in google. In this case you have to implement ServiceFactory and you have to use that one in Declarative Services (please correct me if I have not used declarative services only blueprint)
Option 2:
Create your services with the help of ConfigAdmin. You create a configuration with your client bundle and your service provider bundle will catch that and export the necessary service. After the service is provided you can catch the new service registration with the client. You can find nice doc at http://felix.apache.org/site/apache-felix-config-admin.html. Well in case of this option you will be able to get more services by client bundles but I do not think you can use this with Declarative Services (You must catch the configuration changes programmatically).
Option 3:
Instead of registering IMyService register IMyServiceFactory as an OSGi service. that has a createService(name) function. In this case in the client bundles you have to take care of the lifecycles of your IMyService objects (if no more IMyService is used you can "unget" IMyServiceFactory).

Related

Securing a jersey RESTful web service

I'm developing a restful web service that will be consumed by an Android application later on.
Right now, I'm seeking a way to secure the access to my resources:
I found several ways for implementing that on the net, but I can't figure out what is the most appropriate one.
For example, I found that Oauth specifications are more convenient for third-party applications which is not my case.
So what are the most suitable ways for securing jersey APIs, and I'll be glad if someone can provide me with any tutorials/documentations on that.
I'm using a Glassfish v4 server and the Jersey JAX-RS implementation.
After looking at different options I used an authentication filter and basic auth. Very easy to implement.
Some example code:
You need a filter
public class AuthFilter implements ResourceFilter, ContainerRequestFilter {
...
}
And a security context:
public class MySecurityContext implements SecurityContext {
...
}
And a user class:
public class User implements Serializable, Principal {
...
}
Finally, you can add the filters you need like so: (pass your ResourceConfig object to this function)
private void prepareFilters(ResourceConfig rc) {
rc.getProperties().put("com.sun.jersey.spi.container.ContainerRequestFilters",
getClassListing(new Class[]{
AuthFilter.class
}));
rc.getProperties().put("com.sun.jersey.spi.container.ContainerResponseFilters",
getClassListing(new Class[]{
CORSFilter.class, //You might not need this
GZIPContentEncodingFilter.class //You might not need this
}));
rc.getProperties().put("com.sun.jersey.spi.container.ResourceFilters",
getClassListing(new Class[]{
RolesAllowedResourceFilterFactory.class
}));
}
BTW, you can add #Context SecurityContext securityContext; to your resource class(es) or the individual methods for more fine grained access control. The SecurityContext will be injected into the context of your resource so you can access the User object per request with
With this setup you can annotate your REST methods with #PermitAll, #RolesAllowed, etc which gives you a good level of control over your RESTful interface.
I just finished my stateless (without sessions) user auth and management with Jersey.
Let me know if you want a full example or if you want to give it a try yourself ;)
The simplest way would be using the Java EE build-in Container Managed Security model to secure your rest resources as described in this tutorial. It allows you to configure the security based on users and roles stored in a database or file realm in the web.xml or the the classes themselves.
The disadvantage would be that you must start a session, extract the JSESSIONID and send it in each of your requests so that the server can verify it, but that makes your services more 'stateful' and violates the statelessness of the rest architecture.
Another way would be implementing custom security by using WebFilters, like sending the user name and password with each of your requests and verity them based on the information in a special db. If the information doesn't match the information stored in the database a redirect or a special error code can be returend in the Response object.
The best approach I think is using OAuth2 as described in this specification. Dependend on what kind of client you are using (desktop, web page, mobile client) there are different workflows and apart from that lots of benefits like creating tokens for special scopes of your application (read-only or full access,...). Google provides many different apis that can be accessed by the same account. If an applications only needs data from the calendar api, the requested token only gives you access to this special api and not to the entire resources of the account (like mail data, notes, etc). Another point would be that the security handling is decoupled from the client and no password must be stored in the client application.
You can either implement everything on your own or use a open source project like this. It provides a description on how it works and the code is very good but it has many dependencies to spring frameworks. For my use case I've startend replacing them by vanilla Java EE 7 code and create a solution based on the idea of this open source project. The reason behind the replacements was that it's more future-proof and it avoids class loader problems during the deployment.
In the Android app a Authenticator can be implemented for secure storing of the token.

OSGI bundle priority mechanism

I have one java application which uses OSGI model :
I have two preexisting bundles :
com.mos
com.login
com.login has a implementation and registration of Authenticator service (own service for authentication).com.login as well as com.mos uses this authentication service.
Now I am writing one new bundle (com.new) and I have to add / modify Authenticator Service so I have written my own implementation of it.
Once I start my program / application, if my new bundle com.new runs after com.login then all bundles uses new Authenticator Service.But If com.new bundles runs before com.login then old Authenticator Service is available.
Is there any mechanism in OSGI where we give some priority something like which bundle should start first.
The OSGi bundle startlevels allow you to influence the start order for each bundle.
See the according javadocs http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/startlevel/package-summary.html
But I would not recommend to do that.
Start levels should usually not be used as a way to control service startup. In OSGi service start orders are not guaranteed and services may come and go at will.
Making your new bundle (com.new) depending on the specific implementation of your Authenticator service would do the trick and guarante the correct order.
In general, when you have multiple OSGi services available, you have two options to pick one:
Service Filter
Service Ranking
Service Filter can be used to filter out services based on service properties as described here or here.
Service Ranking published by the service makes them eligible to be picked up based on the service ranking. The one with highest service ranking will be picked up as described here or here.
According to the documentation of the BundleContext.getServiceReference() method:
If multiple such services exist, the service with the highest priority is selected. This priority is defined as the service reference with the highest ranking (as specified in its Constants.SERVICE_RANKING property) is returned.
If there is a tie in ranking, the service with the lowest service ID (as specified in its Constants.SERVICE_ID property); that is, the service that was registered first is returned.

WSDL is changed after publishing

When I publish a web service created from a WSDL, the WSDL which is created after publishing is different than the original one. The difference is that WSDL/XSD created after publishing had additional element(ARG0) which wraps all root elements.
Because of the reason above, I could not share original WSDL/XSD to client developers since original WSDL and the one created after publishing is not same.
I am using Java as a programming language and JAX-WS.
using API javax.xml.ws.Endpoint to publish the web service without needing any Application server.
Endpoint.publish(url,webserviceinstance)
Thanks in advance.
Since the problem is unneccesary wrapping issue, I focused on wrapping annotations. Eventually I have found out that there is a related annotation for this issue. After adding following annotation statement at the beginning of Class ,problem has been solved.
#SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE)
public class WebServiceHandler implements WebService {
//....
}
From now on, I can make succesfull request created from original WSDL to deployed machine.
If you post the wsdl, a better assessment can be made. Given that you are seeing an unexpected wrapper, my guess is that jax-ws is interpreting your original wsdl differently than you intend. The page here (http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/) discusses different wsdl configurations. My suggestion is that you follow the instructions for using the document/literal/wrapped convention as it is more or less in the mainstream for soap-based services.
The resulting published wsdl will still likely be a little different in terms of service name, port name or namespace unless you use the #Webservice annotation attributes to force these to particular values, but they will be consistent such that you can provide the published wsdl to your clients and expect success.
The most common reason for this type of issue is that the class implementing the Web service doesn't have an #WebService annotation with the correct endpointInterface attribute. In fact, it is not sufficient to implement the endpoint interface generated from the WSDL.

Adding aspects on services across OSGi bundles

I have an OSGi bundle (that is not owned by me - so I cannot change it!) that exposes (exports) a service EchoService, and I want to attach an aspect to methods of this service (so as to perform some pre/post processing around it). These are deployed on the Apache Felix container.
I've written my own OSGi bundle (that obviously imports the EchoService), and attaches Spring aspects to it using standard Spring AOP. However, looks like the aspects are not attached and my interceptor is not being invoked.
I suspect that this is because I'm trying to intercept a service that does not belong to my bundle (which seems reasonable). Is that correct? How can I overcome this?
Here's what my interceptor/aspect looks like:
#Before("serviceOperation()")
public void before(JoinPoint jp) {
logger.debug("Entering method: " + jp.toShortString());
}
#AfterReturning("serviceOperation()")
public void after(JoinPoint jp) {
logger.debug("Exiting method: " + jp.toShortString());
}
I'm not an AOP nor a Spring expert, but maybe I could give you some ideas. As far as I see Spring use standard J2SE dynamic proxies for AOP proxies. Hence your clients should use the proxy instead of the original EchoService object. This is also true when you're using CGLIB proxies because "the proxies are created by sub-classing the actual class".
If your client bundles asking for an EchoService you have to pass them the proxy somehow. For this inside an OSGi container you should also export an EchoService (proxy) and make sure that the clients use the proxied service/bundle, not the original. You can accomplish this by setting a different version number for the (proxied) package and set this version as an import requirement in your client bundles. (I suppose you can modify the clients of EchoService.) For services you can set a property when you're registering it and modify the clients to query only for services which have this property.
If you are not able to modify the client bundles another solution could be wrapping the original bundle as an internal jar in your bundle. You can call the wrapped bundle's activator from your activator and pass them a modified BundleContext. This BundleContext should catch the registering service calls and register the proxy object instead of the original EchoService. You can use simple delegate pattern since BundleContext, ServiceListener etc. are usually interfaces. I suppose it could work but it maybe has other challenges.

How do I write an application that more or less acts as a container?

I am planning an application that must provide services that are very much like those of a Java EE container to third party extension code. Basically, what this app does is find a set of work items (currently, the plan is to use Hibernate) and dispatch them to work item consumers.
The work item consumers load the item details, invoke third party extension code, and then if the third party code did not fail, update some state on the work item and commit all work done.
I am explicitly not writing this as a Java EE application. Essentially, my application must provide many of the services of a container, however; it must provide transaction management, connection pooling and management, and a certain amount of deployment support. How do I either A) provide these directly, or B) choose a third party library to provide them. Due to a requirement of the larger project, the extension writers will be using Hibernate, if that makes any difference.
It's worth noting that, of all of the features I've mentioned, the one I know least about is transaction management. How can I provide this service to extension code running in my container?
Hi I recommend using the Spring Framework. It provides a nice way to bring together a lot of the various services you are talking about.
For instance to address your specific needs:
Transaction Management/Connection pooling
I built a spring-based stand-alone application that used Apache commons connection pooling. Also I believe spring has some kind of transaction mgmt built in.
Deployment support
I use ant to deploy and run things as a front-loader. It works pretty well. I just fork a seperate process using ant to run my Spring stand-alone app.
Threading.
Spring has support for Quartz which deals well with threads and thread pools
DAO
Spring integrates nicely with Hibernate and other similar projects
Configuration
Using its xml property definitions -- Spring is pretty good for multiple-environment configuration.
Spring does have transaction management. You can define a DataSource in your application context using Apache DBCP (using a org.apache.commons.dbcp.BasicDataSourceorg.springframework.jdbc.datasource.DataSourceTransactionManager for the DataSource. After that, any object in your application can define its own transactions programatically if you pass it the TransactionManager, or you can use AOP interceptors on the object's definition in your application context, to define which methods need to be run inside a transaction.
Or, the easier approach nowadays with Spring is to use the #Transactional annotation in any method that needs to be run inside a transaction, and to add something like this to your application context (assuming your transactionManager is named txManager):
<tx:annotation-driven transaction-manager="txManager"/>
This way your application will easily accept new components later on, which can have transaction management simply by using the #Transactional annotation or by directly creating transactions through a PlatformTransactionManager that they will receive through a setter (so you can pass it when you define the object in your app context).
You could try Atomikos TransactionsEssentials for Java transaction management and connection pooling (JDBC+JMS) in a J2SE environment. No need for any appservers, and it is much more fun to work with ;-)
HTH
Guy

Categories