1

I am trying to log Web service operation when marshalSendAndReceive is called. so that I can log any webservice calls that use marshalSendAndReceive like below. but somehow below logWebserviceOperation is not being called. Is somehting wrong on my @Before ..? or am i missing something.

package com.julia;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    
    public static void main(String[] args) {
        
        SpringApplication.run(Application.class, args);
        
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

}
package com.julia.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.transport.http.HttpComponentsMessageSender;

import com.julia.service.SOAPConnector;

import static com.julia.config.ApplicationConstants.CONTEXT_PATH_1;  //contstants to set the Jaxb context path
import static com.julia.config.ApplicationConstants.CONTEXT_PATH_2;
import static com.julia.config.ApplicationConstants.CONTEXT_PATH_3;

@Configuration
@RefreshScope
public class ParserConfig {
    
    @Value("${application.WSSessionTimeoutInMilliSec}")
    private int timeout;
    
    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setPackagesToScan(CONTEXT_PATH_1,CONTEXT_PATH_2, CONTEXT_PATH_3);
        return marshaller;
    }

    @Bean
    public SOAPConnector soapConnector(Jaxb2Marshaller marshaller) {
        SOAPConnector client = new SOAPConnector();
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);

        HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
        messageSender.setConnectionTimeout(timeout);

        client.setMessageSender(messageSender);
        
        return client;
    }
    
}
package com.julia.service;

import java.io.IOException;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.transport.context.TransportContext;
import org.springframework.ws.transport.context.TransportContextHolder;
import org.springframework.ws.transport.http.HttpUrlConnection;

@Service
@RefreshScope
public class SOAPConnector extends WebServiceGatewaySupport {

    private static final Logger LOGGER = LogManager.getLogger(SOAPConnector.class);
    
    public Object callWebService(String url, Object request) {
        return getWebServiceTemplate().marshalSendAndReceive(url, request);
    }
}
package com.julia.logging;

import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    private static final Logger LOGGER = LogManager.getLogger(LoggingAspect.class);

    public LoggingAspect() {
    }
    
    @Before("execution(* org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(..))")
    public void logWebserviceOperation(JoinPoint jp) {
        Object[] methodArgs = jp.getArgs();
        String uri = methodArgs[0].toString();
        String payload = String.valueOf(methodArgs[1]);
        LOGGER.log("uri:" + uri);
        LOGGER.log("payload :" + payload);
    }
dreamcrash
  • 47,137
  • 25
  • 94
  • 117
Julia
  • 133
  • 11
  • Could you share a [MCVE](https://stackoverflow.com/help/minimal-reproducible-example) ? – R.G Feb 01 '21 at 15:28
  • R.G I've updated the codes a little more. please let me know if there is anything you need... – Julia Feb 01 '21 at 17:04

1 Answers1

2

Spring AOP can only advice a Spring container managed bean.

From the code shared , WebServiceTemplate instance the advice is targeting is not a Spring bean.

public Object callWebService(String url, Object request) {
    return getWebServiceTemplate().marshalSendAndReceive(url, request);
}

WebServiceGatewaySupport.getWebServiceTemplate() method is from where the WebServiceTemplate instance is obtained . The default logic is to construct a new instance of WebServiceTemplate class.

Based on the reference documentation WebServiceTemplateBuilder could be used to create a WebServiceTemplate bean.

WebServiceGatewaySupport.setWebServiceTempate() can then be used to set the bean. Do read on the notes when doing so.

Alternatively , you could advice the SOAPConnector.callWebService(..) which should provide you the same log.

@Before("execution(* com.julia.service.SOAPConnector.callWebService(..)) && args(url,request)")
    public void logWebserviceOperation(JoinPoint jp,String url, Object request) {
        LOGGER.log("uri:" + url);
        LOGGER.log("payload :" + request);
    }
R.G
  • 6,436
  • 3
  • 19
  • 28