I'm using Guice to route requests in my web app, and I'd like to modularize the routing of some of the URL patterns I'll be handling. Ideally, I'd like to be able to do something like this in my ServletModule:
delegate("/foo/bar/*").to(SomeOtherServletModule.class);
// in SomeOtherServletModule.configureServlets:
serve("/foo/bar/quux").with(Quux.class);
Or even better:
delegatePrefix("/foo/bar/").to(SomeOtherServletModule.class);
// in SomeOtherServletModule.configureServlets:
serve("/quux").with(Quux.class); // prefix removed
Is this possible in Guice? It seems that Guice tries really hard to make the bindings installed by ServletModules a singleton, which is in turn stored who-knows-where by GuiceServletContextListener to be used by GuiceFilter, but I'd like to un-singleton this so I can delegate like this, instead of having everything tightly bound in a single function.
I am the creator of Guice Servlet. This is basically not allowed as you are describing, as we felt it would be confusing for modules that are not intended to be used this way.
For example, many modules contribute filters that register at "/*" to provide some interception functionality (such as transactions). These could accidentally stop working if you auto-prefixed them. Given that servlet modules can be transitively installed, this is not as simple as being vigilant about one piece of code. Also, with regex bindings (example: /\.html$/), how does one handle prefixes? Do we support them (difficult problem)? Or do we simply register regex bindings normally and make a surprising exception for them?
Considering that what you're asking for is trivially achieved with a constructor in SomeOtherServletModule("/myprefix") that knows how to map itself correctly, we decided not to provide this functionality.
Related
I have a component declared using the #Component annotation, in which there is a set of methods that implement communication with another api, in my product there are operations that are prohibited for a user with an anonymous id. I want to create an annotation, for example #ProhibitedForAnonym, which, every time the method is called, will check the ID of the anonymous customer, with the ID in the method parameter and throw an error if the IDs match. But I don't understand how to do annotation processing in OSGI, maybe some kind of interceptor?
There is no general interception framework in OSGi. However, you could do interception in the following ways:
Don't. Personally, I feel that since we've lambdas a code-based solution has won hands on over a 'magic' annotation check. It is about the same number of characters but a lambda based call allows me to single step, provide context to the security check, does not suffer from the THIS problem, is testable, and requires no complex framework with lots of bug opportunities.
Use the byte code weaving support in OSGi. You need to register a weaver early and then weave any class that has these annotations. You can take a look at https://github.com/aQute-os/biz.aQute.osgi.util/tree/master/biz.aQute.trace for an example of how to use the byte code weaver. Make sure your weaver is there first. If you use bndtools you can add it to the -runpath to run before anybody else. Or use start levels.
Use proxying. You can 'hide' and original service with the Service Hooks and then register a proxy. In the proxy you can then do the annotation check. This also requires that this code runs first and cannot be updated. I think the spec has an example of this
You might want to read: https://www.aqute.biz/appnotes/interceptors.html
I checked out this SO Post which discusses using RequestMapping in interface. Although the post contains ways to achieve this but it does not mention the pros and cons of doing this.
Architecture wise , is this a bad idea to use controller as interface?
What benefit will we achieve in terms of polymorphism for controller?
There is nothing wrong with putting #RequestMapping on the interface. However make sure you have the right reasons to do it. Polymorphism is probably not a good reason, you will not have a different concrete implementation swapped in at runtime or something like that.
On the other hand, for example, Swagger codegen generates interfaces with #RequestMapping and all the annotations on the methods, fields and return types (together with #Api definitions etc.). Your controller then implements this interface. In this case it makes a lot of sense because it is just enforcing you to respect the Swagger / OpenAPI interface definition originally defined in Yaml. There is a nice side-effect that it makes your controller much cleaner. (Clients can also use the same Yaml to generate their own client stubs for their own language frameworks).
If you opt to do this, make sure you use the latest version of the Spring Framework, because there were some bugs which were fixed only very recently, where not all annotations were being inherited.
https://github.com/spring-projects/spring-framework/issues/15682
If you are stuck with an older Spring version, you might need to repeat the same annotations in your controller.
So, the real reason this would make sense is to enforce the interface contract, and separate the interface definition (together with any information pertaining to the interface) from the actual concrete implementation.
While some arguments against this are that
the request mapping is an implementation detail, or
since you only have one active controller implementation, you might as well put it on the implementation,
(others will probably be provided in different answers soon,)
I was recently faced with the same decision to put jax-rs annotations on the interface or the implementation. So, since everything always "depends" on some context, I want to give you an argument for putting the RequestMapping (or e.g. #Path, etc if not using spring) on the interface:
If you are not using HATEOAS or discovering the endpoints via some other means, the endpoint url, http method, etc. are usually fixed and a static part of your backend API. Therefore, you might as well put it on an interface. This was the case for me because I control both the client and the server side.
The controller usually has only one active implementation, so the reason for doing so is not polymorphism. But your implementation usually has a lot more dependencies than the plain interface. So if you export/provide only your interface to clients (e.g. in a seperate jar/java project/...), you only provide things that the clients really require. In my specific case, I delivered the annotated interface so that a client implementation could can it using a Rest-Client-Library and detect the endpoint paths automatically.
I am trying to have an annotation #FeatureDependent be used on methods to signal that the method requires certain things to be enabled in order for it to work. And I was wondering if it was possible to have a method called everytime a method with #FeatureDependent was called which would check if the criteria were met for the method to be called.
It sounds like you are describing Aspect Oriented Programming (AOI). This technique allows you to address "cross-cutting" concerns, tasks like logging, security, and transaction management which tend to affect many methods in the same manner. Your use case sounds like it would be a good fit for AOP.
There are two common approaches to AOP. The first mechanism is to create objects in a container (e.g. a Spring container). The container can then scan the class, detect any advice that needs to be applied, and apply the advice via dynamic proxies (Googling Spring and AOP is a good place to start with this). The downside is that your components will need to be constructed by a container so it makes sense for larger components.
The second approach is an extra compilation step (sometimes done at compilation, sometimes done as a separate compilation phase, and sometimes done by a weaving class loader) to wire in the additional methods. This is typically called "weaving" and AspectJ is a common library to look into for this.
Both approaches will allow you to apply "advice" (code run before and after a method invocation) based on annotations on an object. Explaining either in more detail would be beyond the scope of a SO answer but I hope it can get you started.
I should warn that AOP has gotten a bit of a reputation for complicating the flow of an application and tending to be difficult to understand and debug. As a result it has declined in popularity lately.
Another approach is to use something like Servlet Filters, basically a single choke point for all requests and workflows where you can apply various logging & security mechanisms. Such an approach tends to be a little easier to understand and involve a bit less "black magic".
To explain the use case in as few words as possible, we have a set of controllers (and associated services) that we want to deprecate. In this same project we have introduced fancy new stuff to take its place. For the simplicity sake, all the same REST endpoints are implemented by both sets of work. The only difference being the first set of controllers are namespaced to /v1/ and the latter /v2/.
To verify that all this new work actually works in production, the goal was to incrementally push traffic in that direction. Whether it is "make 5% of the traffic go to the new stuff" or "for all calls dealing with orders from Factory X go to the new stuff" or some other piece of routing logic.
I'm trying not to touch the old code (that would require retesting all of it), so figured I could just hijack how Spring maps a request to a controller. Initially I thought I could I extend RequestMappingHandlerMapping and override the lookupHandlerMethod() call, but while that method is protected in the Abstract base class the very important map of handlerMethods and urlMap are private: leaving me in the lurch when it comes to providing a differing but existing handlerMethod.
I'd like to leverage as much as I can from the AbstractHandlerMethodMapping and the RequestMappingHandlerMapping classes. Currently, without access to the handler maps, I'm debating whether to completely use them, but change the lookupPath string and create my own HttpServerRequest class where I've edited the request URI to match my "new" controllers.
Any ideas? I'm hoping there is something I am missing.
Lots of frameworks let me expose an ejb as a webservice.
But then 2 months after publishing the initial service I need to change the ejb or any part of its interface. I still have clients that need to access the old interface, so I obviously need to have 2 webservices with different signatures.
Anyone have any suggestions on how I can do this, preferably letting the framework do the grunt work of creating wrappers and copying logic (unless there's an even smarter way).
I can choose webservice framework on basis of this, so suggestions are welcome.
Edit: I know my change is going to break compatibility,and I am fully aware that I will need two services with different namespaces at the same time. But how can I do it in a simple manner ?
I don't think, you need any additional frameworks to do this. Java EE lets you directly expose the EJB as a web service (since EJB 2.1; see example for J2EE 1.4), but with EE 5 it's even simpler:
#WebService
#SOAPBinding(style = Style.RPC)
public interface ILegacyService extends IOtherLegacyService {
// the interface methods
...
}
#Stateless
#Local(ILegacyService.class)
#WebService(endpointInterface = "...ILegacyService", ...)
public class LegacyServiceImpl implements ILegacyService {
// implementation of ILegacyService
}
Depending on your application server, you should be able to provide ILegacyService at any location that fits. As jezell said, you should try to put changes that do not change the contract directly into this interface. If you have additional changes, you may just provide another implementation with a different interface. Common logic can be pulled up into a superclass of LegacyServiceImpl.
I'm not an EBJ guy, but I can tell you how this is generally handled in the web service world. If you have a non-breaking change to the contract (for instance, adding a property that is optional), then you can simply update the contract and consumers should be fine.
If you have a breaking change to a contract, then the way to handle it is to create a new service with a new namespace for it's types. For instance, if your first service had a namespace of:
http://myservice.com/2006
Your new one might have:
http://myservice.com/2009
Expose this contract to new consumers.
How you handle the old contract is up to you. You might direct all the requests to an old server and let clients choose when to upgrade to the new servers. If you can use some amount of logic to upgrade the requests to the format that the new service expects, then you can rip out the old service's logic and replace it with calls to the new. Or, you might just deprecate it all together and fail all calls to the old service.
PS: This is much easier to handle if you create message class objects rather than reusing domain entities.
Ok here goes;
it seems like dozer.sourceforge.net is an acceptable starting-point for doing the grunt work of copying data between two parallel structures. I suppose a lot of web frameworks can generate client proxies that can be re-used in a server context to maintain compatibility.