Spring AsyncServlet with ActiveMQ, Camel and Jetty - spring-mvc

I'm trying to use Spring AsyncServlet with Camel and ActiveMQ. I'm using the following versions.
<spring.version>3.2.0.M1</spring.version>
<camel.version>2.10.0</camel.version>
<jetty.version>8.1.3.v20120416</jetty.version>
<activemq.version>5.6.0</activemq.version>
I want to push messages to clients that are connected to the server (Jetty).
My Camel routes looks like the following.
from("mina:udp://source_machine:9998").to("activemq:myqueue");
I've the following in my Spring/Camel configuration based on this.
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="vm://localhost:61616" />
</bean>
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="maxConnections" value="8" />
<property name="maximumActive" value="500" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory" />
<property name="transacted" value="false" />
<property name="concurrentConsumers" value="10" />
</bean>
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="configuration" ref="jmsConfig" />
</bean>
Using the above configuration I'm able to input messages into my queue (at least I don't get any errors.) However, I've no idea how to read from this queue.
Is this the correct way of configuring ActiveMQ when using Spring, Camel and Jetty ?
How do I add/register a MessageListener javax.jms.MessageListener so that I can read from my queue.
How can I control the queue size and make the queue non-persistent?
It it possible to add multiple listeners
Thanks.

Your config looks good for activemq. No idea about jetty. There is no jetty config in the snippet you provided.
In a camel route you can simply use a from activemq endpoint to listen on the queue.
from("activemq:myqueue").to("log:test");
Btw. I typically use the jms ednpoint instead of the ActiveMQ one. This has the advantage that it is easier to switch to another jms provider if you have to at some point.
You can also use the connectionfactory and use you own DefaultMessageListenerContainer in a bean. See the spring configs for how to do this but this has nothing to do with camel then.
You can control the queue size in the activemq config. Using the http://activemq.apache.org/producer-flow-control.html.
You can not make a queue no persistent but you can define the messages you send to be non persistent. http://activemq.apache.org/how-do-i-disable-persistence.html
You can define many listeners and you can even define the number of threads for one listener using the option maxConcurrentConsumers on the from endpoint above.

Related

How the external authentication handled in WSO2 APIM for an external/Third Party APIs

I am using WSO2 APIM (2.5.0) and IS (5.6.0). They both are integrated and working well.
Now, if I onboard an third party API in API Management and using oauth token I can be able to access it. But question is how to handle any external or third party APIs which has its own authentication.
SO basically, using WSO2 APIM token I can be able to access the onboarded API to use but we will not be able to get any response as the onboarded API has its own authentication (basic or oauth).
How to achieve this in APIM.
Any help or guidance will be helpful.
EDIT:
Here is the sequence I am using (Thanks Bee for the guidance)
<sequence xmlns="http://ws.apache.org/ns/synapse" name="backend-token-sequence">
<property name="inputmessage" expression="get-property('registry', 'gov:/Login/msg/inputmessage.json')" scope="default" type="STRING"/>
<script language="js">
var payload = mc.getProperty("inputmessage");
mc.setPayloadJSON(payload)
</script>
<header name="Content-Type" scope="transport" value="application/json"/>
<property name="messageType" value="application/json" scope="axis2" type="STRING" description="messageType"/>
<property name="temp" expression="$axis2:REST_URL_POSTFIX"/>
<property name="REST_URL_POSTFIX" action="remove" scope="axis2"/>
<property name="DISABLE_CHUNKING" value="true" scope="axis2" type="STRING"/>
<call blocking="true">
<endpoint>
<http uri-template="https://xx.com/auth/login" method="POST" />
</endpoint>
</call>
<property name="x-access-token" scope="transport" expression="json-eval($.token)"/>
<property name="REST_URL_POSTFIX" scope="axis2" expression="$ctx:temp"/>
</sequence>
This is the inflow sequence which is being used to one of API.
I am calling API using APIM URL with GET Method, passing APIM bearer token
Thanks
WSO2 APIM out of the box supports basic auth and digest auth as backend security schemas.
In addition to that, using custom sequences you can pass any kind of security token to the backend.
For backends with OAuth, you have 2 options.
(1) Send backend token as well in the API request (inbound to APIM) and then forward it to the backend.
(2) Use a custom sequence to call the external token API and take a new token for the backend and then forward it to the backend.
<property name="temp" expression="$axis2:REST_URL_POSTFIX"/>
<property name="REST_URL_POSTFIX" action="remove" scope="axis2"/>
<call blocking="true">
<endpoint>
<http uri-template="https://external_idp.com/token" method="GET" />
</endpoint>
</call>
<property name="BackendAuthHeader" scope="transport" expression="json-eval($.tokenresponse.token)"/>
<property name="REST_URL_POSTFIX" scope="axis2" expression="$ctx:temp"/>
I recommend (1) due to its simplicity.
Edit: More about option (1):
If your backend expects a header something other than "Authorization" header you can simply send that header with your requests and it will be sent to the backend.
However, if your backend also expects the "Authorization" header, then it becomes a conflict as you can't use the same header to pass 2 tokens (1 for GW and 1 for backend). To solve that problem, you can use the custom authorization header for gateway feature.

