Apache Camel + Spring-WS + Authorization - java

I have a project using apache camel, and I have to consume a WS ..
.setHeader(HttpHeaders.AUTHORIZATION, constant("Basic {base64"))
.to("spring-ws:http://myhost.com.br?soapAction=myAction")
And I get the follow error : org.springframework.ws.client.WebServiceTransportException: Unauthorized [401]
If I send using soap-ui just with the header, it's work well.
Any ideas? Thanks a lot.

From http://people.apache.org/~dkulp/camel/spring-web-services.html
A custom message sender or factory in the registry can be referenced like this:
from("direct:example")
.to("spring-ws:http://foo.com/bar?messageFactory=#messageFactory&messageSender=#messageSender")
Spring configuration:
<!-- authenticate using HTTP Basic Authentication -->
<bean id="messageSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
<property name="credentials">
<bean class="org.apache.commons.httpclient.UsernamePasswordCredentials">
<constructor-arg index="0" value="admin"/>
<constructor-arg index="1" value="secret"/>
</bean>
</property>
</bean>
<!-- force use of Sun SAAJ implementation, http://static.springsource.org/spring-ws/sites/1.5/faq.html#saaj-jboss -->
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="messageFactory">
<bean class="com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl"></bean>
</property>
</bean>

Related

HttpConnectionManagerParams not working for HTTPS URL

We use Apache Camel's camel-http component to integrate with HTTP endpoints, HttpConnectionManagerParams is used to configure defaultconnectionsPerHost and maxTotalConnections.
<bean class="org.apache.commons.httpclient.params.HttpConnectionManagerParams" id="MyHttpConnectionManagerParams">
<property name="defaultMaxConnectionsPerHost" value="20"/>
<property name="maxTotalConnections" value="200"/>
</bean>
Above parameters takes effect only if the endpoint URL is over HTTP, same configuration becomes void and default HttpConnectionManager takes effect when endpoint is over HTTPS.
Is there something to be additionally configured for HTTPS url?
Adding below beans has solved works for me.
Agreed there is no component named HTTPS in Camel but things are working with below configuration both in older and newer versions of Apache Camel.
<bean class="org.apache.camel.component.http.HttpComponent" id="http">
<property name="camelContext" ref="myCamelContext"/>
<property name="httpConnectionManager" ref="MyHttpConnectionManager"/>
</bean>
<bean class="org.apache.camel.component.http.HttpComponent" id="https">
<property name="camelContext" ref="myCamelContext"/>
<property name="httpConnectionManager" ref="MyHttpConnectionManager"/>
</bean>
<bean class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager" id="MyHttpConnectionManager">
<property name="params" ref="MyHttpConnectionManagerParams"/>
</bean>
<bean class="org.apache.commons.httpclient.params.HttpConnectionManagerParams" id="MyHttpConnectionManagerParams">
<property name="defaultMaxConnectionsPerHost" value="100"/>
<property name="maxTotalConnections" value="500"/>
</bean>

transactional not working in spring data neo4j

I am using spring-data-neo4j for my neo4j database in my application,i want to have transactional APIs in my service layer but it seems that #transaction is not working.
Service Layer:
#Transactional('neo4jTransactionManager')
def savePerson(){
Person person=new Person()
person.setName("prabh")
person.setDistance(100)
PersonRepository.save(person)
int i=10/0;
}
Configuration :
<context:component-scan base-package="neo4j"></context:component-scan>
<bean id="graphDatabaseService"
class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase">
<constructor-arg value="http://localhost:7474/db/data" />
</bean>
<neo4j:config graphDatabaseService="graphDatabaseService"
base-package="neo4j" />
<neo4j:repositories base-package="neo4j" />
<bean id="neo4jTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">
<constructor-arg ref="graphDatabaseService" />
</bean>
</property>
<property name="userTransaction">
<bean class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">
<constructor-arg ref="graphDatabaseService" />
</bean>
</property>
</bean>
<tx:annotation-driven mode="aspectj"
transaction-manager="neo4jTransactionManager" />
</beans>
I am using rest server of neo4j database.
That's what the documentation says, for remote access there is no transactionality due to Neo4j's REST API not exposing transactions over the wire in the past
In the next milestone (and the current 3.3.0.BUILD-SNAPSHOT) build a new remoting integration is used, which exposes transactions over the wire and is also much faster than the existing one.

How to make embedded Jetty use the AppContext it's defined in as parent context for servlets

