package be.error.wsproxy.interceptors.internalchain; import java.util.ArrayList; import java.util.List; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.spi.LoggingEvent; import org.mockito.Mockito; import org.springframework.ws.context.MessageContext; import org.testng.Assert; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import be.error.wsproxy.interceptors.logging.LoggingXPathInterceptor; import be.error.wsproxy.interceptors.logging.MandatoryXPathValueAbsentException; import be.error.wsproxy.interceptors.logging.WebServiceMessageXPathExpressionMetaData; import be.error.wsproxy.interceptors.logging.WebServiceMessageXPathExpressionMetaData.XPathExpressionResultCardinality; @Test public class LoggingXPathInterceptorTest { private final String xml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:common=\"http://common.error.be\" xmlns:service=" + "\"http://service.error.be\"><soapenv:Header><common:OwnOtherElement>ownOtherBogusValue</common:OwnOtherElement><common:SomeId>12345</common:SomeId><SomeElement>" + "bogusValue</SomeElement></soapenv:Header><soapenv:Body><service:SomeService><FirstElement><FirstElementFirstChild>val</FirstElementFirstChild></FirstElement>" + "<SecondElement>123</SecondElement></service:SomeService></soapenv:Body></soapenv:Envelope>"; private LoggingXPathInterceptor xpathLoggedActivityInterceptor; private MessageContext messageContext; private final DummyAppender dummyAppender = new DummyAppender(); @BeforeTest public void initAppender() { Logger logger = Logger.getLogger(LoggingXPathInterceptor.class); logger.setLevel(Level.DEBUG); logger.addAppender(dummyAppender); } @AfterTest public void removeAppender() { // logger.removeAppender(dummyAppender); } @BeforeMethod public void setup() { dummyAppender.clearEvents(); messageContext = Mockito.mock(MessageContext.class); Mockito.when(messageContext.getRequest()).thenReturn(WebserviceTestSupport.createSoapWebServiceMessage(xml)); Mockito.when(messageContext.getResponse()).thenReturn(WebserviceTestSupport.createSoapWebServiceMessage(xml)); xpathLoggedActivityInterceptor = new LoggingXPathInterceptor(); } /** * In this scenario we expect that one logging is made of level debug. The message should contain the information * requested by the xpaths we used for the request and response. */ public void testAllGoodScenario() throws Exception { xpathLoggedActivityInterceptor.addRequestXPaths(new WebServiceMessageXPathExpressionMetaData( "//*[local-name()='SomeService']/*[local-name()='SecondElement']", "someKey")); xpathLoggedActivityInterceptor.handleRequest(messageContext, null); xpathLoggedActivityInterceptor.handleResponse(messageContext, null); Assert.assertEquals(dummyAppender.getEvents().size(), 1); LoggingEvent loggingEvent = dummyAppender.getEvents().iterator().next(); Assert.assertEquals(loggingEvent.getLevel(), Level.DEBUG); Assert.assertEquals(loggingEvent.getMessage().toString(), "SID:{http://service.error.be}SomeService XPATHID:someKey VALUE:123"); } /** * In this scenario we expect that one logging is made of level debug and one of warning. The warning originates in * not finding the requested xpath which has a mandatory but non blocking nature. */ public void testParameterWarningScenario() throws Exception { WebServiceMessageXPathExpressionMetaData webServiceMessageXPathExpressionMetaData = new WebServiceMessageXPathExpressionMetaData( "//*[local-name()='SomeService']/*[local-name()='ThisDoesNotExist']", "someKey"); xpathLoggedActivityInterceptor.addRequestXPaths(webServiceMessageXPathExpressionMetaData); xpathLoggedActivityInterceptor.handleRequest(messageContext, null); xpathLoggedActivityInterceptor.handleResponse(messageContext, null); Assert.assertEquals(dummyAppender.getEvents().size(), 1); LoggingEvent loggingEvent = dummyAppender.getEvents().iterator().next(); Assert.assertEquals(loggingEvent.getLevel(), Level.DEBUG); Assert.assertEquals(loggingEvent.getMessage().toString(), "SID:{http://service.error.be}SomeService XPATHID:someKey VALUE:"); } /** * In this scenario we expect that one logging is made of level error. The error originates in not finding the * requested xpath which has a mandatory blocking nature. */ public void testParameterErrorRequestScenario() throws Exception { WebServiceMessageXPathExpressionMetaData webServiceMessageXPathExpressionMetaData = new WebServiceMessageXPathExpressionMetaData( "//*[local-name()='SomeService']/*[local-name()='ThisDoesNotExist']", "someKey"); webServiceMessageXPathExpressionMetaData .setXPathExpressionResultCardinality(XPathExpressionResultCardinality.MANDATORY_BLOCKING); xpathLoggedActivityInterceptor.addRequestXPaths(webServiceMessageXPathExpressionMetaData); try { xpathLoggedActivityInterceptor.handleRequest(messageContext, null); } catch (MandatoryXPathValueAbsentException mandatoryXpathValueAbsentException) { // We need to manually call handleFault (which is normally done by the framework) xpathLoggedActivityInterceptor.handleFault(messageContext, null); } Assert.assertEquals(dummyAppender.getEvents().size(), 1); LoggingEvent loggingEvent = dummyAppender.getEvents().iterator().next(); Assert.assertEquals(loggingEvent.getLevel(), Level.ERROR); Assert.assertEquals( loggingEvent.getMessage().toString(), "SID:{http://service.error.be}SomeService Payload:<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + "<service:SomeService xmlns:service=\"http://service.error.be\"><FirstElement><FirstElementFirstChild>" + "val</FirstElementFirstChild></FirstElement><SecondElement>123</SecondElement></service:SomeService>"); } /** * In this scenario we expect that two logging are made. One of level debug which extracts the request xpath * normally from the request and one of error because the requested xpath is not present in the reponse but marked * as mandatory blocking. */ public void testParameterErrorReponseScenario() throws Exception { WebServiceMessageXPathExpressionMetaData webServiceMessageXPathExpressionMetaData = new WebServiceMessageXPathExpressionMetaData( "//*[local-name()='SomeService']/*[local-name()='ThisDoesNotExist']", "someKey"); webServiceMessageXPathExpressionMetaData .setXPathExpressionResultCardinality(XPathExpressionResultCardinality.MANDATORY_BLOCKING); xpathLoggedActivityInterceptor.addResponseXPaths(webServiceMessageXPathExpressionMetaData); xpathLoggedActivityInterceptor.addRequestXPaths(new WebServiceMessageXPathExpressionMetaData( "//*[local-name()='SomeService']/*[local-name()='SecondElement']", "someKey")); xpathLoggedActivityInterceptor.handleRequest(messageContext, null); try { xpathLoggedActivityInterceptor.handleResponse(messageContext, null); } catch (MandatoryXPathValueAbsentException mandatoryXpathValueAbsentException) { // We need to manually call handleFault (which is normally done by the framework) xpathLoggedActivityInterceptor.handleFault(messageContext, null); } Assert.assertEquals(dummyAppender.getEvents().size(), 2); LoggingEvent loggingEvent = dummyAppender.getEvents().get(0); Assert.assertEquals(loggingEvent.getLevel(), Level.DEBUG); Assert.assertEquals(loggingEvent.getMessage().toString(), "SID:{http://service.error.be}SomeService XPATHID:someKey VALUE:123"); loggingEvent = dummyAppender.getEvents().get(1); Assert.assertEquals(loggingEvent.getLevel(), Level.ERROR); Assert.assertEquals( loggingEvent.getMessage().toString(), "SID:{http://service.error.be}SomeService Payload:<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + "<service:SomeService xmlns:service=\"http://service.error.be\"><FirstElement><FirstElementFirstChild>" + "val</FirstElementFirstChild></FirstElement><SecondElement>123</SecondElement></service:SomeService>"); } private static class DummyAppender extends AppenderSkeleton { private final List<LoggingEvent> events = new ArrayList<>(); @Override public void close() { // Do nothing } @Override protected void append(LoggingEvent event) { events.add(event); } @Override public boolean requiresLayout() { return false; } public void clearEvents() { events.clear(); } public List<LoggingEvent> getEvents() { return events; } } }