Logging in spring with method interceptors - web-services

I want to use method interceptors in spring 3 to accomplish logging in my app, so that I can trace which methods are called thru the app.
Is there a tutorial (or suggestion) on how to use method interceptors for logging in spring?
It would seem like something that has been done numerous times, but I have not been able to find much data on it.

The Spring reference has a whole chapter on Spring AOP that serves as a very detailed guide for doing what you're looking for. Try that, and if you have some more specific questions, ask.

Spring's org.springframework.aop.interceptor.CustomizableTraceInterceptor lets you achieve this out of the box.
You can customize the interceptor to your need to log argument and returned value of a method.
Example:-
<aop:config>
<aop:advisor advice-ref="loggingAdvisor"
pointcut="execution(public * com.x.y.z.AbstractCommand.*(..))" />
</aop:config>
<bean id="loggingAdvisor"
class="org.springframework.aop.interceptor.CustomizableTraceInterceptor">
<property name="loggerName" value="logger-name" />
<property name="enterMessage" value="Entering $[methodName]($[arguments])" />
<property name="exitMessage" value="Leaving $[methodName](): $[returnValue]" />
</bean>
Spring Document
Similiar SOF question answered

Related

WSO2 ESB REST API Chaining issue

I am facing some issues when doing service chaining is WSO2 ESB. Below is the xml file.
Following is my use case. I need to call Service 1, get the response, do validation check on it and then call Service 2. Through the below code I am successfully able to call Service 1. For the service two request, I have hard coded the request in the payload. Issue is coming when setting the header parameters. The header properties are not getting set due to which call to Service 2 is not going. For testing purpose I have kept both the URLs same.
Please let me know the following:
1. How to set HTTP Header values.
2. Is there a way to persist the Initial input request and then use it in the second Service call.
Although your synapse configs are not there I'll answer your question.
You can do this two ways. One is by using the Header Mediator. You can reffer this Doc. Example code below,
<header name="Accept" value="image/jpeg" scope="transport"/>
The second approach is using the property mediator, You can set the Header value and set the scope to transport. So the Header property will be added.
What you simply need to do it assign the original request content to a Property, so you can use it later. There are many ways to do this, Following example is by using the enrich mediator
<enrich>
<source type="body" clone="true"/>
<target type="property" property="request"/>
</enrich>

Apache ServiceMix! Request-Replay Web Service message

Hello!
I'm trying to learn some Apache Camel and Apache CXF and of course I've ran into some problems.
What I'm trying to do:
Send timed SOAP messages from ESB to some web service, wait for the reponse from the web service and process it. I'm using Apache ServiceMix!.
What I've done:
Implemented a WSDL file with two operations PingOutput (what I'm sending) and PingInput (what I want to receive from the WS).
Implemented a CXF Endpoint (http://127.0.0.1:8090/ping_ws is a WS mocked with SoapUI):
<cxf:cxfEndpoint address="http://127.0.0.1:8090/ping_ws"
id="Ping_Mocked_WS" wsdlURL="ping.wsdl">
<cxf:properties>
<entry key="dataFormat" value="PAYLOAD" />
</cxf:properties>
</cxf:cxfEndpoint>
Implemented a Camel route:
<camelContext xmlns="http://camel.apache.org/schema/spring" streamCache="true">
<route id="ping-ws">
<from uri="timer://ping_timer?fixedRate=true&period=10000"/>
<bean ref="PingBean" method="createPingRequest" />
<to uri="cxf:bean:Ping_Mocked_WS"/>
<bean ref="PingBean" method="processPingResponse" />
</route>
</camelContext>
What I do not understand:
Why the <bean ref="PingBean" method="processPingResponse" /> gets the correct response from SoapUI (the PingOutput operation defined in WSDL)?
Is this the correct way to achieve my goal? And by this way I mean with one single route?
The codes work correctly, I might have some typos here, please do not mind them.
Thanks!
Ad 1)
Likely because the type defined in the method signature of the processPingResponse method. Camel uses bean parameter binding, and based on the type, it uses its type converter to convert to the given type.
And as the payload is a SOAP response in XML it can use JAXB to convert from XML to the type from the method signature.
To do so it uses camel-jaxb which ServiceMix comes with out of the box.
Ad2)
The route works. What it is you want to do differently?