Why Spring interceptor is bypassed for bad URLs?

My web application runs on Spring (MVC) 4.2.9.RELEASE, Hibernate 5.1.3.Final, and Spring Data 1.8.2.RELEASE.
I have the following interceptor in the Spring context.
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="1"/>
<property name="interceptors">
<list>
...
<ref local="myIntercepter" />
...
</list>
</property>
</bean>
The interceptor "myIntercepter" is able to intercept valid URLs such as
http://localhost/s?mid=cflbv1zipb8d7&lang=en_US
However, for the following invalid URL (has a question mark in the end)
http://localhost/s?mid=cflbv1zipb8d7&lang=en_US?
The interceptor does not get called. I am not sure why this behavior happens. I have to make sure all web traffic to go through the interceptor.
If you want to make sure a piece of code gets executed for every web request coming in, I'd recommend using a Filter instead of a HandlerInterceptor. Spring MVC might be trying to parse the querystring or something to that effect prior to the interceptor being called, or it can't find a handler due to the invalid url.

How to avoid display jssession id in Url using spring 4 java annotation configuration

I found is that jsessionid is injected in the url, how can i avoid displaying jsessionid in url. I am using cookies for to have store login information I have not used any http session. I found below suggestion in xml configuration how would I write using spring java annotation configuration can anyone just let me know
<property name="securityContextRepository" ref="securityContextRepositoryNoJSession"/>
<bean id="securityContextRepositoryNoJSession" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository">
<property name="disableUrlRewriting" value="true"/>
</bean>

How to configure Shiro + Spring MVC when #Controller REDIRECTS to a login page

