/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.wsf.framework.invocation;
import java.net.URL;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.jboss.logging.Logger;
import org.jboss.wsf.common.DOMWriter;
import org.jboss.wsf.framework.management.recording.RecordFactory;
import org.jboss.wsf.spi.deployment.Endpoint;
import org.jboss.wsf.spi.invocation.EndpointAssociation;
import org.jboss.wsf.spi.management.recording.Record;
import org.jboss.wsf.spi.management.recording.RecordGroupAssociation;
import org.jboss.wsf.spi.management.recording.RecordProcessor;
import org.jboss.wsf.spi.management.recording.Record.MessageType;
import org.jboss.wsf.test.GenericSOAPHandler;
/**
* This handler is responsible for collecting the information about the
* messages being exchanged and recording them on the server side. This
* is performed delegating to the RecordProcessors installed into the
* current endpoint.
*
* @author alessio.soldano@jboss.com
* @since 8-Dec-2007
*/
public class RecordingServerHandler extends GenericSOAPHandler
{
// provide logging
private static Logger log = Logger.getLogger(RecordingServerHandler.class);
@SuppressWarnings("unchecked")
protected boolean handleInbound(MessageContext ctx)
{
Endpoint endpoint = EndpointAssociation.getEndpoint();
if (endpoint != null && isRecording(endpoint))
{
Record record = RecordFactory.newRecord();
RecordGroupAssociation.pushGroupID(record.getGroupID());
record.setDate(new Date());
HttpServletRequest httpServletRequest = (HttpServletRequest)ctx.get(MessageContext.SERVLET_REQUEST);
if (httpServletRequest != null)
{
try
{
record.setDestinationHost(new URL(httpServletRequest.getRequestURL().toString()).getHost());
record.setSourceHost(httpServletRequest.getRemoteHost());
}
catch (Exception e)
{
log.warn("Unable to read from the http servlet request! " + e.getMessage());
}
}
record.setHeaders((Map<String,List<String>>)(ctx.get(MessageContext.HTTP_REQUEST_HEADERS)));
record.setMessageType(MessageType.INBOUND);
record.setOperation((QName)ctx.get(MessageContext.WSDL_OPERATION));
boolean processEnvelope = false;
for (Iterator<RecordProcessor> it = endpoint.getRecordProcessors().iterator(); it.hasNext() && !processEnvelope; )
{
processEnvelope = it.next().isProcessEnvelope();
}
if (processEnvelope) //skip message processing if not required since it's very time-consuming
{
SOAPMessageContext soapCtx = (SOAPMessageContext)ctx;
try
{
SOAPEnvelope soapEnv = soapCtx.getMessage().getSOAPPart().getEnvelope();
if (soapEnv != null)
{
record.setEnvelope(DOMWriter.printNode(soapEnv, true));
}
}
catch (SOAPException ex)
{
log.error("Cannot trace SOAPMessage", ex);
}
}
endpoint.processRecord(record);
}
return true;
}
@SuppressWarnings("unchecked")
protected boolean handleOutbound(MessageContext ctx)
{
Endpoint endpoint = EndpointAssociation.getEndpoint();
if (endpoint != null && isRecording(endpoint))
{
String groupID = RecordGroupAssociation.popGroupID();
Record record = RecordFactory.newRecord(groupID);
record.setDate(new Date());
record.setHeaders((Map<String,List<String>>)(ctx.get(MessageContext.HTTP_RESPONSE_HEADERS)));
record.setMessageType(MessageType.OUTBOUND);
record.setOperation((QName)ctx.get(MessageContext.WSDL_OPERATION));
boolean processEnvelope = false;
for (Iterator<RecordProcessor> it = endpoint.getRecordProcessors().iterator(); it.hasNext() && !processEnvelope; )
{
processEnvelope = it.next().isProcessEnvelope();
}
if (processEnvelope) //skip message processing if not required since it's very time-consuming
{
SOAPMessageContext soapCtx = (SOAPMessageContext)ctx;
try
{
SOAPEnvelope soapEnv = soapCtx.getMessage().getSOAPPart().getEnvelope();
if (soapEnv != null)
{
record.setEnvelope(DOMWriter.printNode(soapEnv, true));
}
}
catch (SOAPException ex)
{
log.error("Cannot trace SOAPMessage", ex);
}
}
endpoint.processRecord(record);
}
return true;
}
public boolean handleFault(MessageContext ctx)
{
return handleOutbound(ctx);
}
/**
* Returns true if there's at least a record processor in recording mode
*
* @param endpoint
* @return
*/
private boolean isRecording(Endpoint endpoint)
{
List<RecordProcessor> processors = endpoint.getRecordProcessors();
if (processors == null || processors.isEmpty())
{
return false;
}
for (RecordProcessor processor : processors)
{
if (processor.isRecording())
{
return true;
}
}
return false;
}
}