blob: 41cce080b501207da01bfff9b18c39f7cca28237 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/* $Rev$ $Date$ */
/**
* Axis2/C service implementation that dispatches requests to SCA Web service components.
*/
#define WANT_HTTPD_LOG 1
#include "value.hpp"
#include "string.hpp"
#include "../../modules/http/httpd.hpp"
#include "axis2.hpp"
namespace tuscany {
namespace webservice {
/**
* Initialize the service.
*/
int AXIS2_CALL serviceInit(unused axis2_svc_skeleton_t* svc_skeleton, unused const axutil_env_t* env) {
return AXIS2_SUCCESS;
}
/**
* Free the service.
*/
int AXIS2_CALL serviceFree(axis2_svc_skeleton_t* svc_skeleton, const axutil_env_t* env) {
if (svc_skeleton)
AXIS2_FREE(env->allocator, svc_skeleton);
return AXIS2_SUCCESS;
}
typedef struct axis2_apache2_out_transport_info {
axis2_http_out_transport_info_t out_transport_info;
request_rec* request;
axis2_char_t *encoding;
} axis2_apache2_out_transport_info_t;
extern "C" {
extern module axis2_module;
}
/**
* Service invoke function, called by Axis2/C.
*/
axiom_node_t *AXIS2_CALL serviceInvoke(unused axis2_svc_skeleton_t* svc_skeleton, const axutil_env_t* env, axiom_node_t* node, axis2_msg_ctx_t* msg_ctx) {
// Check that we have an input node
if (node == NULL || axiom_node_get_node_type(node, env) != AXIOM_ELEMENT)
return NULL;
axiom_element_t* const e = (axiom_element_t*) axiom_node_get_data_element(node, env);
if (e == NULL)
return NULL;
// Get the function name
const char* const func = axiom_element_get_localname(e, env);
if (func == NULL)
return NULL;
// Get the target endpoint address
const axis2_endpoint_ref_t* const epr = axis2_msg_ctx_get_from(msg_ctx, env);
if (epr == NULL)
return NULL;
unused const string address = axis2_endpoint_ref_get_address(epr, env);
// Get the underlying HTTPD request
axis2_out_transport_info_t* const tinfo = axis2_msg_ctx_get_out_transport_info(msg_ctx, env);
axis2_apache2_out_transport_info_t* const httpinfo = (axis2_apache2_out_transport_info_t*)tinfo;
request_rec* const r = httpinfo->request;
debug_httpdRequest(r, "webservice::serviceInvoke");
// Parse the request Axiom node and construct request expression
Axis2Context ax(env);
const failable<const list<value> > lv = axiomNodeToValues(node, ax);
if (!hasContent(lv))
return NULL;
const value expr = mklist<value>(func, content(lv));
debug(expr, "webservice::serviceInvoke::expr");
// Retrieve the target lambda function from the HTTPD request and invoke it
const value* const rv = const_cast<const value*>((value*)ap_get_module_config(r->request_config, &axis2_module));
cout << "relay: " << rv << endl;
const lvvlambda relay = *rv;
const value res = relay(expr);
debug(res, "webservice::serviceInvoke::result");
// Construct response Axiom node
const failable<axiom_node_t*> rnode = valuesToAxiomNode(res, ax);
if (!hasContent(rnode))
return NULL;
return content(rnode);
}
/**
* Return a new service skeleton.
*/
const axis2_svc_skeleton_ops_t serviceOps = {
serviceInit,
serviceInvoke,
NULL,
serviceFree,
NULL
};
AXIS2_EXTERN axis2_svc_skeleton_t *AXIS2_CALL serviceSkeleton(const axutil_env_t* env) {
axis2_svc_skeleton_t* svc_skeleton = (axis2_svc_skeleton_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_skeleton_t));
svc_skeleton->ops = &serviceOps;
svc_skeleton->func_array = NULL;
return svc_skeleton;
}
}
}
extern "C"
{
/**
* Axis2/C service entry point functions.
*/
AXIS2_EXPORT int axis2_get_instance(struct axis2_svc_skeleton** inst, const axutil_env_t* env) {
*inst = tuscany::webservice::serviceSkeleton(env);
if (inst == NULL)
return AXIS2_FAILURE;
return AXIS2_SUCCESS;
}
AXIS2_EXPORT int axis2_remove_instance(axis2_svc_skeleton_t* inst, const axutil_env_t* env) {
if (inst != NULL)
return AXIS2_SVC_SKELETON_FREE(inst, env);
return AXIS2_FAILURE;
}
}