package gov.samhsa.acs.common.cxf; import java.util.List; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; import javax.xml.ws.Endpoint; import org.apache.cxf.endpoint.Client; import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxws.spring.EndpointDefinitionParser.SpringEndpointImpl; import org.apache.cxf.message.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CXFLoggingConfigurer { private final static Logger LOGGER = LoggerFactory .getLogger(CXFLoggingConfigurer.class); private static final String ADD = "Adding"; private static final String REMOVE = "Removing"; private boolean enableLoggingInterceptors; private final Optional<SpringEndpointImpl> endpoint; private final Optional<Client> client; public CXFLoggingConfigurer(Client client) { this.endpoint = Optional.empty(); this.client = Optional.of(client); } public CXFLoggingConfigurer(Endpoint endpoint) { if (!(endpoint instanceof SpringEndpointImpl)) { final String error = "Endpoint is not an instance of org.apache.cxf.jaxws.spring.EndpointDefinitionParser.SpringEndpointImpl"; LOGGER.error(error); throw new CXFLoggingConfigurerException(error); } this.endpoint = Optional.of((SpringEndpointImpl) endpoint); this.client = Optional.empty(); this.enableLoggingInterceptors = false; } public boolean isEnableLoggingInterceptors() { return this.enableLoggingInterceptors; } public synchronized void setEnableLoggingInterceptors( boolean enableLoggingInterceptors) { this.endpoint.ifPresent(ep -> configureInterceptors( ep::getInInterceptors, ep::getOutInterceptors, serviceNameWithInvokingInstance(ep, this), enableLoggingInterceptors)); this.client.ifPresent(client -> configureInterceptors( client::getInInterceptors, client::getOutInterceptors, serviceNameWithInvokingInstance(client, this), enableLoggingInterceptors)); this.enableLoggingInterceptors = enableLoggingInterceptors; } public static final void configureInterceptors(Client client, boolean enableLoggingInterceptors) { configureInterceptors(client::getInInterceptors, client::getOutInterceptors, client.getEndpoint().getService() .getName()::toString, enableLoggingInterceptors); } public static final void configureInterceptors(Client client, Supplier<String> serviceName, boolean enableLoggingInterceptors) { configureInterceptors(client::getInInterceptors, client::getOutInterceptors, serviceName, enableLoggingInterceptors); } public static final void configureInterceptors( Supplier<List<Interceptor<? extends Message>>> inInterceptors, Supplier<List<Interceptor<? extends Message>>> outInterceptors, Supplier<String> serviceName, boolean enableLoggingInterceptors) { if (enableLoggingInterceptors) { LOGGER.info("Enabling CXF logging interceptors at " + serviceName.get()); if (inInterceptors .get() .stream() .noneMatch( interceptor -> interceptor instanceof LoggingInInterceptor)) { final LoggingInInterceptor loggingInInterceptor = new LoggingInInterceptor(); byLoggingDebug(ADD).accept(loggingInInterceptor); inInterceptors.get().add(loggingInInterceptor); } if (outInterceptors .get() .stream() .noneMatch( interceptor -> interceptor instanceof LoggingOutInterceptor)) { final LoggingOutInterceptor loggingOutInterceptor = new LoggingOutInterceptor(); byLoggingDebug(ADD).accept(loggingOutInterceptor); outInterceptors.get().add(loggingOutInterceptor); } } else { LOGGER.info("Disabling CXF logging interceptors at " + serviceName.get()); inInterceptors.get().stream() .filter(by(LoggingInInterceptor.class)) .peek(byLoggingDebug(REMOVE)) .forEach(inInterceptors.get()::remove); outInterceptors.get().stream() .filter(by(LoggingOutInterceptor.class)) .peek(byLoggingDebug(REMOVE)) .forEach(outInterceptors.get()::remove); } } public static final Supplier<String> serviceNameWithInvokingInstance( Client client, Object invokingInstance) { return serviceNameWithInvokingInstance(client.getEndpoint() .getService().getName()::toString, invokingInstance); } public static final Supplier<String> serviceNameWithInvokingInstance( SpringEndpointImpl endpoint, Object invokingInstance) { return serviceNameWithInvokingInstance( endpoint.getServiceName()::toString, invokingInstance); } private static final <T> Predicate<? super Interceptor<? extends Message>> by( Class<T> clazz) { return interceptor -> interceptor.getClass() == clazz; } private static final Consumer<? super Interceptor<? extends Message>> byLoggingDebug( String logMsgPrefix) { return interceptor -> LOGGER.debug(new StringBuilder() .append(logMsgPrefix).append(" - ") .append(interceptor.getClass().toString()).toString()); } private static final Supplier<String> serviceNameWithInvokingInstance( Supplier<String> serviceName, Object invokingInstance) { return () -> new StringBuilder().append(serviceName.get()) .append("; invoking instance: ") .append(invokingInstance.toString()).toString(); } }