SmartLifecycleRoleController get status - spring

How to get the status of the endpoints annotated with #Role that we can start / stop with the SmartLifecycleRoleController?
There doesn't seem to be a method for that, should we use another controller?

It's not currently supported; you'd have to use reflection to get a reference to the lifecycles map and iterate over it.
Or you could subclass it and declare it as a bean with name IntegrationContextUtils.INTEGRATION_LIFECYCLE_ROLE_CONTROLLER and intercept all the add calls.
I opened a JIRA Issue to provide access.

Related

Using RequestScope without ServletModule

I was exploring #RequestScoped and was wondering if there's way to use it without installing ServletModule. I am using Guice 3.0 + Jersey 1.17 and probably don't want to use GuiceContainer & GuiceServletContextListener.
I want object creation(injections) per request depending on some user input in the Jersey request. Is it possible? What can be performance & security considerations of using GuiceContainer if I had to replace my existing ServletContextListener with that of Guice?
If there's a way of using RequestScope as per my needs, can you give me some references for the same?
It is possible to bind a custom Scope implementation to a predefined scoping annotation like #RequestScoped. It does mean that then you cannot use ServletModule, since you can't bind two different implementations to the same scoping annotation.
See the documentation on Custom Scopes for details. You will need to write code to determine what constitutes a "request" for purposes of scoping, and trigger entering and exiting the scope as necessary.
For example, in the normal Guice implementation, ServletScopes.RequestScope uses a ThreadLocal initialized in GuiceFilter to keep track of what the current request is.

Spring messaging websockets - how to call setMessageCodec

I am trying to use Spring websockets with Genson instead of Jackson. When I try and connect from a client I get the following:
java.lang.IllegalStateException: A SockJsMessageCodec is required but not available: Add Jackson 2 to the classpath, or configure a custom SockJsMessageCodec.
It would appear I need to set a custom message codec.
I can see that a .setMessageCodec method appears on the TransportHandlingSockJsService but I can't see anywhere in the configuration options where I can actually set it.
I think the the .setMessageCodec method should be present on the SockJsServiceRegistration class so it can be set from configuration...but it isn't...any ideas?
EDIT: I believe this is a bug so have raised: https://jira.spring.io/browse/SPR-12091
Have a look at this issue https://jira.spring.io/browse/SPR-11184.
It looks like that you could implement it by overriding the configureMessageConverters method in WebSocketMessageBrokerConfigurer.

Passing a Spring bean to a Camel component

I have a custom component of type FooComponent which is added to the route by the following lines:
from("foo://bar?args=values&etc")
.bean(DownstreamComponent.class)
...
FooComponent creates an endpoint and consumer (of type FooConsumer) which in turn emits messages which get to the DownstreamComponent and the rest of the pipeline.
For monitoring, I need the FooComponent consumer to call a method on a non-Camel object, which I'm creating as a Spring bean. The Camel pipeline is very performance sensitive so I'm unable to divide the FooComponent into two halves and insert the monitor call as a Camel component between them (my preferred solution, since FooComponent shouldn't really have to know about the monitor). And I'm reluctant to turn the method call into a Camel Message that will be picked up by the monitoring component later in the pipeline, as the pipeline filtering becomes complicated later and I don't want to meddle with it more than necessary.
Somewhere inside FooConsumer, I have:
// in the class
#Autowired
Monitor monitor;
// inside the consumer's run method
monitor.noticeSomething();
The problem is that monitor will never be set to the Monitor bean which is created in the rest of the application. As I understand it, it's because FooConsumer itself is not visible to Spring -- an object of that type is created normally inside FooComponent.
So, how can I get FooComponent to find the Monitor instance that it needs to use?
Can I pass it in when the route is created? This seems tricky because the definition is a faux URL "foo://bar?args=values&etc"; I haven't found how to pass Java objects that way.
Can I get Spring to find that #Autowired annotation inside FooConsumer and inject the monitor object somehow?
If you have a singleton instance of Monitor you ought to be able to #Autowire it in the FooComponent class. As Camel will let Spring dependency inject when creating the FooComponent.
Then you can pass on the monitor instance when you create the endpoint / consumer from your component.
The easiest thing to do is to create a Monitor property on the FooComponent class, and wire it in like any other bean.
<bean id="monitorBean" class="my.Monitor"/>
<bean id="foo" class="my.FooComponent">
<property name="monitor" ref="monitorBean"/>
</bean>
Then in your FooConsumer, when you need to get hold of the monitor, call:
Monitor monitor = ((FooComponent) getEndpoint().getComponent()).getMonitor();
If you were changing the monitor bean on a per-endpoint basis, you could use Camel's nifty # syntax to locate a bean with that id, and inject it into an Endpoint property.
foo:something?monitor=#monitorBean
Then to use it in your FooConsumer you simply say:
Monitor monitor = ((FooEndpoint) getEndpoint()).getMonitor();

Spring overwriting controller

I provide a highly customisable application to my clients which is working totally by itself. But If one my client wants to overwrite any Controller, I want to replace my implementation by theirs. However just overwriting the controller causes an ambiguous definition of mappings.
I have been using Component Scanning to load beans.
The potential solutions came to my mind are:
Using component scanner with excluding by a custom filter? (This seems not so easy)
Using a xxxxPostProcessor to remove some beans? (How?)
Any help?
If I got your Question properly,
You can differ implementation by changing URL to particular Implementation name
Say Telecom is interface and AirtelImpl and RelianceImpl are Controllers then
Your request mapping
#RequestMapping(value= "/airtel/doBilling")
#RequestMapping(value= "/reliance/doBilling")
In this way, Implementation flow will differ.
I have followed these steps:
Created a custom annotation: #Devoted
Created a custom ImportBeanDefinitionRegistrar. Iterated already registered bean definitions to find out `#Devoted #Controller's and removed them.
Based on a request I will provide implementation details.

Webapi DefaultHttpControllerSelector does not properly resolve my controller

I have an WebApi application that contains some controllers (they are registered using the extension method RegisterApiControllers). This application references another assembly that contains other controllers that I don't want to expose(I have checked that they are not registered in the container). It happens that both have an OrderController, and when I try to access the /api/Order url, I get an exception "Multiple types were found that match the controller named 'order'." and the stack trace shows that I was in DefaultHttpControllerSelector.
I have seen that AutofacControllerFactory used to exist and there was even a ConfigureWebApi that registered it, but it is not anymore present in the default branch.(you can see it here http://alexmg.com/post/2012/03/09/Autofac-ASPNET-Web-API-(Beta)-Integration.aspx)
It seems also that we can not filter the namespace of the route definition in WebApi (it is possible to MVC).
So any idea on how I can use only the Controller registered in my Autofac container and not use the DefaultHttpControllerSelector that seems to scan all referenced assemblies to discover controller?
Thanks
The problem is that registering the controller with autofac is not really related to the routing process. Only once the routing process has identified which controller to dispatch to will Autofac be called to resolve the type.
It looks like, from digging around in the source, that you would need to write a replacement IHttpControllerSelector in order to handle two controllers with the same name. (which really sucks BTW).
You might be able replace the DefaultHttpControllerTypeResolver with an instance that is passed a predicate that filters out the controllers from the assembly that you want to ignore. It's a bit of a kludgy solution but might work.
Actually, you might be able to replace the DefaultHttpControllerTypeResolver completely with one that is based on registrations in your Autofac container. It is a very simple interface, so as long as Autofac have a some kind of discovery mechanism, you should be golden.
public interface IHttpControllerTypeResolver
{
ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver);
}

Resources