I have a standalone java app that now runs an embedded Jetty server to expose a RESTful API for HTTP. It does make heavy use of Spring beans for everything from Hibernate to Jetty. I have Jetty configured with a DispatcherServlet ( the thought being that adding a non-REST API in the future will be as simple as making the new Controller and mapping it correctly for the dispatcher).
My app has a class with a main method that creates a ClassPathXmlApplicationContext from my appContext.xml to start everything up.
ApplicationContext ac= new ClassPathXmlApplicationContext(new String[] { "appContext.xml" });
I don't know how to make beans defined in the context config file for the DispatcherServlet have access to beans defined in the appContext.xml where jetty is defined. My Jetty definition looks like this:
<bean id="JettyServer" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
<constructor-arg>
<bean id="threadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<property name="minThreads" value="2"/>
<property name="maxThreads" value="10"/>
</bean>
</constructor-arg>
<property name="connectors">
<list>
<bean id="Connector" class="org.eclipse.jetty.server.ServerConnector">
<constructor-arg ref="JettyServer"/>
<property name="port" value="8090"/>
</bean>
</list>
</property>
<property name="handler">
<bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<bean class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="contextPath" value="/"/>
<property name="servletHandler">
<bean class="org.eclipse.jetty.servlet.ServletHandler">
<property name="servlets">
<list>
<bean class="org.eclipse.jetty.servlet.ServletHolder">
<property name="name" value="DefaultServlet"/>
<property name="servlet">
<bean class="org.springframework.web.servlet.DispatcherServlet"/>
</property>
<property name="initParameters">
<map>
<entry key="contextConfigLocation" value="classpath:./DefaultServlet.xml" />
</map>
</property>
</bean>
</list>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping">
<property name="pathSpecs">
<list><value>/</value></list>
</property>
<property name="servletName" value="DefaultServlet"/>
</bean>
</list>
</property>
</bean>
</property>
</bean>
<bean class="org.eclipse.jetty.server.handler.RequestLogHandler">
<property name="requestLog">
<bean class="org.eclipse.jetty.server.NCSARequestLog">
<constructor-arg value="/opt/impulse/logs/jetty-yyyy_mm_dd.log"/>
<property name="extended" value="false" />
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
Then in DefaultServlet.xml I try to defined a bean with a property references a bean defined in appContext.xml, which is what breaks.
<bean id="restApiController" class="com.mycompany.myapp.api.controllers.RESTfulController">
<property name="someBean" ref="someBean"/>
</bean>
You are bootstrapping Jetty with applicationContext.xml, which in turn sets up jetty with your servlet configuration. Inside it you are configuring your servlet with the contextConfigLocation parameter pointing to the servlet application context. It will still run as a webapp, even if you embed it. So you need to provide your servlet with the config to your other beans as well. I suggest that you extract the jetty setup into it's own file, and then the rest of your beans in a different file. You then supply the other context file in the contextConfigLocation.
Edit
If you really need to share the application context between jetty and your servlet, maybe you can use some of the information in this blog. It seems to be possible, but it looks like you have to wire up the parent/child relationship between the contexts manually.
For me, what worked is setting of ResourceConfig. With DispatcherServlet server was not even able to serve Rest call. So I used ServletContainer. Now Rest call worked but not able to access beans loaded in ApplicationContext. There ResourceConfig registration helped. Below was my configuration that I came up after long R & D. I had Jetty version 9.2.11.v20150529 and Spring 4.1.2.RELEASE
<bean class="org.eclipse.jetty.servlet.ServletHolder">
<property name="name" value="DefaultServlet"/>
<property name="servlet">
<bean id="servletContainer" class="org.glassfish.jersey.servlet.ServletContainer">
<constructor-arg>
<ref bean="config" />
</constructor-arg>
</bean>
</property>
</bean>
<bean id="config" class="org.glassfish.jersey.server.ResourceConfig" />
Basically I set ResourceConfig under ServletContainer. Then in application, I fetched all beans loaded in my applicationContext and register with this Resource config like below
ResourceConfig restConfig = (ResourceConfig)webContext.getBean("config");
String[] beans = context.getBeanDefinitionNames();
for(String bean : beans)
restConfig.registerInstances(context.getBean(bean));
Well, webContext here is WebAppContext which is required instead of ServletContaxtHandler. So instead of below lines as mentioned in question
<bean class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="contextPath" value="/"/>
I have
<!-- To work with Spring , we need WebAppContext instead of ServletContext -->
<!-- <bean id="servletContextHandler" class="org.eclipse.jetty.servlet.ServletContextHandler"> -->
<constructor-arg name="webApp" value="./target/classes/" />
<constructor-arg name="contextPath" value="/" />

AnnotationMethodHandlerExceptionResolver message converters

I want to configure AnnotationMethodHandlerExceptionResolver by adding jackson message converter. The problem is that I have already configured message converters in <mvc:message-converters> by creating a bean, and I can't reference it in AnnotationMethodHandlerExceptionResolver neither use ref in <mvc:message-conferters>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean id="mappingJackson2" class="pl.styall.scylla.json.config.CustomMappingJackson2">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="outboundExceptionAdapter"
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
<property name="messageConverters">
<list>
<ref bean="mappingJackson2" />
</list>
</property>
</bean>
I could define two beans one for <mvc:message-converters> and AnnotationMethodHandlerExceptionResolver, but it is probably not the best idea. Is there other way to do this?
This is not supported yet, but it is on the 3.2 backlog. So it might be supported in 3.2.
See Add support for <ref> in addition to <bean> for <mvc:message-converters> for the Spring feature request.

How to force disable JSR-303 support in Spring 3?

I have some legacy Spring MVC code mixed with gwt code in same artifact (built using maven) and I cannot make it run. It wants validation provider at runtime which i do not need (since I'm not using any JSR-303 validation annotations) and do not want in CP (it may conflict with some app containers this artifact will be deployed in)
How to force spring not to do any JSR-303 validations and get rid of runtime dependency on validation provider?
PS artifact has validation-api in CP since GWT is using it somehow
PPS
Seems like removing <mvc:annotation-driven/> from Spring config fixes this.
Binding and classic validations still works (I have <context:annotation-config/> enabled)
As you already discovered, <mvc:annotation-driven/> sets a lot of features including JSR-303. The equivalent is
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="0" />
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator" />
</bean>
</property>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.FormHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="conversion-service"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
So you may substitute the tag onto this xml configuration and remove parts you don't need.

Categories