summaryrefslogtreecommitdiffstats
path: root/src/core/clientapi
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/clientapi')
-rw-r--r--src/core/clientapi/Makefile.am17
-rw-r--r--src/core/clientapi/async_result.c83
-rw-r--r--src/core/clientapi/callback.c272
-rw-r--r--src/core/clientapi/callback_recv.c199
-rw-r--r--src/core/clientapi/listener_manager.c302
-rw-r--r--src/core/clientapi/op_client.c1439
-rw-r--r--src/core/clientapi/options.c1068
-rw-r--r--src/core/clientapi/stub.c228
-rw-r--r--src/core/clientapi/svc_client.c1624
9 files changed, 5232 insertions, 0 deletions
diff --git a/src/core/clientapi/Makefile.am b/src/core/clientapi/Makefile.am
new file mode 100644
index 0000000..8dead6f
--- /dev/null
+++ b/src/core/clientapi/Makefile.am
@@ -0,0 +1,17 @@
+noinst_LTLIBRARIES = libaxis2_clientapi.la
+libaxis2_clientapi_la_SOURCES = async_result.c \
+ callback.c \
+ listener_manager.c \
+ callback_recv.c \
+ stub.c \
+ options.c \
+ op_client.c \
+ svc_client.c
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_builddir)/src/core/engine \
+ -I$(top_builddir)/src/core/deployment \
+ -I$(top_builddir)/util/include \
+ -I$(top_builddir)/util/include/platforms \
+ -I$(top_builddir)/axiom/include \
+ -I$(top_builddir)/neethi/include
diff --git a/src/core/clientapi/async_result.c b/src/core/clientapi/async_result.c
new file mode 100644
index 0000000..693e283
--- /dev/null
+++ b/src/core/clientapi/async_result.c
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#include <axis2_async_result.h>
+#include <axis2_const.h>
+#include <axutil_hash.h>
+
+struct axis2_async_result
+{
+
+ /** result message context */
+ axis2_msg_ctx_t *result;
+};
+
+AXIS2_EXTERN axis2_async_result_t *AXIS2_CALL
+axis2_async_result_create(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * result)
+{
+ axis2_async_result_t *async_result = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ async_result = AXIS2_MALLOC(env->allocator, sizeof(axis2_async_result_t));
+ if(!async_result)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create asynchronous result.");
+ return NULL;
+ }
+
+ async_result->result = NULL;
+
+ if(result)
+ {
+ async_result->result = result; /* shallow copy */
+ }
+
+ return async_result;
+}
+
+AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
+axis2_async_result_get_envelope(
+ axis2_async_result_t * async_result,
+ const axutil_env_t * env)
+{
+ if(async_result->result)
+ {
+ return axis2_msg_ctx_get_soap_envelope(async_result->result, env);
+ }
+
+ return NULL;
+}
+
+AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
+axis2_async_result_get_result(
+ axis2_async_result_t * async_result,
+ const axutil_env_t * env)
+{
+ return async_result->result;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_async_result_free(
+ axis2_async_result_t * async_result,
+ const axutil_env_t * env)
+{
+ AXIS2_FREE(env->allocator, async_result);
+}
diff --git a/src/core/clientapi/callback.c b/src/core/clientapi/callback.c
new file mode 100644
index 0000000..6f875df
--- /dev/null
+++ b/src/core/clientapi/callback.c
@@ -0,0 +1,272 @@
+/*
+ * 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.
+ */
+
+#include <axis2_callback.h>
+#include <axis2_const.h>
+#include <axutil_hash.h>
+
+struct axis2_callback
+{
+
+ /** callback complete? */
+ axis2_bool_t complete;
+
+ /** envelope corresponding to the result */
+ axiom_soap_envelope_t *envelope;
+
+ /** message context corresponding to the result */
+ axis2_msg_ctx_t *msg_ctx;
+
+ /** error code */
+ int error;
+
+ /** to store callback specific data */
+ void *data;
+ axutil_thread_mutex_t *mutex;
+
+ /**
+ * This function is called by invoke_on_complete.
+ * Users could provide this method so that they can define what to be
+ * done when the callback returns on completion.
+ * @param callback pointer to callback struct
+ * @param env pointer to environment struct
+ * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
+ */
+ axis2_status_t
+ (
+ AXIS2_CALL * on_complete)
+ (
+ axis2_callback_t * callback,
+ const axutil_env_t * env);
+
+ /**
+ * This function is called by report_error.
+ * Users could provide this method so that they can define what to be done
+ * when the callback returns an error.
+ * @param callback pointer to callback struct
+ * @param env pointer to environment struct
+ * @param exception error code representing the error
+ * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
+ */
+ axis2_status_t
+ (
+ AXIS2_CALL * on_error)
+( axis2_callback_t * callback,
+const axutil_env_t * env,
+const int exception);
+};
+
+static axis2_status_t AXIS2_CALL axis2_callback_on_complete(
+ axis2_callback_t * callback,
+ const axutil_env_t * env);
+
+static axis2_status_t AXIS2_CALL axis2_callback_on_error(
+ axis2_callback_t * callback,
+ const axutil_env_t * env,
+ int exception);
+
+AXIS2_EXTERN axis2_callback_t *AXIS2_CALL
+axis2_callback_create(
+ const axutil_env_t * env)
+{
+ axis2_callback_t *callback = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ callback = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_t));
+ if(!callback)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create callback.");
+ return NULL;
+ }
+
+ callback->complete = AXIS2_FALSE;
+ callback->envelope = NULL;
+ callback->msg_ctx = NULL;
+ callback->error = AXIS2_ERROR_NONE;
+ callback->data = NULL;
+ callback->mutex = NULL;
+ callback->on_complete = axis2_callback_on_complete;
+ callback->on_error = axis2_callback_on_error;
+
+ callback->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT);
+ return callback;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_invoke_on_complete(
+ axis2_callback_t * callback,
+ const axutil_env_t * env,
+ axis2_async_result_t * result)
+{
+ axis2_status_t status = AXIS2_FAILURE;
+
+ callback->envelope = axis2_async_result_get_envelope(result, env);
+ callback->msg_ctx = axis2_async_result_get_result(result, env);
+ axis2_msg_ctx_increment_ref(callback->msg_ctx, env); /* this will be set in opclient's msgctx
+ map and will be deleted from there */
+
+ status = callback->on_complete(callback, env);
+
+ return status;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_report_error(
+ axis2_callback_t * callback,
+ const axutil_env_t * env,
+ const int exception)
+{
+ axis2_callback_set_error(callback, env, exception);
+ return callback->on_error(callback, env, exception);
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_callback_get_complete(
+ const axis2_callback_t * callback,
+ const axutil_env_t * env)
+{
+ return callback->complete;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_set_complete(
+ axis2_callback_t * callback,
+ const axutil_env_t * env,
+ const axis2_bool_t complete)
+{
+ callback->complete = complete;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
+axis2_callback_get_envelope(
+ const axis2_callback_t * callback,
+ const axutil_env_t * env)
+{
+ return callback->envelope;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_set_envelope(
+ axis2_callback_t * callback,
+ const axutil_env_t * env,
+ axiom_soap_envelope_t * envelope)
+{
+ callback->envelope = envelope;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
+axis2_callback_get_msg_ctx(
+ const axis2_callback_t * callback,
+ const axutil_env_t * env)
+{
+ return callback->msg_ctx;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_set_msg_ctx(
+ axis2_callback_t * callback,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ callback->msg_ctx = msg_ctx;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_callback_get_error(
+ const axis2_callback_t * callback,
+ const axutil_env_t * env)
+{
+ return callback->error;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_set_error(
+ axis2_callback_t * callback,
+ const axutil_env_t * env,
+ const int error)
+{
+ callback->error = error;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_callback_free(
+ axis2_callback_t * callback,
+ const axutil_env_t * env)
+{
+ if(callback->mutex)
+ {
+ axutil_thread_mutex_destroy(callback->mutex);
+ }
+
+ AXIS2_FREE(env->allocator, callback);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_set_data(
+ axis2_callback_t * callback,
+ void *data)
+{
+ callback->data = (void *)data;
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN void *AXIS2_CALL
+axis2_callback_get_data(
+ const axis2_callback_t * callback)
+{
+ return callback->data;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_callback_set_on_complete(
+ axis2_callback_t * callback,
+ axis2_on_complete_func_ptr func)
+{
+ callback->on_complete = func;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_callback_set_on_error(
+ axis2_callback_t * callback,
+ axis2_on_error_func_ptr func)
+{
+ callback->on_error = func;
+}
+
+static axis2_status_t AXIS2_CALL
+axis2_callback_on_complete(
+ axis2_callback_t * callback,
+ const axutil_env_t * env)
+{
+ return AXIS2_SUCCESS;
+}
+
+static axis2_status_t AXIS2_CALL
+axis2_callback_on_error(
+ axis2_callback_t * callback,
+ const axutil_env_t * env,
+ int exception)
+{
+ return AXIS2_SUCCESS;
+}
diff --git a/src/core/clientapi/callback_recv.c b/src/core/clientapi/callback_recv.c
new file mode 100644
index 0000000..f45ed87
--- /dev/null
+++ b/src/core/clientapi/callback_recv.c
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+#include "axis2_callback_recv.h"
+#include <axis2_const.h>
+#include <axutil_hash.h>
+
+struct axis2_callback_recv
+{
+ /** base context struct */
+ axis2_msg_recv_t *base;
+ axis2_bool_t base_deep_copy;
+
+ /** callback map */
+ axutil_hash_t *callback_map;
+ axutil_thread_mutex_t *mutex;
+};
+
+static axis2_status_t AXIS2_CALL axis2_callback_recv_receive(
+ axis2_msg_recv_t * msg_recv,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ void *callback_recv_param);
+
+AXIS2_EXTERN axis2_callback_recv_t *AXIS2_CALL
+axis2_callback_recv_create(
+ const axutil_env_t * env)
+{
+ axis2_callback_recv_t *callback_recv = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ callback_recv = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_recv_t));
+
+ if(!callback_recv)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create callback receive.");
+ return NULL;
+ }
+
+ callback_recv->base = NULL;
+ callback_recv->base_deep_copy = AXIS2_TRUE;
+ callback_recv->callback_map = NULL;
+ callback_recv->mutex = NULL;
+
+ callback_recv->base = axis2_msg_recv_create(env);
+ if(!callback_recv->base)
+ {
+ axis2_callback_recv_free(callback_recv, env);
+ return NULL;
+ }
+ axis2_msg_recv_set_derived(callback_recv->base, env, callback_recv);
+ axis2_msg_recv_set_receive(callback_recv->base, env, axis2_callback_recv_receive);
+
+ callback_recv->callback_map = axutil_hash_make(env);
+ if(!callback_recv->callback_map)
+ {
+ axis2_callback_recv_free(callback_recv, env);
+ return NULL;
+ }
+
+ callback_recv->mutex = axutil_thread_mutex_create(env->allocator, AXIS2_THREAD_MUTEX_DEFAULT);
+ return callback_recv;
+}
+
+AXIS2_EXTERN axis2_msg_recv_t *AXIS2_CALL
+axis2_callback_recv_get_base(
+ axis2_callback_recv_t * callback_recv,
+ const axutil_env_t * env)
+{
+ callback_recv->base_deep_copy = AXIS2_FALSE;
+ return callback_recv->base;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_callback_recv_free(
+ axis2_callback_recv_t * callback_recv,
+ const axutil_env_t * env)
+{
+ if(callback_recv->mutex)
+ {
+ axutil_thread_mutex_destroy(callback_recv->mutex);
+ }
+
+ if(callback_recv->callback_map)
+ {
+ axutil_hash_index_t *hi = NULL;
+ const void *key = NULL;
+ void *val = NULL;
+ for(hi = axutil_hash_first(callback_recv->callback_map, env); hi; hi = axutil_hash_next(
+ env, hi))
+ {
+ axutil_hash_this(hi, &key, NULL, &val);
+ if(key)
+ {
+ AXIS2_FREE(env->allocator, (char *)key);
+ }
+ if(val)
+ {
+ axis2_callback_t *callback = (axis2_callback_t *) val;
+ axis2_callback_free(callback, env);
+ }
+
+ }
+
+ axutil_hash_free(callback_recv->callback_map, env);
+ }
+
+ if(callback_recv->base && callback_recv->base_deep_copy)
+ {
+ axis2_msg_recv_free(callback_recv->base, env);
+ }
+
+ if(callback_recv)
+ {
+ AXIS2_FREE(env->allocator, callback_recv);
+ }
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_callback_recv_add_callback(
+ axis2_callback_recv_t * callback_recv,
+ const axutil_env_t * env,
+ const axis2_char_t * msg_id,
+ axis2_callback_t * callback)
+{
+ if(msg_id)
+ {
+ axis2_char_t *mid = axutil_strdup(env, msg_id);
+ axutil_hash_set(callback_recv->callback_map, mid, AXIS2_HASH_KEY_STRING, callback);
+ }
+ return AXIS2_SUCCESS;
+}
+
+/* In the dual channel invocations client set a callback function to be invoked when a resonse
+ * is received from the server. When the response is received by the listening port of the
+ * listener manager, in the engine receive call the message is finally hit by callback receiver
+ * which is an implementation of the axis2 message receiver. This is the function that is called
+ * at that stage. The client set callback function is called from within here.
+ */
+static axis2_status_t AXIS2_CALL
+axis2_callback_recv_receive(
+ axis2_msg_recv_t * msg_recv,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx,
+ void *callback_recv_param)
+{
+ axis2_callback_recv_t *callback_recv = NULL;
+ axis2_relates_to_t *relates_to = NULL;
+ axis2_msg_info_headers_t *msg_info_headers = NULL;
+
+ callback_recv = axis2_msg_recv_get_derived(msg_recv, env);
+
+ msg_info_headers = axis2_msg_ctx_get_msg_info_headers(msg_ctx, env);
+ if(msg_info_headers)
+ {
+ relates_to = axis2_msg_info_headers_get_relates_to(msg_info_headers, env);
+ if(relates_to)
+ {
+ const axis2_char_t *msg_id = axis2_relates_to_get_value(relates_to, env);
+ if(msg_id)
+ {
+ axis2_async_result_t *result = NULL;
+ axis2_callback_t *callback = (axis2_callback_t *)axutil_hash_get(
+ callback_recv->callback_map, msg_id, AXIS2_HASH_KEY_STRING);
+
+ result = axis2_async_result_create(env, msg_ctx);
+ if(callback && result)
+ {
+ axis2_callback_invoke_on_complete(callback, env, result);
+ axis2_callback_set_complete(callback, env, AXIS2_TRUE);
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, NULL);
+ }
+
+ axis2_async_result_free(result, env);
+ if(callback && result)
+ return AXIS2_SUCCESS;
+ }
+ }
+ }
+
+ return AXIS2_FAILURE;
+}
+
diff --git a/src/core/clientapi/listener_manager.c b/src/core/clientapi/listener_manager.c
new file mode 100644
index 0000000..1e3e3f2
--- /dev/null
+++ b/src/core/clientapi/listener_manager.c
@@ -0,0 +1,302 @@
+/*
+ * 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.
+ */
+
+#include <axis2_listener_manager.h>
+#include <axis2_const.h>
+#include <axutil_hash.h>
+#include <axis2_transport_receiver.h>
+
+/**
+ * keep information about the listener for a given transport
+ */
+typedef struct axis2_transport_listener_state
+{
+ int waiting_calls;
+
+ axis2_transport_receiver_t *listener;
+
+} axis2_transport_listener_state_t;
+
+struct axis2_listener_manager
+{
+
+ /** hash map of listeners */
+ axis2_transport_listener_state_t *listener_map[AXIS2_TRANSPORT_ENUM_MAX];
+ axutil_thread_t *listener_thread[AXIS2_TRANSPORT_ENUM_MAX];
+
+ /** configuration context */
+ axis2_conf_ctx_t *conf_ctx;
+};
+
+typedef struct axis2_listener_manager_worker_func_args
+{
+ const axutil_env_t *env;
+ axis2_listener_manager_t *listner_manager;
+ axis2_transport_receiver_t *listener;
+} axis2_listener_manager_worker_func_args_t;
+
+void *AXIS2_THREAD_FUNC axis2_listener_manager_worker_func(
+ axutil_thread_t * thd,
+ void *data);
+
+AXIS2_EXTERN axis2_listener_manager_t *AXIS2_CALL
+axis2_listener_manager_create(
+ const axutil_env_t * env)
+{
+ axis2_listener_manager_t *listener_manager = NULL;
+ int i = 0;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ listener_manager = AXIS2_MALLOC(env->allocator, sizeof(axis2_listener_manager_t));
+
+ if(!listener_manager)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create listener manager.");
+ return NULL;
+ }
+
+ listener_manager->conf_ctx = NULL;
+
+ for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++)
+ {
+ listener_manager->listener_map[i] = NULL;
+ listener_manager->listener_thread[i] = NULL;
+ }
+
+ return listener_manager;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_listener_manager_make_sure_started(
+ axis2_listener_manager_t * listener_manager,
+ const axutil_env_t * env,
+ const AXIS2_TRANSPORT_ENUMS transport,
+ axis2_conf_ctx_t * conf_ctx)
+{
+ axis2_transport_listener_state_t *tl_state = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE);
+
+ if(listener_manager->conf_ctx)
+ {
+ if(conf_ctx != listener_manager->conf_ctx)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CLIENT_SIDE_SUPPORT_ONLY_ONE_CONF_CTX,
+ AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Only one configuration context is supported at client side.");
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ listener_manager->conf_ctx = conf_ctx;
+ }
+
+ tl_state = listener_manager->listener_map[transport];
+
+ if(!tl_state)
+ {
+ /*means this transport not yet started, start the transport */
+ axis2_transport_in_desc_t *transport_in = NULL;
+ axis2_conf_t *conf = NULL;
+ axis2_transport_receiver_t *listener = NULL;
+
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(conf)
+ {
+ transport_in = axis2_conf_get_transport_in(conf, env, transport);
+ if(transport_in)
+ {
+ listener = axis2_transport_in_desc_get_recv(transport_in, env);
+ if(listener)
+ {
+ axutil_thread_t *worker_thread = NULL;
+ axis2_listener_manager_worker_func_args_t *arg_list = NULL;
+ arg_list = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_listener_manager_worker_func_args_t));
+ if(!arg_list)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Cannot create listener manager worker function arguments.");
+ return AXIS2_FAILURE;
+ }
+ arg_list->env = env;
+ arg_list->listner_manager = listener_manager;
+ arg_list->listener = listener;
+#ifdef AXIS2_SVR_MULTI_THREADED
+ if (env->thread_pool)
+ {
+ worker_thread =
+ axutil_thread_pool_get_thread(env->thread_pool,
+ axis2_listener_manager_worker_func,
+ (void *) arg_list);
+ if (!worker_thread)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Thread creation failed"
+ "Invoke non blocking failed");
+ }
+ else
+ {
+ /*axutil_thread_pool_thread_detach(env->thread_pool,
+ worker_thread);*/
+ /* we should not detach this, because, in the dual channel case
+ we should be able to terminate the thread before deleting the listener */
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Thread pool not set in environment."
+ " Cannot invoke call non blocking");
+ }
+#else
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Threading not enabled."
+ " Cannot start separate listener");
+ return AXIS2_FAILURE;
+#endif
+
+ tl_state = AXIS2_MALLOC(env->allocator,
+ sizeof(axis2_transport_listener_state_t));
+
+ if(!tl_state)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Cannot create transport listener state.");
+ }
+ else
+ {
+ tl_state->listener = listener;
+ tl_state->waiting_calls = 0;
+ listener_manager->listener_map[transport] = tl_state;
+ listener_manager->listener_thread[transport] = worker_thread;
+ }
+ }
+ }
+ }
+ }
+
+ if(tl_state)
+ {
+ tl_state->waiting_calls++;
+ return AXIS2_SUCCESS;
+ }
+ else
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_listener_manager_stop(
+ axis2_listener_manager_t * listener_manager,
+ const axutil_env_t * env,
+ const AXIS2_TRANSPORT_ENUMS transport)
+{
+ axis2_transport_listener_state_t *tl_state = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_thread_t *listener_thread = NULL;
+
+ tl_state = listener_manager->listener_map[transport];
+ listener_thread = listener_manager->listener_thread[transport];
+
+ if(tl_state)
+ {
+ tl_state->waiting_calls--;
+ if(tl_state->waiting_calls == 0)
+ {
+ status = axis2_transport_receiver_stop(tl_state->listener, env);
+ if(status == AXIS2_SUCCESS)
+ listener_manager->listener_map[transport] = NULL;
+ }
+ }
+
+ if(listener_thread)
+ {
+ axutil_thread_pool_exit_thread(env->thread_pool, listener_thread);
+ listener_manager->listener_thread[transport] = NULL;
+ }
+
+ return status;
+}
+
+AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
+axis2_listener_manager_get_reply_to_epr(
+ const axis2_listener_manager_t * listener_manager,
+ const axutil_env_t * env,
+ const axis2_char_t * svc_name,
+ const AXIS2_TRANSPORT_ENUMS transport)
+{
+ axis2_transport_listener_state_t *tl_state = NULL;
+
+ tl_state = listener_manager->listener_map[transport];
+ if(tl_state)
+ {
+ return axis2_transport_receiver_get_reply_to_epr(tl_state->listener, env, svc_name);
+ }
+ return NULL;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_listener_manager_free(
+ axis2_listener_manager_t * listener_manager,
+ const axutil_env_t * env)
+{
+ int i = 0;
+
+ for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++)
+ {
+ if(listener_manager->listener_map[i])
+ AXIS2_FREE(env->allocator, listener_manager->listener_map[i]);
+ }
+
+ AXIS2_FREE(env->allocator, listener_manager);
+}
+
+AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL
+axis2_listener_manager_get_conf_ctx(
+ const axis2_listener_manager_t * listener_manager,
+ const axutil_env_t * env)
+{
+ return listener_manager->conf_ctx;
+}
+
+void *AXIS2_THREAD_FUNC
+axis2_listener_manager_worker_func(
+ axutil_thread_t * thd,
+ void *data)
+{
+ axis2_listener_manager_worker_func_args_t *args_list = NULL;
+ const axutil_env_t *th_env = NULL;
+
+ args_list = (axis2_listener_manager_worker_func_args_t *)data;
+ if(!args_list)
+ return NULL;
+
+ th_env = axutil_init_thread_env(args_list->env);
+ /* Start the protocol server. For examlle if protocol is http axis2_http_server_start function
+ * of the axis2_http_receiver is called.
+ */
+ if(args_list->listener)
+ {
+ axis2_transport_receiver_start(args_list->listener, th_env);
+ }
+ return NULL;
+}
diff --git a/src/core/clientapi/op_client.c b/src/core/clientapi/op_client.c
new file mode 100644
index 0000000..3ccb776
--- /dev/null
+++ b/src/core/clientapi/op_client.c
@@ -0,0 +1,1439 @@
+/*
+ * 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.
+ */
+
+#include <axis2_op_client.h>
+#include <axis2_const.h>
+#include <axutil_hash.h>
+#include <axutil_uuid_gen.h>
+#include <axis2_listener_manager.h>
+#include <axis2_engine.h>
+#include "axis2_callback_recv.h"
+#include <axiom_xml_reader.h>
+#include <axis2_core_utils.h>
+#include <axiom_soap_envelope.h>
+#include <axiom_soap_const.h>
+#include <axiom_soap_body.h>
+#include <axutil_types.h>
+#include <platforms/axutil_platform_auto_sense.h>
+
+struct axis2_op_client
+{
+ axis2_svc_ctx_t *svc_ctx;
+
+ axis2_options_t *options;
+
+ axis2_op_ctx_t *op_ctx;
+
+ axis2_callback_t *callback;
+
+ axis2_bool_t completed;
+
+ /* to hold the locally created async result */
+ axis2_async_result_t *async_result;
+
+ axis2_callback_recv_t *callback_recv;
+
+ /** message exchange pattern */
+ axis2_char_t *mep;
+
+ axis2_char_t *soap_version_uri;
+ axutil_string_t *soap_action;
+ axis2_char_t *wsa_action;
+ axis2_bool_t reuse;
+
+};
+
+typedef struct axis2_op_client_worker_func_args
+{
+ const axutil_env_t *env;
+ axis2_op_client_t *op_client;
+ axis2_callback_t *callback;
+ axis2_op_t *op;
+ axis2_msg_ctx_t *msg_ctx;
+} axis2_op_client_worker_func_args_t;
+
+void *AXIS2_THREAD_FUNC axis2_op_client_worker_func(
+ axutil_thread_t * thd,
+ void *data);
+
+static axis2_char_t *AXIS2_CALL axis2_op_client_get_transport_from_url(
+ const axis2_char_t * url,
+ const axutil_env_t * env);
+
+AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL
+axis2_op_client_create(
+ const axutil_env_t * env,
+ axis2_op_t * op,
+ axis2_svc_ctx_t * svc_ctx,
+ axis2_options_t * options)
+{
+ axis2_op_client_t *op_client = NULL;
+ const axis2_char_t *mep_uri = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, op, NULL);
+ AXIS2_PARAM_CHECK(env->error, svc_ctx, NULL);
+ AXIS2_PARAM_CHECK(env->error, options, NULL);
+
+ op_client = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_client_t));
+ if(!op_client)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create op client.");
+ return NULL;
+ }
+
+ /** initialize data */
+ op_client->callback = NULL;
+ op_client->completed = AXIS2_FALSE;
+ op_client->reuse = AXIS2_FALSE;
+ op_client->async_result = NULL;
+ op_client->callback_recv = NULL;
+
+ op_client->options = options;
+ op_client->svc_ctx = svc_ctx;
+
+ op_client->mep = NULL;
+ op_client->soap_version_uri = NULL;
+ op_client->soap_action = NULL;
+ op_client->wsa_action = NULL;
+
+ op_client->op_ctx = axis2_op_ctx_create(env, op, op_client->svc_ctx);
+ if(!(op_client->op_ctx))
+ {
+ axis2_op_client_free(op_client, env);
+ return NULL;
+ }
+
+ mep_uri = axis2_op_get_msg_exchange_pattern(op, env);
+
+ if(!mep_uri)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_DETERMINE_MEP, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find message exchange pattern uri.");
+ axis2_op_client_free(op_client, env);
+ return NULL;
+ }
+
+ op_client->mep = axutil_strdup(env, mep_uri);
+
+ op_client->soap_version_uri = axutil_strdup(env, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI);
+ if(!(op_client->soap_version_uri))
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap version uri.");
+ axis2_op_client_free(op_client, env);
+ return NULL;
+ }
+
+ /** initialize parser for thread safety */
+ axiom_xml_reader_init();
+ return op_client;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_set_options(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ const axis2_options_t * options)
+{
+ if(op_client->options)
+ {
+ axis2_options_free(op_client->options, env);
+ }
+ op_client->options = (axis2_options_t *)options;
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN const axis2_options_t *AXIS2_CALL
+axis2_op_client_get_options(
+ const axis2_op_client_t * op_client,
+ const axutil_env_t * env)
+{
+ return op_client->options;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_add_msg_ctx(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * mc)
+{
+ axis2_msg_ctx_t *out_msg_ctx = NULL, *in_msg_ctx = NULL;
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ /* Don't use AXIS2_PARAM_CHECK to verify op_client, as it clobbers
+ env->error->status_code on no error destroying the information
+ therein that an error has already occurred. */
+ if(!op_client)
+ {
+ if(axutil_error_get_status_code(env->error) == AXIS2_SUCCESS)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
+ }
+ return AXIS2_FAILURE;
+ }
+ /* mc message context pointer may be NULL, e.g., when no response message
+ is received */
+
+ if(op_client->op_ctx)
+ {
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "op_ctx is NULL, unable to continue");
+ return AXIS2_FAILURE;
+ }
+
+ if(msg_ctx_map)
+ {
+ out_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT];
+ in_msg_ctx = msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN];
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "msg_ctx_map is NULL, unable to continue");
+ return AXIS2_FAILURE;
+ }
+
+ if(op_client->reuse)
+ {
+ /* This is the second invocation using the same service client,
+ so reset */
+ if(out_msg_ctx)
+ {
+ axis2_msg_ctx_free(out_msg_ctx, env);
+ out_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
+ }
+
+ if(in_msg_ctx)
+ {
+ axis2_msg_ctx_free(in_msg_ctx, env);
+ in_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL;
+ }
+
+ axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_FALSE);
+ op_client->reuse = AXIS2_FALSE;
+ }
+
+ if(out_msg_ctx && in_msg_ctx)
+ {
+ /* may be this is the second invocation using the same service clinet,
+ so reset */
+ axis2_msg_ctx_free(out_msg_ctx, env);
+ out_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
+ axis2_msg_ctx_free(in_msg_ctx, env);
+ in_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = NULL;
+ axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_FALSE);
+ }
+
+ if(!out_msg_ctx)
+ {
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = mc;
+ }
+ else
+ {
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = mc;
+ axis2_op_ctx_set_complete(op_client->op_ctx, env, AXIS2_TRUE);
+ }
+
+ if(out_msg_ctx && !mc)
+ {
+ axutil_property_t *dump_property;
+ axis2_char_t *dump_value = NULL;
+ if(!axis2_msg_ctx_get_doing_rest(out_msg_ctx, env))
+ {
+ dump_property = axis2_msg_ctx_get_property(out_msg_ctx, env, AXIS2_DUMP_INPUT_MSG_TRUE);
+ if(dump_property)
+ {
+ dump_value = (axis2_char_t *)axutil_property_get_value(dump_property, env);
+ }
+ }
+
+ if(axutil_strcmp(dump_value, AXIS2_VALUE_TRUE))
+ {
+ axis2_msg_ctx_free(out_msg_ctx, env);
+ out_msg_ctx = NULL;
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = NULL;
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_add_out_msg_ctx(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * mc)
+{
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env);
+
+ if(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT])
+ {
+ axis2_msg_ctx_free(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT], env);
+ }
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_OUT] = mc;
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_add_in_msg_ctx(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * mc)
+{
+ axis2_msg_ctx_t **msg_ctx_map = NULL;
+
+ msg_ctx_map = axis2_op_ctx_get_msg_ctx_map(op_client->op_ctx, env);
+
+ if(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN])
+ {
+ axis2_msg_ctx_free(msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN], env);
+ }
+ msg_ctx_map[AXIS2_WSDL_MESSAGE_LABEL_IN] = mc;
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN const axis2_msg_ctx_t *AXIS2_CALL
+axis2_op_client_get_msg_ctx(
+ const axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ const axis2_wsdl_msg_labels_t message_label)
+{
+ return axis2_op_ctx_get_msg_ctx(op_client->op_ctx, env, message_label);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_set_callback(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_callback_t * callback)
+{
+ if(op_client->callback)
+ {
+ axis2_callback_free(op_client->callback, env);
+ }
+
+ op_client->callback = callback;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_callback_t *AXIS2_CALL
+axis2_op_client_get_callback(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env)
+{
+ return op_client->callback;
+}
+
+/* This function is called from service client irrespective of the message exchange pattern
+ * and whether one/two way channel used.
+ */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_execute(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ const axis2_bool_t block)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_msg_ctx_t *msg_ctx = NULL;
+
+ axis2_transport_out_desc_t *transport_out = NULL;
+ axis2_transport_in_desc_t *transport_in = NULL;
+
+ axis2_status_t status = AXIS2_FAILURE;
+ axis2_op_t *op = NULL;
+ axis2_char_t *msg_id = NULL;
+
+ if(op_client->completed)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Op client execute failed. Already completed.");
+ return AXIS2_FAILURE;
+ }
+
+ conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env);
+
+ msg_ctx = (axis2_msg_ctx_t *)axis2_op_client_get_msg_ctx(op_client, env,
+ AXIS2_WSDL_MESSAGE_LABEL_OUT);
+
+ if(!msg_ctx)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Op client execute failed. Message context is not valid.");
+ return AXIS2_FAILURE;
+ }
+
+ axis2_msg_ctx_set_options(msg_ctx, env, op_client->options);
+
+ /**
+ if the transport to use for sending is not specified, try to find it
+ from the URL or the client option.
+ */
+ transport_out = axis2_options_get_transport_out(op_client->options, env);
+ if(!transport_out)
+ {
+ axis2_endpoint_ref_t *to_epr = NULL;
+ axutil_property_t *property = NULL;
+ property = axis2_options_get_property(op_client->options, env, AXIS2_TARGET_EPR);
+ if(property)
+ {
+ to_epr = axutil_property_get_value(property, env);
+ }
+
+ if(!to_epr)
+ {
+ to_epr = axis2_options_get_to(op_client->options, env);
+ }
+
+ if(!to_epr)
+ {
+ to_epr = axis2_msg_ctx_get_to(msg_ctx, env);
+ }
+
+ transport_out = axis2_op_client_infer_transport(op_client, env, to_epr);
+ }
+
+ if(!transport_out)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Op client execute failed. Cannot find transport out.");
+ return AXIS2_FAILURE;
+ }
+
+ if(!(axis2_msg_ctx_get_transport_out_desc(msg_ctx, env)))
+ {
+ axis2_msg_ctx_set_transport_out_desc(msg_ctx, env, transport_out);
+ }
+
+ transport_in = axis2_options_get_transport_in(op_client->options, env);
+ if(!transport_in)
+ {
+ axis2_conf_ctx_t *conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env);
+
+ if(conf_ctx)
+ {
+ axis2_conf_t *conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(conf)
+ {
+ transport_in = axis2_conf_get_transport_in(conf, env,
+ axis2_transport_out_desc_get_enum(transport_out, env));
+ }
+ }
+ }
+ if(!transport_in)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Op client execute failed. Cannot find transport in.");
+ return AXIS2_FAILURE;
+ }
+
+ if(!(axis2_msg_ctx_get_transport_in_desc(msg_ctx, env)))
+ {
+ axis2_msg_ctx_set_transport_in_desc(msg_ctx, env, transport_in);
+ }
+
+ op = axis2_op_ctx_get_op(op_client->op_ctx, env);
+
+ if(!op)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Op client execute failed. Cannot find operation.");
+ return AXIS2_FAILURE;
+ }
+ status = axis2_op_client_prepare_invocation(op_client, env, op, msg_ctx);
+ if(status != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Op client execute failed. Preparing for invocation failed.");
+ return AXIS2_FAILURE;
+ }
+ msg_id = (axis2_char_t *)axutil_uuid_gen(env);
+ axis2_msg_ctx_set_message_id(msg_ctx, env, msg_id);
+ if(msg_id)
+ {
+ AXIS2_FREE(env->allocator, msg_id);
+ msg_id = NULL;
+ }
+
+ /* If dual channel. */
+ if(axis2_options_get_use_separate_listener(op_client->options, env))
+ {
+ axis2_engine_t *engine = NULL;
+
+ if(op_client->callback)
+ {
+ AXIS2_CALLBACK_RECV_ADD_CALLBACK(op_client->callback_recv, env,
+ axis2_msg_ctx_get_msg_id(msg_ctx, env), op_client->callback);
+ }
+
+ axis2_msg_ctx_set_op_ctx(msg_ctx, env, axis2_op_find_op_ctx(op, env, msg_ctx,
+ op_client-> svc_ctx));
+ axis2_msg_ctx_set_svc_ctx(msg_ctx, env, op_client->svc_ctx);
+
+ /* send the message */
+ engine = axis2_engine_create(env, conf_ctx);
+ if(!engine)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Op client execute failed due to engine creation failure.");
+ return AXIS2_FAILURE;
+ }
+ axis2_engine_send(engine, env, msg_ctx);
+ axis2_engine_free(engine, env);
+ }
+ else /* Same channel will be used irrespective of message exchange pattern. */
+ {
+ if(block)
+ {
+ axis2_msg_ctx_t *response_mc = NULL;
+
+ axis2_msg_ctx_set_svc_ctx(msg_ctx, env, op_client->svc_ctx);
+ axis2_msg_ctx_set_conf_ctx(msg_ctx, env, axis2_svc_ctx_get_conf_ctx(
+ op_client-> svc_ctx, env));
+ axis2_msg_ctx_set_op_ctx(msg_ctx, env, op_client->op_ctx);
+
+ /*Send the SOAP Message and receive a response */
+ response_mc = axis2_op_client_two_way_send(env, msg_ctx);
+ if(!response_mc)
+ {
+ const axis2_char_t *mep = axis2_op_get_msg_exchange_pattern(op, env);
+ if(!(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY)) || !(axutil_strcmp(mep,
+ AXIS2_MEP_URI_ROBUST_OUT_ONLY)))
+ {
+ if(env->error)
+ {
+ return env->error->status_code;
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ axis2_op_client_add_msg_ctx(op_client, env, response_mc);
+ }
+ else
+ {
+ axis2_op_client_worker_func_args_t *arg_list = NULL;
+ arg_list = AXIS2_MALLOC(env->allocator, sizeof(axis2_op_client_worker_func_args_t));
+ if(!arg_list)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Cannot create op client worker function argument list.");
+ return AXIS2_FAILURE;
+ }
+ arg_list->env = env;
+ arg_list->op_client = op_client;
+ arg_list->callback = op_client->callback;
+ arg_list->op = op;
+ arg_list->msg_ctx = msg_ctx;
+#ifdef AXIS2_SVR_MULTI_THREADED
+ if (env->thread_pool)
+ {
+ axutil_thread_t *worker_thread = NULL;
+ worker_thread = axutil_thread_pool_get_thread(env->thread_pool,
+ axis2_op_client_worker_func,
+ (void *)
+ arg_list);
+ if (!worker_thread)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Thread creation failed call invoke non blocking");
+ }
+ else
+ {
+ axutil_thread_pool_thread_detach(env->thread_pool,
+ worker_thread);
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Thread pool not set in environment"
+ "Cannot invoke call non blocking");
+ }
+#else
+ axis2_op_client_worker_func(NULL, (void *)arg_list);
+#endif
+
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_reset(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env)
+{
+ if(!op_client->completed)
+ return AXIS2_FAILURE;
+
+ op_client->completed = AXIS2_FALSE;
+
+ op_client->op_ctx = NULL;
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_complete(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * mc)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_listener_manager_t *listener_manager = NULL;
+ AXIS2_TRANSPORT_ENUMS transport = AXIS2_TRANSPORT_ENUM_HTTP;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(mc, env);
+
+ if(!conf_ctx)
+ return AXIS2_FAILURE;
+
+ if(!listener_manager)
+ return AXIS2_FAILURE;
+
+ return axis2_listener_manager_stop(listener_manager, env, transport);
+}
+
+AXIS2_EXTERN axis2_op_ctx_t *AXIS2_CALL
+axis2_op_client_get_operation_context(
+ const axis2_op_client_t * op_client,
+ const axutil_env_t * env)
+{
+ return op_client->op_ctx;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_op_client_free(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env)
+{
+ if(!op_client)
+ return;
+
+ /*if(op_client->callback)
+ {
+ axis2_callback_free(op_client->callback, env);
+ }*/
+
+ if(op_client->op_ctx)
+ {
+ axis2_op_ctx_free(op_client->op_ctx, env);
+ op_client->op_ctx = NULL;
+ }
+
+ if(op_client->soap_version_uri)
+ {
+ AXIS2_FREE(env->allocator, op_client->soap_version_uri);
+ }
+
+ if(op_client->mep)
+ {
+ AXIS2_FREE(env->allocator, op_client->mep);
+ }
+
+ if(axis2_options_get_xml_parser_reset(op_client->options, env))
+ {
+ axiom_xml_reader_cleanup();
+ }
+
+ AXIS2_FREE(env->allocator, op_client);
+}
+
+/* This function is the thread worker function for the single channel non blocking case. Here
+ * being non-blocking implies that message is two way. */
+void *AXIS2_THREAD_FUNC
+axis2_op_client_worker_func(
+ axutil_thread_t * thd,
+ void *data)
+{
+ axis2_op_client_worker_func_args_t *args_list = NULL;
+ axis2_op_ctx_t *op_ctx = NULL;
+ axis2_msg_ctx_t *response = NULL;
+ axutil_env_t *th_env = NULL;
+ axutil_thread_pool_t *th_pool = NULL;
+
+ args_list = (axis2_op_client_worker_func_args_t *)data;
+ if(!args_list)
+ {
+ return NULL;
+ }
+
+ th_env = axutil_init_thread_env(args_list->env);
+
+ op_ctx = axis2_op_ctx_create(th_env, args_list->op, args_list->op_client->svc_ctx);
+ if(!op_ctx)
+ {
+ return NULL;
+ }
+ axis2_msg_ctx_set_op_ctx(args_list->msg_ctx, th_env, op_ctx);
+ axis2_msg_ctx_set_svc_ctx(args_list->msg_ctx, th_env, args_list->op_client->svc_ctx);
+
+ /* send the request and wait for response */
+ response = axis2_op_client_two_way_send(th_env, args_list->msg_ctx);
+
+ /* We do not need to handle the NULL response here because this thread function is called only
+ * in the single channel non blocking case which, imply this is two way message by design.
+ */
+
+ /* Here after the code is a subset of what callback receiver do in dual channel case.*/
+ axis2_op_client_add_msg_ctx(args_list->op_client, th_env, response);
+ args_list->op_client->async_result = axis2_async_result_create(th_env, response);
+
+ if(args_list->callback)
+ {
+ axis2_callback_invoke_on_complete(args_list->callback, th_env,
+ args_list->op_client->async_result);
+
+ axis2_callback_set_complete(args_list->callback, th_env, AXIS2_TRUE);
+ }
+
+ /* Clean up memory */
+ axis2_async_result_free(args_list->op_client->async_result, th_env);
+
+ axis2_op_ctx_free(op_ctx, th_env);
+
+ th_pool = th_env->thread_pool;
+
+ AXIS2_FREE(th_env->allocator, args_list);
+
+ if(th_env)
+ {
+ axutil_free_thread_env(th_env);
+ th_env = NULL;
+ }
+ axutil_thread_pool_exit_thread(th_pool, thd);
+ return NULL;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_set_callback_recv(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_callback_recv_t * callback_recv)
+{
+ op_client->callback_recv = callback_recv;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axutil_string_t *AXIS2_CALL
+axis2_op_client_get_soap_action(
+ const axis2_op_client_t * op_client,
+ const axutil_env_t * env)
+{
+ return op_client->soap_action;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_prepare_invocation(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_op_t * op,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_svc_t *svc = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, op, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE);
+
+ /* make sure operation's MEP is the same as given MEP */
+ if(op_client->mep)
+ {
+ if(axutil_strcmp(op_client->mep, axis2_op_get_msg_exchange_pattern(op, env)))
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_MISMATCH_IN_MEP_CLIENT, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Message exchange pattern of op client and operation are different.");
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_BE_NULL_IN_MEP_CLIENT, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Message exchange pattern of op client is not valid.");
+ return AXIS2_FAILURE;
+ }
+ /* If operation has a parent service get it */
+ svc = axis2_op_get_parent(op, env);
+ if(svc)
+ {
+ axis2_svc_ctx_set_svc(op_client->svc_ctx, env, svc);
+ }
+ else
+ {
+ svc = axis2_svc_ctx_get_svc(op_client->svc_ctx, env);
+ if(svc)
+ {
+ axis2_op_t *temp_op = NULL;
+ const axutil_qname_t *op_qname = axis2_op_get_qname(op, env);
+ temp_op = axis2_svc_get_op_with_qname(svc, env, op_qname);
+ if(!temp_op)
+ {
+ axis2_svc_add_op(svc, env, op);
+ }
+ }
+ }
+
+ if(op_client->wsa_action)
+ {
+ axis2_msg_ctx_set_wsa_action(msg_ctx, env, op_client->wsa_action);
+ }
+
+ if(op_client->soap_action)
+ {
+ axis2_msg_ctx_set_soap_action(msg_ctx, env, op_client->soap_action);
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
+axis2_op_client_prepare_soap_envelope(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axiom_node_t * to_send)
+{
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axiom_soap_envelope_t *envelope = NULL;
+ int soap_version = AXIOM_SOAP12;
+
+ if(op_client->svc_ctx)
+ {
+ msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(op_client-> svc_ctx, env),
+ NULL, NULL);
+ }
+
+ if(!msg_ctx)
+ {
+ return NULL;
+ }
+
+ if(op_client->soap_version_uri)
+ {
+ if(!(axutil_strcmp(op_client->soap_version_uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI)))
+ soap_version = AXIOM_SOAP11;
+ else
+ soap_version = AXIOM_SOAP12;
+ }
+
+ envelope = axiom_soap_envelope_create_default_soap_envelope(env, soap_version);
+ if(!envelope)
+ {
+ return NULL;
+ }
+
+ if(to_send)
+ {
+ axiom_soap_body_t *soap_body = NULL;
+ soap_body = axiom_soap_envelope_get_body(envelope, env);
+ if(soap_body)
+ {
+ axiom_node_t *node = NULL;
+ node = axiom_soap_body_get_base_node(soap_body, env);
+ if(node)
+ {
+ axiom_node_add_child(node, env, to_send);
+ }
+ }
+ }
+
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, envelope);
+
+ return msg_ctx;
+}
+
+AXIS2_EXTERN axis2_transport_out_desc_t *AXIS2_CALL
+axis2_op_client_infer_transport(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_endpoint_ref_t * epr)
+{
+ axis2_char_t *transport = NULL;
+ axis2_transport_out_desc_t *transport_out_desc = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+ AXIS2_TRANSPORT_ENUMS transport_enum = AXIS2_TRANSPORT_ENUM_MAX;
+
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Start:axis2_op_client_infer_transport");
+
+ /* We first try the client option */
+ transport_enum = axis2_options_get_sender_transport_protocol(op_client->options, env);
+ if(transport_enum == AXIS2_TRANSPORT_ENUM_MAX)
+ {
+ /* If we couldn't find the transport we default to HTTP */
+ transport_enum = AXIS2_TRANSPORT_ENUM_HTTP;
+ /* We try to infer transport from the url */
+ if(epr)
+ {
+ const axis2_char_t *to_url = axis2_endpoint_ref_get_address(epr, env);
+
+ transport = axis2_op_client_get_transport_from_url(to_url, env);
+ }
+
+ if(transport)
+ {
+ if(!axutil_strcmp(transport, AXIS2_TRANSPORT_HTTP))
+ {
+ transport_enum = AXIS2_TRANSPORT_ENUM_HTTP;
+ }
+ else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_HTTPS))
+ {
+ transport_enum = AXIS2_TRANSPORT_ENUM_HTTPS;
+ }
+ else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_XMPP))
+ {
+ transport_enum = AXIS2_TRANSPORT_ENUM_XMPP;
+ }
+ else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_TCP))
+ {
+ transport_enum = AXIS2_TRANSPORT_ENUM_TCP;
+ }
+ else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_AMQP))
+ {
+ transport_enum = AXIS2_TRANSPORT_ENUM_AMQP;
+ }
+ else if(!axutil_strcmp(transport, AXIS2_TRANSPORT_UDP))
+ {
+ transport_enum = AXIS2_TRANSPORT_ENUM_UDP;
+ }
+
+ AXIS2_FREE(env->allocator, transport);
+ transport = NULL;
+ }
+ }
+ conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(conf)
+ {
+ transport_out_desc = axis2_conf_get_transport_out(conf, env, transport_enum);
+ }
+ }
+ if(!transport_out_desc)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot infer transport");
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CANNOT_INFER_TRANSPORT, AXIS2_FAILURE);
+ }
+ AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "End:axis2_op_client_infer_transport");
+ return transport_out_desc;
+}
+
+AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
+axis2_op_client_create_default_soap_envelope(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env)
+{
+ axiom_soap_envelope_t *envelope = NULL;
+
+ if(!(axutil_strcmp(AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI, op_client->soap_version_uri)))
+ {
+ envelope = axiom_soap_envelope_create_with_soap_version_prefix(env, AXIOM_SOAP12, NULL);
+ }
+
+ if(!(axutil_strcmp(AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI, op_client->soap_version_uri)))
+ {
+ envelope = axiom_soap_envelope_create_with_soap_version_prefix(env, AXIOM_SOAP11, NULL);
+ }
+ return envelope;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_engage_module(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ const axutil_qname_t * qname)
+{
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_conf_t *conf = NULL;
+
+ if(op_client->svc_ctx)
+ {
+ conf_ctx = axis2_svc_ctx_get_conf_ctx(op_client->svc_ctx, env);
+ if(conf_ctx)
+ {
+ conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+ if(conf)
+ {
+ /*if it is already engaged do not engage it again */
+ if(!(axis2_conf_is_engaged(conf, env, qname)))
+ {
+ return axis2_conf_engage_module(conf, env, qname);
+ }
+ }
+ }
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_set_soap_version_uri(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ const axis2_char_t * soap_version_uri)
+{
+ if(op_client->soap_version_uri)
+ {
+ AXIS2_FREE(env->allocator, op_client->soap_version_uri);
+ op_client->soap_version_uri = NULL;
+ }
+
+ if(soap_version_uri)
+ {
+ op_client->soap_version_uri = axutil_strdup(env, soap_version_uri);
+ if(!(op_client->soap_version_uri))
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap version uri.");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_set_soap_action(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axutil_string_t * soap_action)
+{
+ if(op_client->soap_action)
+ {
+ axutil_string_free(op_client->soap_action, env);
+ op_client->soap_action = NULL;
+ }
+
+ if(soap_action)
+ {
+ op_client->soap_action = axutil_string_clone(soap_action, env);
+ if(!(op_client->soap_action))
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create soap action.");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_op_client_set_wsa_action(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ const axis2_char_t * wsa_action)
+{
+ if(op_client->wsa_action)
+ {
+ AXIS2_FREE(env->allocator, op_client->wsa_action);
+ op_client->wsa_action = NULL;
+ }
+
+ if(wsa_action)
+ {
+ op_client->wsa_action = axutil_strdup(env, wsa_action);
+ if(!(op_client->wsa_action))
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create wsa action.");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+static axis2_char_t *AXIS2_CALL
+axis2_op_client_get_transport_from_url(
+ const axis2_char_t * url,
+ const axutil_env_t * env)
+{
+ axis2_char_t *transport = NULL;
+ const axis2_char_t *start = NULL;
+ const axis2_char_t *end = NULL;
+ AXIS2_PARAM_CHECK(env->error, url, NULL);
+ start = url;
+ end = url;
+ while((*end) && (*end) != ':')
+ end++;
+
+ if((*end) == ':')
+ {
+ const axis2_char_t *c = NULL;
+ transport = AXIS2_MALLOC(env->allocator, (end - start + 1) * sizeof(char));
+ if(!transport)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "No memory. Cannot create transport protocol identifier.");
+ return NULL;
+ }
+
+ for(c = start; c < end; c++)
+ transport[c - start] = *c;
+ transport[c - start] = '\0';
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "URL is malformed or does not contain a transport protocol");
+ }
+ return transport;
+}
+
+AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL
+axis2_op_client_get_svc_ctx(
+ const axis2_op_client_t * op_client,
+ const axutil_env_t * env)
+{
+ return op_client->svc_ctx;
+}
+
+/* This function is called only for single channel invocations */
+AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
+axis2_op_client_two_way_send(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_engine_t *engine = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+ axis2_msg_ctx_t *response = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_op_t *op = NULL;
+ axiom_soap_envelope_t *response_envelope = NULL;
+ axutil_property_t *property = NULL;
+ long index = -1;
+ axis2_bool_t wait_indefinitely = AXIS2_FALSE;
+ axis2_char_t *mep = NULL;
+
+ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+ engine = axis2_engine_create(env, conf_ctx);
+ if(!engine)
+ return NULL;
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TIMEOUT_IN_SECONDS);
+ if(property)
+ {
+ axis2_char_t *value = axutil_property_get_value(property, env);
+ if(value)
+ index = AXIS2_ATOI(value);
+ if(index == -1)
+ {
+ wait_indefinitely = AXIS2_TRUE;
+ index = 1;
+ }
+ }
+
+ status = axis2_engine_send(engine, env, msg_ctx);
+
+ axis2_engine_free(engine, env);
+ engine = NULL;
+
+ if(status != AXIS2_SUCCESS)
+ {
+ if(AXIS2_ERROR_GET_STATUS_CODE(env->error) == AXIS2_SUCCESS)
+ {
+ AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE);
+ }
+ return NULL;
+ }
+
+ op = axis2_msg_ctx_get_op(msg_ctx, env);
+ if(op)
+ {
+ mep = (axis2_char_t *)axis2_op_get_msg_exchange_pattern(op, env);
+ }
+
+ if(!mep)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_MEP_CANNOT_DETERMINE_MEP, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot determine message exchange pattern.");
+ return NULL;
+ }
+
+ /* handle one way non robust case */
+ if(!(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY)))
+ {
+ return NULL;
+ }
+
+ /* create the response */
+ response = axis2_msg_ctx_create(env, conf_ctx,
+ axis2_msg_ctx_get_transport_in_desc(msg_ctx, env), axis2_msg_ctx_get_transport_out_desc(
+ msg_ctx, env));
+ if(!response)
+ return NULL;
+
+ axis2_msg_ctx_set_server_side(response, env, AXIS2_FALSE);
+ axis2_msg_ctx_set_conf_ctx(response, env, axis2_msg_ctx_get_conf_ctx(msg_ctx, env));
+ axis2_msg_ctx_set_svc_grp_ctx(response, env, axis2_msg_ctx_get_svc_grp_ctx(msg_ctx, env));
+
+ /* If request is REST we assume the response is REST, so set the variable */
+ axis2_msg_ctx_set_doing_rest(response, env, axis2_msg_ctx_get_doing_rest(msg_ctx, env));
+ axis2_msg_ctx_set_status_code(response, env, axis2_msg_ctx_get_status_code(msg_ctx, env));
+
+ if(op)
+ {
+ axis2_op_register_op_ctx(op, env, response, axis2_msg_ctx_get_op_ctx(msg_ctx, env));
+ }
+
+ /* set response envelope */
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ engine = NULL;
+ }
+ response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env);
+ if(response_envelope)
+ {
+ axis2_msg_ctx_set_soap_envelope(response, env, response_envelope);
+ engine = axis2_engine_create(env, conf_ctx);
+ if(engine)
+ {
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HANDLER_ALREADY_VISITED);
+ if(property)
+ {
+ axis2_char_t *value = axutil_property_get_value(property, env);
+ if(!axutil_strcmp(AXIS2_VALUE_TRUE, value))
+ {
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ }
+ return response;
+ }
+ }
+ status = axis2_engine_receive(engine, env, response);
+ }
+ }
+ else
+ {
+ while(!response_envelope && index > 0)
+ {
+ /*wait till the response arrives */
+ AXIS2_SLEEP(1);
+ if(!wait_indefinitely)
+ index--;
+ response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env);
+ }
+ /* if it is a two way message, then the status should be in error,
+ else it is a one way message */
+ if(response_envelope)
+ {
+ axis2_msg_ctx_set_soap_envelope(response, env, response_envelope);
+ /* There could be a scenariao where the message has already passed
+ * through the incoming phases. eg. Reliable Messaging 1.0 two
+ * way single channel
+ */
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_HANDLER_ALREADY_VISITED);
+ if(property)
+ {
+ axis2_char_t *value = axutil_property_get_value(property, env);
+ if(!axutil_strcmp(AXIS2_VALUE_TRUE, value))
+ {
+ return response;
+ }
+ }
+ engine = axis2_engine_create(env, conf_ctx);
+ if(engine)
+ {
+ status = axis2_engine_receive(engine, env, response);
+ if(status != AXIS2_SUCCESS)
+ return NULL;
+ }
+ }
+ else
+ {
+ if(AXIS2_ERROR_GET_STATUS_CODE(env->error) != AXIS2_SUCCESS)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE,
+ AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Response is not valid. Blocking invocation expects response.");
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ engine = NULL;
+ }
+ axis2_msg_ctx_free(response, env);
+ return NULL;
+ }
+ }
+ }
+
+ /*following is no longer valid. Just keeping for others view*/
+
+ /* property is NULL, and we set null for AXIS2_TRANSPORT_IN in msg_ctx to
+ avoid double free of this property */
+ /*axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property);*/
+
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ engine = NULL;
+ }
+ if(!(axutil_strcmp(mep, AXIS2_MEP_URI_ROBUST_OUT_ONLY)) && response)
+ {
+ if(axis2_msg_ctx_get_doing_rest(response, env) && axis2_msg_ctx_get_status_code(response,
+ env) >= 400)
+ {
+ /* All HTTP 4xx and 5xx status codes are treated as errors */
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP client transport error.");
+ return NULL;
+ }
+ switch(axis2_msg_ctx_get_status_code(response, env))
+ {
+ /* In a SOAP request HTTP status code 500 is used for errors */
+ case 500:
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_HTTP_CLIENT_TRANSPORT_ERROR, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "HTTP client transport error.");
+ break;
+ case 0:
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE,
+ AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Response is not valid. Blocking invocation expects response.");
+ break;
+ case -1:
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE,
+ AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Response is not valid. Blocking invocation expects response.");
+ break;
+ }
+
+ if(response)
+ {
+ axis2_msg_ctx_free(response, env);
+ }
+
+ return NULL;
+ }
+ return response;
+}
+
+AXIS2_EXTERN axis2_msg_ctx_t *AXIS2_CALL
+axis2_op_client_receive(
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_engine_t *engine = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+ axis2_msg_ctx_t *response = NULL;
+ axis2_conf_ctx_t *conf_ctx = NULL;
+ axis2_op_t *op = NULL;
+ axiom_soap_envelope_t *response_envelope = NULL;
+ axutil_property_t *property = NULL;
+
+ /* create the response */
+ response = axis2_msg_ctx_create(env, conf_ctx,
+ axis2_msg_ctx_get_transport_in_desc(msg_ctx, env), axis2_msg_ctx_get_transport_out_desc(
+ msg_ctx, env));
+ if(!response)
+ return NULL;
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_TRANSPORT_IN);
+ if(property)
+ {
+ axis2_msg_ctx_set_property(response, env, AXIS2_TRANSPORT_IN, property);
+ property = NULL;
+ }
+
+ op = axis2_msg_ctx_get_op(msg_ctx, env);
+ if(op)
+ {
+ axis2_op_register_op_ctx(op, env, response, axis2_msg_ctx_get_op_ctx(msg_ctx, env));
+ }
+ axis2_msg_ctx_set_server_side(response, env, AXIS2_FALSE);
+ axis2_msg_ctx_set_conf_ctx(response, env, axis2_msg_ctx_get_conf_ctx(msg_ctx, env));
+ axis2_msg_ctx_set_svc_grp_ctx(response, env, axis2_msg_ctx_get_svc_grp_ctx(msg_ctx, env));
+
+ /* If request is REST we assume the response is REST, so set the variable */
+ axis2_msg_ctx_set_doing_rest(response, env, axis2_msg_ctx_get_doing_rest(msg_ctx, env));
+
+ response_envelope = axis2_msg_ctx_get_response_soap_envelope(msg_ctx, env);
+ if(response_envelope)
+ {
+ axis2_msg_ctx_set_soap_envelope(response, env, response_envelope);
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ engine = NULL;
+ }
+
+ engine = axis2_engine_create(env, conf_ctx);
+ if(engine)
+ {
+ status = axis2_engine_receive(engine, env, response);
+ if(status != AXIS2_SUCCESS)
+ {
+ return NULL;
+ }
+ }
+
+ }
+ else
+ {
+ /* if it is a two way message, then the status should be in error,
+ else it is a one way message */
+ if(AXIS2_ERROR_GET_STATUS_CODE(env->error) != AXIS2_SUCCESS)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_BLOCKING_INVOCATION_EXPECTS_RESPONSE,
+ AXIS2_FAILURE);
+ return NULL;
+ }
+ }
+
+ /* property is NULL, and we set null for AXIS2_TRANSPORT_IN in msg_ctx to
+ avoid double free of this property */
+ axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property);
+
+ if(engine)
+ {
+ axis2_engine_free(engine, env);
+ engine = NULL;
+ }
+ return response;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_op_client_set_reuse(
+ axis2_op_client_t * op_client,
+ const axutil_env_t * env,
+ axis2_bool_t reuse)
+{
+ op_client->reuse = reuse;
+}
diff --git a/src/core/clientapi/options.c b/src/core/clientapi/options.c
new file mode 100644
index 0000000..26c5d33
--- /dev/null
+++ b/src/core/clientapi/options.c
@@ -0,0 +1,1068 @@
+/*
+ * 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.
+ */
+
+#include <axis2_options.h>
+#include <axis2_const.h>
+#include <axutil_hash.h>
+#include <axiom_soap_const.h>
+#include <axis2_msg_info_headers.h>
+#include <axutil_array_list.h>
+#include <axis2_http_transport.h>
+
+struct axis2_options
+{
+
+ /** parent options */
+ axis2_options_t *parent;
+
+ axutil_hash_t *properties;
+
+ axis2_char_t *soap_version_uri;
+
+ int soap_version;
+
+ long timeout_in_milli_seconds;
+
+ axis2_bool_t use_separate_listener;
+
+ /** addressing specific properties */
+ axis2_msg_info_headers_t *msg_info_headers;
+
+ axis2_transport_receiver_t *receiver;
+
+ axis2_transport_in_desc_t *transport_in;
+
+ AXIS2_TRANSPORT_ENUMS transport_in_protocol;
+
+ /** for sending and receiving messages */
+ axis2_transport_out_desc_t *transport_out;
+ AXIS2_TRANSPORT_ENUMS sender_transport_protocol;
+
+ axis2_bool_t manage_session;
+ axis2_bool_t enable_mtom;
+ axutil_string_t *soap_action;
+ axis2_bool_t xml_parser_reset;
+};
+
+AXIS2_EXTERN axis2_options_t *AXIS2_CALL
+axis2_options_create(
+ const axutil_env_t * env)
+{
+ axis2_options_t *options = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ options = AXIS2_MALLOC(env->allocator, sizeof(axis2_options_t));
+ if(!options)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create options.");
+ return NULL;
+ }
+
+ options->parent = NULL;
+ options->properties = NULL;
+ options->soap_version_uri = NULL;
+ options->timeout_in_milli_seconds = -1;
+ options->use_separate_listener = -1;
+ options->receiver = NULL;
+ options->transport_in = NULL;
+ options->transport_in_protocol = AXIS2_TRANSPORT_ENUM_MAX;
+ options->transport_out = NULL;
+ options->sender_transport_protocol = AXIS2_TRANSPORT_ENUM_MAX;
+ options->manage_session = -1;
+ options->soap_version = AXIOM_SOAP12;
+ options->enable_mtom = AXIS2_FALSE;
+ options->soap_action = NULL;
+ options->xml_parser_reset = AXIS2_TRUE;
+
+ options->msg_info_headers = axis2_msg_info_headers_create(env, NULL, NULL);
+ if(!options->msg_info_headers)
+ {
+ axis2_options_free(options, env);
+ return NULL;
+ }
+
+ options->properties = axutil_hash_make(env);
+ if(!options->properties)
+ {
+ axis2_options_free(options, env);
+ return NULL;
+ }
+
+ return options;
+}
+
+AXIS2_EXTERN axis2_options_t *AXIS2_CALL
+axis2_options_create_with_parent(
+ const axutil_env_t * env,
+ axis2_options_t * parent)
+{
+
+ axis2_options_t *options = NULL;
+
+ options = axis2_options_create(env);
+
+ if(options)
+ {
+ options->parent = parent;
+ }
+ return options;
+}
+
+AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
+axis2_options_get_action(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ const axis2_char_t *action = NULL;
+ action = axis2_msg_info_headers_get_action(options->msg_info_headers, env);
+
+ if(!action && options->parent)
+ {
+ return axis2_options_get_action(options->parent, env);
+ }
+
+ return action;
+}
+
+AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
+axis2_options_get_fault_to(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ axis2_endpoint_ref_t *fault_to = NULL;
+
+ fault_to = axis2_msg_info_headers_get_fault_to(options->msg_info_headers, env);
+
+ if(!fault_to && options->parent)
+ {
+ return axis2_options_get_fault_to(options->parent, env);
+ }
+
+ return fault_to;
+}
+
+AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
+axis2_options_get_from(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ axis2_endpoint_ref_t *from = NULL;
+
+ from = axis2_msg_info_headers_get_from(options->msg_info_headers, env);
+
+ if(!from && options->parent)
+ {
+ return axis2_options_get_from(options->parent, env);
+ }
+
+ return from;
+}
+
+AXIS2_EXTERN axis2_transport_receiver_t *AXIS2_CALL
+axis2_options_get_transport_receiver(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(!options->receiver && options->parent)
+ {
+ return axis2_options_get_transport_receiver(options->parent, env);
+ }
+
+ return options->receiver;
+}
+
+AXIS2_EXTERN axis2_transport_in_desc_t *AXIS2_CALL
+axis2_options_get_transport_in(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(!options->transport_in && options->parent)
+ {
+ return axis2_options_get_transport_in(options->parent, env);
+ }
+
+ return options->transport_in;
+}
+
+AXIS2_EXTERN AXIS2_TRANSPORT_ENUMS AXIS2_CALL
+axis2_options_get_transport_in_protocol(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(options->parent)
+ {
+ return axis2_options_get_transport_in_protocol(options->parent, env);
+ }
+
+ return options->transport_in_protocol;
+}
+
+AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
+axis2_options_get_message_id(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ const axis2_char_t *message_id = NULL;
+
+ message_id = axis2_msg_info_headers_get_message_id(options->msg_info_headers, env);
+
+ if(!message_id && options->parent)
+ {
+ return axis2_options_get_message_id(options->parent, env);
+ }
+
+ return message_id;
+}
+
+AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
+axis2_options_get_properties(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(!axutil_hash_count(options->properties) && options->parent)
+ {
+ return axis2_options_get_properties(options->parent, env);
+ }
+
+ return options->properties;
+}
+
+AXIS2_EXTERN void *AXIS2_CALL
+axis2_options_get_property(
+ const axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_char_t * key)
+{
+ void *property = NULL;
+
+ property = axutil_hash_get(options->properties, key, AXIS2_HASH_KEY_STRING);
+
+ if(!property && options->parent)
+ {
+ return axis2_options_get_property(options->parent, env, key);
+ }
+
+ return property;
+}
+
+AXIS2_EXTERN axis2_relates_to_t *AXIS2_CALL
+axis2_options_get_relates_to(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ axis2_relates_to_t *relates_to = NULL;
+
+ relates_to = axis2_msg_info_headers_get_relates_to(options->msg_info_headers, env);
+
+ if(!relates_to && options->parent)
+ {
+ return axis2_options_get_relates_to(options->parent, env);
+ }
+
+ return relates_to;
+}
+
+AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
+axis2_options_get_reply_to(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ axis2_endpoint_ref_t *reply_to = NULL;
+
+ reply_to = axis2_msg_info_headers_get_reply_to(options->msg_info_headers, env);
+
+ if(!reply_to && options->parent)
+ {
+ return axis2_options_get_reply_to(options->parent, env);
+ }
+
+ return reply_to;
+}
+
+AXIS2_EXTERN axis2_transport_out_desc_t *AXIS2_CALL
+axis2_options_get_transport_out(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(!options->transport_out && options->parent)
+ {
+ return axis2_options_get_transport_out(options->parent, env);
+ }
+
+ return options->transport_out;
+}
+
+AXIS2_EXTERN AXIS2_TRANSPORT_ENUMS AXIS2_CALL
+axis2_options_get_sender_transport_protocol(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(options->parent)
+ {
+ return axis2_options_get_sender_transport_protocol(options->parent, env);
+ }
+
+ return options->sender_transport_protocol;
+}
+
+AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
+axis2_options_get_soap_version_uri(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(!options->soap_version_uri && options->parent)
+ {
+ return axis2_options_get_soap_version_uri(options->parent, env);
+ }
+
+ if(options->soap_version_uri)
+ {
+ return options->soap_version_uri;
+ }
+ return AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
+
+}
+
+AXIS2_EXTERN long AXIS2_CALL
+axis2_options_get_timeout_in_milli_seconds(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(options->timeout_in_milli_seconds == -1)
+ {
+ if(options->parent)
+ {
+ return axis2_options_get_timeout_in_milli_seconds(options->parent, env);
+ }
+ else
+ {
+ return AXIS2_DEFAULT_TIMEOUT_MILLISECONDS;
+ }
+ }
+
+ return options->timeout_in_milli_seconds;
+}
+
+AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
+axis2_options_get_to(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ axis2_endpoint_ref_t *to = NULL;
+
+ to = axis2_msg_info_headers_get_to(options->msg_info_headers, env);
+
+ if(!to && options->parent)
+ {
+ return axis2_options_get_to(options->parent, env);
+ }
+
+ return to;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_options_get_use_separate_listener(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(options->use_separate_listener == -1)
+ {
+ if(options->parent)
+ {
+ return axis2_options_get_use_separate_listener(options->parent, env);
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ return options->use_separate_listener;
+}
+
+AXIS2_EXTERN axis2_options_t *AXIS2_CALL
+axis2_options_get_parent(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ return options->parent;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_parent(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_options_t * parent)
+{
+ options->parent = (axis2_options_t *)parent;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_action(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_char_t * action)
+{
+ axis2_msg_info_headers_set_action(options->msg_info_headers, env, action);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_fault_to(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_endpoint_ref_t * fault_to)
+{
+ axis2_msg_info_headers_set_fault_to(options->msg_info_headers, env, fault_to);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_from(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_endpoint_ref_t * from)
+{
+ axis2_msg_info_headers_set_from(options->msg_info_headers, env, from);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_to(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_endpoint_ref_t * to)
+{
+ axis2_msg_info_headers_set_to(options->msg_info_headers, env, to);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_transport_receiver(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_transport_receiver_t * receiver)
+{
+ options->receiver = receiver;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_transport_in(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_transport_in_desc_t * transport_in)
+{
+ options->transport_in = transport_in;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_transport_in_protocol(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const AXIS2_TRANSPORT_ENUMS transport_in_protocol)
+{
+ options->transport_in_protocol = transport_in_protocol;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_message_id(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_char_t * message_id)
+{
+ axis2_msg_info_headers_set_message_id(options->msg_info_headers, env, message_id);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_properties(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axutil_hash_t * properties)
+{
+ if(options->properties)
+ {
+ axutil_hash_free(options->properties, env);
+ }
+ options->properties = properties;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_property(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_char_t * property_key,
+ const void *property)
+{
+ axutil_hash_set(options->properties, property_key, AXIS2_HASH_KEY_STRING, property);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_relates_to(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_relates_to_t * relates_to)
+{
+ axis2_msg_info_headers_set_relates_to(options->msg_info_headers, env, relates_to);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_reply_to(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_endpoint_ref_t * reply_to)
+{
+ axis2_msg_info_headers_set_reply_to(options->msg_info_headers, env, reply_to);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_transport_out(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_transport_out_desc_t * transport_out)
+{
+ options->transport_out = transport_out;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_sender_transport(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const AXIS2_TRANSPORT_ENUMS sender_transport,
+ axis2_conf_t * conf)
+{
+ options->transport_out = axis2_conf_get_transport_out(conf, env, sender_transport);
+
+ if(!options->transport_out)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_soap_version_uri(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_char_t * soap_version_uri)
+{
+ if(options->soap_version_uri)
+ {
+ AXIS2_FREE(env->allocator, options->soap_version_uri);
+ options->soap_version_uri = NULL;
+ }
+
+ if(soap_version_uri)
+ {
+ options->soap_version_uri = axutil_strdup(env, soap_version_uri);
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_timeout_in_milli_seconds(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const long timeout_in_milli_seconds)
+{
+ options->timeout_in_milli_seconds = timeout_in_milli_seconds;
+ /* set the property AXIS2_HTTP_CONNECTION_TIMEOUT,
+ * to be picked up by http_sender
+ */
+ if(options->timeout_in_milli_seconds > 0)
+ {
+ axis2_char_t time_str[19]; /* supports 18 digit timeout */
+ axutil_property_t *property = axutil_property_create(env);
+ sprintf(time_str, "%ld", options->timeout_in_milli_seconds);
+ if(property)
+ {
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value(property, env, axutil_strdup(env, time_str));
+ axis2_options_set_property(options, env, AXIS2_HTTP_CONNECTION_TIMEOUT, property);
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_transport_info(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const AXIS2_TRANSPORT_ENUMS sender_transport,
+ const AXIS2_TRANSPORT_ENUMS receiver_transport,
+ const axis2_bool_t use_separate_listener)
+{
+ /*
+ here we check for the legal combination
+ */
+ if(!use_separate_listener)
+ {
+ if(sender_transport != receiver_transport)
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ axis2_options_set_use_separate_listener(options, env, use_separate_listener);
+ }
+ axis2_options_set_transport_in_protocol(options, env, receiver_transport);
+ options->sender_transport_protocol = sender_transport;
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_use_separate_listener(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_bool_t use_separate_listener)
+{
+ axutil_property_t *property = NULL;
+
+ options->use_separate_listener = use_separate_listener;
+
+ if(use_separate_listener)
+ {
+ property = axutil_property_create(env);
+ axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
+ axis2_options_set_property(options, env, AXIS2_USE_SEPARATE_LISTENER, property);
+ }
+ else
+ {
+ property = axutil_property_create(env);
+ axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
+ axis2_options_set_property(options, env, AXIS2_USE_SEPARATE_LISTENER, property);
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_add_reference_parameter(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axiom_node_t * reference_parameter)
+{
+ axis2_msg_info_headers_add_ref_param(options->msg_info_headers, env, reference_parameter);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_manage_session(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_bool_t manage_session)
+{
+ options->manage_session = manage_session;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_options_get_manage_session(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(options->manage_session == -1)
+ {
+ if(options->parent)
+ {
+ return axis2_options_get_manage_session(options->parent, env);
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ return options->manage_session;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_msg_info_headers(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_msg_info_headers_t * msg_info_headers)
+{
+ if(options->msg_info_headers)
+ {
+ axis2_msg_info_headers_free(options->msg_info_headers, env);
+ }
+
+ options->msg_info_headers = msg_info_headers;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_msg_info_headers_t *AXIS2_CALL
+axis2_options_get_msg_info_headers(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ return options->msg_info_headers;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_options_free(
+ axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ if(options->properties)
+ {
+ axutil_hash_index_t *hi = NULL;
+ void *val = NULL;
+ const void *key = NULL;
+ for(hi = axutil_hash_first(options->properties, env); hi; hi = axutil_hash_next(env, hi))
+ {
+ axutil_property_t *property = NULL;
+
+ axutil_hash_this(hi, &key, NULL, &val);
+ property = (axutil_property_t *)val;
+
+ if(property)
+ {
+ axutil_property_free(property, env);
+ }
+ }
+ axutil_hash_free(options->properties, env);
+ }
+
+ if(options->soap_version_uri)
+ {
+ AXIS2_FREE(env->allocator, options->soap_version_uri);
+ }
+
+ if(options->msg_info_headers)
+ {
+ axis2_msg_info_headers_free(options->msg_info_headers, env);
+ }
+
+ if(options->soap_action)
+ {
+ axutil_string_free(options->soap_action, env);
+ }
+
+ AXIS2_FREE(env->allocator, options);
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_options_get_soap_version(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ return options->soap_version;
+
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_soap_version(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const int soap_version)
+{
+ if(soap_version == AXIOM_SOAP11)
+ {
+ options->soap_version = soap_version;
+ axis2_options_set_soap_version_uri(options, env, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI);
+ }
+ else
+ {
+ options->soap_version = AXIOM_SOAP12;
+ axis2_options_set_soap_version_uri(options, env, AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_enable_mtom(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axis2_bool_t enable_mtom)
+{
+ options->enable_mtom = enable_mtom;
+
+ if(enable_mtom)
+ {
+ axutil_property_t *property = axutil_property_create(env);
+ if(property)
+ {
+ axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST);
+ axutil_property_set_value(property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
+ axis2_options_set_property(options, env, AXIS2_ENABLE_MTOM, property);
+ }
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_options_get_enable_mtom(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ return options->enable_mtom;
+}
+
+AXIS2_EXTERN axutil_string_t *AXIS2_CALL
+axis2_options_get_soap_action(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ return options->soap_action;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_soap_action(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axutil_string_t * soap_action)
+{
+ if(options->soap_action)
+ {
+ axutil_string_free(options->soap_action, env);
+ options->soap_action = NULL;
+ }
+
+ if(soap_action)
+ {
+ options->soap_action = axutil_string_clone(soap_action, env);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_options_get_xml_parser_reset(
+ const axis2_options_t * options,
+ const axutil_env_t * env)
+{
+ return options->xml_parser_reset;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_xml_parser_reset(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_bool_t xml_parser_reset)
+{
+ options->xml_parser_reset = xml_parser_reset;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_enable_rest(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_bool_t enable_rest)
+{
+ axutil_property_t *rest_property = NULL;
+
+ if(enable_rest)
+ {
+ rest_property = axutil_property_create(env);
+ axutil_property_set_value(rest_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
+ axis2_options_set_property(options, env, AXIS2_ENABLE_REST, rest_property);
+ }
+ else
+ {
+ rest_property = axutil_property_create(env);
+ axutil_property_set_value(rest_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
+ axis2_options_set_property(options, env, AXIS2_ENABLE_REST, rest_property);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_test_http_auth(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_bool_t test_http_auth)
+{
+ axutil_property_t *test_auth_property = NULL;
+
+ if(test_http_auth)
+ {
+ test_auth_property = axutil_property_create(env);
+ axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
+ axis2_options_set_property(options, env, AXIS2_TEST_HTTP_AUTH, test_auth_property);
+ }
+ else
+ {
+ test_auth_property = axutil_property_create(env);
+ axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
+ axis2_options_set_property(options, env, AXIS2_TEST_HTTP_AUTH, test_auth_property);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_test_proxy_auth(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_bool_t test_proxy_auth)
+{
+ axutil_property_t *test_auth_property = NULL;
+
+ if(test_proxy_auth)
+ {
+ test_auth_property = axutil_property_create(env);
+ axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
+ axis2_options_set_property(options, env, AXIS2_TEST_PROXY_AUTH, test_auth_property);
+ }
+ else
+ {
+ test_auth_property = axutil_property_create(env);
+ axutil_property_set_value(test_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
+ axis2_options_set_property(options, env, AXIS2_TEST_PROXY_AUTH, test_auth_property);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_http_method(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_char_t * http_method)
+{
+ axutil_property_t *method_property = NULL;
+
+ method_property = axutil_property_create(env);
+ axutil_property_set_value(method_property, env, axutil_strdup(env, http_method));
+ axis2_options_set_property(options, env, AXIS2_HTTP_METHOD, method_property);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_http_headers(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ axutil_array_list_t * http_header_list)
+{
+ axutil_property_t *headers_property = NULL;
+
+ headers_property = axutil_property_create(env);
+ axutil_property_set_value(headers_property, env, http_header_list);
+ axis2_options_set_property(options, env, AXIS2_TRANSPORT_HEADER_PROPERTY, headers_property);
+ axutil_property_set_free_func(headers_property, env, axutil_array_list_free_void_arg);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_proxy_auth_info(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_char_t * username,
+ const axis2_char_t * password,
+ const axis2_char_t * auth_type)
+{
+ axis2_bool_t force_proxy_auth = AXIS2_FALSE;
+ axutil_property_t *prop_pw = NULL;
+ axutil_property_t *prop_un = NULL;
+
+ prop_un = axutil_property_create(env);
+ axutil_property_set_value(prop_un, env, axutil_strdup(env, username));
+ axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_UNAME, prop_un);
+
+ prop_pw = axutil_property_create(env);
+ axutil_property_set_value(prop_pw, env, axutil_strdup(env, password));
+ axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_PASSWD, prop_pw);
+
+ if(auth_type)
+ {
+ if((axutil_strcasecmp(auth_type, AXIS2_PROXY_AUTH_TYPE_BASIC) == 0) || (axutil_strcasecmp(
+ auth_type, AXIS2_PROXY_AUTH_TYPE_DIGEST) == 0))
+ {
+ force_proxy_auth = AXIS2_TRUE;
+ }
+ }
+ if(force_proxy_auth)
+ {
+ axutil_property_t *proxy_auth_property = axutil_property_create(env);
+ axutil_property_t *proxy_auth_type_property = axutil_property_create(env);
+
+ axutil_property_set_value(proxy_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
+ axis2_options_set_property(options, env, AXIS2_FORCE_PROXY_AUTH, proxy_auth_property);
+
+ axutil_property_set_value(proxy_auth_type_property, env, axutil_strdup(env, auth_type));
+ axis2_options_set_property(options, env, AXIS2_PROXY_AUTH_TYPE, proxy_auth_type_property);
+ }
+ else
+ {
+ axutil_property_t *proxy_auth_property = axutil_property_create(env);
+ axutil_property_set_value(proxy_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
+ axis2_options_set_property(options, env, AXIS2_FORCE_PROXY_AUTH, proxy_auth_property);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_options_set_http_auth_info(
+ axis2_options_t * options,
+ const axutil_env_t * env,
+ const axis2_char_t * username,
+ const axis2_char_t * password,
+ const axis2_char_t * auth_type)
+{
+ axis2_bool_t force_http_auth = AXIS2_FALSE;
+ axutil_property_t *prop_un = NULL;
+ axutil_property_t *prop_pw = NULL;
+
+ prop_un = axutil_property_create(env);
+ axutil_property_set_value(prop_un, env, axutil_strdup(env, username));
+ axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_UNAME, prop_un);
+
+ prop_pw = axutil_property_create(env);
+ axutil_property_set_value(prop_pw, env, axutil_strdup(env, password));
+ axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_PASSWD, prop_pw);
+
+ if(auth_type)
+ {
+ if((axutil_strcasecmp(auth_type, AXIS2_HTTP_AUTH_TYPE_BASIC) == 0) || (axutil_strcasecmp(
+ auth_type, AXIS2_HTTP_AUTH_TYPE_DIGEST) == 0))
+ {
+ force_http_auth = AXIS2_TRUE;
+ }
+ }
+ if(force_http_auth)
+ {
+ axutil_property_t *http_auth_property = axutil_property_create(env);
+ axutil_property_t *http_auth_type_property = axutil_property_create(env);
+
+ axutil_property_set_value(http_auth_property, env, axutil_strdup(env, AXIS2_VALUE_TRUE));
+ axis2_options_set_property(options, env, AXIS2_FORCE_HTTP_AUTH, http_auth_property);
+
+ axutil_property_set_value(http_auth_type_property, env, axutil_strdup(env, auth_type));
+ axis2_options_set_property(options, env, AXIS2_HTTP_AUTH_TYPE, http_auth_type_property);
+ }
+ else
+ {
+ axutil_property_t *http_auth_property = axutil_property_create(env);
+ axutil_property_set_value(http_auth_property, env, axutil_strdup(env, AXIS2_VALUE_FALSE));
+ axis2_options_set_property(options, env, AXIS2_FORCE_HTTP_AUTH, http_auth_property);
+ }
+ return AXIS2_SUCCESS;
+}
+
diff --git a/src/core/clientapi/stub.c b/src/core/clientapi/stub.c
new file mode 100644
index 0000000..2b27274
--- /dev/null
+++ b/src/core/clientapi/stub.c
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+#include <axis2_stub.h>
+
+struct axis2_stub
+{
+ axis2_svc_client_t *svc_client;
+ axis2_options_t *options;
+};
+
+AXIS2_EXTERN axis2_stub_t *AXIS2_CALL
+axis2_stub_create(
+ const axutil_env_t * env)
+{
+ axis2_stub_t *stub = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+
+ stub = (axis2_stub_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_stub_t));
+
+ if(!stub)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create stub.");
+ return NULL;
+ }
+ stub->svc_client = NULL;
+ stub->options = NULL;
+
+ return stub;
+}
+
+AXIS2_EXTERN axis2_stub_t *AXIS2_CALL
+axis2_stub_create_with_endpoint_ref_and_client_home(
+ const axutil_env_t * env,
+ axis2_endpoint_ref_t * endpoint_ref,
+ const axis2_char_t * client_home)
+{
+ axis2_stub_t *stub = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, endpoint_ref, NULL);
+
+ stub = (axis2_stub_t *)axis2_stub_create(env);
+
+ if(!stub)
+ {
+ return NULL;
+ }
+
+ stub->svc_client = axis2_svc_client_create(env, client_home);
+
+ if(!stub->svc_client)
+ {
+ axis2_stub_free(stub, env);
+ return NULL;
+ }
+
+ stub->options = axis2_options_create(env);
+ if(!stub->options)
+ {
+ axis2_stub_free(stub, env);
+ return NULL;
+ }
+
+ axis2_svc_client_set_options(stub->svc_client, env, stub->options);
+
+ axis2_options_set_to(stub->options, env, endpoint_ref);
+
+ return stub;
+}
+
+AXIS2_EXTERN axis2_stub_t *AXIS2_CALL
+axis2_stub_create_with_endpoint_uri_and_client_home(
+ const axutil_env_t * env,
+ const axis2_char_t * endpoint_uri,
+ const axis2_char_t * client_home)
+{
+ axis2_stub_t *stub = NULL;
+ axis2_endpoint_ref_t *endpoint_ref = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+ AXIS2_PARAM_CHECK(env->error, endpoint_uri, NULL);
+
+ endpoint_ref = axis2_endpoint_ref_create(env, endpoint_uri);
+ if(!endpoint_ref)
+ {
+ return NULL;
+ }
+ stub = (axis2_stub_t *)axis2_stub_create_with_endpoint_ref_and_client_home(env, endpoint_ref,
+ client_home);
+
+ if(!stub)
+ {
+ return NULL;
+ }
+
+ return stub;
+}
+
+void AXIS2_CALL
+axis2_stub_free(
+ axis2_stub_t * stub,
+ const axutil_env_t * env)
+{
+ if(stub)
+ {
+ if(stub->svc_client)
+ {
+ axis2_svc_client_free(stub->svc_client, env);
+ }
+
+ AXIS2_FREE(env->allocator, stub);
+ }
+}
+
+axis2_status_t AXIS2_CALL
+axis2_stub_set_endpoint_ref(
+ axis2_stub_t * stub,
+ const axutil_env_t * env,
+ axis2_endpoint_ref_t * endpoint_ref)
+{
+ AXIS2_PARAM_CHECK(env->error, endpoint_ref, AXIS2_FAILURE);
+ axis2_options_set_to(stub->options, env, endpoint_ref);
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_stub_set_endpoint_uri(
+ axis2_stub_t * stub,
+ const axutil_env_t * env,
+ const axis2_char_t * endpoint_uri)
+{
+ axis2_endpoint_ref_t *endpoint_ref = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, endpoint_uri, AXIS2_FAILURE);
+
+ endpoint_ref = axis2_endpoint_ref_create(env, endpoint_uri);
+ if(!endpoint_ref)
+ {
+ return AXIS2_FAILURE;
+ }
+ axis2_options_set_to(stub->options, env, endpoint_ref);
+
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t AXIS2_CALL
+axis2_stub_set_use_separate_listener(
+ axis2_stub_t * stub,
+ const axutil_env_t * env,
+ const axis2_bool_t use_separate_listener)
+{
+ return axis2_options_set_use_separate_listener(stub->options, env, use_separate_listener);
+}
+
+axis2_status_t AXIS2_CALL
+axis2_stub_engage_module(
+ axis2_stub_t * stub,
+ const axutil_env_t * env,
+ const axis2_char_t * module_name)
+{
+ AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE);
+
+ return axis2_svc_client_engage_module(stub->svc_client, env, module_name);
+}
+
+axis2_status_t AXIS2_CALL
+axis2_stub_set_soap_version(
+ axis2_stub_t * stub,
+ const axutil_env_t * env,
+ const int soap_version)
+{
+ if(!stub->options)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Cannot set soap version. Stub option is not valid.");
+ return AXIS2_FAILURE;
+ }
+ return axis2_options_set_soap_version(stub->options, env, soap_version);
+}
+
+const axis2_char_t *AXIS2_CALL
+axis2_stub_get_svc_ctx_id(
+ const axis2_stub_t * stub,
+ const axutil_env_t * env)
+{
+ const axis2_svc_ctx_t *svc_ctx = NULL;
+ const axis2_char_t *svc_ctx_id = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, stub, NULL);
+
+ svc_ctx = axis2_svc_client_get_svc_ctx(stub->svc_client, env);
+ svc_ctx_id = axis2_svc_ctx_get_svc_id(svc_ctx, env);
+ return svc_ctx_id;
+}
+
+axis2_svc_client_t *AXIS2_CALL
+axis2_stub_get_svc_client(
+ const axis2_stub_t * stub,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, stub, NULL);
+ return stub->svc_client;
+}
+
+axis2_options_t *AXIS2_CALL
+axis2_stub_get_options(
+ const axis2_stub_t * stub,
+ const axutil_env_t * env)
+{
+ return stub->options;
+}
diff --git a/src/core/clientapi/svc_client.c b/src/core/clientapi/svc_client.c
new file mode 100644
index 0000000..d25f340
--- /dev/null
+++ b/src/core/clientapi/svc_client.c
@@ -0,0 +1,1624 @@
+/*
+ * 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.
+ */
+
+#include <axis2_svc_client.h>
+#include <axis2_phases_info.h>
+#include <axis2_const.h>
+#include <axutil_hash.h>
+#include <axutil_uri.h>
+#include "axis2_callback_recv.h"
+#include <axiom_soap_const.h>
+#include <axiom_soap_body.h>
+#include <axiom_soap_header.h>
+#include <axiom_util.h>
+#include <axis2_listener_manager.h>
+#include <axis2_module_desc.h>
+#include <axutil_array_list.h>
+#include <axis2_options.h>
+#include <axis2_conf_init.h>
+#include <platforms/axutil_platform_auto_sense.h>
+#include <stdio.h>
+#include <axutil_generic_obj.h>
+#include <axis2_http_transport.h>
+#include <axis2_http_header.h>
+#include <neethi_util.h>
+#include <axis2_policy_include.h>
+
+struct axis2_svc_client
+{
+ axis2_svc_t *svc;
+
+ axis2_conf_t *conf;
+
+ axis2_conf_ctx_t *conf_ctx;
+
+ axis2_svc_ctx_t *svc_ctx;
+
+ axis2_options_t *options;
+
+ axis2_options_t *override_options;
+
+ /* SOAP Headers */
+ axutil_array_list_t *headers;
+
+ /* for receiving the async messages */
+ axis2_callback_recv_t *callback_recv;
+
+ axis2_listener_manager_t *listener_manager;
+
+ axis2_op_client_t *op_client;
+
+ axiom_soap_envelope_t *last_response_soap_envelope;
+
+ axis2_bool_t last_response_has_fault;
+
+ axis2_bool_t reuse;
+
+ axis2_bool_t auth_failed;
+
+ axis2_bool_t required_auth_is_http;
+
+ axis2_char_t *auth_type;
+
+ axutil_array_list_t *http_headers;
+
+ int http_status_code;
+
+ axis2_bool_t keep_externally_passed_ctx_and_svc;
+
+};
+
+static void
+axis2_svc_client_set_http_info(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx);
+
+static axis2_svc_t *
+axis2_svc_client_create_annonymous_svc(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env);
+
+static axis2_bool_t
+axis2_svc_client_init_transports_from_conf_ctx(
+ const axutil_env_t * env,
+ axis2_svc_client_t * svc_client,
+ axis2_conf_ctx_t * conf_ctx,
+ const axis2_char_t * client_home);
+
+static axis2_bool_t
+axis2_svc_client_init_data(
+ const axutil_env_t * env,
+ axis2_svc_client_t * svc_client);
+
+static axis2_bool_t
+axis2_svc_client_fill_soap_envelope(
+ const axutil_env_t * env,
+ axis2_svc_client_t * svc_client,
+ axis2_msg_ctx_t * msg_ctx,
+ const axiom_node_t * payload);
+
+AXIS2_EXTERN axis2_svc_client_t *AXIS2_CALL
+axis2_svc_client_create(
+ const axutil_env_t * env,
+ const axis2_char_t * client_home)
+{
+ axis2_svc_client_t *svc_client = NULL;
+
+ AXIS2_ENV_CHECK(env, NULL);
+ svc_client = axis2_svc_client_create_with_conf_ctx_and_svc(env, client_home, NULL, NULL);
+
+ return svc_client;
+}
+
+AXIS2_EXTERN axis2_svc_client_t *AXIS2_CALL
+axis2_svc_client_create_with_conf_ctx_and_svc(
+ const axutil_env_t * env,
+ const axis2_char_t * client_home,
+ axis2_conf_ctx_t * conf_ctx,
+ axis2_svc_t * svc)
+{
+ axis2_svc_client_t *svc_client = NULL;
+ axis2_svc_grp_t *svc_grp = NULL;
+ axis2_svc_grp_ctx_t *svc_grp_ctx = NULL;
+ const axis2_char_t *svc_grp_name = NULL;
+
+ svc_client = AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_client_t));
+ if(!svc_client)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create service client.");
+ return NULL;
+ }
+
+ svc_client->svc = NULL;
+ svc_client->conf = NULL;
+ svc_client->conf_ctx = NULL;
+ svc_client->svc_ctx = NULL;
+ svc_client->options = NULL;
+ svc_client->override_options = NULL;
+ svc_client->headers = NULL;
+ svc_client->callback_recv = NULL;
+ svc_client->listener_manager = NULL;
+ svc_client->op_client = NULL;
+ svc_client->last_response_soap_envelope = NULL;
+ svc_client->last_response_has_fault = AXIS2_FALSE;
+ svc_client->reuse = AXIS2_FALSE;
+ svc_client->auth_failed = AXIS2_FALSE;
+ svc_client->required_auth_is_http = AXIS2_FALSE;
+ svc_client->auth_type = NULL;
+ svc_client->http_headers = NULL;
+ svc_client->keep_externally_passed_ctx_and_svc = AXIS2_FALSE;
+
+ if(!axis2_svc_client_init_data(env, svc_client))
+ {
+ axis2_svc_client_free(svc_client, env);
+ return NULL;
+ }
+
+ /*create the default conf_ctx if it is NULL */
+ if(!axis2_svc_client_init_transports_from_conf_ctx(env, svc_client, conf_ctx, client_home))
+ {
+ axis2_svc_client_free(svc_client, env);
+ return NULL;
+ }
+
+ svc_client->conf = axis2_conf_ctx_get_conf(svc_client->conf_ctx, env);
+
+ if(svc)
+ {
+ svc_client->keep_externally_passed_ctx_and_svc = AXIS2_TRUE;
+ svc_client->svc = svc;
+ }
+ else
+ {
+ svc_client->svc = axis2_svc_client_create_annonymous_svc(svc_client, env);
+ if(!svc_client->svc)
+ {
+ axis2_svc_client_free(svc_client, env);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create annonymous service.");
+ return NULL;
+ }
+ }
+
+ /** add the service to the config context if it isn't in there already */
+ if(!axis2_conf_get_svc(svc_client->conf, env, axis2_svc_get_name(svc_client->svc, env)))
+ {
+ axis2_conf_add_svc(svc_client->conf, env, svc_client->svc);
+ }
+
+ /** create a service context for myself: create a new service group
+ context and then get the service context for myself as I'll need that
+ later for stuff that I gotta do */
+ svc_grp = axis2_svc_get_parent(svc_client->svc, env);
+ if(!svc_grp)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot access service group of service client.");
+ return NULL;
+ }
+
+ svc_grp_ctx = axis2_svc_grp_get_svc_grp_ctx(svc_grp, env, svc_client->conf_ctx);
+ if(!svc_grp_ctx)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Cannot access service group context of service client.");
+ return NULL;
+ }
+
+ svc_grp_name = axis2_svc_grp_get_name(svc_grp, env);
+ if(!svc_grp_name)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Cannot access service group name of service client.");
+ return NULL; /* service group name is mandatory */
+ }
+
+ axis2_conf_ctx_register_svc_grp_ctx(svc_client->conf_ctx, env, svc_grp_name, svc_grp_ctx);
+
+ svc_client->svc_ctx = axis2_svc_grp_ctx_get_svc_ctx(svc_grp_ctx, env, axis2_svc_get_name(
+ svc_client->svc, env));
+
+ return svc_client;
+}
+
+AXIS2_EXTERN axis2_svc_t *AXIS2_CALL
+axis2_svc_client_get_svc(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+ return svc_client->svc;
+}
+
+AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL
+axis2_svc_client_get_conf_ctx(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+ return svc_client->conf_ctx;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_set_options(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axis2_options_t * options)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+ if(svc_client->options)
+ {
+ axis2_options_free(svc_client->options, env);
+ }
+ svc_client->options = (axis2_options_t *)options;
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN const axis2_options_t *AXIS2_CALL
+axis2_svc_client_get_options(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+ return svc_client->options;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_set_override_options(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axis2_options_t * override_options)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+ if(svc_client->override_options)
+ {
+ axis2_options_free(svc_client->override_options, env);
+ }
+
+ svc_client->override_options = (axis2_options_t *)override_options;
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN const axis2_options_t *AXIS2_CALL
+axis2_svc_client_get_override_options(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+ return svc_client->override_options;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_engage_module(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axis2_char_t * module_name)
+{
+ axis2_module_desc_t *module = NULL;
+ axutil_qname_t *mod_qname = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE);
+
+ mod_qname = axutil_qname_create(env, module_name, NULL, NULL);
+
+ if(!mod_qname)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ module = axis2_conf_get_module(svc_client->conf, env, mod_qname);
+
+ axutil_qname_free(mod_qname, env);
+ mod_qname = NULL;
+
+ if(module)
+ {
+ return axis2_svc_engage_module(svc_client->svc, env, module, svc_client->conf);
+ }
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_disengage_module(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axis2_char_t * module_name)
+{
+ axis2_module_desc_t *module = NULL;
+ axutil_qname_t *mod_qname = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, module_name, AXIS2_FAILURE);
+
+ mod_qname = axutil_qname_create(env, module_name, NULL, NULL);
+ if(!mod_qname)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ module = axis2_conf_get_module(svc_client->conf, env, mod_qname);
+ axutil_qname_free(mod_qname, env);
+ mod_qname = NULL;
+
+ if(module)
+ {
+ return axis2_svc_disengage_module(svc_client->svc, env, module, svc_client->conf);
+ }
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_add_header(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ axiom_node_t * header)
+{
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+ if(!svc_client->headers)
+ {
+ svc_client->headers = axutil_array_list_create(env, 0);
+ if(!svc_client->headers)
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ axutil_array_list_add(svc_client->headers, env, header);
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_remove_all_headers(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ int i = 0;
+ int size = 0;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+
+ if(!svc_client->headers)
+ {
+ return AXIS2_SUCCESS;
+ }
+
+ size = axutil_array_list_size(svc_client->headers, env);
+
+ for(i = size - 1; i > -1; i--)
+ {
+ axutil_array_list_remove(svc_client->headers, env, i);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_send_robust_with_op_qname(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axutil_qname_t * op_qname,
+ const axiom_node_t * payload)
+{
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axis2_status_t status = AXIS2_FAILURE;
+ axis2_bool_t qname_free_flag = AXIS2_FALSE;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+
+ if(!op_qname)
+ {
+ op_qname = axutil_qname_create(env, AXIS2_ANON_ROBUST_OUT_ONLY_OP, NULL, NULL);
+ if(!op_qname)
+ {
+ return AXIS2_FAILURE;
+ }
+ qname_free_flag = AXIS2_TRUE;
+ }
+ else
+ {
+ axis2_op_t *op = NULL;
+ axis2_char_t *mep = NULL;
+ axis2_svc_t *svc = NULL;
+ svc = axis2_svc_client_get_svc(svc_client, env);
+ if(!svc)
+ {
+ return AXIS2_FAILURE;
+ }
+ op = axis2_svc_get_op_with_qname(svc, env, op_qname);
+ if(!op)
+ {
+ return AXIS2_FAILURE;
+ }
+ mep = (axis2_char_t *)axis2_op_get_msg_exchange_pattern(op, env);
+ if(!mep || axutil_strcmp(AXIS2_MEP_URI_OUT_ONLY, mep) != 0)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s%s",
+ "To use this method opeation uri should be", AXIS2_MEP_URI_OUT_ONLY);
+ return AXIS2_FAILURE;
+ }
+ }
+
+ svc_client->auth_failed = AXIS2_FALSE;
+ svc_client->required_auth_is_http = AXIS2_FALSE;
+ if(svc_client->auth_type)
+ {
+ AXIS2_FREE(env->allocator, svc_client->auth_type);
+ }
+ svc_client->auth_type = NULL;
+
+ msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env), NULL,
+ NULL);
+ if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload))
+ {
+ return AXIS2_FAILURE;
+ }
+
+ if(!axis2_svc_client_create_op_client(svc_client, env, op_qname))
+ {
+ return AXIS2_FAILURE;
+ }
+
+ axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx);
+ status = axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE);
+ axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
+ svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
+ svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
+ if(axis2_msg_ctx_get_auth_type(msg_ctx, env))
+ {
+ svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env));
+ }
+
+ if(qname_free_flag)
+ {
+ axutil_qname_free((axutil_qname_t *)op_qname, env);
+ }
+
+ return status;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_send_robust(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axiom_node_t * payload)
+{
+ return axis2_svc_client_send_robust_with_op_qname(svc_client, env, NULL, payload);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_svc_client_fire_and_forget_with_op_qname(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axutil_qname_t * op_qname,
+ const axiom_node_t * payload)
+{
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ axis2_bool_t qname_free_flag = AXIS2_FALSE;
+
+ AXIS2_PARAM_CHECK_VOID(env->error, svc_client);
+
+ if(!op_qname)
+ {
+ op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_ONLY_OP, NULL, NULL);
+ if(!op_qname)
+ {
+ return;
+ }
+ qname_free_flag = AXIS2_TRUE;
+ }
+
+ svc_client->auth_failed = AXIS2_FALSE;
+ svc_client->required_auth_is_http = AXIS2_FALSE;
+ if(svc_client->auth_type)
+ {
+ AXIS2_FREE(env->allocator, svc_client->auth_type);
+ }
+ svc_client->auth_type = NULL;
+
+ msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env), NULL,
+ NULL);
+ if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload))
+ {
+ return;
+ }
+
+ if(!axis2_svc_client_create_op_client(svc_client, env, op_qname))
+ {
+ return;
+ }
+
+ axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx);
+ axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE);
+ axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
+ svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
+ svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
+ if(axis2_msg_ctx_get_auth_type(msg_ctx, env))
+ {
+ svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env));
+ }
+
+ if(qname_free_flag)
+ {
+ axutil_qname_free((axutil_qname_t *)op_qname, env);
+ }
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_svc_client_fire_and_forget(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axiom_node_t * payload)
+{
+ axis2_svc_client_fire_and_forget_with_op_qname(svc_client, env, NULL, payload);
+}
+
+AXIS2_EXTERN axiom_node_t *AXIS2_CALL
+axis2_svc_client_send_receive_with_op_qname(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axutil_qname_t * op_qname,
+ const axiom_node_t * payload)
+{
+ axiom_soap_envelope_t *soap_envelope = NULL;
+ axiom_soap_body_t *soap_body = NULL;
+ axiom_node_t *soap_node = NULL;
+ axis2_op_t *op = NULL;
+ axutil_param_t *param = NULL;
+ axutil_uri_t *action_uri = NULL;
+ axis2_char_t *action_str = NULL;
+ axis2_bool_t qname_free_flag = AXIS2_FALSE;
+
+ axis2_msg_ctx_t *res_msg_ctx = NULL;
+ axis2_msg_ctx_t *msg_ctx = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+
+ svc_client->last_response_soap_envelope = NULL;
+ svc_client->last_response_has_fault = AXIS2_FALSE;
+ svc_client->auth_failed = AXIS2_FALSE;
+ svc_client->required_auth_is_http = AXIS2_FALSE;
+ if(svc_client->auth_type)
+ {
+ AXIS2_FREE(env->allocator, svc_client->auth_type);
+ }
+ svc_client->auth_type = NULL;
+
+ op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname);
+ if(op)
+ {
+ param = axis2_op_get_param(op, env, AXIS2_SOAP_ACTION);
+ if(param)
+ {
+ action_uri = (axutil_uri_t *)axutil_param_get_value(param, env);
+ action_str = axutil_uri_to_string(action_uri, env, AXIS2_URI_UNP_OMITUSERINFO);
+ axis2_options_set_action(svc_client->options, env, action_str);
+ }
+ }
+
+ if(!op_qname)
+ {
+ op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL);
+ if(!op_qname)
+ return NULL;
+
+ qname_free_flag = AXIS2_TRUE;
+ }
+
+ /* If dual channel blocking. We come to this block if the client indicate to use
+ * a separate listener but don't provide a callback function to acted upon when
+ * response is received in the listener thread. What we do here is we create a callback
+ * and call axis2_svc_client_send_receive_non_blocking_with_op_qname with it. */
+ if(axis2_options_get_use_separate_listener(svc_client->options, env))
+ {
+ axis2_callback_t *callback = NULL;
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ long index = 0;
+
+ /* This means doing a Request-Response invocation using two channels.
+ If the transport is a two way transport (e.g. http), only one channel is used
+ (e.g. in http cases 202 OK is sent to say no response available).
+ Axis2 gets blocked and return when the response is available. */
+
+ callback = axis2_callback_create(env);
+ if(!callback)
+ {
+ return NULL;
+ }
+
+ /* Call two channel non blocking invoke to do the work and wait on the callback. We don't
+ * set a callback function for the callback. That functionality is handled here.
+ */
+ axis2_svc_client_send_receive_non_blocking_with_op_qname(svc_client, env, op_qname,
+ payload, callback);
+
+ index = axis2_options_get_timeout_in_milli_seconds(svc_client->options, env) / 10;
+
+ while(!axis2_callback_get_complete(callback, env))
+ {
+ if(index-- >= 0)
+ {
+ AXIS2_USLEEP(10000);
+ }
+ else
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_RESPONSE_TIMED_OUT, AXIS2_FAILURE);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Response time out.");
+ return NULL;
+ }
+ }
+
+ soap_envelope = axis2_callback_get_envelope(callback, env);
+ msg_ctx = axis2_callback_get_msg_ctx(callback, env);
+ axis2_op_client_add_in_msg_ctx(svc_client->op_client, env, msg_ctx);
+
+ /* start of hack to get rid of memory leak */
+ /*msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client-> svc_ctx, env),
+ NULL, NULL);
+ if(!msg_ctx)
+ return NULL;
+
+ axis2_op_client_add_in_msg_ctx(svc_client->op_client, env, msg_ctx);
+
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope);*/
+ /* end of hack to get rid of memory leak */
+
+ /* process the result of the invocation */
+ if(!soap_envelope)
+ {
+ if(axis2_callback_get_error(callback, env) != AXIS2_ERROR_NONE)
+ {
+ AXIS2_ERROR_SET(env->error, axis2_callback_get_error(callback, env), AXIS2_FAILURE);
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client->svc_ctx, env),
+ NULL, NULL);
+ if(!msg_ctx)
+ return NULL;
+
+ if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload))
+ {
+ return NULL;
+ }
+
+ if(!axis2_svc_client_create_op_client(svc_client, env, op_qname))
+ {
+ return NULL;
+ }
+
+ axis2_op_client_add_msg_ctx(svc_client->op_client, env, msg_ctx);
+ axis2_op_client_execute(svc_client->op_client, env, AXIS2_TRUE);
+ axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
+ svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
+ svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
+ if(axis2_msg_ctx_get_auth_type(msg_ctx, env))
+ {
+ svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env));
+ }
+ res_msg_ctx = (axis2_msg_ctx_t *)axis2_op_client_get_msg_ctx(svc_client-> op_client, env,
+ AXIS2_WSDL_MESSAGE_LABEL_IN);
+
+ if(res_msg_ctx)
+ {
+ soap_envelope = axis2_msg_ctx_get_soap_envelope(res_msg_ctx, env);
+ }
+ else
+ {
+ axis2_op_client_add_msg_ctx(svc_client->op_client, env, res_msg_ctx);
+ /* set in msg_ctx to be NULL to reset */
+ }
+ }
+
+ if(qname_free_flag)
+ {
+ axutil_qname_free((axutil_qname_t *)op_qname, env);
+ }
+
+ if(!soap_envelope)
+ {
+ return NULL;
+ }
+ svc_client->last_response_soap_envelope = soap_envelope;
+
+ soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
+
+ if(!soap_body)
+ {
+ axiom_node_t *node = axiom_soap_envelope_get_base_node(soap_envelope, env);
+ if(node)
+ {
+ axiom_element_t *envelope_element = (axiom_element_t *)axiom_node_get_data_element(
+ node, env);
+ axiom_util_get_first_child_element_with_localname(envelope_element, env, node,
+ AXIOM_SOAP_BODY_LOCAL_NAME, &soap_node);
+ if(soap_node)
+ {
+ return axiom_node_get_first_element(soap_node, env);
+ }
+ }
+ return NULL;
+ }
+
+ if(axis2_msg_ctx_get_doing_rest(res_msg_ctx, env))
+ {
+ /* All HTTP 4xx and 5xx status codes are treated as errors */
+ if(axis2_msg_ctx_get_status_code(res_msg_ctx, env) >= 400)
+ {
+ svc_client->last_response_has_fault = AXIS2_TRUE;
+ }
+ else
+ {
+ svc_client->last_response_has_fault = AXIS2_FALSE;
+ }
+ }
+ else
+ {
+ svc_client->last_response_has_fault = axiom_soap_body_has_fault(soap_body, env);
+ }
+
+ if(AXIOM_SOAP11 == axiom_soap_envelope_get_soap_version(soap_envelope, env))
+ {
+ axiom_soap_body_convert_fault_to_soap11(soap_body, env);
+ }
+
+ soap_node = axiom_soap_body_get_base_node(soap_body, env);
+ if(!soap_node)
+ {
+ return NULL;
+ }
+ return axiom_node_get_first_element(soap_node, env);
+}
+
+AXIS2_EXTERN axiom_node_t *AXIS2_CALL
+axis2_svc_client_send_receive(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axiom_node_t * payload)
+{
+ return axis2_svc_client_send_receive_with_op_qname(svc_client, env, NULL, payload);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_svc_client_send_receive_non_blocking_with_op_qname(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axutil_qname_t * op_qname,
+ const axiom_node_t * payload,
+ axis2_callback_t * callback)
+{
+ axis2_msg_ctx_t *msg_ctx = NULL;
+ AXIS2_TRANSPORT_ENUMS transport_in_protocol;
+ axis2_bool_t qname_free_flag = AXIS2_FALSE;
+
+ AXIS2_PARAM_CHECK_VOID(env->error, svc_client);
+
+ if(!op_qname)
+ {
+ op_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL);
+ if(!op_qname)
+ return;
+ qname_free_flag = AXIS2_TRUE;
+ }
+
+ svc_client->auth_failed = AXIS2_FALSE;
+ svc_client->required_auth_is_http = AXIS2_FALSE;
+ if(svc_client->auth_type)
+ {
+ AXIS2_FREE(env->allocator, svc_client->auth_type);
+ }
+ svc_client->auth_type = NULL;
+
+ msg_ctx = axis2_msg_ctx_create(env, axis2_svc_ctx_get_conf_ctx(svc_client-> svc_ctx, env),
+ NULL, NULL);
+ if(!msg_ctx)
+ return;
+
+ if(!axis2_svc_client_fill_soap_envelope(env, svc_client, msg_ctx, payload))
+ {
+ return;
+ }
+
+ if(!axis2_svc_client_create_op_client(svc_client, env, op_qname))
+ {
+ return;
+ }
+
+ axis2_op_client_set_callback(svc_client->op_client, env, callback);
+ axis2_op_client_add_out_msg_ctx(svc_client->op_client, env, msg_ctx);
+
+ /* If dual channel */
+ if(axis2_options_get_use_separate_listener(svc_client->options, env))
+ {
+ axis2_op_t *op = NULL;
+
+ transport_in_protocol = axis2_options_get_transport_in_protocol(svc_client->options, env);
+ if(transport_in_protocol == AXIS2_TRANSPORT_ENUM_MAX)
+ {
+ axis2_options_set_transport_in_protocol(svc_client->options, env,
+ AXIS2_TRANSPORT_ENUM_HTTP);
+ transport_in_protocol = AXIS2_TRANSPORT_ENUM_HTTP;
+ }
+ axis2_listener_manager_make_sure_started(svc_client->listener_manager, env,
+ transport_in_protocol, svc_client->conf_ctx);
+ /* Following sleep is required to ensure the listener is ready to receive response.
+ If it is missing, the response gets lost. - Samisa */
+ AXIS2_USLEEP(1);
+
+ op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname);
+ /* At the end of the incoming flow this message receiver will be hit */
+ axis2_op_set_msg_recv(op, env,
+ AXIS2_CALLBACK_RECV_GET_BASE(svc_client-> callback_recv, env));
+ axis2_op_client_set_callback_recv(svc_client->op_client, env, svc_client->callback_recv);
+ }
+
+ axis2_op_client_execute(svc_client->op_client, env, AXIS2_FALSE);
+ axis2_svc_client_set_http_info(svc_client, env, msg_ctx);
+ svc_client->auth_failed = axis2_msg_ctx_get_auth_failed(msg_ctx, env);
+ svc_client->required_auth_is_http = axis2_msg_ctx_get_required_auth_is_http(msg_ctx, env);
+ if(axis2_msg_ctx_get_auth_type(msg_ctx, env))
+ {
+ svc_client->auth_type = axutil_strdup(env, axis2_msg_ctx_get_auth_type(msg_ctx, env));
+ }
+
+ if(qname_free_flag)
+ {
+ axutil_qname_free((axutil_qname_t *)op_qname, env);
+ op_qname = NULL;
+ }
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_svc_client_send_receive_non_blocking(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axiom_node_t * payload,
+ axis2_callback_t * callback)
+{
+ axis2_svc_client_send_receive_non_blocking_with_op_qname(svc_client, env, NULL, payload,
+ callback);
+}
+
+AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL
+axis2_svc_client_create_op_client(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axutil_qname_t * op_qname)
+{
+ axis2_op_t *op = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+
+ op = axis2_svc_get_op_with_qname(svc_client->svc, env, op_qname);
+
+ if(!op)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find operation to create op client.");
+ return NULL;
+ }
+
+ if(!(svc_client->op_client) || svc_client->reuse)
+ {
+ if((svc_client->reuse) && (svc_client->op_client))
+ axis2_op_client_free(svc_client->op_client, env);
+ svc_client->op_client = axis2_op_client_create(env, op, svc_client->svc_ctx,
+ svc_client->options);
+ }
+
+ /**
+ If override options have been set, that means we need to make sure
+ those options override the options of even the operation client. So,
+ what we do is switch the parents around to make that work.
+ */
+ if(svc_client->override_options)
+ {
+ axis2_options_set_parent(svc_client->override_options, env, axis2_op_client_get_options(
+ svc_client-> op_client, env));
+ axis2_op_client_set_options(svc_client->op_client, env, svc_client->override_options);
+ }
+ svc_client->reuse = AXIS2_TRUE;
+ axis2_op_client_set_reuse(svc_client->op_client, env, svc_client->reuse);
+ return svc_client->op_client;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_finalize_invoke(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_TRANSPORT_ENUMS transport_in_protocol;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+
+ transport_in_protocol = axis2_options_get_transport_in_protocol(svc_client->options, env);
+
+ if(svc_client->listener_manager)
+ {
+ return axis2_listener_manager_stop(svc_client->listener_manager, env, transport_in_protocol);
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN const axis2_endpoint_ref_t *AXIS2_CALL
+axis2_svc_client_get_own_endpoint_ref(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ const axis2_char_t * transport)
+{
+ return NULL;
+}
+
+AXIS2_EXTERN const axis2_endpoint_ref_t *AXIS2_CALL
+axis2_svc_client_get_target_endpoint_ref(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ return NULL;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_set_target_endpoint_ref(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ axis2_endpoint_ref_t * target_endpoint_ref)
+{
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_svc_ctx_t *AXIS2_CALL
+axis2_svc_client_get_svc_ctx(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+ return svc_client->svc_ctx;
+}
+
+static axis2_bool_t
+axis2_svc_client_init_transports_from_conf_ctx(
+ const axutil_env_t * env,
+ axis2_svc_client_t * svc_client,
+ axis2_conf_ctx_t * conf_ctx,
+ const axis2_char_t * client_home)
+{
+ svc_client->conf_ctx = conf_ctx;
+ if(!svc_client->conf_ctx)
+ {
+ svc_client->conf_ctx = axis2_build_client_conf_ctx(env, client_home);
+ if(!svc_client->conf_ctx)
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ else
+ {
+ svc_client->keep_externally_passed_ctx_and_svc = AXIS2_TRUE;
+ }
+
+ if(!svc_client->listener_manager)
+ {
+ svc_client->listener_manager = axis2_listener_manager_create(env);
+ if(!svc_client->listener_manager)
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ return AXIS2_TRUE;
+}
+
+static axis2_bool_t
+axis2_svc_client_init_data(
+ const axutil_env_t * env,
+ axis2_svc_client_t * svc_client)
+{
+ svc_client->svc = NULL;
+ svc_client->conf_ctx = NULL;
+ svc_client->svc_ctx = NULL;
+
+ svc_client->options = axis2_options_create(env);
+ if(!svc_client->options)
+ {
+ return AXIS2_FALSE;
+ }
+
+ svc_client->override_options = NULL;
+ svc_client->headers = NULL;
+
+ if(svc_client->callback_recv)
+ {
+ AXIS2_CALLBACK_RECV_FREE(svc_client->callback_recv, env);
+ svc_client->callback_recv = NULL;
+ }
+
+ svc_client->callback_recv = axis2_callback_recv_create(env);
+ if(!svc_client->callback_recv)
+ {
+ return AXIS2_FALSE;
+ }
+
+ return AXIS2_TRUE;
+}
+
+static axis2_svc_t *
+axis2_svc_client_create_annonymous_svc(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+
+ /**
+ now add anonymous operations to the axis2 service for use with the
+ shortcut client API. NOTE: We only add the ones we know we'll use
+ later in the convenience API; if you use
+ this constructor then you can't expect any magic!
+ */
+ axutil_qname_t *tmp_qname;
+ axis2_svc_t *svc;
+ axis2_op_t *op_out_in, *op_out_only, *op_robust_out_only;
+ axis2_phases_info_t *info = NULL;
+
+ tmp_qname = axutil_qname_create(env, AXIS2_ANON_SERVICE, NULL, NULL);
+ if(!tmp_qname)
+ {
+ return NULL;
+ }
+
+ svc = axis2_svc_create_with_qname(env, tmp_qname);
+ axutil_qname_free(tmp_qname, env);
+ if(!svc)
+ {
+ return NULL;
+ }
+
+ tmp_qname = axutil_qname_create(env, AXIS2_ANON_OUT_IN_OP, NULL, NULL);
+ if(!tmp_qname)
+ {
+ return NULL;
+ }
+ op_out_in = axis2_op_create_with_qname(env, tmp_qname);
+ axutil_qname_free(tmp_qname, env);
+
+ tmp_qname = axutil_qname_create(env, AXIS2_ANON_OUT_ONLY_OP, NULL, NULL);
+ if(!tmp_qname)
+ {
+ return NULL;
+ }
+ op_out_only = axis2_op_create_with_qname(env, tmp_qname);
+ axutil_qname_free(tmp_qname, env);
+
+ tmp_qname = axutil_qname_create(env, AXIS2_ANON_ROBUST_OUT_ONLY_OP, NULL, NULL);
+ if(!tmp_qname)
+ {
+ return NULL;
+ }
+ op_robust_out_only = axis2_op_create_with_qname(env, tmp_qname);
+ axutil_qname_free(tmp_qname, env);
+
+ if(!op_out_in || !op_out_only || !op_robust_out_only)
+ {
+ AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+ if(op_out_in)
+ {
+ axis2_op_free(op_out_in, env);
+ }
+ if(op_out_only)
+ {
+ axis2_op_free(op_out_only, env);
+ }
+ if(op_robust_out_only)
+ {
+ axis2_op_free(op_robust_out_only, env);
+ }
+
+ return NULL;
+ }
+
+ axis2_op_set_msg_exchange_pattern(op_out_in, env, AXIS2_MEP_URI_OUT_IN);
+ axis2_op_set_msg_exchange_pattern(op_out_only, env, AXIS2_MEP_URI_OUT_ONLY);
+ axis2_op_set_msg_exchange_pattern(op_robust_out_only, env, AXIS2_MEP_URI_ROBUST_OUT_ONLY);
+
+ /* Setting operation phase */
+ info = axis2_conf_get_phases_info(svc_client->conf, env);
+ axis2_phases_info_set_op_phases(info, env, op_out_in);
+ axis2_phases_info_set_op_phases(info, env, op_out_only);
+ axis2_phases_info_set_op_phases(info, env, op_robust_out_only);
+ axis2_svc_add_op(svc, env, op_out_in);
+ axis2_svc_add_op(svc, env, op_out_only);
+ axis2_svc_add_op(svc, env, op_robust_out_only);
+ return svc;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axis2_svc_client_free(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ if(!svc_client)
+ {
+ return;
+ }
+
+ if(svc_client->headers)
+ {
+ axis2_svc_client_remove_all_headers(svc_client, env);
+ axutil_array_list_free(svc_client->headers, env);
+ svc_client->headers = NULL;
+ }
+
+ if(svc_client->svc && !svc_client->keep_externally_passed_ctx_and_svc)
+ {
+ axis2_svc_free(svc_client->svc, env);
+ }
+
+ if(svc_client->callback_recv)
+ {
+ AXIS2_CALLBACK_RECV_FREE(svc_client->callback_recv, env);
+ }
+
+ if(svc_client->op_client)
+ {
+ axis2_op_client_free(svc_client->op_client, env);
+ svc_client->op_client = NULL;
+ }
+
+ if(svc_client->options)
+ {
+ axis2_options_free(svc_client->options, env);
+ }
+
+ if(svc_client->listener_manager)
+ {
+ axis2_listener_manager_free(svc_client->listener_manager, env);
+ }
+
+ if(svc_client->conf_ctx && !svc_client->keep_externally_passed_ctx_and_svc)
+ {
+ axis2_conf_ctx_free(svc_client->conf_ctx, env);
+ }
+
+ if(svc_client->auth_type)
+ {
+ AXIS2_FREE(env->allocator, svc_client->auth_type);
+ }
+
+ if(svc_client->http_headers)
+ {
+ axis2_svc_client_set_http_info(svc_client, env, NULL);
+ }
+
+ AXIS2_FREE(env->allocator, svc_client);
+
+ return;
+}
+
+static axis2_bool_t
+axis2_svc_client_fill_soap_envelope(
+ const axutil_env_t * env,
+ axis2_svc_client_t * svc_client,
+ axis2_msg_ctx_t * msg_ctx,
+ const axiom_node_t * payload)
+{
+ const axis2_char_t *soap_version_uri;
+ int soap_version;
+ axiom_soap_envelope_t *envelope = NULL;
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+
+ soap_version_uri = axis2_options_get_soap_version_uri(svc_client->options, env);
+
+ if(!soap_version_uri)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find soap version uri.");
+ return AXIS2_FALSE;
+ }
+
+ if(axutil_strcmp(soap_version_uri, AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI) == 0)
+ {
+ soap_version = AXIOM_SOAP11;
+ }
+ else
+ {
+ soap_version = AXIOM_SOAP12;
+ }
+
+ envelope = axiom_soap_envelope_create_default_soap_envelope(env, soap_version);
+ if(!envelope)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot create default soap envelope.");
+ return AXIS2_FALSE;
+ }
+
+ if(svc_client->headers)
+ {
+ axiom_soap_header_t *soap_header = NULL;
+ soap_header = axiom_soap_envelope_get_header(envelope, env);
+
+ if(soap_header)
+ {
+ axiom_node_t *header_node = NULL;
+ header_node = axiom_soap_header_get_base_node(soap_header, env);
+
+ if(header_node)
+ {
+ int size = 0;
+ int i = 0;
+ size = axutil_array_list_size(svc_client->headers, env);
+ while(i < size)
+ {
+ axiom_node_t *node = NULL;
+ node = axutil_array_list_remove(svc_client->headers, env, 0);
+ /* This removes and retrieves data. The order of the
+ * removal is chosen such that the headers are appended
+ * in the order they were added.
+ */
+ size--;
+ if(node)
+ {
+ axiom_node_add_child(header_node, env, node);
+ }
+ }
+ }
+ }
+ }
+
+ if(payload)
+ {
+ axiom_soap_body_t *soap_body = NULL;
+ soap_body = axiom_soap_envelope_get_body(envelope, env);
+ if(soap_body)
+ {
+ axiom_node_t *node = NULL;
+ node = axiom_soap_body_get_base_node(soap_body, env);
+ if(node)
+ {
+ axiom_node_add_child(node, env, (axiom_node_t *)payload);
+ }
+ }
+ }
+
+ axis2_msg_ctx_set_soap_envelope(msg_ctx, env, envelope);
+
+ return AXIS2_TRUE;
+}
+
+AXIS2_EXTERN axis2_op_client_t *AXIS2_CALL
+axis2_svc_client_get_op_client(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+ return svc_client->op_client;
+}
+
+AXIS2_EXTERN axiom_soap_envelope_t *AXIS2_CALL
+axis2_svc_client_get_last_response_soap_envelope(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, NULL);
+ return svc_client->last_response_soap_envelope;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_svc_client_get_last_response_has_fault(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE);
+ return svc_client->last_response_has_fault;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_svc_client_get_http_auth_required(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE);
+ if(svc_client->auth_failed && svc_client->required_auth_is_http)
+ {
+ return AXIS2_TRUE;
+ }
+ return AXIS2_FALSE;
+}
+
+AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+axis2_svc_client_get_proxy_auth_required(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FALSE);
+ if(svc_client->auth_failed && !svc_client->required_auth_is_http)
+ {
+ return AXIS2_TRUE;
+ }
+ return AXIS2_FALSE;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axis2_svc_client_get_auth_type(
+ const axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ return svc_client->auth_type;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_set_proxy_with_auth(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ axis2_char_t * proxy_host,
+ axis2_char_t * proxy_port,
+ axis2_char_t * username,
+ axis2_char_t * password)
+{
+ axis2_transport_out_desc_t *trans_desc = NULL;
+ axis2_conf_t *conf = NULL;
+ axutil_param_container_t *param_container;
+ axutil_param_t *param;
+ axis2_char_t *proxy = AXIS2_HTTP_PROXY_API;
+ axutil_hash_t *attribute;
+ axutil_generic_obj_t *host_obj = NULL;
+ axutil_generic_obj_t *port_obj = NULL;
+ axutil_generic_obj_t *username_obj = NULL;
+ axutil_generic_obj_t *password_obj = NULL;
+ axiom_attribute_t *host_attr = NULL;
+ axiom_attribute_t *port_attr = NULL;
+ axiom_attribute_t *username_attr = NULL;
+ axiom_attribute_t *password_attr = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, proxy_host, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, proxy_port, AXIS2_FAILURE);
+
+ if(svc_client->conf)
+ {
+ conf = svc_client->conf;
+ trans_desc = axis2_conf_get_transport_out(conf, env, AXIS2_TRANSPORT_ENUM_HTTP);
+ if(!trans_desc)
+ {
+ return AXIS2_FAILURE;
+ }
+ param_container = axis2_transport_out_desc_param_container(trans_desc, env);
+ param = axutil_param_create(env, proxy, (void *)NULL);
+
+ if(!param)
+ {
+ return AXIS2_FAILURE;
+ }
+
+ attribute = axutil_hash_make(env);
+ host_obj = axutil_generic_obj_create(env);
+ port_obj = axutil_generic_obj_create(env);
+ host_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_HOST, proxy_host, NULL);
+ port_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_PORT, proxy_port, NULL);
+ axutil_generic_obj_set_value(host_obj, env, host_attr);
+ axutil_generic_obj_set_free_func(host_obj, env, axiom_attribute_free_void_arg);
+ axutil_generic_obj_set_value(port_obj, env, port_attr);
+ axutil_generic_obj_set_free_func(port_obj, env, axiom_attribute_free_void_arg);
+
+ axutil_hash_set(attribute, AXIS2_HTTP_PROXY_HOST, AXIS2_HASH_KEY_STRING, host_obj);
+ axutil_hash_set(attribute, AXIS2_HTTP_PROXY_PORT, AXIS2_HASH_KEY_STRING, port_obj);
+ if(username && password)
+ {
+ username_obj = axutil_generic_obj_create(env);
+ password_obj = axutil_generic_obj_create(env);
+ username_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_USERNAME, username, NULL);
+ password_attr = axiom_attribute_create(env, AXIS2_HTTP_PROXY_PASSWORD, password, NULL);
+ axutil_generic_obj_set_value(username_obj, env, username_attr);
+ axutil_generic_obj_set_value(password_obj, env, password_attr);
+ axutil_generic_obj_set_free_func(username_obj, env, axiom_attribute_free_void_arg);
+ axutil_generic_obj_set_free_func(password_obj, env, axiom_attribute_free_void_arg);
+ axutil_hash_set(attribute, AXIS2_HTTP_PROXY_USERNAME, AXIS2_HASH_KEY_STRING,
+ username_obj);
+ axutil_hash_set(attribute, AXIS2_HTTP_PROXY_PASSWORD, AXIS2_HASH_KEY_STRING,
+ password_obj);
+ }
+ axutil_param_set_attributes(param, env, attribute);
+ axutil_param_container_add_param(param_container, env, param);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_set_proxy(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ axis2_char_t * proxy_host,
+ axis2_char_t * proxy_port)
+{
+ return axis2_svc_client_set_proxy_with_auth(svc_client, env, proxy_host, proxy_port, NULL, NULL);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_set_policy_from_om(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ axiom_node_t * root_node)
+{
+ neethi_policy_t *neethi_policy = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+ neethi_policy = neethi_util_create_policy_from_om(env, root_node);
+
+ if(neethi_policy)
+ {
+ return axis2_svc_client_set_policy(svc_client, env, neethi_policy);
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_set_policy(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ neethi_policy_t * policy)
+{
+
+ axis2_svc_t *svc = NULL;
+ axis2_desc_t *desc = NULL;
+ axis2_policy_include_t *policy_include = NULL;
+
+ AXIS2_PARAM_CHECK(env->error, svc_client, AXIS2_FAILURE);
+ AXIS2_PARAM_CHECK(env->error, policy, AXIS2_FAILURE);
+
+ svc = axis2_svc_client_get_svc(svc_client, env);
+
+ if(!svc)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Cannot find service of service client. Cannot set policy.");
+ return AXIS2_FAILURE;
+ }
+
+ desc = axis2_svc_get_base(svc, env);
+ if(!desc)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "Cannot find service description of service client. Cannot set policy.");
+ return AXIS2_FAILURE;
+ }
+
+ policy_include = axis2_desc_get_policy_include(desc, env);
+ if(!policy_include)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find policy include. Cannot set policy.");
+ return AXIS2_FAILURE;
+ }
+
+ axis2_policy_include_add_policy_element(policy_include, env, AXIS2_SERVICE_POLICY, policy);
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axis2_svc_client_get_http_headers(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ return svc_client->http_headers;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_svc_client_get_http_status_code(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ return svc_client->http_status_code;
+}
+
+void
+axis2_svc_client_set_http_info(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env,
+ axis2_msg_ctx_t * msg_ctx)
+{
+ axis2_transport_in_desc_t *transport_in = NULL;
+ axutil_param_t *expose_headers_param = NULL;
+ axis2_bool_t expose_headers = AXIS2_FALSE;
+
+ if(msg_ctx)
+ {
+ transport_in = axis2_msg_ctx_get_transport_in_desc(msg_ctx, env);
+ if(transport_in)
+ {
+ expose_headers_param = axutil_param_container_get_param(
+ axis2_transport_in_desc_param_container(transport_in, env), env,
+ AXIS2_EXPOSE_HEADERS);
+ }
+ if(expose_headers_param)
+ {
+ axis2_char_t *expose_headers_value = NULL;
+ expose_headers_value = axutil_param_get_value(expose_headers_param, env);
+ if(expose_headers_value && 0 == axutil_strcasecmp(expose_headers_value,
+ AXIS2_VALUE_TRUE))
+ {
+ expose_headers = AXIS2_TRUE;
+ }
+ }
+ }
+ if(expose_headers)
+ {
+ if(svc_client->http_headers == axis2_msg_ctx_get_http_output_headers(msg_ctx, env))
+ {
+ svc_client->http_status_code = axis2_msg_ctx_get_status_code(msg_ctx, env);
+ return;
+ }
+ }
+
+ if(svc_client->http_headers)
+ {
+ axis2_http_header_t *header = NULL;
+ while(axutil_array_list_size(svc_client->http_headers, env))
+ {
+ header = (axis2_http_header_t *)axutil_array_list_remove(svc_client->http_headers, env,
+ 0);
+ if(header)
+ {
+ axis2_http_header_free(header, env);
+ }
+ }
+ axutil_array_list_free(svc_client->http_headers, env);
+ svc_client->http_headers = NULL;
+ }
+ svc_client->http_status_code = 0;
+
+ if(msg_ctx)
+ {
+ if(expose_headers)
+ {
+ svc_client->http_headers = axis2_msg_ctx_extract_http_output_headers(msg_ctx, env);
+ }
+ svc_client->http_status_code = axis2_msg_ctx_get_status_code(msg_ctx, env);
+ }
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axis2_svc_client_close(
+ axis2_svc_client_t * svc_client,
+ const axutil_env_t * env)
+{
+ axis2_status_t status = AXIS2_FAILURE;
+ axutil_property_t *property = NULL;
+ axis2_endpoint_ref_t *replyto = NULL;
+
+ property = axutil_property_create_with_args(env, 0, 0, 0, AXIS2_VALUE_TRUE);
+ axis2_options_set_property(svc_client->options, env, AXIS2_SVC_CLIENT_CLOSED, property);
+ replyto = axis2_options_get_reply_to(svc_client->options, env);
+ if(replyto)
+ {
+ axiom_node_t *reply = NULL;
+
+ reply = axis2_svc_client_send_receive(svc_client, env, NULL);
+ if(reply)
+ {
+ status = AXIS2_SUCCESS;
+ }
+ }
+ else
+ {
+ status = axis2_svc_client_send_robust(svc_client, env, NULL);
+ }
+
+ return status;
+}
+