| /* |
| * 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; |
| } |
| |
| } |