| /* |
| * 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_utils.h> |
| #include <sandesha2_ack_mgr.h> |
| #include <sandesha2_constants.h> |
| #include <sandesha2_property_bean.h> |
| #include <sandesha2_seq_property_bean.h> |
| #include <sandesha2_ack_range.h> |
| #include <sandesha2_spec_specific_consts.h> |
| #include <sandesha2_seq_property_mgr.h> |
| #include <sandesha2_sender_mgr.h> |
| #include <sandesha2_sender_bean.h> |
| #include <axutil_string.h> |
| #include <axutil_uuid_gen.h> |
| #include <axis2_addr.h> |
| #include <axis2_core_utils.h> |
| #include <axutil_property.h> |
| #include <axutil_array_list.h> |
| #include <sandesha2_msg_init.h> |
| #include <sandesha2_seq_ack.h> |
| #include <axis2_op.h> |
| #include <sandesha2_msg_creator.h> |
| #include <axis2_transport_out_desc.h> |
| |
| AXIS2_EXTERN sandesha2_msg_ctx_t *AXIS2_CALL |
| sandesha2_ack_mgr_generate_ack_msg( |
| const axutil_env_t *env, |
| sandesha2_msg_ctx_t *ref_rm_msg, |
| axis2_char_t *seq_id, |
| sandesha2_seq_property_mgr_t *seq_prop_mgr) |
| { |
| axis2_msg_ctx_t *ref_msg = NULL; |
| axis2_conf_ctx_t *conf_ctx = NULL; |
| |
| axis2_endpoint_ref_t *to = NULL; |
| axis2_endpoint_ref_t *temp_to = NULL; |
| axis2_msg_ctx_t *ack_msg_ctx = NULL; |
| axutil_property_t *property = NULL; |
| sandesha2_msg_ctx_t *ack_rm_msg = NULL; |
| /*axiom_soap_envelope_t *soap_env = NULL;*/ |
| axis2_op_ctx_t *op_ctx = NULL; |
| axis2_char_t *uuid = NULL; |
| |
| AXIS2_PARAM_CHECK(env->error, seq_id, NULL); |
| AXIS2_PARAM_CHECK(env->error, seq_prop_mgr, NULL); |
| |
| ref_msg = sandesha2_msg_ctx_get_msg_ctx(ref_rm_msg, env); |
| conf_ctx = axis2_msg_ctx_get_conf_ctx(ref_msg, env); |
| |
| temp_to = axis2_msg_ctx_get_reply_to(ref_msg, env); |
| if(temp_to) |
| { |
| to = axis2_endpoint_ref_create(env, axis2_endpoint_ref_get_address(temp_to, env)); |
| } |
| if(!to) |
| { |
| sandesha2_seq_property_bean_t *acks_to_bean = NULL; |
| axis2_char_t *acks_to_str = NULL; |
| |
| acks_to_bean = sandesha2_seq_property_mgr_retrieve(seq_prop_mgr, env, |
| seq_id, SANDESHA2_SEQ_PROP_ACKS_TO_EPR); |
| if(acks_to_bean) |
| { |
| acks_to_str = sandesha2_seq_property_bean_get_value(acks_to_bean, env); |
| to = axis2_endpoint_ref_create(env, acks_to_str); |
| sandesha2_seq_property_bean_free(acks_to_bean, env); |
| } |
| } |
| |
| ack_msg_ctx = sandesha2_utils_create_new_related_msg_ctx(env, ref_rm_msg); |
| property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, |
| AXIS2_FALSE, 0, AXIS2_VALUE_TRUE); |
| if(property) |
| { |
| axis2_msg_ctx_set_property(ack_msg_ctx, env, SANDESHA2_APPLICATION_PROCESSING_DONE, property); |
| property = NULL; |
| } |
| |
| ack_rm_msg = sandesha2_msg_init_init_msg(env, ack_msg_ctx); |
| sandesha2_msg_ctx_set_rm_ns_val(ack_rm_msg, env, |
| sandesha2_msg_ctx_get_rm_ns_val(ref_rm_msg, env)); |
| |
| uuid = axutil_uuid_gen(env); |
| if(uuid) |
| { |
| axis2_msg_ctx_set_wsa_message_id(ack_msg_ctx, env, uuid); |
| AXIS2_FREE(env->allocator, uuid); |
| } |
| |
| /*soap_env = axiom_soap_envelope_create_default_soap_envelope(env, |
| * sandesha2_utils_get_soap_version(env, axis2_msg_ctx_get_soap_envelope(ref_msg, env))); |
| axis2_msg_ctx_set_soap_envelope(ack_msg_ctx, env, soap_env);*/ |
| |
| axis2_msg_ctx_set_to(ack_msg_ctx, env, to); |
| |
| /* Adding the sequence acknowledgement part */ |
| sandesha2_msg_creator_add_ack_msg(env, ack_rm_msg, seq_id, seq_prop_mgr); |
| axis2_msg_ctx_set_property(ack_msg_ctx, env, AXIS2_TRANSPORT_IN, NULL); |
| |
| op_ctx = axis2_msg_ctx_get_op_ctx(ref_msg, env); |
| axis2_op_ctx_set_response_written(op_ctx, env, AXIS2_TRUE); |
| |
| property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, |
| AXIS2_FALSE, 0, AXIS2_VALUE_TRUE); |
| axis2_msg_ctx_set_property(ref_msg, env, SANDESHA2_ACK_WRITTEN, property); |
| axis2_msg_ctx_set_server_side(ack_msg_ctx, env, AXIS2_TRUE); |
| |
| return ack_rm_msg; |
| } |
| |
| /** |
| * This is used to get the acked messages of a sequence. If this is an outgoing |
| * message the sequence_identifier should be the outgoing sequenceID. |
| * |
| * @param sequence_identifier |
| * @param out_going_msg |
| * @return |
| */ |
| AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL |
| sandesha2_ack_mgr_get_client_completed_msgs_list( |
| const axutil_env_t *env, |
| axis2_char_t *rms_seq_id, |
| sandesha2_seq_property_mgr_t *seq_prop_mgr) |
| { |
| sandesha2_seq_property_bean_t *internal_seq_bean = NULL; |
| axis2_char_t *internal_seq_id = NULL; |
| sandesha2_seq_property_bean_t *completed_msgs_bean = NULL; |
| axutil_array_list_t *completed_msg_list = NULL; |
| |
| /* First trying to get it from the internal sequence id.*/ |
| internal_seq_bean = sandesha2_seq_property_mgr_retrieve(seq_prop_mgr, env, |
| rms_seq_id, SANDESHA2_SEQUENCE_PROPERTY_RMS_INTERNAL_SEQ_ID); |
| if(internal_seq_bean != NULL) |
| { |
| internal_seq_id = sandesha2_seq_property_bean_get_value( |
| internal_seq_bean, env); |
| } |
| if(internal_seq_id != NULL) |
| { |
| completed_msgs_bean = sandesha2_seq_property_mgr_retrieve(seq_prop_mgr, |
| env, internal_seq_id, |
| SANDESHA2_SEQ_PROP_CLIENT_COMPLETED_MESSAGES); |
| } |
| if(completed_msgs_bean == NULL) |
| { |
| completed_msgs_bean = sandesha2_seq_property_mgr_retrieve(seq_prop_mgr, |
| env, rms_seq_id, |
| SANDESHA2_SEQ_PROP_CLIENT_COMPLETED_MESSAGES); |
| } |
| if(completed_msgs_bean != NULL) |
| { |
| axis2_char_t *value = sandesha2_seq_property_bean_get_value( |
| completed_msgs_bean, env); |
| completed_msg_list = sandesha2_utils_get_array_list_from_string(env, value); |
| } |
| else |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, |
| "[sandesha2]completed_msgs_bean is NULL"); |
| AXIS2_ERROR_SET(env->error, SANDESHA2_ERROR_COMPLETED_MSGS_BEAN_IS_NULL, |
| AXIS2_FAILURE); |
| return NULL; |
| } |
| return completed_msg_list; |
| } |
| |
| AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL |
| sandesha2_ack_mgr_get_svr_completed_msgs_list( |
| const axutil_env_t *env, |
| axis2_char_t *rmd_seq_id, |
| sandesha2_seq_property_mgr_t *seq_prop_mgr) |
| { |
| sandesha2_seq_property_bean_t *completed_msgs_bean = NULL; |
| axutil_array_list_t *completed_msg_list = NULL; |
| |
| completed_msgs_bean = sandesha2_seq_property_mgr_retrieve(seq_prop_mgr, |
| env, rmd_seq_id, |
| SANDESHA2_SEQ_PROP_SERVER_COMPLETED_MESSAGES); |
| if(completed_msgs_bean) |
| { |
| axis2_char_t *value = sandesha2_seq_property_bean_get_value( |
| completed_msgs_bean, env); |
| completed_msg_list = sandesha2_utils_get_array_list_from_string(env, value); |
| } |
| else |
| { |
| AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, |
| "[sandesha2]completed_msgs_bean is NULL"); |
| AXIS2_ERROR_SET(env->error, SANDESHA2_ERROR_COMPLETED_MSGS_BEAN_IS_NULL, |
| AXIS2_FAILURE); |
| return NULL; |
| } |
| return completed_msg_list; |
| } |
| |
| AXIS2_EXTERN axis2_bool_t AXIS2_CALL |
| sandesha2_ack_mgr_verify_seq_completion( |
| const axutil_env_t *env, |
| axutil_array_list_t *ack_ranges, |
| long last_msg_no) |
| { |
| axutil_hash_t *hash = NULL; |
| axis2_char_t tmp[32]; |
| int i = 0; |
| long start = 1; |
| |
| AXIS2_PARAM_CHECK(env->error, ack_ranges, AXIS2_FALSE); |
| |
| hash = axutil_hash_make(env); |
| for(i = 0; i< axutil_array_list_size(ack_ranges, env); i++) |
| { |
| sandesha2_ack_range_t *ack_range = NULL; |
| |
| ack_range = axutil_array_list_get(ack_ranges, env, i); |
| sprintf(tmp, "%ld", sandesha2_ack_range_get_lower_value(ack_range, env)); |
| axutil_hash_set(hash, tmp, AXIS2_HASH_KEY_STRING, ack_range); |
| } |
| |
| while(AXIS2_TRUE) |
| { |
| sandesha2_ack_range_t *ack_range = NULL; |
| long upper_value = -1; |
| |
| sprintf(tmp, "%ld", start); |
| ack_range = axutil_hash_get(hash, tmp, AXIS2_HASH_KEY_STRING); |
| |
| |
| if(!ack_range) |
| { |
| break; |
| } |
| upper_value = sandesha2_ack_range_get_upper_value(ack_range, env); |
| if(upper_value >= last_msg_no) |
| { |
| if(hash) |
| { |
| axutil_hash_free(hash, env); |
| } |
| return AXIS2_TRUE; |
| } |
| start = sandesha2_ack_range_get_upper_value(ack_range, env) + 1; |
| } |
| |
| if(hash) |
| { |
| axutil_hash_free(hash, env); |
| } |
| return AXIS2_FALSE; |
| } |
| |
| |
| AXIS2_EXTERN axis2_status_t AXIS2_CALL |
| sandesha2_ack_mgr_piggyback_acks_if_present( |
| const axutil_env_t *env, |
| axis2_char_t *seq_id, |
| sandesha2_msg_ctx_t *target_rm_msg_ctx, |
| sandesha2_storage_mgr_t *storage_mgr, |
| sandesha2_seq_property_mgr_t *seq_prop_mgr, |
| sandesha2_sender_mgr_t *sender_mgr) |
| { |
| axis2_conf_ctx_t *conf_ctx = NULL; |
| sandesha2_sender_bean_t *find_bean = NULL; |
| axis2_char_t *to_str = NULL; |
| axis2_msg_ctx_t *target_msg_ctx = NULL; |
| axis2_endpoint_ref_t *to_epr = NULL; |
| axutil_array_list_t *found_list = NULL; |
| |
| AXIS2_PARAM_CHECK(env->error, target_rm_msg_ctx, AXIS2_FAILURE); |
| AXIS2_PARAM_CHECK(env->error, storage_mgr, AXIS2_FAILURE); |
| |
| target_msg_ctx = sandesha2_msg_ctx_get_msg_ctx(target_rm_msg_ctx, env); |
| conf_ctx = axis2_msg_ctx_get_conf_ctx(target_msg_ctx, env); |
| |
| find_bean = sandesha2_sender_bean_create(env); |
| sandesha2_sender_bean_set_msg_type(find_bean, env, SANDESHA2_MSG_TYPE_ACK); |
| AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "dam_seq_id:%s", seq_id); |
| sandesha2_sender_bean_set_seq_id(find_bean, env, seq_id); |
| sandesha2_sender_bean_set_send(find_bean, env, AXIS2_TRUE); |
| sandesha2_sender_bean_set_resend(find_bean, env, AXIS2_FALSE); |
| |
| to_epr = sandesha2_msg_ctx_get_to(target_rm_msg_ctx, env); |
| if(to_epr) |
| { |
| to_str = (axis2_char_t*)axis2_endpoint_ref_get_address(to_epr, env); |
| } |
| |
| found_list = sandesha2_sender_mgr_find_by_sender_bean(sender_mgr, env, find_bean); |
| if(find_bean) |
| { |
| sandesha2_sender_bean_free(find_bean, env); |
| } |
| |
| if(found_list) |
| { |
| int i = 0, j = 0, size = 0; |
| |
| size = axutil_array_list_size(found_list, env); |
| for(i = 0; i < size; i++) |
| { |
| sandesha2_sender_bean_t *sender_bean = NULL; |
| long timenow = 0; |
| |
| timenow = sandesha2_utils_get_current_time_in_millis(env); |
| sender_bean = axutil_array_list_get(found_list, env, i); |
| |
| if(sender_bean && sandesha2_sender_bean_get_time_to_send(sender_bean, env) <= timenow) |
| { |
| axis2_msg_ctx_t *ack_msg_ctx = NULL; |
| axis2_char_t *to = NULL; |
| sandesha2_msg_ctx_t *ack_rm_msg_ctx = NULL; |
| sandesha2_seq_ack_t *seq_ack = NULL; |
| axis2_char_t *msg_ctx_ref_key = NULL; |
| axis2_endpoint_ref_t *to_ref = NULL; |
| |
| msg_ctx_ref_key = sandesha2_sender_bean_get_msg_ctx_ref_key(sender_bean, env); |
| ack_msg_ctx = sandesha2_storage_mgr_retrieve_msg_ctx(storage_mgr, env, msg_ctx_ref_key, |
| conf_ctx, AXIS2_FALSE); |
| |
| if(ack_msg_ctx) |
| { |
| to_ref = axis2_msg_ctx_get_to(ack_msg_ctx, env); |
| } |
| |
| if(to_ref) |
| { |
| to = (axis2_char_t*)axis2_endpoint_ref_get_address(to_ref, env); |
| } |
| else |
| { |
| if(ack_msg_ctx) |
| { |
| axis2_msg_ctx_free(ack_msg_ctx, env); |
| } |
| |
| sandesha2_sender_bean_free(sender_bean, env); |
| continue; |
| } |
| |
| if(axutil_strcmp(to, to_str)) |
| { |
| if(ack_msg_ctx) |
| { |
| axis2_msg_ctx_free(ack_msg_ctx, env); |
| } |
| |
| sandesha2_sender_bean_free(sender_bean, env); |
| continue; |
| } |
| |
| sandesha2_sender_mgr_remove(sender_mgr, env, sandesha2_sender_bean_get_msg_id( |
| sender_bean, env)); |
| |
| sandesha2_storage_mgr_remove_msg_ctx(storage_mgr, env, msg_ctx_ref_key, conf_ctx, -1); |
| ack_rm_msg_ctx = sandesha2_msg_init_init_msg(env, ack_msg_ctx); |
| |
| if(SANDESHA2_MSG_TYPE_ACK != sandesha2_msg_ctx_get_msg_type(ack_rm_msg_ctx, env)) |
| { |
| AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "[sandesha2] Invalid ack message entry"); |
| if(ack_msg_ctx) |
| { |
| axis2_msg_ctx_free(ack_msg_ctx, env); |
| } |
| |
| if(ack_rm_msg_ctx) |
| { |
| sandesha2_msg_ctx_free(ack_rm_msg_ctx, env); |
| } |
| |
| sandesha2_sender_bean_free(sender_bean, env); |
| continue; |
| } |
| |
| seq_ack = sandesha2_msg_ctx_get_seq_ack(ack_rm_msg_ctx, env); |
| /* When we set seq_ack to target rm message context taken from acknowledgment rm message |
| * context ,there happen freeing at both contexts if we do not increment ref.*/ |
| sandesha2_seq_ack_increment_ref(seq_ack, env); |
| sandesha2_msg_ctx_set_seq_ack(target_rm_msg_ctx, env, seq_ack); |
| sandesha2_msg_ctx_add_soap_envelope(target_rm_msg_ctx, env); |
| |
| if(ack_msg_ctx) |
| { |
| axis2_msg_ctx_free(ack_msg_ctx, env); |
| } |
| |
| if(ack_rm_msg_ctx) |
| { |
| sandesha2_msg_ctx_free(ack_rm_msg_ctx, env); |
| } |
| |
| sandesha2_sender_bean_free(sender_bean, env); |
| break; |
| } |
| |
| for(j = i++; j < size; j++) |
| { |
| sandesha2_sender_bean_t *sender_bean = NULL; |
| |
| sender_bean = axutil_array_list_get(found_list, env, j); |
| |
| if(sender_bean) |
| { |
| sandesha2_sender_bean_free(sender_bean, env); |
| sender_bean = NULL; |
| } |
| } |
| |
| if(sender_bean) |
| { |
| sandesha2_sender_bean_free(sender_bean, env); |
| } |
| } |
| |
| axutil_array_list_free(found_list, env); |
| } |
| |
| return AXIS2_SUCCESS; |
| } |
| |