AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_engine_receive_fault( axis2_engine_t * engine, const axutil_env_t * env, axis2_msg_ctx_t * msg_ctx) { axis2_op_ctx_t *op_ctx = NULL; AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_receive_fault"); AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); if(!op_ctx) { /* If we do not have an op context that means this may be an incoming dual channel response. So try to dispatch the service */ axis2_conf_ctx_t *conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); if(conf_ctx) { axis2_conf_t *conf = axis2_conf_ctx_get_conf(conf_ctx, env); if(conf) { axutil_array_list_t *phases = axis2_conf_get_in_phases_upto_and_including_post_dispatch(conf, env); if(phases) { if(axis2_msg_ctx_is_paused(msg_ctx, env)) { axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); } else { axis2_engine_invoke_phases(engine, env, phases, msg_ctx); } } } } } op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); /* Find and execute the fault in flow handlers */ if(op_ctx) { axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); axutil_array_list_t *phases = axis2_op_get_fault_in_flow(op, env); if(axis2_msg_ctx_is_paused(msg_ctx, env)) { axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); } else { axis2_engine_invoke_phases(engine, env, phases, msg_ctx); } } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_engine_receive_fault"); return AXIS2_SUCCESS; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_engine_invoke_phases( axis2_engine_t * engine, const axutil_env_t * env, axutil_array_list_t * phases, axis2_msg_ctx_t * msg_ctx) { int i = 0; int count = 0; axis2_status_t status = AXIS2_SUCCESS; AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_invoke_phases"); AXIS2_PARAM_CHECK(env->error, phases, AXIS2_FAILURE); AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); if(phases) count = axutil_array_list_size(phases, env); for(i = 0; (i < count && !(axis2_msg_ctx_is_paused(msg_ctx, env))); i++) { axis2_phase_t *phase = (axis2_phase_t *)axutil_array_list_get(phases, env, i); status = axis2_phase_invoke(phase, env, msg_ctx); if(status != AXIS2_SUCCESS) { const axis2_char_t *phase_name = axis2_phase_get_name(phase, env); AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invoking phase %s failed", phase_name); return status; } } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "End:axis2_engine_invoke_phases"); return AXIS2_SUCCESS; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_engine_resume_receive( axis2_engine_t * engine, const axutil_env_t * env, axis2_msg_ctx_t * msg_ctx) { axis2_status_t status = AXIS2_FAILURE; axis2_conf_ctx_t *conf_ctx = NULL; axis2_conf_t *conf = NULL; axutil_array_list_t *phases = NULL; AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_resume_receive"); /* Find and invoke the phases */ conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); conf = axis2_conf_ctx_get_conf(conf_ctx, env); phases = axis2_conf_get_in_phases_upto_and_including_post_dispatch(conf, env); axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); /* Invoking the message receiver */ if(axis2_msg_ctx_get_server_side(msg_ctx, env) && !axis2_msg_ctx_is_paused(msg_ctx, env)) { /* Invoke the message receivers */ axis2_op_ctx_t *op_ctx = NULL; status = axis2_engine_check_must_understand_headers(env, msg_ctx); if(status != AXIS2_SUCCESS) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Checking for must understand headers failed"); return status; } op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); if(op_ctx) { axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); if(op) { axis2_msg_recv_t *receiver = NULL; receiver = axis2_op_get_msg_recv(op, env); if(!receiver) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Message receiver not set in operation description"); return AXIS2_FAILURE; } status = axis2_msg_recv_receive(receiver, env, msg_ctx, axis2_msg_recv_get_derived( receiver, env)); } } } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_engine_resume_receive"); return status; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_engine_resume_invocation_phases( axis2_engine_t * engine, const axutil_env_t * env, axutil_array_list_t * phases, axis2_msg_ctx_t * msg_ctx) { int i = 0; int count = 0; axis2_bool_t found_match = AXIS2_FALSE; AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_resume_invocation_phases"); AXIS2_PARAM_CHECK(env->error, phases, AXIS2_FAILURE); AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); axis2_msg_ctx_set_paused(msg_ctx, env, AXIS2_FALSE); count = axutil_array_list_size(phases, env); for(i = 0; i < count && !(axis2_msg_ctx_is_paused(msg_ctx, env)); i++) { axis2_phase_t *phase = (axis2_phase_t *)axutil_array_list_get(phases, env, i); const axis2_char_t *phase_name = axis2_phase_get_name(phase, env); const axis2_char_t *paused_phase_name = axis2_msg_ctx_get_paused_phase_name(msg_ctx, env); /* Skip invoking handlers until we find the paused phase */ if(phase_name && paused_phase_name && 0 == axutil_strcmp(phase_name, paused_phase_name)) { int paused_handler_i = -1; found_match = AXIS2_TRUE; paused_handler_i = axis2_msg_ctx_get_current_handler_index(msg_ctx, env); /* Invoke the paused handler and rest of the handlers of the paused * phase */ axis2_phase_invoke_start_from_handler(phase, env, paused_handler_i, msg_ctx); } else { /* Now we have found the paused phase and invoked the rest of the * handlers of that phase, invoke all the phases after that */ if(found_match) { axis2_phase_invoke(phase, env, msg_ctx); } } } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "End:axis2_engine_resume_invocation_phases"); return AXIS2_SUCCESS; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_engine_resume_send( axis2_engine_t * engine, const axutil_env_t * env, axis2_msg_ctx_t * msg_ctx) { axis2_op_ctx_t *op_ctx = NULL; axutil_array_list_t *phases = NULL; axis2_status_t status = AXIS2_FAILURE; AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_resume_send"); /* Invoke the phases */ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); if(op_ctx) { axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); if(op) { phases = axis2_op_get_out_flow(op, env); } } axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); /* Invoking transport sender */ if(!axis2_msg_ctx_is_paused(msg_ctx, env)) { /* Write the message to the wire */ axis2_transport_out_desc_t *transport_out = NULL; axis2_transport_sender_t *sender = NULL; transport_out = axis2_msg_ctx_get_transport_out_desc(msg_ctx, env); if(transport_out) { sender = axis2_transport_out_desc_get_sender(transport_out, env); if(sender) { status = AXIS2_TRANSPORT_SENDER_INVOKE(sender, env, msg_ctx); } } } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_engine_resume_send"); return status; }
static axis2_status_t AXIS2_CALL axis2_msg_recv_receive_impl( axis2_msg_recv_t * msg_recv, const axutil_env_t * env, axis2_msg_ctx_t * msg_ctx, void *callback_recv_param) { axis2_msg_ctx_t *out_msg_ctx = NULL; axis2_engine_t *engine = NULL; axis2_conf_ctx_t *conf_ctx = NULL; axis2_op_ctx_t *op_ctx = NULL; axis2_svc_ctx_t *svc_ctx = NULL; axis2_status_t status = AXIS2_FAILURE; AXIS2_ENV_CHECK(env, AXIS2_FAILURE); AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "[axis2]Entry:axis2_msg_recv_receive_impl"); out_msg_ctx = axis2_core_utils_create_out_msg_ctx(env, msg_ctx); if(!out_msg_ctx) { return AXIS2_FAILURE; } op_ctx = axis2_msg_ctx_get_op_ctx(out_msg_ctx, env); if(!op_ctx) { axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx); axis2_msg_ctx_free(out_msg_ctx, env); return AXIS2_FAILURE; } status = axis2_op_ctx_add_msg_ctx(op_ctx, env, out_msg_ctx); if(!status) { axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx); axis2_msg_ctx_free(out_msg_ctx, env); return status; } status = axis2_op_ctx_add_msg_ctx(op_ctx, env, msg_ctx); if(!status) { return status; } status = axis2_msg_recv_invoke_business_logic(msg_recv, env, msg_ctx, out_msg_ctx); if(AXIS2_SUCCESS != status) { axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx); axis2_msg_ctx_free(out_msg_ctx, env); return status; } svc_ctx = axis2_op_ctx_get_parent(op_ctx, env); conf_ctx = axis2_svc_ctx_get_conf_ctx(svc_ctx, env); engine = axis2_engine_create(env, conf_ctx); if(!engine) { axis2_msg_ctx_free(out_msg_ctx, env); return AXIS2_FAILURE; } if(axis2_msg_ctx_get_soap_envelope(out_msg_ctx, env)) { axiom_soap_envelope_t *soap_envelope = axis2_msg_ctx_get_soap_envelope(out_msg_ctx, env); if(soap_envelope) { axiom_soap_body_t *body = axiom_soap_envelope_get_body(soap_envelope, env); if(body) { /* in case of a SOAP fault, we got to return failure so that transport gets to know that it should send 500 */ if(axiom_soap_body_has_fault(body, env)) { status = AXIS2_FAILURE; axis2_msg_ctx_set_fault_soap_envelope(msg_ctx, env, soap_envelope); axis2_msg_ctx_set_soap_envelope(out_msg_ctx, env, NULL); } else { /* if it is two way and not a fault then send through engine. if it is one way we do not need to do an engine send */ status = axis2_engine_send(engine, env, out_msg_ctx); } } } } axis2_engine_free(engine, env); /* Reset the out message context to avoid double freeing at http worker. For example if this is * not done here both in and out message context will try to free the transport out stream * which will result in memory corruption. */ if(!axis2_msg_ctx_is_paused(out_msg_ctx, env) && !axis2_msg_ctx_is_keep_alive(out_msg_ctx, env)) { axis2_core_utils_reset_out_msg_ctx(env, out_msg_ctx); } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "[axis2]Exit:axis2_msg_recv_receive_impl"); return status; (void)callback_recv_param; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_phase_invoke( axis2_phase_t * phase, const axutil_env_t * env, axis2_msg_ctx_t * msg_ctx) { int idx = 0, size = 0; axis2_status_t status = AXIS2_SUCCESS; AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Entry:axis2_phase_invoke"); axis2_msg_ctx_set_paused_phase_name(msg_ctx, env, phase->name); if(phase->first_handler) { if(axis2_msg_ctx_is_paused(msg_ctx, env)) { AXIS2_LOG_INFO(env->log, "Message context is paused in the phase %s", phase->name); return AXIS2_SUCCESS; } else { const axis2_char_t *handler_name = axutil_string_get_buffer(axis2_handler_get_name( phase->first_handler, env), env); AXIS2_LOG_INFO(env->log, "Invoke the first handler %s within the phase %s", handler_name, phase->name); status = axis2_handler_invoke(phase->first_handler, env, msg_ctx); if(!status) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Handler %s invoke failed within phase %s", handler_name, phase->name); return status; } } } /* Invoking the rest of handlers except first_handler and last_handler */ size = axutil_array_list_size(phase->handlers, env); while(idx < size) { if(axis2_msg_ctx_is_paused(msg_ctx, env)) { break; } else { axis2_handler_t *handler = (axis2_handler_t *)axutil_array_list_get(phase->handlers, env, idx); if(handler) { const axis2_char_t *handler_name = axutil_string_get_buffer(axis2_handler_get_name( handler, env), env); AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Invoke the handler %s within the phase %s", handler_name, phase->name); /* Test code. This is used when valgrind is used to find leaks in Axis2/C modules.*/ /*if(!axutil_strcmp(handler_name, "SandeshaGlobalInHandler") || !axutil_strcmp( handler_name, "SandeshaInHandler")) { AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "dam_handler_name %s. dam_phase_name %s", handler_name, phase->name); if(!axutil_strcmp(handler_name, "SandeshaGlobalInHandler")) { status = sandesha2_global_in_handler_invoke(phase->first_handler, env, msg_ctx); } if(!axutil_strcmp(handler_name, "SandeshaInHandler")) { status = sandesha2_in_handler_invoke(phase->first_handler, env, msg_ctx); } } else*/ status = axis2_handler_invoke(handler, env, msg_ctx); if(!status) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Handler %s invoke failed within phase %s", handler_name, phase->name); return status; } /* idx increment should be done after the invoke function. If the invocation failed this handler is taken care of and no need to revoke again */ idx++; axis2_msg_ctx_set_current_handler_index(msg_ctx, env, idx); } } } /* If phase last handler is there invoke it here */ if(phase->last_handler) { if(axis2_msg_ctx_is_paused(msg_ctx, env)) { AXIS2_LOG_INFO(env->log, "Message context is paused in the phase %s", phase->name); return AXIS2_SUCCESS; } else { const axis2_char_t *handler_name = axutil_string_get_buffer(axis2_handler_get_name( phase->last_handler, env), env); AXIS2_LOG_INFO(env->log, "Invoke the last handler %s within the phase %s", handler_name, phase->name); status = axis2_handler_invoke(phase->last_handler, env, msg_ctx); if(!status) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Handler %s invoke failed within phase %s", handler_name, phase->name); return status; } } } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_phase_invoke"); return AXIS2_SUCCESS; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_engine_send( axis2_engine_t * engine, const axutil_env_t * env, axis2_msg_ctx_t * msg_ctx) { axis2_status_t status = AXIS2_SUCCESS; axis2_op_ctx_t *op_ctx = NULL; axutil_array_list_t *phases = NULL; axis2_conf_ctx_t *conf_ctx = NULL; axis2_conf_t *conf = NULL; AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "axis2_engine_send start"); AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); /* Find and invoke the phases */ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); if(op_ctx) { axis2_op_t *op = axis2_op_ctx_get_op(op_ctx, env); if(op) { phases = axis2_op_get_out_flow(op, env); } } if(axis2_msg_ctx_is_paused(msg_ctx, env)) { /* Message has paused, so rerun it from the position it stopped. The handler which paused the message will be the first one to resume invocation */ status = axis2_engine_resume_invocation_phases(engine, env, phases, msg_ctx); if(status != AXIS2_SUCCESS) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Resuming invocation of phases failed"); return status; } conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); if(conf_ctx) { conf = axis2_conf_ctx_get_conf(conf_ctx, env); if(conf) { axutil_array_list_t *global_out_phase = axis2_conf_get_out_phases(conf, env); if(global_out_phase) { axis2_engine_invoke_phases(engine, env, global_out_phase, msg_ctx); } } } } else { status = axis2_engine_invoke_phases(engine, env, phases, msg_ctx); if(status != AXIS2_SUCCESS) { return status; } conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); if(conf_ctx) { conf = axis2_conf_ctx_get_conf(conf_ctx, env); if(conf) { axutil_array_list_t *global_out_phase = axis2_conf_get_out_phases(conf, env); if(global_out_phase) { axis2_engine_invoke_phases(engine, env, global_out_phase, msg_ctx); } } } } if(!(axis2_msg_ctx_is_paused(msg_ctx, env))) { /* Write the message to wire */ axis2_transport_sender_t *transport_sender = NULL; axis2_transport_out_desc_t *transport_out = axis2_msg_ctx_get_transport_out_desc(msg_ctx, env); if(transport_out) { transport_sender = axis2_transport_out_desc_get_sender(transport_out, env); if(!transport_sender) return AXIS2_FAILURE; status = AXIS2_TRANSPORT_SENDER_INVOKE(transport_sender, env, msg_ctx); if(status != AXIS2_SUCCESS) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport sender invoke failed"); return status; } } else { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport out is not set in message context"); return AXIS2_FAILURE; } } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "axis2_engine_send end successfully"); return AXIS2_SUCCESS; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_engine_receive( axis2_engine_t * engine, const axutil_env_t * env, axis2_msg_ctx_t * msg_ctx) { axis2_conf_ctx_t *conf_ctx = NULL; axis2_conf_t *conf = NULL; axis2_op_ctx_t *op_ctx = NULL; axis2_op_t *op = NULL; axutil_array_list_t *pre_calculated_phases = NULL; axutil_array_list_t *op_specific_phases = NULL; axis2_status_t status = AXIS2_FAILURE; AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Start:axis2_engine_receive"); AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); conf = axis2_conf_ctx_get_conf(conf_ctx, env); pre_calculated_phases = axis2_conf_get_in_phases_upto_and_including_post_dispatch(conf, env); if(axis2_msg_ctx_is_paused(msg_ctx, env)) { /* The message has paused, so re-run them from the position they stopped. */ axis2_engine_resume_invocation_phases(engine, env, pre_calculated_phases, msg_ctx); if(axis2_msg_ctx_is_paused(msg_ctx, env)) { AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Message context is paused. So return here."); return AXIS2_SUCCESS; } /* Resume op specific phases */ op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); if(op_ctx) { op = axis2_op_ctx_get_op(op_ctx, env); op_specific_phases = axis2_op_get_in_flow(op, env); axis2_engine_resume_invocation_phases(engine, env, op_specific_phases, msg_ctx); if(axis2_msg_ctx_is_paused(msg_ctx, env)) { AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Message context is paused. So return here."); return AXIS2_SUCCESS; } } } else { status = axis2_engine_invoke_phases(engine, env, pre_calculated_phases, msg_ctx); if(status != AXIS2_SUCCESS) { if(axis2_msg_ctx_get_server_side(msg_ctx, env)) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invoking pre-calculated phases failed"); return status; } } if(axis2_msg_ctx_is_paused(msg_ctx, env)) { AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Message context is paused. So return here."); return AXIS2_SUCCESS; } op_ctx = axis2_msg_ctx_get_op_ctx(msg_ctx, env); if(op_ctx) { op = axis2_op_ctx_get_op(op_ctx, env); op_specific_phases = axis2_op_get_in_flow(op, env); status = axis2_engine_invoke_phases(engine, env, op_specific_phases, msg_ctx); if(status != AXIS2_SUCCESS) { axis2_char_t *op_name = NULL; op_name = axutil_qname_get_localpart(axis2_op_get_qname(op, env), env); AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Invoking operation specific phases failed for operation %s", op_name); return status; } if(axis2_msg_ctx_is_paused(msg_ctx, env)) { AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "Message context is paused. So return here."); return AXIS2_SUCCESS; } } } if((axis2_msg_ctx_get_server_side(msg_ctx, env)) && !(axis2_msg_ctx_is_paused(msg_ctx, env))) { axis2_msg_recv_t *receiver = NULL; status = axis2_engine_check_must_understand_headers(env, msg_ctx); if(status != AXIS2_SUCCESS) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Check for must understand headers failed"); return status; } /* Invoke the message receivers */ if(!op) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Operation not found"); return AXIS2_FAILURE; } receiver = axis2_op_get_msg_recv(op, env); if(!receiver) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Message receiver not set in operation description"); return AXIS2_FAILURE; } status = axis2_msg_recv_receive(receiver, env, msg_ctx, axis2_msg_recv_get_derived( receiver, env)); } AXIS2_LOG_TRACE(env->log, AXIS2_LOG_SI, "Exit:axis2_engine_receive"); return status; }