I have a typical Spring MVC + GWT architecture with Apache Shiro as a security layer.
Problem:
No matter what protocol is used for a request to the App server, pages should be returned in the protocol specified in the request's "X-Forwarded-Proto" header (so, app server can receive a HTTP request, but if the header says HTTPS, it should respond using HTTPS). Obviously, the configuration specified in the Shiro-Spring tutorial won't work as it has nothing to do with the protocols (login.jsp will be returned using the protocol used in request):
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.jsp"/>
<property name="filterChainDefinitions">
<value>
/** = authc
</value>
</property>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
</bean>
<bean id="myRealm" class="com.myapp.security.DBRealm">
<property name="credentialsMatcher" ref="sha256Matcher"/>
</bean>
Possible solution:
Use #Controller to REDIRECT to the login view with the specified protocol:
#RequestMapping(value="/login", method=RequestMethod.GET)
public RedirectView doLogin(HttpServletRequest req) throws MalformedURLException {
URL originalURL = new URL(req.getRequestURL().toString());
return new RedirectView(new URL(req.getHeader("X-Forwarded-Proto"), originalURL.getHost(), "/login.jsp").toString());
}
and change the loginUrl in shiro configuration to point to /login, so that #controller catches it:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login"/>
... leave everything else the same
</bean>
But with this configuration, although I get the same login page, the myRealm (com.myapp.security.DBRealm) is not triggered at all (meaning, the credentials are not checked), and login always fails. Seems like the redirected page loses the "hook" to the realm.
Any ideas on what I am doing wrong?
The reason this is failing is because the Shiro authc Filter (a FormAuthenticationFilter) expects the loginUrl to be the one where the login attempt occurs.
That is, when authc filters a request that matches the loginUrl, it will automatically support form-based authentication. Because you are redirecting the end-user to a URL that does not match the loginUrl (i.e. loginUrl=/login, but you redirect them to /login.jsp), the authc filter won't perform a login.
Your best option IMO:
Subclass FormAuthenticationFilter and override the redirectToLogin method to use your X-Forwarded-Proto logic. Then redefine 'authc' to be your custom subclass. For example, using shiro .ini:
[main]
...
authc = com.foo.my.FormAuthenticationFilterSubclass
Also, if you want this behavior in Shiro directly (so Shiro looks for that header when performing a redirect by default) so you can remove your subclass, please open a feature request in Apache Shiro's Jira.

How to enable Spring 3.0 MappingJacksonHttpMessageConverter with #ResponseBody AND pre-Spring-3.0 Controller SimpleUrlHandlerMapping together?

As the title suggests, I'm trying and failing to get the following combination working in Spring 3.0:
pre-Spring-3.0 controllers mapped with SimpleUrlHandlerMapping, and,
a Spring-3.0 #Controller using MappingJacksonHttpMessageConverter and #ResponseBody to return JSON.
All the pieces work - except when put together!
In more detail, I have an existing Spring web-app which includes many pre-Spring-3.0 controllers. These implement Controller and are mapped explicitly with a SimpleUrlHandlerMapping bean. (So one solution is to change them all to #Controller style). The same web-app (DispatcherServlet) also supports several newer controllers annotated with #Controller.
My bean config includes the following, and all is good:
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/path/name.ext">mySpring25Controller</prop>
</props>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
</bean>
Now I'm adding, to a new controller annotated with #Controller and #RequestMapping, use of MappingJacksonHttpMessageConverter so that with #ResponseBody some of my methods can return JSON via Jackson - to Ajax calls. Again all is good:
<!-- to generate JSON responses using Jackson (without using <mvc:annotation-driven/>) -->
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter"/>
</list>
</property>
</bean>
The problem is that now my explicit mappings defined in the SimpleUrlHandlerMapping bean are no longer working:
[http-8081-Processor25] ERROR org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/mayapp].[springapp] - Servlet.service() for servlet springapp threw exception
javax.servlet.ServletException: No adapter for handler [com.mycom.controller.mySpring25Controller ...]: Does your handler implement a supported interface like Controller?
at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:985)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:773)
These mappings still appear in my log at start-up (SimpleUrlHandlerMapping - Mapped URL path ... etc) - but evidently are now broken somehow.
INFO org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/path/name.ext] onto handler [com.mycom.controller.mySpring25Controller ....]
I started with <mvc:annotation-driven/> which had the same problem. I've tried re-ordering without success, including order properties. And I've also not found an explanation in the Spring docs. It seems there is some interaction in the Spring auto-magic which I haven't got to the bottom of.
Interesting problem anyone? Insight gratefully received!
Post and ye shall find (delayed by 8 hours for lack of reputation)!
As per post No adapter for handler exception the answer appears to be that the explicit AnnotationMethodHandlerAdapter definition blows away the implicit SimpleControllerHandlerAdapter which was previously satisfying the SimpleUrlHandlerMapping mappings.
So add it explicitly:
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter">
</bean>
And we're good, though at the same time you might also need to introduce also an explicit replacement for the implicit HttpRequestHandlerAdapter also blown away:
<bean
class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter">
</bean>

Resources