blob: 936f5ef32397431dc60e1f3122edd8425c272164 [file] [log] [blame]
/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sandesha2_msg_init.h>
#include <sandesha2_seq_property_mgr.h>
#include <sandesha2_permanent_seq_property_mgr.h>
#include <sandesha2_spec_specific_consts.h>
#include <sandesha2_utils.h>
#include <sandesha2_ack_mgr.h>
#include <sandesha2_constants.h>
#include <sandesha2_msg_ctx.h>
#include <sandesha2_acks_to.h>
#include <sandesha2_address.h>
#include <sandesha2_seq_offer.h>
#include <sandesha2_accept.h>
#include <sandesha2_create_seq.h>
#include <sandesha2_create_seq_res.h>
#include <sandesha2_seq.h>
#include <sandesha2_terminate_seq.h>
#include <sandesha2_terminate_seq_res.h>
#include <sandesha2_ack_requested.h>
#include <sandesha2_close_seq.h>
#include <sandesha2_close_seq_res.h>
#include <sandesha2_make_connection.h>
#include <sandesha2_msg_pending.h>
#include <sandesha2_rm_elements.h>
#include <sandesha2_client_constants.h>
#include <axis2_conf_ctx.h>
#include <axis2_ctx.h>
#include <axis2_msg_ctx.h>
#include <axutil_property.h>
#include <axutil_log.h>
#include <axutil_uuid_gen.h>
#include <axis2_addr.h>
#include <axiom_soap_envelope.h>
#include <axiom_soap_body.h>
#include <axiom_node.h>
/**
* Adds the message parts to the sandesha2_msg_ctx.
*
* @param msg_ctx
* @param rm_msg_ctx
*/
static axis2_status_t
populate_rm_msg_ctx(
const axutil_env_t *env,
axis2_msg_ctx_t *msg_ctx,
sandesha2_msg_ctx_t *rm_msg_ctx);
/**
* This is used to validate the message.
* Also set an Message type. Possible types are given in the sandesha2_constants
*
* @param rm_msg_ctx
* @return
*/
static axis2_bool_t validate_msg(
const axutil_env_t *env,
sandesha2_msg_ctx_t *rm_msg_ctx);
static void add_op_if_null(
const axutil_env_t *env,
axis2_msg_ctx_t *msg_ctx);
/**
* Called to create a rm_msg_ctx out of an message context. Finds out things
* like rm version and message type as well.
*
* @param ctx
* @param assumed_rm_ns
* this is used for validation (to find out weather the rm_ns of the current
* message is equal to the regietered rm_ns of the sequence).
* If NULL validation will not happen.
*
* @return
*/
sandesha2_msg_ctx_t *
sandesha2_msg_init_init_msg(
const axutil_env_t *env,
axis2_msg_ctx_t *msg_ctx)
{
sandesha2_msg_ctx_t *rm_msg_ctx = NULL;
rm_msg_ctx = sandesha2_msg_ctx_create(env, msg_ctx);
populate_rm_msg_ctx(env, msg_ctx, rm_msg_ctx);
validate_msg(env, rm_msg_ctx);
return rm_msg_ctx;
}
static axis2_status_t
populate_rm_msg_ctx(
const axutil_env_t *env,
axis2_msg_ctx_t *msg_ctx,
sandesha2_msg_ctx_t *rm_msg_ctx)
{
axis2_char_t *addressing_ns = NULL;
axis2_char_t *rm_ns = NULL;
axis2_char_t *action = NULL;
axutil_property_t *prop = NULL;
axis2_ctx_t *ctx = NULL;
axiom_soap_envelope_t *envelope = NULL;
sandesha2_rm_elements_t *rm_elements = NULL;
sandesha2_create_seq_t *create_seq = NULL;
sandesha2_create_seq_res_t *create_seq_res = NULL;
sandesha2_seq_t *seq = NULL;
sandesha2_seq_ack_t *seq_ack = NULL;
sandesha2_terminate_seq_t *terminate_seq = NULL;
sandesha2_terminate_seq_res_t *terminate_seq_res = NULL;
sandesha2_ack_requested_t *ack_request = NULL;
sandesha2_close_seq_t *close_seq = NULL;
sandesha2_close_seq_res_t *close_seq_res = NULL;
sandesha2_make_connection_t *make_conn = NULL;
sandesha2_msg_pending_t *msg_pending = NULL;
/* If client side and the addressing version is not set.
* Assuming the default addressing version.
*/
AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "[sandesha2]Entry:populate_rm_msg_ctx");
if(msg_ctx)
{
ctx = axis2_msg_ctx_get_base(msg_ctx, env);
if(ctx)
{
prop = axis2_ctx_get_property(ctx, env, AXIS2_WSA_VERSION);
}
}
if(prop)
{
addressing_ns = axutil_property_get_value(prop, env);
}
if(!addressing_ns && !axis2_msg_ctx_get_server_side(msg_ctx, env))
{
addressing_ns = AXIS2_WSA_NAMESPACE;
}
rm_elements = sandesha2_rm_elements_create(env);
envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env);
action = (axis2_char_t*)axis2_msg_ctx_get_wsa_action(msg_ctx, env);
sandesha2_rm_elements_from_soap_envelope(rm_elements, env, envelope, action);
create_seq = sandesha2_rm_elements_get_create_seq(rm_elements, env);
if(create_seq)
{
sandesha2_msg_ctx_set_create_seq(rm_msg_ctx, env, create_seq);
rm_ns = sandesha2_create_seq_get_namespace_value(create_seq, env);
}
create_seq_res = sandesha2_rm_elements_get_create_seq_res(rm_elements, env);
if(create_seq_res)
{
sandesha2_msg_ctx_set_create_seq_res(rm_msg_ctx, env, create_seq_res);
rm_ns = sandesha2_create_seq_res_get_namespace_value(create_seq_res, env);
/*add_op_if_null(env, msg_ctx);*/
}
seq = sandesha2_rm_elements_get_seq(rm_elements, env);
if(seq)
{
sandesha2_msg_ctx_set_sequence(rm_msg_ctx, env, seq);
rm_ns = sandesha2_seq_get_namespace_value(
seq, env);
}
seq_ack = sandesha2_rm_elements_get_seq_ack(rm_elements, env);
if(seq_ack)
{
sandesha2_msg_ctx_set_seq_ack(rm_msg_ctx, env, seq_ack);
rm_ns = sandesha2_seq_ack_get_namespace_value(
seq_ack, env);
/*add_op_if_null(env, msg_ctx);*/
}
terminate_seq = sandesha2_rm_elements_get_terminate_seq(rm_elements, env);
if(terminate_seq)
{
sandesha2_msg_ctx_set_terminate_seq(rm_msg_ctx, env, terminate_seq);
rm_ns = sandesha2_terminate_seq_get_namespace_value(
terminate_seq, env);
/*add_op_if_null(env, msg_ctx);*/
}
terminate_seq_res = sandesha2_rm_elements_get_terminate_seq_res(rm_elements,
env);
if(terminate_seq_res)
{
sandesha2_msg_ctx_set_terminate_seq_res(rm_msg_ctx, env,
terminate_seq_res);
rm_ns = sandesha2_terminate_seq_res_get_namespace_value(
terminate_seq_res, env);
/*add_op_if_null(env, msg_ctx);*/
}
ack_request = sandesha2_rm_elements_get_ack_requested(rm_elements, env);
if(ack_request)
{
sandesha2_msg_ctx_set_ack_requested(rm_msg_ctx, env,
ack_request);
rm_ns = sandesha2_ack_requested_get_namespace_value(
ack_request, env);
}
close_seq = sandesha2_rm_elements_get_close_seq(rm_elements, env);
if(close_seq)
{
sandesha2_msg_ctx_set_close_seq(rm_msg_ctx, env,
close_seq);
rm_ns = sandesha2_close_seq_get_namespace_value(
close_seq, env);
add_op_if_null(env, msg_ctx);
}
close_seq_res = sandesha2_rm_elements_get_close_seq_res(rm_elements, env);
if(close_seq_res)
{
sandesha2_msg_ctx_set_close_seq_res(rm_msg_ctx, env,
close_seq_res);
rm_ns = sandesha2_close_seq_res_get_namespace_value(
close_seq_res, env);
/*add_op_if_null(env, msg_ctx);*/
}
make_conn = sandesha2_rm_elements_get_make_connection(rm_elements, env);
if(make_conn)
{
sandesha2_msg_ctx_set_make_connection(rm_msg_ctx, env, make_conn);
rm_ns = sandesha2_make_connection_get_namespace_value(make_conn, env);
/*add_op_if_null(env, msg_ctx);*/
}
msg_pending = sandesha2_rm_elements_get_msg_pending(rm_elements, env);
if(msg_pending)
{
sandesha2_msg_ctx_set_msg_pending(rm_msg_ctx, env, msg_pending);
rm_ns = sandesha2_msg_pending_get_namespace_value(msg_pending, env);
/*add_op_if_null(env, msg_ctx);*/
}
sandesha2_msg_ctx_set_rm_ns_val(rm_msg_ctx, env, rm_ns);
if(addressing_ns)
{
sandesha2_msg_ctx_set_addr_ns_val(rm_msg_ctx, env, addressing_ns);
}
if(rm_elements)
{
sandesha2_rm_elements_free(rm_elements, env);
}
AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "[sandesha2]Exit:populate_rm_msg_ctx");
return AXIS2_SUCCESS;
}
static axis2_bool_t validate_msg(
const axutil_env_t *env,
sandesha2_msg_ctx_t *rm_msg_ctx)
{
axis2_conf_ctx_t *conf_ctx = NULL;
axis2_msg_ctx_t *temp_msg_ctx = NULL;
axis2_char_t *seq_id = NULL;
axis2_char_t *rm_ns = NULL;
axis2_char_t *prop_key = NULL;
sandesha2_seq_property_mgr_t *seq_prop_mgr = NULL;
sandesha2_create_seq_t *create_seq = NULL;
sandesha2_create_seq_res_t *create_seq_res = NULL;
sandesha2_terminate_seq_t *terminate_seq = NULL;
sandesha2_terminate_seq_res_t *terminate_seq_res = NULL;
sandesha2_seq_ack_t *seq_ack = NULL;
sandesha2_seq_t *seq = NULL;
sandesha2_ack_requested_t *ack_request = NULL;
sandesha2_close_seq_t *close_seq = NULL;
sandesha2_close_seq_res_t *close_seq_res = NULL;
sandesha2_make_connection_t *make_conn = NULL;
int temp_flow = -1;
axis2_char_t *dbname = NULL;
AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI,
"[sandesha2]Entry:validate_msg");
temp_msg_ctx = sandesha2_msg_ctx_get_msg_ctx(rm_msg_ctx, env);
conf_ctx = axis2_msg_ctx_get_conf_ctx(temp_msg_ctx, env);
dbname = sandesha2_util_get_dbname(env, conf_ctx);
seq_prop_mgr = sandesha2_permanent_seq_property_mgr_create(env, dbname);
create_seq = sandesha2_msg_ctx_get_create_seq(rm_msg_ctx, env);
create_seq_res = sandesha2_msg_ctx_get_create_seq_res(rm_msg_ctx, env);
terminate_seq = sandesha2_msg_ctx_get_terminate_seq(rm_msg_ctx, env);
terminate_seq_res = sandesha2_msg_ctx_get_terminate_seq_res(rm_msg_ctx, env);
seq_ack = sandesha2_msg_ctx_get_seq_ack(rm_msg_ctx, env);
seq = sandesha2_msg_ctx_get_sequence(rm_msg_ctx, env);
ack_request = sandesha2_msg_ctx_get_ack_requested(rm_msg_ctx, env);
close_seq = sandesha2_msg_ctx_get_close_seq(rm_msg_ctx, env);
close_seq_res = sandesha2_msg_ctx_get_close_seq_res(rm_msg_ctx, env);
make_conn = sandesha2_msg_ctx_get_make_connection(rm_msg_ctx, env);
/* Setting message type */
if(create_seq)
{
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_CREATE_SEQ);
}
else if(create_seq_res)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_CREATE_SEQ_RESPONSE);
idf = sandesha2_create_seq_res_get_identifier(create_seq_res, env);
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(terminate_seq)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_TERMINATE_SEQ);
idf = sandesha2_terminate_seq_get_identifier(terminate_seq, env);
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(terminate_seq_res)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_TERMINATE_SEQ_RESPONSE);
idf = sandesha2_terminate_seq_res_get_identifier(terminate_seq_res, env);
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(seq)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_APPLICATION);
idf = sandesha2_seq_get_identifier(seq, env);
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(seq_ack)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_ACK);
idf = sandesha2_seq_ack_get_identifier(seq_ack, env);
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(ack_request)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_ACK_REQUEST);
idf = sandesha2_ack_requested_get_identifier(ack_request, env);
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(close_seq)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_CLOSE_SEQ);
idf = sandesha2_close_seq_get_identifier(close_seq, env);
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(close_seq_res)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env,
SANDESHA2_MSG_TYPE_CLOSE_SEQ_RESPONSE);
idf = sandesha2_close_seq_res_get_identifier(close_seq_res, env);
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(make_conn)
{
sandesha2_identifier_t *idf = NULL;
sandesha2_mc_address_t *address = NULL;
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env, SANDESHA2_MSG_TYPE_MAKE_CONNECTION_MSG);
idf = sandesha2_make_connection_get_identifier(make_conn, env);
address = sandesha2_make_connection_get_address(make_conn, env);
if(idf)
{
seq_id = sandesha2_identifier_get_identifier(idf, env);
}
else if(address)
{
/* TODO Get seq_id based on the anonymous address */
}
else
{
AXIS2_ERROR_SET(env->error,
SANDESHA2_ERROR_INVALID_MAKE_CONNECTION_MSG, AXIS2_FAILURE);
AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
"[sandesha2]Invalid MakeConnection message. Either Address "\
"or Identifier must be present");
if(seq_prop_mgr)
sandesha2_seq_property_mgr_free(seq_prop_mgr, env);
return AXIS2_FALSE;
}
}
else
{
sandesha2_msg_ctx_set_msg_type(rm_msg_ctx, env, SANDESHA2_MSG_TYPE_UNKNOWN);
}
temp_flow = axis2_msg_ctx_get_flow(temp_msg_ctx, env);
if(temp_flow == AXIS2_IN_FLOW)
{
prop_key = axutil_strdup(env, seq_id);
}
else
{
sandesha2_seq_property_bean_t *internal_seq_id_bean = NULL;
internal_seq_id_bean = sandesha2_seq_property_mgr_retrieve(seq_prop_mgr,
env, seq_id, SANDESHA2_SEQUENCE_PROPERTY_RMS_INTERNAL_SEQ_ID);
if(internal_seq_id_bean)
{
prop_key = axutil_strdup(env, sandesha2_seq_property_bean_get_value(
internal_seq_id_bean, env));
sandesha2_seq_property_bean_free(internal_seq_id_bean, env);
}
}
rm_ns = sandesha2_msg_ctx_get_rm_ns_val(rm_msg_ctx, env);
if(seq_id)
{
axis2_char_t *spec_version = NULL;
axis2_char_t *seq_rm_ns = NULL;
spec_version = sandesha2_utils_get_rm_version(env, prop_key,
seq_prop_mgr);
if(prop_key)
{
AXIS2_FREE(env->allocator, prop_key);
prop_key = NULL;
}
if(spec_version)
{
seq_rm_ns = sandesha2_spec_specific_consts_get_rm_ns_val(env,
spec_version);
}
if(spec_version)
AXIS2_FREE(env->allocator, spec_version);
if(seq_rm_ns && rm_ns)
{
if(0 != axutil_strcmp(seq_rm_ns, rm_ns))
{
AXIS2_ERROR_SET(env->error,
SANDESHA2_ERROR_RM_NS_VALUE_IS_DIFFERENT_FROM_REGISTERED_NS_FOR_SEQ,
AXIS2_FAILURE);
if(seq_prop_mgr)
sandesha2_seq_property_mgr_free(seq_prop_mgr, env);
return AXIS2_FALSE;
}
}
}
if(prop_key)
AXIS2_FREE(env->allocator, prop_key);
if(seq_prop_mgr)
sandesha2_seq_property_mgr_free(seq_prop_mgr, env);
AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI,
"[sandesha2]Exit:validate_msg");
return AXIS2_TRUE;
}
/**
* When a response comes back in MakeConnection back channel it may need an
* operation added to the message context.
*/
static void add_op_if_null(
const axutil_env_t *env,
axis2_msg_ctx_t *msg_ctx)
{
axis2_op_t *op = NULL;
op = axis2_msg_ctx_get_op(msg_ctx, env);
if(!op)
{
axis2_svc_t *svc = NULL;
axutil_qname_t *tmp_qname = NULL;
AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
"[sandesha2]Message context operation is NULL. So adding default operation");
tmp_qname = axutil_qname_create(env, "__OPERATION_OUT_IN__", NULL, NULL);
if (!tmp_qname)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
return;
}
svc = axis2_msg_ctx_get_svc(msg_ctx, env);
if(svc)
{
op = axis2_svc_get_op_with_qname(svc, env, tmp_qname);
}
if(!op)
{
axis2_status_t status = AXIS2_FAILURE;
axis2_conf_ctx_t *conf_ctx = NULL;
axis2_conf_t *conf = NULL;
axis2_phases_info_t *info = NULL;
op = axis2_op_create_with_qname(env, tmp_qname);
axis2_op_set_msg_exchange_pattern(op, env, AXIS2_MEP_URI_OUT_IN);
conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
conf = axis2_conf_ctx_get_conf(conf_ctx, env);
info = axis2_conf_get_phases_info(conf, env);
axis2_phases_info_set_op_phases(info, env, op);
status = axis2_svc_add_op(svc, env, op);
if(AXIS2_SUCCESS == status)
{
status = axis2_msg_ctx_set_op(msg_ctx, env, op);
if(AXIS2_SUCCESS != status)
{
axis2_op_free(op, env);
op = NULL;
}
}
else
{
axis2_op_free(op, env);
op = NULL;
}
}
if(tmp_qname)
{
axutil_qname_free(tmp_qname, env);
}
axis2_msg_ctx_set_op(msg_ctx, env, op);
}
}