Apache CFX Schema validation - contract first

I am developing a Web service using Apache CXF and contract first approach with schema validation. Problem is, that validation is not working. There is no error, so it like is not activated. But validation is configured.
So, I have took a look to official Apache CXF examples you can find here.
I took a look to wsdl_first example and modify it adding schema validation and some restriction in WSDL:
<!-- HTTP Endpoint -->
<jaxws:endpoint xmlns:customer="http://customerservice.example.com/"
id="CustomerServiceHTTP" address="http://localhost:9090/CustomerServicePort"
serviceName="customer:CustomerServiceService" endpointName="customer:CustomerServiceEndpoint"
implementor="com.example.customerservice.server.CustomerServiceImpl">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
<!-- schema validation-->
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
To my surprise, it doesn't work either.
OK, so I took a look to wsdl_first_xmlbeans example, where according with the README.txt file, it also shows how CXF configuration can be used to enable schema validation.
And for this example, schema validation works. The difference between both examples is that the second one use JAX-WS APIs and with the XMLBeans approach. Does it have something to do? Why schema validation is not working for first example? Probably, I am missing something.
For validation on the service side, it would likely need to have a wsdlLocation attribute set on the jaxws:endpoint so it would load the WSDL (that would then contain the schemas). Currently, the validation in that example is on the client side only. If you run the service, the log shows:
INFO: Creating Service {http://server.customerservice.example.com/}CustomerServiceImplService from class com.example.customerservice.CustomerService
which shows it's not using the WSDL at all.

Spring web services validation

I've two kinds of webservices:
webservices that need the request to be validated
others that must not be validated by Spring.
Is this possible in Spring?
I know about ValidatingInterceptor, but can we have two of these?
The reason for not validating one type of web service is that the request is not defined: what's sent in the request, depends on many things.
I am using Spring 3.0, with schema XSD's for my webservices.
Any suggestions?
Adi
You can use two payloadroot within a interceptor for that purpose.
All you need to do is to set validateRequest/validateResponse as true or false as required.
Here is a sample:
<sws:interceptors>
<sws:payloadRoot namespaceUri="uri1">
<bean id="validator1forUri1"
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor"
p:schema="classpath:/WEB-INF/xsds/tovalidate.xsd" p:validateRequest="true"
p:validateResponse="true" />
</sws:payloadRoot>
<sws:payloadRoot namespaceUri="uri2">
<bean id="validator2forUri2"
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor"
p:schema="classpath:/WEB-INF/xsds/nottovalidate.xsd"
p:validateRequest="false" p:validateResponse="false" />
</sws:payloadRoot>
</sws:interceptors>

Configuring an HTTP proxy in a Spring web app

I have been searching around for a proper way to configure an HTTP proxy in a Spring web application. Unfortunately, each time the results I get are about AOP proxies and not HTTP proxies.
Basically, one module of my application is running a webservice client configure in the Spring XML file with JAX-WS, giving something like :
<bean id="heartBeatWebservice" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="the.web.service.interface"/>
<property name="wsdlDocumentUrl" value="http://thehost:theport/theservicename.wsdl"/>
<property name="serviceName" value="TheServiceName"/>
<property name="namespaceUri" value="http://the.namespace/"/>
<property name="portName" value="TheWebServicePortName"/>
</bean>
But my app has to run behind an HTTP proxy for being able to call the web service, and I must acknowledge that I don't know how to do it properly within the Spring context.
I tried in some main class that I wrote to try out this code at first :
System.setProperty("http.proxyHost", "my.proxy.addr");
System.setProperty("http.proxyPort", "8080");
Unfortunately, it didn't work as expected. I assume there is a nice way to configure an HTTP proxy in a Spring context but can't find out how ...
Can you give me a hint ?
There isn't any Spring-specific HTTP proxy configuration required.
It should use the standard Java HTTP proxy settings, so you're going along the right lines.
Can you try running the main class using -Dhttp.proxyHost=my.proxy.host -Dhttp.proxyPort=8080 rather than using System.setProperty?