pplx::task<std::vector<cloud_queue_message>> cloud_queue::peek_messages_async(size_t message_count, const queue_request_options& options, operation_context context) const { queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_message_uri(service_client(), *this); std::shared_ptr<core::storage_command<std::vector<cloud_queue_message>>> command = std::make_shared<core::storage_command<std::vector<cloud_queue_message>>>(uri); command->set_build_request(std::bind(protocol::get_messages, message_count, std::chrono::seconds(0LL), /* is_peek */ true, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_preprocess_response(std::bind(protocol::preprocess_response<std::vector<cloud_queue_message>>, std::vector<cloud_queue_message>(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_postprocess_response([] (const web::http::http_response& response, const request_result&, const core::ostream_descriptor&, operation_context context) -> pplx::task<std::vector<cloud_queue_message>> { UNREFERENCED_PARAMETER(context); protocol::message_reader reader(response.body()); std::vector<protocol::cloud_message_list_item> queue_items = reader.move_items(); std::vector<cloud_queue_message> results; results.reserve(queue_items.size()); for (std::vector<protocol::cloud_message_list_item>::iterator it = queue_items.begin(); it != queue_items.end(); ++it) { cloud_queue_message message(it->move_content(), it->move_id(), it->move_pop_receipt(), it->insertion_time(), it->expiration_time(), it->next_visible_time(), it->dequeue_count()); results.push_back(message); } return pplx::task_from_result(results); }); return core::executor<std::vector<cloud_queue_message>>::execute_async(command, modified_options, context); }
pplx::task<void> cloud_queue::add_message_async(cloud_queue_message& message, std::chrono::seconds time_to_live, std::chrono::seconds initial_visibility_timeout, queue_request_options& options, operation_context context) { if (time_to_live.count() <= 0LL) { throw std::invalid_argument(protocol::error_non_positive_time_to_live); } if (time_to_live.count() > 604800LL) { throw std::invalid_argument(protocol::error_large_time_to_live); } if (initial_visibility_timeout.count() < 0LL) { throw std::invalid_argument(protocol::error_negative_initial_visibility_timeout); } if (initial_visibility_timeout.count() > 604800LL) { throw std::invalid_argument(protocol::error_large_initial_visibility_timeout); } queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_message_uri(service_client(), *this); std::shared_ptr<core::storage_command<void>> command = std::make_shared<core::storage_command<void>>(uri); command->set_build_request(std::bind(protocol::add_message, message, time_to_live, initial_visibility_timeout, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_preprocess_response(std::bind(protocol::preprocess_response_void, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); return core::executor<void>::execute_async(command, modified_options, context); }
pplx::task<cloud_queue_message> cloud_queue::peek_message_async(const queue_request_options& options, operation_context context) const { queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_message_uri(service_client(), *this); std::shared_ptr<core::storage_command<cloud_queue_message>> command = std::make_shared<core::storage_command<cloud_queue_message>>(uri); command->set_build_request(std::bind(protocol::get_messages, 1U, std::chrono::seconds(0LL), /* is_peek */ true, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_preprocess_response(std::bind(protocol::preprocess_response<cloud_queue_message>, cloud_queue_message(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_postprocess_response([] (const web::http::http_response& response, const request_result&, const core::ostream_descriptor&, operation_context context) -> pplx::task<cloud_queue_message> { UNREFERENCED_PARAMETER(context); protocol::message_reader reader(response.body()); std::vector<protocol::cloud_message_list_item> queue_items = reader.move_items(); if (!queue_items.empty()) { protocol::cloud_message_list_item& item = queue_items.front(); cloud_queue_message message(item.move_content(), item.move_id(), item.move_pop_receipt(), item.insertion_time(), item.expiration_time(), item.next_visible_time(), item.dequeue_count()); return pplx::task_from_result(message); } return pplx::task_from_result(cloud_queue_message()); }); return core::executor<cloud_queue_message>::execute_async(command, modified_options, context); }
pplx::task<std::vector<table_result>> cloud_table::execute_batch_async(const table_batch_operation& operation, const table_request_options& options, operation_context context) const { table_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_table_uri(service_client(), *this, operation); std::vector<table_operation> operations = operation.operations(); if (operations.size() == 0U) { throw std::invalid_argument(protocol::error_empty_batch_operation); } utility::string_t partition_key = operations.front().entity().partition_key(); for (std::vector<table_operation>::const_iterator itr = operations.cbegin(); itr != operations.cend(); ++itr) { if (partition_key.compare(itr->entity().partition_key()) != 0) { throw std::invalid_argument(protocol::error_batch_operation_partition_key_mismatch); } } bool is_query = false; for (std::vector<table_operation>::const_iterator itr = operations.cbegin(); itr != operations.cend(); ++itr) { if (itr->operation_type() == table_operation_type::retrieve_operation) { if (is_query) { throw std::invalid_argument(protocol::error_batch_operation_retrieve_count); } is_query = true; } } if (is_query && operations.size() != 1) { throw std::invalid_argument(protocol::error_batch_operation_retrieve_mix); } // TODO: Pre-create a stream for the response to pass to response handler in other functions too so the response doesn't need to be copied Concurrency::streams::stringstreambuf response_buffer; std::shared_ptr<core::storage_command<std::vector<table_result>>> command = std::make_shared<core::storage_command<std::vector<table_result>>>(uri); command->set_build_request(std::bind(protocol::execute_batch_operation, response_buffer, *this, operation, options.payload_format(), is_query, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_location_mode(is_query ? core::command_location_mode::primary_or_secondary : core::command_location_mode::primary_only); command->set_preprocess_response(std::bind(protocol::preprocess_response<std::vector<table_result>>, std::vector<table_result>(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_postprocess_response([response_buffer, operations, is_query] (const web::http::http_response& response, const request_result&, const core::ostream_descriptor&, operation_context context) mutable -> pplx::task<std::vector<table_result>> { UNREFERENCED_PARAMETER(context); return response.content_ready().then([response_buffer, operations, is_query](const web::http::http_response& response) mutable -> pplx::task<std::vector<table_result>> { std::vector<table_result> batch_result = protocol::table_response_parsers::parse_batch_results(response, response_buffer, is_query, operations.size()); return pplx::task_from_result(batch_result); }); }); return core::executor<std::vector<table_result>>::execute_async(command, modified_options, context); }
pplx::task<void> cloud_queue::upload_metadata_async(const queue_request_options& options, operation_context context) { queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_uri(service_client(), *this); std::shared_ptr<core::storage_command<void>> command = std::make_shared<core::storage_command<void>>(uri); command->set_build_request(std::bind(protocol::upload_queue_metadata, metadata(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_preprocess_response(std::bind(protocol::preprocess_response_void, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); return core::executor<void>::execute_async(command, modified_options, context); }
pplx::task<table_result> cloud_table::execute_async(const table_operation& operation, const table_request_options& options, operation_context context) const { table_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_table_uri(service_client(), *this, operation); // Do not throw an exception when the retrieve fails because the entity does not exist bool allow_not_found = operation.operation_type() == table_operation_type::retrieve_operation; std::shared_ptr<core::storage_command<table_result>> command = std::make_shared<core::storage_command<table_result>>(uri); command->set_build_request(std::bind(protocol::execute_operation, operation, options.payload_format(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_location_mode(operation.operation_type() == azure::storage::table_operation_type::retrieve_operation ? core::command_location_mode::primary_or_secondary : core::command_location_mode::primary_only); command->set_preprocess_response([allow_not_found] (const web::http::http_response& response, const request_result& result, operation_context context) -> table_result { if (!allow_not_found || response.status_code() != web::http::status_codes::NotFound) { protocol::preprocess_response_void(response, result, context); } return table_result(); }); command->set_postprocess_response([] (const web::http::http_response& response, const request_result&, const core::ostream_descriptor&, operation_context context) -> pplx::task<table_result> { UNREFERENCED_PARAMETER(context); int status_code = response.status_code(); utility::string_t etag = protocol::table_response_parsers::parse_etag(response); if (status_code == web::http::status_codes::NoContent) { table_result result; result.set_http_status_code(status_code); result.set_etag(std::move(etag)); return pplx::task_from_result(result); } else { return response.extract_json().then([status_code, etag] (const web::json::value& obj) -> table_result { table_entity entity = protocol::parse_table_entity(obj); if (entity.etag().empty()) { entity.set_etag(etag); } table_result result; result.set_http_status_code(status_code); result.set_etag(std::move(etag)); result.set_entity(std::move(entity)); return result; }); } }); return core::executor<table_result>::execute_async(command, modified_options, context); }
pplx::task<void> cloud_queue::download_attributes_async(const queue_request_options& options, operation_context context) { queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_uri(service_client(), *this); std::shared_ptr<core::storage_command<void>> command = std::make_shared<core::storage_command<void>>(uri); command->set_build_request(std::bind(protocol::download_queue_metadata, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_location_mode(core::command_location_mode::primary_or_secondary); command->set_preprocess_response([this](const web::http::http_response& response, const request_result& result, operation_context context) { protocol::preprocess_response_void(response, result, context); m_metadata = protocol::parse_metadata(response); m_approximate_message_count = protocol::parse_approximate_messages_count(response); }); return core::executor<void>::execute_async(command, modified_options, context); }
pplx::task<void> cloud_queue::upload_permissions_async(const queue_permissions& permissions, const queue_request_options& options, operation_context context) { queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_uri(service_client(), *this); protocol::access_policy_writer<queue_shared_access_policy> writer; concurrency::streams::istream stream(concurrency::streams::bytestream::open_istream(writer.write(permissions.policies()))); std::shared_ptr<core::storage_command<void>> command = std::make_shared<core::storage_command<void>>(uri); command->set_build_request(std::bind(protocol::set_queue_acl, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_preprocess_response(std::bind(protocol::preprocess_response_void, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); return core::istream_descriptor::create(stream).then([command, context, modified_options](core::istream_descriptor request_body) -> pplx::task<void> { command->set_request_body(request_body); return core::executor<void>::execute_async(command, modified_options, context); }); }
pplx::task<bool> cloud_queue::delete_async_impl(const queue_request_options& options, operation_context context, bool allow_not_found) { queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_uri(service_client(), *this); std::shared_ptr<core::storage_command<bool>> command = std::make_shared<core::storage_command<bool>>(uri); command->set_build_request(std::bind(protocol::delete_queue, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_preprocess_response([allow_not_found] (const web::http::http_response& response, const request_result& result, operation_context context) -> bool { if (allow_not_found && response.status_code() == web::http::status_codes::NotFound) { return false; } protocol::preprocess_response_void(response, result, context); return true; }); return core::executor<bool>::execute_async(command, modified_options, context); }
pplx::task<queue_permissions> cloud_queue::download_permissions_async(const queue_request_options& options, operation_context context) const { queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_uri(service_client(), *this); std::shared_ptr<core::storage_command<queue_permissions>> command = std::make_shared<core::storage_command<queue_permissions>>(uri); command->set_build_request(std::bind(protocol::get_queue_acl, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_location_mode(core::command_location_mode::primary_or_secondary); command->set_preprocess_response(std::bind(protocol::preprocess_response<queue_permissions>, queue_permissions(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_postprocess_response([] (const web::http::http_response& response, const request_result&, const core::ostream_descriptor&, operation_context context) -> pplx::task<queue_permissions> { UNREFERENCED_PARAMETER(context); queue_permissions permissions; protocol::access_policy_reader<queue_shared_access_policy> reader(response.body()); permissions.set_policies(reader.move_policies()); return pplx::task_from_result<queue_permissions>(permissions); }); return core::executor<queue_permissions>::execute_async(command, modified_options, context); }
pplx::task<bool> cloud_queue::exists_async_impl(const queue_request_options& options, operation_context context, bool allow_secondary) const { queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_uri(service_client(), *this); std::shared_ptr<core::storage_command<bool>> command = std::make_shared<core::storage_command<bool>>(uri); command->set_build_request(std::bind(protocol::download_queue_metadata, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_location_mode(allow_secondary ? core::command_location_mode::primary_or_secondary : core::command_location_mode::primary_only); command->set_preprocess_response([] (const web::http::http_response& response, const request_result& result, operation_context context) -> bool { if (response.status_code() != web::http::status_codes::NotFound) { protocol::preprocess_response_void(response, result, context); return true; } return false; }); return core::executor<bool>::execute_async(command, modified_options, context); }
pplx::task<table_query_segment> cloud_table::execute_query_segmented_async(const table_query& query, const continuation_token& token, const table_request_options& options, operation_context context) const { table_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_table_uri(service_client(), *this, query, token); std::shared_ptr<core::storage_command<table_query_segment>> command = std::make_shared<core::storage_command<table_query_segment>>(uri); command->set_build_request(std::bind(protocol::execute_query, options.payload_format(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_location_mode(core::command_location_mode::primary_or_secondary, token.target_location()); command->set_preprocess_response(std::bind(protocol::preprocess_response<table_query_segment>, table_query_segment(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_postprocess_response([] (const web::http::http_response& response, const request_result& result, const core::ostream_descriptor&, operation_context context) -> pplx::task<table_query_segment> { UNREFERENCED_PARAMETER(context); continuation_token next_token = protocol::table_response_parsers::parse_continuation_token(response, result); return response.extract_json().then([next_token] (const web::json::value& obj) -> table_query_segment { table_query_segment query_segment(protocol::table_response_parsers::parse_query_results(obj), std::move(next_token)); return query_segment; }); }); return core::executor<table_query_segment>::execute_async(command, modified_options, context); }
pplx::task<void> cloud_queue::update_message_async(cloud_queue_message& message, std::chrono::seconds visibility_timeout, bool update_content, queue_request_options& options, operation_context context) { if (message.id().empty()) { throw std::invalid_argument(protocol::error_empty_message_id); } if (message.pop_receipt().empty()) { throw std::invalid_argument(protocol::error_empty_message_pop_receipt); } if (visibility_timeout.count() < 0LL) { throw std::invalid_argument(protocol::error_negative_visibility_timeout); } if (visibility_timeout.count() > 604800LL) { throw std::invalid_argument(protocol::error_large_visibility_timeout); } queue_request_options modified_options = get_modified_options(options); storage_uri uri = protocol::generate_queue_message_uri(service_client(), *this, message); std::shared_ptr<core::storage_command<void>> command = std::make_shared<core::storage_command<void>>(uri); command->set_build_request(std::bind(protocol::update_message, message, visibility_timeout, update_content, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); command->set_authentication_handler(service_client().authentication_handler()); command->set_preprocess_response([&message] (const web::http::http_response& response, const request_result& result, operation_context context) mutable { protocol::preprocess_response_void(response, result, context); message.set_pop_receipt(protocol::parse_pop_receipt(response)); message.set_next_visible_time(protocol::parse_next_visible_time(response)); }); return core::executor<void>::execute_async(command, modified_options, context); }