| /* |
| * Copyright 2004,2005 The Apache Software Foundation. |
| * |
| * 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. |
| */ |
| |
| #include "osoa/sca/export.h" |
| #if defined(WIN32) || defined (_WINDOWS) |
| #pragma warning(disable: 4091) |
| #endif |
| |
| #include <axis2_client.h> |
| |
| #include <axis2_error_default.h> |
| #include <axis2_log_default.h> |
| #include <axis2_defines.h> |
| #include <axiom_soap_const.h> |
| #include <platforms/axis2_platform_auto_sense.h> |
| |
| #include <sdo_axiom.h> |
| #include "Axis2Client.h" |
| |
| |
| #include <osoa/sca/sca.h> |
| using namespace osoa::sca; |
| #include "tuscany/sca/core/SCARuntime.h" |
| #include "tuscany/sca/util/Logging.h" |
| #include "tuscany/sca/model/WSBinding.h" |
| #include "tuscany/sca/util/Utils.h" |
| #include "tuscany/sca/util/Exceptions.h" |
| |
| using namespace tuscany::sca::ws; |
| |
| |
| using namespace commonj::sdo; |
| using namespace commonj::sdo_axiom; |
| |
| Axis2Client::Axis2Client(ExternalService* extService) |
| : externalService(extService) |
| { |
| } |
| |
| Axis2Client::~Axis2Client() |
| { |
| } |
| |
| void Axis2Client::invoke(tuscany::sca::Operation& operation) |
| { |
| LOGENTRY(1, "Axis2Client::invoke"); |
| |
| // From the external service ws-binding, get the namespace of the wsdl endpoint |
| WSBinding* binding = (WSBinding *)externalService->getBinding(); |
| // TODO check 0 throw |
| |
| string portNamespace = binding->getWSDLNamespaceURL(); |
| |
| // Lookup the wsdl model from the module, keyed on the namespace |
| // (the wsdl will have been loaded at startup, based on the information in the config file) |
| Wsdl* wsdlDefinition = externalService->getContainingModule()->findWsdl(portNamespace); |
| if (wsdlDefinition == 0) |
| { |
| string msg = "WSDL not found for " + portNamespace; |
| throw SystemConfigurationException(msg.c_str()); |
| } |
| |
| const string& operationName = operation.getName(); |
| |
| // Match the operation in Operation to the operation in the wsdl port type. |
| const WsdlOperation& wsdlOperation = wsdlDefinition->findOperation( |
| binding->getServiceName(), |
| binding->getPortName(), |
| operationName); |
| |
| // Initialize Axis2 stuff |
| axis2_allocator_t *allocator = axis2_allocator_init (NULL); |
| axis2_log_t *log = axis2_log_create(allocator, NULL, "tuscany_client.log"); |
| axis2_error_t *error = axis2_error_create(allocator); |
| axis2_env_t *env = axis2_env_create_with_error_log(allocator, error, log); |
| env->log->level = AXIS2_LOG_LEVEL_TRACE; |
| axis2_error_init(); |
| |
| axis2_char_t* address = (axis2_char_t*)wsdlOperation.getEndpoint().c_str(); |
| axis2_char_t* opName = (axis2_char_t*)operationName.c_str(); |
| axis2_char_t* soap_action = (axis2_char_t*)wsdlOperation.getSoapAction().c_str(); |
| axis2_char_t* serviceName = (axis2_char_t*)binding->getServiceName().c_str(); |
| |
| // create OM from Operation and wsdlOperation |
| axiom_node_t* payload = createPayload(operation, wsdlOperation, env); |
| |
| /* Create EPR with given address */ |
| axis2_endpoint_ref_t* endpoint_ref = axis2_endpoint_ref_create(env, address); |
| |
| /* Setup options */ |
| axis2_options_t* options = axis2_options_create(env); |
| AXIS2_OPTIONS_SET_TO(options, env, endpoint_ref); |
| int soap_version = AXIOM_SOAP11; |
| if (wsdlOperation.getSoapVersion() == WsdlOperation::SOAP12) |
| { |
| soap_version = AXIOM_SOAP12; |
| } |
| |
| AXIS2_OPTIONS_SET_SOAP_VERSION(options, env, soap_version); |
| AXIS2_OPTIONS_SET_ACTION(options, env, soap_action); |
| |
| /* Create service client */ |
| |
| axis2_char_t* client_home = AXIS2_GETENV("AXIS2C_HOME"); |
| if (!client_home) |
| { |
| throw SystemConfigurationException("Environment error: AXIS2C_HOME not set"); |
| } |
| axis2_svc_client_t* svc_client = axis2_svc_client_create(env, client_home); |
| if (!svc_client) |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "invoke FAILED: Error code:" |
| " %d :: %s", env->error->error_number, |
| AXIS2_ERROR_GET_MESSAGE(env->error)); |
| |
| throw ServiceRuntimeException("Axis2Client: axis2_svc_client_create failed"); |
| } |
| |
| /* Set service client options */ |
| AXIS2_SVC_CLIENT_SET_OPTIONS(svc_client, env, options); |
| |
| /* Send request */ |
| axiom_node_t* ret_node = AXIS2_SVC_CLIENT_SEND_RECEIVE(svc_client, env, payload); |
| if(ret_node) |
| { |
| setReturn(ret_node, operation, wsdlOperation, env); |
| } |
| else |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invoke failed: Error code:" |
| " %d :: %s", env->error->error_number, |
| AXIS2_ERROR_GET_MESSAGE(env->error)); |
| throw ServiceRuntimeException("Axis2Client: Invoke failed"); |
| } |
| |
| if (svc_client) |
| { |
| AXIS2_SVC_CLIENT_FREE(svc_client, env); |
| svc_client = NULL; |
| } |
| |
| LOGEXIT(1, "Axis2Client::invoke"); |
| } |
| |
| axiom_node_t* Axis2Client::createPayload(Operation& operation, |
| const WsdlOperation& wsdlOp, |
| axis2_env_t* env) |
| { |
| LOGENTRY(1, "Axis2Client::createPayload"); |
| axiom_node_t* requestOM = NULL; |
| |
| // map the operation request to the wsdl |
| if (wsdlOp.isDocumentStyle()) |
| { |
| // Document style |
| // only support single part messages - WS-I compliant |
| |
| // Build up the payload as an SDO |
| |
| // Get the data factory for the module (it will already have the typecreates loaded for the xsds) |
| DataFactoryPtr dataFactory = externalService->getContainingModule()->getDataFactory(); |
| DataObjectPtr requestDO = dataFactory->create(wsdlOp.getInputTypeUri().c_str(), |
| wsdlOp.getInputTypeName().c_str()); |
| |
| // Each parameter in the operation should be a property on the request dataobject |
| for (int i=0; i<operation.getNParms(); i++) |
| { |
| Operation::Parameter& parm = operation.getParameter(i); |
| switch(parm.getType()) |
| { |
| case Operation::BOOL: |
| { |
| requestDO->setBoolean(i, *(bool*)parm.getValue()); |
| break; |
| } |
| case Operation::SHORT: |
| { |
| requestDO->setShort(i, *(short*)parm.getValue()); |
| break; |
| } |
| case Operation::LONG: |
| { |
| requestDO->setLong(i, *(long*)parm.getValue()); |
| break; |
| } |
| case Operation::USHORT: |
| { |
| requestDO->setInteger(i, *(unsigned short*)parm.getValue()); |
| break; |
| } |
| case Operation::ULONG: |
| { |
| requestDO->setInteger(i, *(unsigned long*)parm.getValue()); |
| break; |
| } |
| case Operation::FLOAT: |
| { |
| requestDO->setFloat(i, *(float*)parm.getValue()); |
| break; |
| } |
| case Operation::DOUBLE: |
| { |
| requestDO->setDouble(i, *(double*)parm.getValue()); |
| break; |
| } |
| case Operation::LONGDOUBLE: |
| { |
| requestDO->setDouble(i, *(long double*)parm.getValue()); |
| break; |
| } |
| case Operation::CHARS: |
| { |
| requestDO->setCString(i, *(char**)parm.getValue()); |
| break; |
| } |
| case Operation::STRING: |
| { |
| requestDO->setCString(i, (*(string*)parm.getValue()).c_str()); |
| break; |
| } |
| case Operation::DATAOBJECT: |
| { |
| requestDO->setDataObject(i, *(DataObjectPtr*)parm.getValue()); |
| break; |
| } |
| default: throw "unsupported parameter type"; |
| } |
| } |
| |
| // Create the Axiom object from the request dataobject |
| AxiomHelper myHelper; |
| requestOM = myHelper.toAxiomNode(requestDO); |
| } |
| else |
| { |
| // RPC |
| } |
| |
| // Logging start |
| axiom_xml_writer_t* xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_FALSE, AXIS2_FALSE, AXIS2_XML_PARSER_TYPE_BUFFER); |
| axiom_output_t* om_output = axiom_output_create( env, xml_writer); |
| |
| AXIOM_NODE_SERIALIZE(requestOM, env, om_output); |
| axis2_char_t* buffer = (axis2_char_t*)AXIOM_XML_WRITER_GET_XML(xml_writer, env); |
| LOGINFO_1(3, "Sending this OM node in XML : %s \n", buffer); |
| AXIOM_OUTPUT_FREE(om_output, env); |
| AXIS2_FREE((env)->allocator, buffer); |
| // Logging end |
| |
| return requestOM; |
| |
| LOGEXIT(1, "Axis2Client::createPayload"); |
| } |
| |
| void Axis2Client::setReturn(axiom_node_t* ret_node, |
| Operation& operation, |
| const WsdlOperation& wsdlOp, |
| axis2_env_t* env) |
| { |
| LOGENTRY(1, "Axis2Client::setReturn"); |
| /* Get the response value from the SOAP message */ |
| |
| // logging start |
| axiom_xml_writer_t* writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, AXIS2_XML_PARSER_TYPE_BUFFER); |
| axiom_output_t* om_output = axiom_output_create (env, writer); |
| AXIOM_NODE_SERIALIZE (ret_node, env, om_output); |
| axis2_char_t* buffer = (axis2_char_t*)AXIOM_XML_WRITER_GET_XML(writer, env); |
| LOGINFO_1(3,"Received OM node in XML : %s\n", buffer); |
| AXIOM_OUTPUT_FREE(om_output, env); |
| AXIS2_FREE((env)->allocator, buffer); |
| // Logging end |
| |
| |
| if (wsdlOp.isDocumentStyle()) |
| { |
| // Document style |
| |
| DataFactoryPtr dataFactory = externalService->getContainingModule()->getDataFactory(); |
| AxiomHelper myHelper; |
| DataObjectPtr returnDO = myHelper.toSdo(ret_node, dataFactory); |
| |
| unsigned int index = 0; |
| switch(operation.getReturnType()) |
| { |
| case Operation::BOOL: |
| { |
| *(bool*)operation.getReturnValue() = returnDO->getBoolean(index); |
| break; |
| } |
| case Operation::SHORT: |
| { |
| *(short*)operation.getReturnValue() = returnDO->getShort(index); |
| break; |
| } |
| case Operation::LONG: |
| { |
| *(long*)operation.getReturnValue() = returnDO->getLong(index); |
| break; |
| } |
| case Operation::USHORT: |
| { |
| *(unsigned short*)operation.getReturnValue() = (unsigned short)returnDO->getInteger(index); |
| break; |
| } |
| case Operation::ULONG: |
| { |
| *(unsigned long*)operation.getReturnValue() = (unsigned long)returnDO->getInteger(index); |
| break; |
| } |
| case Operation::FLOAT: |
| { |
| *(float*)operation.getReturnValue() = returnDO->getFloat(index); |
| break; |
| } |
| case Operation::DOUBLE: |
| { |
| *(double*)operation.getReturnValue() = returnDO->getDouble(index); |
| break; |
| } |
| case Operation::LONGDOUBLE: |
| { |
| *(long double*)operation.getReturnValue() = returnDO->getDouble(index); |
| break; |
| } |
| case Operation::CHARS: |
| { |
| *(char**)operation.getReturnValue() = strdup(returnDO->getCString(index)); |
| break; |
| } |
| case Operation::STRING: |
| { |
| *(string*)operation.getReturnValue() = returnDO->getCString(index); |
| break; |
| } |
| case Operation::DATAOBJECT: |
| { |
| *(DataObjectPtr*)operation.getReturnValue() = returnDO->getDataObject(index); |
| break; |
| } |
| default:; |
| } |
| } |
| else |
| { |
| // RPC |
| } |
| LOGEXIT(1, "Axis2Client::setReturn"); |
| } |
| |