blob: 20a740be50bdc45f97abc93a37be3bb59dfd16ed [file] [log] [blame]
/* -*- C++ -*- */
/*
* Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Revision 1.1 2004/08/26 roshan
* Added the method "releaseHandlers(string sSessionId)" in order to release the
* Handlers once they are used.
*/
// !!! This include file must be first thing in file !!!
#include "../../platforms/PlatformAutoSense.hpp"
#include <axis/AxisException.hpp>
#include "ClientAxisEngine.h"
#include "../../wsdd/WSDDDeployment.h"
#include "../HandlerPool.h"
#include "../../common/AxisTrace.h"
#include "../../common/AxisGenException.h"
#include "../../common/AxisTrace.h"
extern AXIS_CPP_NAMESPACE_PREFIX WSDDDeployment* g_pWSDDDeployment;
extern AXIS_CPP_NAMESPACE_PREFIX HandlerPool* g_pHandlerPool;
AXIS_CPP_NAMESPACE_START
ClientAxisEngine::
ClientAxisEngine ()
{
logEntryEngine("ClientAxisEngine::ClientAxisEngine")
logExit()
}
ClientAxisEngine::
~ClientAxisEngine ()
{
logEntryEngine("ClientAxisEngine::~ClientAxisEngine")
logExit()
}
MessageData* ClientAxisEngine::
getMessageData ()
{
return m_pMsgData;
}
int ClientAxisEngine::
process (SOAPTransport* pSoap)
{
return process(pSoap, false);
}
int ClientAxisEngine::
process (SOAPTransport* pSoap, bool noResponse)
{
logEntryEngine("ClientAxisEngine::process")
int Status = AXIS_FAIL;
const WSDDService* pService = NULL;
try
{
if (pSoap)
{
m_pSoap = pSoap;
string sSessionId = m_pSoap->getSessionId();
do
{
// Get the service name that was specified in the second parameter of the call
// to setTransportProperty( SOAPACTION_HEADER , "") matches a service name in
// the 'service' part of the WSDD file then call that service now.
const char* pchService = pSoap->getServiceName();
// Check that there is a valid service name.
if( pchService != NULL)
{
// The convention for the service name appears to be service#port
if( strchr( pchService, '#') == NULL)
{
int iStringLength = strlen( pchService);
char * pszService = new char[iStringLength];
memset( pszService, 0, iStringLength);
// If there is no # seperator, then strip off the outer quotes. if they exist !
if(strchr(pchService, '"') == NULL)
memcpy( pszService, pchService, iStringLength);
else
memcpy( pszService, pchService + 1, iStringLength - 2);
pService = g_pWSDDDeployment->getService( pszService);
delete [] pszService;
}
else
{
char * pchTempService = new char [strlen(pchService)+1];
// Skip the starting double quote
strcpy(pchTempService, pchService+1);
// The String returned as the service name has the format "Calculator#add".
// So null terminate string at #.
*(strchr(pchTempService, '#')) = '\0';
// get service description object from the WSDD Deployment object
pService = g_pWSDDDeployment->getService (pchTempService);
delete [] pchTempService;
}
}
//Get Global and Transport Handlers
Status = initializeHandlers (sSessionId, pSoap->getProtocol());
if (AXIS_SUCCESS != Status)
{
logThrowException("AxisEngineException - SERVER_ENGINE_HANDLER_INIT_FAILED")
throw AxisEngineException(SERVER_ENGINE_HANDLER_INIT_FAILED);
}
//Get Service specific Handlers from the pool if configured any
if (pService != NULL)
{
Status = g_pHandlerPool->getRequestFlowHandlerChain(&m_pSReqFChain, sSessionId, pService);
if (AXIS_SUCCESS != Status)
break;
Status = g_pHandlerPool->getResponseFlowHandlerChain(&m_pSResFChain, sSessionId, pService);
if (AXIS_SUCCESS != Status)
break;
}
// Invoke all handlers and then the remote webservice
// we generate response in the same way even if this has failed
Status = invoke (m_pMsgData, noResponse);
}
while (0);
//release the handlers
releaseHandlers(sSessionId);
}
}
catch(AxisException& e)
{
/* Throw a AxisGenException here instead of rethrowing the original exception because
* the original exception may be an transport exception which will go out of scope when
* the transport library is unloaded.
*/
logRethrowException()
throw AxisGenException(e);
}
logExitWithReturnCode(Status)
return Status;
}
void ClientAxisEngine::
releaseHandlers(string sSessionId)
{
logEntryEngine("ClientAxisEngine::releaseHandlers")
// Pool back the Service specific handlers
if (m_pSReqFChain)
g_pHandlerPool->poolHandlerChain(m_pSReqFChain, sSessionId);
if (m_pSResFChain)
g_pHandlerPool->poolHandlerChain(m_pSResFChain, sSessionId);
logExit()
}
int ClientAxisEngine::
invoke (MessageData* pMsg)
{
return invoke(pMsg, false);
}
int ClientAxisEngine::
invoke (MessageData* pMsg, bool noResponse)
{
logEntryEngine("ClientAxisEngine::invoke")
enum AE_LEVEL { AE_START = 1, AE_SERH, AE_GLH, AE_TRH, AE_SERV };
int Status = AXIS_FAIL;
int level = AE_START;
do
{
// Invoke client side service specific request handlers
logDebug("Invoke client side request handlers, if any.")
if (m_pSReqFChain)
{
logDebug("Invoke client side service specific request handlers")
if (AXIS_SUCCESS != (Status = m_pSReqFChain->invoke (pMsg)))
{
logDebug("Invoke of client side service-specific request handlers failed")
break;
}
}
level++; //AE_SERH
// Invoke global request handlers
if (m_pGReqFChain)
{
logDebug("Invoke global request handlers")
if (AXIS_SUCCESS != (Status = m_pGReqFChain->invoke (pMsg)))
{
logDebug("Invoke of global request handlers failed")
break;
}
}
level++; //AE_GLH
// Invoke transport request handlers
if (m_pTReqFChain)
{
logDebug("Invoke transport request handlers")
if (AXIS_SUCCESS != (Status = m_pTReqFChain->invoke (pMsg)))
{
logDebug("Invoke of transport request handlers failed")
break;
}
}
level++; // AE_TRH
// setOutputStream() kicks off serialization step....
if (AXIS_SUCCESS != (Status = m_pSZ->setOutputStream (m_pSoap)))
break;
m_pSoap->openConnection();
m_pSZ->markEndOfStream();
level++; // AE_SERV
pMsg->setPastPivotState (true);
if (AXIS_SUCCESS != (Status = m_pDZ->setInputStream (m_pSoap)))
break;
// Get header and body only if we are expecting a response
if (!noResponse || m_pSoap->isThereResponseData())
{
// version not supported set status to fail
int nSoapVersion = m_pDZ->getVersion ();
if (nSoapVersion == VERSION_LAST)
Status = AXIS_FAIL;
m_pDZ->getHeader ();
m_pDZ->getBody ();
// If one-way messaging and there is response data, then it must be a fault.
if (noResponse)
{
// initiate fault processing. This will result in an exception being thrown.
m_pDZ->initiateFault(NULL);
}
}
}
while (0);
/*
* The case clauses in this switch statement have no breaks.
* Hence, if Everything up to web service invocation was successful
* then all response handlers are invoked. If there was a failure
* at some point the response handlers from that point onwards
* are invoked.
*/
logDebug("Invoke client side response handlers, if any.")
switch (level)
{
case AE_SERV:
// everything success
Status = AXIS_SUCCESS;
// If no response expected, break out.
if (noResponse)
break;
case AE_TRH:
// After invoking the transport handlers (at actual service invokation) it has failed
if (m_pTResFChain)
{
logDebug("Invoke client side transport handlers.")
m_pTResFChain->invoke (pMsg);
}
case AE_GLH:
// transport handlers have failed invoke global response handlers
if (m_pGResFChain)
{
logDebug("Invoke client side global response handlers.")
m_pGResFChain->invoke (pMsg);
}
case AE_SERH: // global handlers have failed
// invoke web service specific response handlers
if (m_pSResFChain)
{
logDebug("Invoke Web service-specific client side handlers.")
m_pSResFChain->invoke (pMsg);
}
case AE_START:;
// service specific handlers have failed
};
logExitWithReturnCode(Status)
return Status;
}
void ClientAxisEngine::
onFault (MessageData* pMsg)
{
}
AXIS_CPP_NAMESPACE_END