diff --git a/sdk/storage/CMakeLists.txt b/sdk/storage/CMakeLists.txt index 5c8f02909..00ee2a9f8 100644 --- a/sdk/storage/CMakeLists.txt +++ b/sdk/storage/CMakeLists.txt @@ -25,3 +25,4 @@ add_subdirectory(azure-storage-common) add_subdirectory(azure-storage-blobs) add_subdirectory(azure-storage-files-datalake) add_subdirectory(azure-storage-files-shares) +add_subdirectory(azure-storage-queues) diff --git a/sdk/storage/azure-storage-queues/CHANGELOG.md b/sdk/storage/azure-storage-queues/CHANGELOG.md new file mode 100644 index 000000000..d97904f4e --- /dev/null +++ b/sdk/storage/azure-storage-queues/CHANGELOG.md @@ -0,0 +1,5 @@ +# Release History + +## 12.0.0-beta.1 (Unreleased) + +- Initial release diff --git a/sdk/storage/azure-storage-queues/CMakeLists.txt b/sdk/storage/azure-storage-queues/CMakeLists.txt new file mode 100644 index 000000000..f71d21d6a --- /dev/null +++ b/sdk/storage/azure-storage-queues/CMakeLists.txt @@ -0,0 +1,86 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) +project(azure-storage-queues LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake-modules") + +include(AzureVcpkg) +include(AzureVersion) +include(AzureCodeCoverage) +include(AzureTransportAdapters) +include(AzureDoxygen) +include(AzureGlobalCompileOptions) + +az_vcpkg_integrate() + +if(NOT AZ_ALL_LIBRARIES) + find_package(azure-storage-common-cpp "12.0.0" CONFIG QUIET) + if(NOT azure-storage-common-cpp_FOUND) + find_package(azure-storage-common-cpp "12.0.0" REQUIRED) + endif() +endif() + +set( + AZURE_STORAGE_QUEUE_HEADER + inc/azure/storage/queues/dll_import_export.hpp + inc/azure/storage/queues/protocol/queue_rest_client.hpp + inc/azure/storage/queues.hpp +) + +set( + AZURE_STORAGE_QUEUE_SOURCE + src/private/package_version.hpp + src/queue_rest_client.cpp +) + +add_library(azure-storage-queues ${AZURE_STORAGE_QUEUE_HEADER} ${AZURE_STORAGE_QUEUE_SOURCE}) + +# make sure that users can consume the project as a library. +add_library(Azure::azure-storage-queues ALIAS azure-storage-queues) + +target_include_directories( + azure-storage-queues + PUBLIC + $ + $ +) + +target_link_libraries(azure-storage-queues PUBLIC Azure::azure-storage-common) + +get_az_version("${CMAKE_CURRENT_SOURCE_DIR}/src/private/package_version.hpp") +generate_documentation(azure-storage-queues ${AZ_LIBRARY_VERSION}) + +az_vcpkg_export( + azure-storage-queues + STORAGE_QUEUES + "azure/storage/queues/dll_import_export.hpp" + ) + +# coverage. Has no effect if BUILD_CODE_COVERAGE is OFF +create_code_coverage(storage azure-storage-queues azure-storage-test) + +if(BUILD_TESTING) + target_sources( + azure-storage-test + PRIVATE + test/ut/macro_guard.cpp + ) + + target_link_libraries(azure-storage-test PRIVATE azure-storage-queues) +endif() + +if(BUILD_STORAGE_SAMPLES) + target_sources( + azure-storage-sample + PRIVATE + sample/queue_getting_started.cpp + ) + + target_link_libraries(azure-storage-sample PRIVATE azure-storage-queues) +endif() diff --git a/sdk/storage/azure-storage-queues/NOTICE.txt b/sdk/storage/azure-storage-queues/NOTICE.txt new file mode 100644 index 000000000..d144a9090 --- /dev/null +++ b/sdk/storage/azure-storage-queues/NOTICE.txt @@ -0,0 +1,483 @@ +azure-storage-queues + +NOTICES AND INFORMATION +Do Not Translate or Localize + +This software incorporates material from third parties. Microsoft makes certain +open source code available at https://3rdpartysource.microsoft.com, or you may +send a check or money order for US $5.00, including the product name, the open +source component name, and version number, to: + +Source Code Compliance Team +Microsoft Corporation +One Microsoft Way +Redmond, WA 98052 +USA + +Notwithstanding any other terms, you may reverse engineer this software to the +extent required to debug changes to any libraries licensed under the GNU Lesser +General Public License. + +------------------------------------------------------------------------------ + +Azure SDK for C++ uses third-party libraries or other resources that may be +distributed under licenses different than the Azure SDK for C++ software. + +In the event that we accidentally failed to list a required notice, please +bring it to our attention. Post an issue or email us: + + azcppsdkhelp@microsoft.com + +The attached notices are provided for information only. + + +License notice for CMake Modules AddGoogleTest +------------------------------------------------------------------- + +BSD 3-Clause License + +Copyright (c) 2017, University of Cincinnati +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License notice for +------------------------------------------------------------------- + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + +License notice for +------------------------------------------------------------------- + +The MIT License (MIT) + +Copyright (c) 2015 Max Woolf + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +License notice for +------------------------------------------------------------------- + +MIT License + +Copyright (c) 2016 Nicolas Seriot + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +License notice for +------------------------------------------------------------------- + +The MIT License (MIT) + +Copyright (c) 2016-2018 Viktor Kirilov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +License notice for +------------------------------------------------------------------- + +The MIT License + +Copyright (c) 2018-2019 Bryan Gillespie + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +License notice for +------------------------------------------------------------------- + +MIT License + +Copyright (c) 2015-2017 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +License notice for amalgamate +------------------------------------------------------------------- + +amalgamate.py - Amalgamate C source and header files +Copyright (c) 2012, Erik Edlund + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Erik Edlund, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License notice for cpplint +------------------------------------------------------------------- + +cpplint.py and its corresponding unit tests are Copyright (C) 2009 Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License notice for libcurl +------------------------------------------------------------------- + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1996 - 2020, Daniel Stenberg, , and many +contributors, see the THANKS file. + +All rights reserved. + +Permission to use, copy, modify, and distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright +notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization of the copyright holder. diff --git a/sdk/storage/azure-storage-queues/cgmanifest.json b/sdk/storage/azure-storage-queues/cgmanifest.json new file mode 100644 index 000000000..9cd1bceeb --- /dev/null +++ b/sdk/storage/azure-storage-queues/cgmanifest.json @@ -0,0 +1,46 @@ +{ + "Registrations": [ + { + "Component": { + "Type": "git", + "git": { + "RepositoryUrl": "https://github.com/cpplint/cpplint", + "CommitHash": "8456631ba3a12842da08238362a90d33fcf47062" + } + }, + "DevelopmentDependency": true + }, + { + "Component": { + "Type": "git", + "git": { + "RepositoryUrl": "https://github.com/edlund/amalgamate", + "CommitHash": "c91f07eea1133aa184f652b8f1398eaf03586208" + } + }, + "DevelopmentDependency": true + }, + { + "Component": { + "Type": "other", + "Other": { + "Name": "clang-format", + "Version": "9.0.0-2", + "DownloadUrl": "https://ubuntu.pkgs.org/18.04/ubuntu-updates-universe-amd64/clang-format-9_9-2~ubuntu18.04.2_amd64.deb.html" + } + }, + "DevelopmentDependency": true + }, + { + "Component": { + "Type": "other", + "Other": { + "Name": "doxygen", + "Version": "1.8.20", + "DownloadUrl": "http://doxygen.nl/files/doxygen-1.8.20-setup.exe" + } + }, + "DevelopmentDependency": true + } + ] +} diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues.hpp new file mode 100644 index 000000000..829762903 --- /dev/null +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues.hpp @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +/** + * @brief Includes all public headers from Azure Storage Queues SDK library. + * + */ + +#pragma once diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/dll_import_export.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/dll_import_export.hpp new file mode 100644 index 000000000..8473a923a --- /dev/null +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/dll_import_export.hpp @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +/** + * @file + * @brief DLL export macro. + */ + +// For explanation, see the comment in azure/core/dll_import_export.hpp + +#pragma once + +/** + * @def AZ_STORAGE_QUEUES_DLLEXPORT + * @brief Applies DLL export attribute, when applicable. + * @note See https://docs.microsoft.com/cpp/cpp/dllexport-dllimport?view=msvc-160. + */ + +#if defined(AZ_STORAGE_QUEUES_DLL) || (0 /*@AZ_STORAGE_QUEUES_DLL_INSTALLED_AS_PACKAGE@*/) +#define AZ_STORAGE_QUEUES_BUILT_AS_DLL 1 +#else +#define AZ_STORAGE_QUEUES_BUILT_AS_DLL 0 +#endif + +#if AZ_STORAGE_QUEUES_BUILT_AS_DLL +#if defined(_MSC_VER) +#if defined(AZ_STORAGE_QUEUES_BEING_BUILT) +#define AZ_STORAGE_QUEUES_DLLEXPORT __declspec(dllexport) +#else // !defined(AZ_STORAGE_QUEUES_BEING_BUILT) +#define AZ_STORAGE_QUEUES_DLLEXPORT __declspec(dllimport) +#endif // AZ_STORAGE_QUEUES_BEING_BUILT +#else // !defined(_MSC_VER) +#define AZ_STORAGE_QUEUES_DLLEXPORT +#endif // _MSC_VER +#else // !AZ_STORAGE_QUEUES_BUILT_AS_DLL +#define AZ_STORAGE_QUEUES_DLLEXPORT +#endif // AZ_STORAGE_QUEUES_BUILT_AS_DLL + +#undef AZ_STORAGE_QUEUES_BUILT_AS_DLL diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/protocol/queue_rest_client.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/protocol/queue_rest_client.hpp new file mode 100644 index 000000000..5051d44f9 --- /dev/null +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/protocol/queue_rest_client.hpp @@ -0,0 +1,2707 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "azure/storage/queues/dll_import_export.hpp" + +namespace Azure { namespace Storage { namespace Queues { + + namespace _detail { + constexpr static const char* ApiVersion = "2018-03-28"; + } // namespace _detail + + namespace Models { + + /** + * @brief Extensible enum used to identify the status of secondary storage endpoint. + */ + class GeoReplicationStatus final { + public: + GeoReplicationStatus() = default; + explicit GeoReplicationStatus(std::string value) : m_value(std::move(value)) {} + bool operator==(const GeoReplicationStatus& other) const { return m_value == other.m_value; } + bool operator!=(const GeoReplicationStatus& other) const { return !(*this == other); } + const std::string& ToString() const { return m_value; } + /** + * The secondary location is active and operational. + */ + AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Live; + /** + * Initial synchronization from the primary location to the secondary location is in progress. + */ + AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Bootstrap; + /** + * The secondary location is temporarily unavailable. + */ + AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Unavailable; + + private: + std::string m_value; + }; // extensible enum GeoReplicationStatus + + /** + * @brief A message object peeked from a queue. + */ + struct PeekedQueueMessage final + { + /** + * The content of the message. + */ + std::string Body; + /** + * A GUID value that identifies the message in the queue. + */ + std::string MessageId; + /** + * The time the message was inserted into the queue. + */ + Azure::DateTime InsertedOn; + /** + * The time that the message will expire and be automatically deleted from the queue. + */ + Azure::DateTime ExpiresOn; + /** + * The number of times the message has been dequeued. + */ + int64_t DequeueCount = 0; + }; // struct PeekedQueueMessage + + /** + * @brief A queue item from the result of + * #Azure::Storage::Queues::QueueServiceClient::ListQueues. + */ + struct QueueItem final + { + /** + * Queue name. + */ + std::string Name; + /** + * A set of name-value pairs associated with a queue as user-defined metadata. + */ + Storage::Metadata Metadata; + }; // struct QueueItem + + /** + * @brief A message object stored in the queue. + */ + struct QueueMessage final + { + /** + * The content of the message. + */ + std::string Body; + /** + * A GUID value that identifies the message in the queue. + */ + std::string MessageId; + /** + * The time the message was inserted into the queue. + */ + Azure::DateTime InsertedOn; + /** + * The time that the message will expire and be automatically deleted from the queue. + */ + Azure::DateTime ExpiresOn; + /** + * This value is required to delete a message. + */ + std::string PopReceipt; + /** + * The time that the message will again become visible in the queue. + */ + Azure::DateTime NextVisibleOn; + /** + * The number of times the message has been dequeued. + */ + int64_t DequeueCount = 0; + }; // struct QueueMessage + + /** + * @brief Determines how long the associated data should persist. + */ + struct RetentionPolicy final + { + /** + * Indicates whether this retention policy is enabled. + */ + bool IsEnabled = false; + /** + * Indicates the number of days that metrics or logging or soft-deleted data should be + * retained. + */ + Azure::Nullable Days; + }; // struct RetentionPolicy + + /** + * @brief Describes how you reference an ACL in a queue. + */ + struct SignedIdentifier final + { + /** + * A unique ID for this signed identifier. + */ + std::string Id; + /** + * Date and time since when this policy is active. + */ + Azure::DateTime StartsOn; + /** + * Date and time the policy expires. + */ + Azure::DateTime ExpiresOn; + /** + * The permissions for this ACL policy. + */ + std::string Permissions; + }; // struct SignedIdentifier + + /** + * @brief Azure analytics logging settings. + */ + struct AnalyticsLogging final + { + /** + * The version of storage analytics to configure. + */ + std::string Version; + /** + * Whether all delete requests should be logged. + */ + bool Delete = false; + /** + * Whether all read requests should be logged. + */ + bool Read = false; + /** + * Whether all write requests should be logged. + */ + bool Write = false; + /** + * Determines how long the data should be persist. + */ + Models::RetentionPolicy RetentionPolicy; + }; // struct AnalyticsLogging + + /** + * @brief Settings for a CORS rule. + */ + struct CorsRule final + { + /** + * A comma-separated list of origin domains that are allowed via CORS, or "*" if all domains + * are allowed. + */ + std::string AllowedOrigins; + /** + * A comma-separated list of HTTP methods that are allowed to be executed by the origin. For + * Azure Storage, permitted methods are DELETE, GET, HEAD, MERGE, POST, OPTIONS or PUT. + */ + std::string AllowedMethods; + /** + * A comma-separated list of headers allowed to be part of the cross-origin request. + */ + std::string AllowedHeaders; + /** + * A comma-separated list of response headers to expose to CORS clients. + */ + std::string ExposedHeaders; + /** + * The number of seconds that the client/browser should cache a preflight response. + */ + int32_t MaxAgeInSeconds = 0; + }; // struct CorsRule + + /** + * @brief Geo-replication information for the secondary storage endpoint. + */ + struct GeoReplication final + { + /** + * Status of the secondary storage endpoint. + */ + GeoReplicationStatus Status; + /** + * All primary writes preceding this value are guaranteed to be available for read operations + * at the secondary. Primary writes after this point in time may or may not be available for + * reads. This value may be null if replication status is bootstrap or unavailable. + */ + Azure::Nullable LastSyncedOn; + }; // struct GeoReplication + + /** + * @brief Summary of request statistics grouped by API in hour or minute aggregates for queues. + */ + struct Metrics final + { + /** + * The version of storage analytics to configure. + */ + std::string Version; + /** + * Indicates whether metrics are enabled for queue service. + */ + bool IsEnabled = false; + /** + * Determines how long the metrics data should persist. + */ + Models::RetentionPolicy RetentionPolicy; + /** + * Indicates whether metrics should generate summary statistics for called API operations. + */ + Azure::Nullable IncludeApis; + }; // struct Metrics + + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::ClearMessages. + */ + struct ClearMessagesResult final + { + }; // struct ClearMessagesResult + + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::Create. + */ + struct CreateQueueResult final + { + /** + * Indicates if the queue was successfully created in this operation. + */ + bool Created = true; + }; // struct CreateQueueResult + + struct DeleteMessageResult final + { + }; // struct DeleteMessageResult + + /** + * @brief Response type for #Azure::Storage::Queues::QueueClientClient::Delete. + */ + struct DeleteQueueResult final + { + /** + * Indicates if the queue was successfully deleted in this operation. + */ + bool Deleted = true; + }; // struct DeleteQueueResult + + enum class ListQueuesIncludeFlags + { + /** + * No extra data should be included. + */ + None = 0, + /** + * Metadata should be included. + */ + Metadata = 1, + }; // bitwise enum ListQueuesIncludeFlags + + inline ListQueuesIncludeFlags operator|(ListQueuesIncludeFlags lhs, ListQueuesIncludeFlags rhs) + { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) | static_cast(rhs)); + } + + inline ListQueuesIncludeFlags& operator|=( + ListQueuesIncludeFlags& lhs, + ListQueuesIncludeFlags rhs) + { + lhs = lhs | rhs; + return lhs; + } + + inline ListQueuesIncludeFlags operator&(ListQueuesIncludeFlags lhs, ListQueuesIncludeFlags rhs) + { + using type = std::underlying_type_t; + return static_cast(static_cast(lhs) & static_cast(rhs)); + } + + inline ListQueuesIncludeFlags& operator&=( + ListQueuesIncludeFlags& lhs, + ListQueuesIncludeFlags rhs) + { + lhs = lhs & rhs; + return lhs; + } + + /** + * @brief Access policy for a queue. + */ + struct QueueAccessPolicy final + { + /** + * A collection of signed identifiers. + */ + std::vector SignedIdentifiers; + }; // struct QueueAccessPolicy + + /** + * @brief Properties of a queue. + */ + struct QueueProperties final + { + /** + * A set of name-value pairs associated with a queue as user-defined metadata. + */ + Storage::Metadata Metadata; + /** + * The approximate number of messages in the queue. This number is not lower than the actual + * number of messages in the queue, but could be higher. + */ + int64_t ApproximateMessageCount; + }; // struct QueueProperties + + /** + * @brief Properties of queue service. + */ + struct QueueServiceProperties final + { + /** + * Azure analytics logging settings. + */ + AnalyticsLogging Logging; + /** + * Summary of request statistics grouped by API in hour aggregates for queues. + */ + Metrics HourMetrics; + /** + * Summary of request statistics grouped by API in minute aggregates for queues. + */ + Metrics MinuteMetrics; + /** + * CORS rules set. + */ + std::vector Cors; + }; // struct QueueServiceProperties + + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::SendMessage. + */ + struct SendMessageResult final + { + /** + * A GUID value that identifies the message in the queue. + */ + std::string MessageId; + /** + * The time the message was inserted into the queue. + */ + Azure::DateTime InsertedOn; + /** + * The time that the message will expire and be automatically deleted from the queue. + */ + Azure::DateTime ExpiresOn; + /** + * This value is required to delete a message. + */ + std::string PopReceipt; + /** + * The time that the message will again become visible in the queue. + */ + Azure::DateTime NextVisibleOn; + }; // struct SendMessageResult + + /** + * @brief Statistics for the storage service. + */ + struct ServiceStatistics final + { + /** + * Geo-replication information for the secondary storage endpoint. + */ + Models::GeoReplication GeoReplication; + }; // struct ServiceStatistics + + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::SetAccessPolicy. + */ + struct SetQueueAccessPolicyResult final + { + }; // struct SetQueueAccessPolicyResult + + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::SetMetadata. + */ + struct SetQueueMetadataResult final + { + }; // struct SetQueueMetadataResult + + /** + * @brief Response type for #Azure::Storage::Queues::QueueServiceClient::SetProperties. + */ + struct SetServicePropertiesResult final + { + }; // struct SetServicePropertiesResult + + /** + * @brief Response type for #Azure::Storage::Queues::QueueClient::UpdateMessage. + */ + struct UpdateMessageResult final + { + /** + * This value is required to delete a message. + */ + std::string PopReceipt; + /** + * The time that the message will again become visible in the queue. + */ + Azure::DateTime NextVisibleOn; + }; // struct UpdateMessageResult + + namespace _detail { + struct ListQueuesResult final + { + std::string ServiceEndpoint; + std::string Prefix; + Azure::Nullable ContinuationToken; + std::vector Items; + }; // struct ListQueuesResult + } // namespace _detail + + namespace _detail { + struct PeekMessagesResult final + { + std::vector Messages; + }; // struct PeekMessagesResult + } // namespace _detail + + namespace _detail { + struct ReceiveMessagesResult final + { + std::vector Messages; + }; // struct ReceiveMessagesResult + } // namespace _detail + + } // namespace Models + + namespace _detail { + + using namespace Models; + + inline std::string ListQueuesIncludeFlagsToString(const ListQueuesIncludeFlags& val) + { + ListQueuesIncludeFlags value_list[] = { + ListQueuesIncludeFlags::Metadata, + }; + const char* string_list[] = { + "metadata", + }; + std::string ret; + for (size_t i = 0; i < sizeof(value_list) / sizeof(ListQueuesIncludeFlags); ++i) + { + if ((val & value_list[i]) == value_list[i]) + { + if (!ret.empty()) + { + ret += ","; + } + ret += string_list[i]; + } + } + return ret; + } + + class QueueRestClient final { + public: + class Service final { + public: + struct ListQueuesOptions final + { + Azure::Nullable Timeout; + Azure::Nullable Prefix; + Azure::Nullable ContinuationToken; + Azure::Nullable MaxResults; + ListQueuesIncludeFlags Include = ListQueuesIncludeFlags::None; + }; // struct ListQueuesOptions + + static Azure::Response ListQueues( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const ListQueuesOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + request.GetUrl().AppendQueryParameter("comp", "list"); + if (options.Prefix.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.Value())); + } + if (options.ContinuationToken.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "marker", _internal::UrlEncodeQueryParameter(options.ContinuationToken.Value())); + } + if (options.MaxResults.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "maxresults", std::to_string(options.MaxResults.Value())); + } + std::string list_queues_include_flags = ListQueuesIncludeFlagsToString(options.Include); + if (!list_queues_include_flags.empty()) + { + request.GetUrl().AppendQueryParameter( + "include", _internal::UrlEncodeQueryParameter(list_queues_include_flags)); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + Models::_detail::ListQueuesResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 200)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + { + const auto& httpResponseBody = httpResponse.GetBody(); + _internal::XmlReader reader( + reinterpret_cast(httpResponseBody.data()), httpResponseBody.size()); + response = ListQueuesResultInternalFromXml(reader); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct GetServicePropertiesOptions final + { + Azure::Nullable Timeout; + }; // struct GetServicePropertiesOptions + + static Azure::Response GetProperties( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const GetServicePropertiesOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("resttype", "service"); + request.GetUrl().AppendQueryParameter("comp", "properties"); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + QueueServiceProperties response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 200)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + { + const auto& httpResponseBody = httpResponse.GetBody(); + _internal::XmlReader reader( + reinterpret_cast(httpResponseBody.data()), httpResponseBody.size()); + response = QueueServicePropertiesFromXml(reader); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct SetServicePropertiesOptions final + { + Azure::Nullable Timeout; + QueueServiceProperties Properties; + }; // struct SetServicePropertiesOptions + + static Azure::Response SetProperties( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const SetServicePropertiesOptions& options, + const Azure::Core::Context& context) + { + (void)options; + std::string xml_body; + { + _internal::XmlWriter writer; + SetServicePropertiesOptionsToXml(writer, options); + xml_body = writer.GetDocument(); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + } + Azure::Core::IO::MemoryBodyStream xml_body_stream( + reinterpret_cast(xml_body.data()), xml_body.length()); + auto request = Azure::Core::Http::Request( + Azure::Core::Http::HttpMethod::Put, url, &xml_body_stream); + request.SetHeader("Content-Length", std::to_string(xml_body_stream.Length())); + request.GetUrl().AppendQueryParameter("restype", "service"); + request.GetUrl().AppendQueryParameter("comp", "properties"); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + SetServicePropertiesResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 202)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct GetServiceStatisticsOptions final + { + Azure::Nullable Timeout; + }; // struct GetServiceStatisticsOptions + + static Azure::Response GetStatistics( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const GetServiceStatisticsOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url); + request.GetUrl().AppendQueryParameter("restype", "service"); + request.GetUrl().AppendQueryParameter("comp", "stats"); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + ServiceStatistics response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 200)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + { + const auto& httpResponseBody = httpResponse.GetBody(); + _internal::XmlReader reader( + reinterpret_cast(httpResponseBody.data()), httpResponseBody.size()); + response = ServiceStatisticsFromXml(reader); + } + return Azure::Response(std::move(response), std::move(pHttpResponse)); + } + + private: + static Models::_detail::ListQueuesResult ListQueuesResultInternalFromXml( + _internal::XmlReader& reader) + { + Models::_detail::ListQueuesResult ret; + enum class XmlTagName + { + k_EnumerationResults, + k_Prefix, + k_NextMarker, + k_Queues, + k_Queue, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "EnumerationResults") + { + path.emplace_back(XmlTagName::k_EnumerationResults); + } + else if (node.Name == "Prefix") + { + path.emplace_back(XmlTagName::k_Prefix); + } + else if (node.Name == "NextMarker") + { + path.emplace_back(XmlTagName::k_NextMarker); + } + else if (node.Name == "Queues") + { + path.emplace_back(XmlTagName::k_Queues); + } + else if (node.Name == "Queue") + { + path.emplace_back(XmlTagName::k_Queue); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 3 && path[0] == XmlTagName::k_EnumerationResults + && path[1] == XmlTagName::k_Queues && path[2] == XmlTagName::k_Queue) + { + ret.Items.emplace_back(QueueItemFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 2 && path[0] == XmlTagName::k_EnumerationResults + && path[1] == XmlTagName::k_Prefix) + { + ret.Prefix = node.Value; + } + else if ( + path.size() == 2 && path[0] == XmlTagName::k_EnumerationResults + && path[1] == XmlTagName::k_NextMarker) + { + ret.ContinuationToken = node.Value; + } + } + else if (node.Type == _internal::XmlNodeType::Attribute) + { + if (path.size() == 1 && path[0] == XmlTagName::k_EnumerationResults + && node.Name == "ServiceEndpoint") + { + ret.ServiceEndpoint = node.Value; + } + } + } + return ret; + } + + static QueueServiceProperties QueueServicePropertiesFromXml(_internal::XmlReader& reader) + { + QueueServiceProperties ret; + enum class XmlTagName + { + k_StorageServiceProperties, + k_Logging, + k_HourMetrics, + k_MinuteMetrics, + k_Cors, + k_CorsRule, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "StorageServiceProperties") + { + path.emplace_back(XmlTagName::k_StorageServiceProperties); + } + else if (node.Name == "Logging") + { + path.emplace_back(XmlTagName::k_Logging); + } + else if (node.Name == "HourMetrics") + { + path.emplace_back(XmlTagName::k_HourMetrics); + } + else if (node.Name == "MinuteMetrics") + { + path.emplace_back(XmlTagName::k_MinuteMetrics); + } + else if (node.Name == "Cors") + { + path.emplace_back(XmlTagName::k_Cors); + } + else if (node.Name == "CorsRule") + { + path.emplace_back(XmlTagName::k_CorsRule); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 2 && path[0] == XmlTagName::k_StorageServiceProperties + && path[1] == XmlTagName::k_Logging) + { + ret.Logging = AnalyticsLoggingFromXml(reader); + path.pop_back(); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::k_StorageServiceProperties + && path[1] == XmlTagName::k_HourMetrics) + { + ret.HourMetrics = MetricsFromXml(reader); + path.pop_back(); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::k_StorageServiceProperties + && path[1] == XmlTagName::k_MinuteMetrics) + { + ret.MinuteMetrics = MetricsFromXml(reader); + path.pop_back(); + } + else if ( + path.size() == 3 && path[0] == XmlTagName::k_StorageServiceProperties + && path[1] == XmlTagName::k_Cors && path[2] == XmlTagName::k_CorsRule) + { + ret.Cors.emplace_back(CorsRuleFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + } + } + return ret; + } + + static ServiceStatistics ServiceStatisticsFromXml(_internal::XmlReader& reader) + { + ServiceStatistics ret; + enum class XmlTagName + { + k_StorageServiceStats, + k_GeoReplication, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "StorageServiceStats") + { + path.emplace_back(XmlTagName::k_StorageServiceStats); + } + else if (node.Name == "GeoReplication") + { + path.emplace_back(XmlTagName::k_GeoReplication); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 2 && path[0] == XmlTagName::k_StorageServiceStats + && path[1] == XmlTagName::k_GeoReplication) + { + ret.GeoReplication = GeoReplicationFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + } + } + return ret; + } + + static AnalyticsLogging AnalyticsLoggingFromXml(_internal::XmlReader& reader) + { + AnalyticsLogging ret; + enum class XmlTagName + { + k_Version, + k_Delete, + k_Read, + k_Write, + k_RetentionPolicy, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "Version") + { + path.emplace_back(XmlTagName::k_Version); + } + else if (node.Name == "Delete") + { + path.emplace_back(XmlTagName::k_Delete); + } + else if (node.Name == "Read") + { + path.emplace_back(XmlTagName::k_Read); + } + else if (node.Name == "Write") + { + path.emplace_back(XmlTagName::k_Write); + } + else if (node.Name == "RetentionPolicy") + { + path.emplace_back(XmlTagName::k_RetentionPolicy); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 1 && path[0] == XmlTagName::k_RetentionPolicy) + { + ret.RetentionPolicy = RetentionPolicyFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_Version) + { + ret.Version = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_Delete) + { + ret.Delete = node.Value == "true"; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_Read) + { + ret.Read = node.Value == "true"; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_Write) + { + ret.Write = node.Value == "true"; + } + } + } + return ret; + } + + static CorsRule CorsRuleFromXml(_internal::XmlReader& reader) + { + CorsRule ret; + enum class XmlTagName + { + k_AllowedOrigins, + k_AllowedMethods, + k_MaxAgeInSeconds, + k_ExposedHeaders, + k_AllowedHeaders, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "AllowedOrigins") + { + path.emplace_back(XmlTagName::k_AllowedOrigins); + } + else if (node.Name == "AllowedMethods") + { + path.emplace_back(XmlTagName::k_AllowedMethods); + } + else if (node.Name == "MaxAgeInSeconds") + { + path.emplace_back(XmlTagName::k_MaxAgeInSeconds); + } + else if (node.Name == "ExposedHeaders") + { + path.emplace_back(XmlTagName::k_ExposedHeaders); + } + else if (node.Name == "AllowedHeaders") + { + path.emplace_back(XmlTagName::k_AllowedHeaders); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_AllowedOrigins) + { + ret.AllowedOrigins = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_AllowedMethods) + { + ret.AllowedMethods = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_MaxAgeInSeconds) + { + ret.MaxAgeInSeconds = std::stoi(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::k_ExposedHeaders) + { + ret.ExposedHeaders = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_AllowedHeaders) + { + ret.AllowedHeaders = node.Value; + } + } + } + return ret; + } + + static GeoReplication GeoReplicationFromXml(_internal::XmlReader& reader) + { + GeoReplication ret; + enum class XmlTagName + { + k_Status, + k_LastSyncTime, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "Status") + { + path.emplace_back(XmlTagName::k_Status); + } + else if (node.Name == "LastSyncTime") + { + path.emplace_back(XmlTagName::k_LastSyncTime); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_Status) + { + ret.Status = GeoReplicationStatus(node.Value); + } + else if (path.size() == 1 && path[0] == XmlTagName::k_LastSyncTime) + { + ret.LastSyncedOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + } + } + return ret; + } + + static Metrics MetricsFromXml(_internal::XmlReader& reader) + { + Metrics ret; + enum class XmlTagName + { + k_Version, + k_Enabled, + k_IncludeAPIs, + k_RetentionPolicy, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "Version") + { + path.emplace_back(XmlTagName::k_Version); + } + else if (node.Name == "Enabled") + { + path.emplace_back(XmlTagName::k_Enabled); + } + else if (node.Name == "IncludeAPIs") + { + path.emplace_back(XmlTagName::k_IncludeAPIs); + } + else if (node.Name == "RetentionPolicy") + { + path.emplace_back(XmlTagName::k_RetentionPolicy); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 1 && path[0] == XmlTagName::k_RetentionPolicy) + { + ret.RetentionPolicy = RetentionPolicyFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_Version) + { + ret.Version = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_Enabled) + { + ret.IsEnabled = node.Value == "true"; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_IncludeAPIs) + { + ret.IncludeApis = node.Value == "true"; + } + } + } + return ret; + } + + static QueueItem QueueItemFromXml(_internal::XmlReader& reader) + { + QueueItem ret; + enum class XmlTagName + { + k_Name, + k_Metadata, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "Name") + { + path.emplace_back(XmlTagName::k_Name); + } + else if (node.Name == "Metadata") + { + path.emplace_back(XmlTagName::k_Metadata); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 1 && path[0] == XmlTagName::k_Metadata) + { + ret.Metadata = MetadataFromXml(reader); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_Name) + { + ret.Name = node.Value; + } + } + } + return ret; + } + + static Metadata MetadataFromXml(_internal::XmlReader& reader) + { + Metadata ret; + int depth = 0; + std::string key; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (depth++ == 0) + { + key = node.Name; + } + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (depth-- == 0) + { + break; + } + } + else if (depth == 1 && node.Type == _internal::XmlNodeType::Text) + { + ret.emplace(std::move(key), node.Value); + } + } + return ret; + } + + static RetentionPolicy RetentionPolicyFromXml(_internal::XmlReader& reader) + { + RetentionPolicy ret; + enum class XmlTagName + { + k_Enabled, + k_Days, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "Enabled") + { + path.emplace_back(XmlTagName::k_Enabled); + } + else if (node.Name == "Days") + { + path.emplace_back(XmlTagName::k_Days); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_Enabled) + { + ret.IsEnabled = node.Value == "true"; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_Days) + { + ret.Days = std::stoi(node.Value); + } + } + } + return ret; + } + + static void SetServicePropertiesOptionsToXml( + _internal::XmlWriter& writer, + const SetServicePropertiesOptions& options) + { + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::StartTag, "StorageServiceProperties"}); + QueueServicePropertiesToXml(writer, options.Properties); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + static void QueueServicePropertiesToXml( + _internal::XmlWriter& writer, + const QueueServiceProperties& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Logging"}); + AnalyticsLoggingToXml(writer, options.Logging); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "HourMetrics"}); + MetricsToXml(writer, options.HourMetrics); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "MinuteMetrics"}); + MetricsToXml(writer, options.MinuteMetrics); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Cors"}); + for (const auto& i : options.Cors) + { + CorsRuleToXml(writer, i); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + static void AnalyticsLoggingToXml( + _internal::XmlWriter& writer, + const AnalyticsLogging& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Version"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Version}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Delete"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.Delete ? "true" : "false"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Read"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.Read ? "true" : "false"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Write"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.Write ? "true" : "false"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"}); + RetentionPolicyToXml(writer, options.RetentionPolicy); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + static void CorsRuleToXml(_internal::XmlWriter& writer, const CorsRule& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "CorsRule"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "AllowedOrigins"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.AllowedOrigins}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "AllowedMethods"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.AllowedMethods}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "AllowedHeaders"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.AllowedHeaders}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "ExposedHeaders"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.ExposedHeaders}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "MaxAgeInSeconds"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, + std::string(), + std::to_string(options.MaxAgeInSeconds)}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + static void MetricsToXml(_internal::XmlWriter& writer, const Metrics& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Version"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Version}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Enabled"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.IsEnabled ? "true" : "false"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + if (options.IncludeApis.HasValue()) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "IncludeAPIs"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, + std::string(), + options.IncludeApis.Value() ? "true" : "false"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"}); + RetentionPolicyToXml(writer, options.RetentionPolicy); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + static void RetentionPolicyToXml( + _internal::XmlWriter& writer, + const RetentionPolicy& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Enabled"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), options.IsEnabled ? "true" : "false"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + if (options.Days.HasValue()) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Days"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, std::string(), std::to_string(options.Days.Value())}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + } + + }; // class Service + + class Queue final { + public: + struct CreateQueueOptions final + { + Azure::Nullable Timeout; + Storage::Metadata Metadata; + }; // struct CreateQueueOptions + + static Azure::Response Create( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const CreateQueueOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url); + request.SetHeader("Content-Length", "0"); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + for (const auto& pair : options.Metadata) + { + request.SetHeader("x-ms-meta-" + pair.first, pair.second); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + CreateQueueResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 201)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + return Azure::Response(std::move(response), std::move(pHttpResponse)); + } + + struct DeleteQueueOptions final + { + Azure::Nullable Timeout; + }; // struct DeleteQueueOptions + + static Azure::Response Delete( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const DeleteQueueOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Delete, url); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + DeleteQueueResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 202)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + return Azure::Response(std::move(response), std::move(pHttpResponse)); + } + + struct SetQueueMetadataOptions final + { + Azure::Nullable Timeout; + Storage::Metadata Metadata; + }; // struct SetQueueMetadataOptions + + static Azure::Response SetMetadata( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const SetQueueMetadataOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, url); + request.SetHeader("Content-Length", "0"); + request.GetUrl().AppendQueryParameter("comp", "metadata"); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + for (const auto& pair : options.Metadata) + { + request.SetHeader("x-ms-meta-" + pair.first, pair.second); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + SetQueueMetadataResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 200)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct GetQueuePropertiesOptions final + { + Azure::Nullable Timeout; + }; // struct GetQueuePropertiesOptions + + static Azure::Response GetProperties( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const GetQueuePropertiesOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Head, url); + request.GetUrl().AppendQueryParameter("comp", "metadata"); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + QueueProperties response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 200)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + for (auto i = httpResponse.GetHeaders().lower_bound("x-ms-meta-"); + i != httpResponse.GetHeaders().end() && i->first.substr(0, 10) == "x-ms-meta-"; + ++i) + { + response.Metadata.emplace(i->first.substr(10), i->second); + } + response.ApproximateMessageCount + = std::stoll(httpResponse.GetHeaders().at("x-ms-approximate-messages-count")); + return Azure::Response(std::move(response), std::move(pHttpResponse)); + } + + struct GetQueueAccessPolicyOptions final + { + Azure::Nullable Timeout; + }; // struct GetQueueAccessPolicyOptions + + static Azure::Response GetAccessPolicy( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const GetQueueAccessPolicyOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + request.GetUrl().AppendQueryParameter("comp", "acl"); + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + QueueAccessPolicy response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 200)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + { + const auto& httpResponseBody = httpResponse.GetBody(); + _internal::XmlReader reader( + reinterpret_cast(httpResponseBody.data()), httpResponseBody.size()); + response = QueueAccessPolicyFromXml(reader); + } + return Azure::Response(std::move(response), std::move(pHttpResponse)); + } + + struct SetQueueAccessPolicyOptions final + { + Azure::Nullable Timeout; + std::vector SignedIdentifiers; + }; // struct SetQueueAccessPolicyOptions + + static Azure::Response SetAccessPolicy( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const SetQueueAccessPolicyOptions& options, + const Azure::Core::Context& context) + { + (void)options; + std::string xml_body; + { + _internal::XmlWriter writer; + SetQueueAccessPolicyOptionsToXml(writer, options); + xml_body = writer.GetDocument(); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + } + Azure::Core::IO::MemoryBodyStream xml_body_stream( + reinterpret_cast(xml_body.data()), xml_body.length()); + auto request = Azure::Core::Http::Request( + Azure::Core::Http::HttpMethod::Put, url, &xml_body_stream); + request.SetHeader("Content-Length", std::to_string(xml_body_stream.Length())); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + request.GetUrl().AppendQueryParameter("comp", "acl"); + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + SetQueueAccessPolicyResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 204)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct SendMessageOptions final + { + Azure::Nullable Timeout; + std::string Body; + Azure::Nullable VisibilityTimeout; + Azure::Nullable TimeToLive; + }; // struct SendMessageOptions + + static Azure::Response SendMessage( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const SendMessageOptions& options, + const Azure::Core::Context& context) + { + (void)options; + std::string xml_body; + { + _internal::XmlWriter writer; + SendMessageOptionsToXml(writer, options); + xml_body = writer.GetDocument(); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + } + Azure::Core::IO::MemoryBodyStream xml_body_stream( + reinterpret_cast(xml_body.data()), xml_body.length()); + auto request = Azure::Core::Http::Request( + Azure::Core::Http::HttpMethod::Post, url, &xml_body_stream); + request.SetHeader("Content-Length", std::to_string(xml_body_stream.Length())); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + if (options.VisibilityTimeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "visibilitytimeout", std::to_string(options.VisibilityTimeout.Value())); + } + if (options.TimeToLive.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "messagettl", std::to_string(options.TimeToLive.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + SendMessageResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 201)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + { + const auto& httpResponseBody = httpResponse.GetBody(); + _internal::XmlReader reader( + reinterpret_cast(httpResponseBody.data()), httpResponseBody.size()); + response = SendMessageResultFromXml(reader); + } + return Azure::Response(std::move(response), std::move(pHttpResponse)); + } + + struct ReceiveMessagesOptions final + { + Azure::Nullable Timeout; + Azure::Nullable MaxMessages; + Azure::Nullable VisibilityTimeout; + }; // struct ReceiveMessagesOptions + + static Azure::Response ReceiveMessages( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const ReceiveMessagesOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + if (options.MaxMessages.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "numofmessages", std::to_string(options.MaxMessages.Value())); + } + if (options.VisibilityTimeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "visibilitytimeout", std::to_string(options.VisibilityTimeout.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + Models::_detail::ReceiveMessagesResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 200)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + { + const auto& httpResponseBody = httpResponse.GetBody(); + _internal::XmlReader reader( + reinterpret_cast(httpResponseBody.data()), httpResponseBody.size()); + response = ReceiveMessagesResultInternalFromXml(reader); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct PeekMessagesOptions final + { + Azure::Nullable Timeout; + Azure::Nullable MaxMessages; + }; // struct PeekMessagesOptions + + static Azure::Response PeekMessages( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const PeekMessagesOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, url); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + request.GetUrl().AppendQueryParameter("peekonly", "true"); + if (options.MaxMessages.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "numofmessages", std::to_string(options.MaxMessages.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + Models::_detail::PeekMessagesResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 200)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + { + const auto& httpResponseBody = httpResponse.GetBody(); + _internal::XmlReader reader( + reinterpret_cast(httpResponseBody.data()), httpResponseBody.size()); + response = PeekMessagesResultInternalFromXml(reader); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct DeleteMessageOptions final + { + Azure::Nullable Timeout; + std::string PopReceipt; + }; // struct DeleteMessageOptions + + static Azure::Response DeleteMessage( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const DeleteMessageOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Delete, url); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + request.GetUrl().AppendQueryParameter( + "popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt)); + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + DeleteMessageResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 204)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct ClearMessagesOptions final + { + Azure::Nullable Timeout; + }; // struct ClearMessagesOptions + + static Azure::Response ClearMessages( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const ClearMessagesOptions& options, + const Azure::Core::Context& context) + { + (void)options; + auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Delete, url); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + ClearMessagesResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 204)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + struct UpdateMessageOptions final + { + std::string Body; + Azure::Nullable Timeout; + std::string PopReceipt; + int32_t VisibilityTimeout; + }; // struct UpdateMessageOptions + + static Azure::Response UpdateMessage( + Azure::Core::Http::_internal::HttpPipeline& pipeline, + const Azure::Core::Url& url, + const UpdateMessageOptions& options, + const Azure::Core::Context& context) + { + (void)options; + std::string xml_body; + { + _internal::XmlWriter writer; + UpdateMessageOptionsToXml(writer, options); + xml_body = writer.GetDocument(); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::End}); + } + Azure::Core::IO::MemoryBodyStream xml_body_stream( + reinterpret_cast(xml_body.data()), xml_body.length()); + auto request = Azure::Core::Http::Request( + Azure::Core::Http::HttpMethod::Put, url, &xml_body_stream); + request.SetHeader("Content-Length", std::to_string(xml_body_stream.Length())); + request.SetHeader("x-ms-version", "2018-03-28"); + if (options.Timeout.HasValue()) + { + request.GetUrl().AppendQueryParameter( + "timeout", std::to_string(options.Timeout.Value())); + } + request.GetUrl().AppendQueryParameter( + "popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt)); + request.GetUrl().AppendQueryParameter( + "visibilitytimeout", std::to_string(options.VisibilityTimeout)); + auto pHttpResponse = pipeline.Send(request, context); + Azure::Core::Http::RawResponse& httpResponse = *pHttpResponse; + UpdateMessageResult response; + auto http_status_code + = static_cast::type>( + httpResponse.GetStatusCode()); + if (!(http_status_code == 204)) + { + throw StorageException::CreateFromResponse(std::move(pHttpResponse)); + } + response.PopReceipt = httpResponse.GetHeaders().at("x-ms-popreceipt"); + response.NextVisibleOn = Azure::DateTime::Parse( + httpResponse.GetHeaders().at("x-ms-time-next-visible"), + Azure::DateTime::DateFormat::Rfc1123); + return Azure::Response( + std::move(response), std::move(pHttpResponse)); + } + + private: + static Models::_detail::PeekMessagesResult PeekMessagesResultInternalFromXml( + _internal::XmlReader& reader) + { + Models::_detail::PeekMessagesResult ret; + enum class XmlTagName + { + k_QueueMessagesList, + k_QueueMessage, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "QueueMessagesList") + { + path.emplace_back(XmlTagName::k_QueueMessagesList); + } + else if (node.Name == "QueueMessage") + { + path.emplace_back(XmlTagName::k_QueueMessage); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 2 && path[0] == XmlTagName::k_QueueMessagesList + && path[1] == XmlTagName::k_QueueMessage) + { + ret.Messages.emplace_back(PeekedQueueMessageFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + } + } + return ret; + } + + static Models::_detail::ReceiveMessagesResult ReceiveMessagesResultInternalFromXml( + _internal::XmlReader& reader) + { + Models::_detail::ReceiveMessagesResult ret; + enum class XmlTagName + { + k_QueueMessagesList, + k_QueueMessage, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "QueueMessagesList") + { + path.emplace_back(XmlTagName::k_QueueMessagesList); + } + else if (node.Name == "QueueMessage") + { + path.emplace_back(XmlTagName::k_QueueMessage); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 2 && path[0] == XmlTagName::k_QueueMessagesList + && path[1] == XmlTagName::k_QueueMessage) + { + ret.Messages.emplace_back(QueueMessageFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + } + } + return ret; + } + + static QueueAccessPolicy QueueAccessPolicyFromXml(_internal::XmlReader& reader) + { + QueueAccessPolicy ret; + enum class XmlTagName + { + k_SignedIdentifiers, + k_SignedIdentifier, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "SignedIdentifiers") + { + path.emplace_back(XmlTagName::k_SignedIdentifiers); + } + else if (node.Name == "SignedIdentifier") + { + path.emplace_back(XmlTagName::k_SignedIdentifier); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + if (path.size() == 2 && path[0] == XmlTagName::k_SignedIdentifiers + && path[1] == XmlTagName::k_SignedIdentifier) + { + ret.SignedIdentifiers.emplace_back(SignedIdentifierFromXml(reader)); + path.pop_back(); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + } + } + return ret; + } + + static SendMessageResult SendMessageResultFromXml(_internal::XmlReader& reader) + { + SendMessageResult ret; + enum class XmlTagName + { + k_QueueMessagesList, + k_QueueMessage, + k_MessageId, + k_InsertionTime, + k_ExpirationTime, + k_PopReceipt, + k_TimeNextVisible, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "QueueMessagesList") + { + path.emplace_back(XmlTagName::k_QueueMessagesList); + } + else if (node.Name == "QueueMessage") + { + path.emplace_back(XmlTagName::k_QueueMessage); + } + else if (node.Name == "MessageId") + { + path.emplace_back(XmlTagName::k_MessageId); + } + else if (node.Name == "InsertionTime") + { + path.emplace_back(XmlTagName::k_InsertionTime); + } + else if (node.Name == "ExpirationTime") + { + path.emplace_back(XmlTagName::k_ExpirationTime); + } + else if (node.Name == "PopReceipt") + { + path.emplace_back(XmlTagName::k_PopReceipt); + } + else if (node.Name == "TimeNextVisible") + { + path.emplace_back(XmlTagName::k_TimeNextVisible); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 3 && path[0] == XmlTagName::k_QueueMessagesList + && path[1] == XmlTagName::k_QueueMessage && path[2] == XmlTagName::k_MessageId) + { + ret.MessageId = node.Value; + } + else if ( + path.size() == 3 && path[0] == XmlTagName::k_QueueMessagesList + && path[1] == XmlTagName::k_QueueMessage + && path[2] == XmlTagName::k_InsertionTime) + { + ret.InsertedOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + path.size() == 3 && path[0] == XmlTagName::k_QueueMessagesList + && path[1] == XmlTagName::k_QueueMessage + && path[2] == XmlTagName::k_ExpirationTime) + { + ret.ExpiresOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if ( + path.size() == 3 && path[0] == XmlTagName::k_QueueMessagesList + && path[1] == XmlTagName::k_QueueMessage && path[2] == XmlTagName::k_PopReceipt) + { + ret.PopReceipt = node.Value; + } + else if ( + path.size() == 3 && path[0] == XmlTagName::k_QueueMessagesList + && path[1] == XmlTagName::k_QueueMessage + && path[2] == XmlTagName::k_TimeNextVisible) + { + ret.NextVisibleOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + } + } + return ret; + } + + static PeekedQueueMessage PeekedQueueMessageFromXml(_internal::XmlReader& reader) + { + PeekedQueueMessage ret; + enum class XmlTagName + { + k_MessageText, + k_MessageId, + k_InsertionTime, + k_ExpirationTime, + k_DequeueCount, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "MessageText") + { + path.emplace_back(XmlTagName::k_MessageText); + } + else if (node.Name == "MessageId") + { + path.emplace_back(XmlTagName::k_MessageId); + } + else if (node.Name == "InsertionTime") + { + path.emplace_back(XmlTagName::k_InsertionTime); + } + else if (node.Name == "ExpirationTime") + { + path.emplace_back(XmlTagName::k_ExpirationTime); + } + else if (node.Name == "DequeueCount") + { + path.emplace_back(XmlTagName::k_DequeueCount); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_MessageText) + { + ret.Body = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_MessageId) + { + ret.MessageId = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_InsertionTime) + { + ret.InsertedOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if (path.size() == 1 && path[0] == XmlTagName::k_ExpirationTime) + { + ret.ExpiresOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if (path.size() == 1 && path[0] == XmlTagName::k_DequeueCount) + { + ret.DequeueCount = std::stoll(node.Value); + } + } + } + return ret; + } + + static QueueMessage QueueMessageFromXml(_internal::XmlReader& reader) + { + QueueMessage ret; + enum class XmlTagName + { + k_MessageText, + k_MessageId, + k_InsertionTime, + k_ExpirationTime, + k_PopReceipt, + k_TimeNextVisible, + k_DequeueCount, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "MessageText") + { + path.emplace_back(XmlTagName::k_MessageText); + } + else if (node.Name == "MessageId") + { + path.emplace_back(XmlTagName::k_MessageId); + } + else if (node.Name == "InsertionTime") + { + path.emplace_back(XmlTagName::k_InsertionTime); + } + else if (node.Name == "ExpirationTime") + { + path.emplace_back(XmlTagName::k_ExpirationTime); + } + else if (node.Name == "PopReceipt") + { + path.emplace_back(XmlTagName::k_PopReceipt); + } + else if (node.Name == "TimeNextVisible") + { + path.emplace_back(XmlTagName::k_TimeNextVisible); + } + else if (node.Name == "DequeueCount") + { + path.emplace_back(XmlTagName::k_DequeueCount); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_MessageText) + { + ret.Body = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_MessageId) + { + ret.MessageId = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_InsertionTime) + { + ret.InsertedOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if (path.size() == 1 && path[0] == XmlTagName::k_ExpirationTime) + { + ret.ExpiresOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if (path.size() == 1 && path[0] == XmlTagName::k_PopReceipt) + { + ret.PopReceipt = node.Value; + } + else if (path.size() == 1 && path[0] == XmlTagName::k_TimeNextVisible) + { + ret.NextVisibleOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123); + } + else if (path.size() == 1 && path[0] == XmlTagName::k_DequeueCount) + { + ret.DequeueCount = std::stoll(node.Value); + } + } + } + return ret; + } + + static SignedIdentifier SignedIdentifierFromXml(_internal::XmlReader& reader) + { + SignedIdentifier ret; + enum class XmlTagName + { + k_Id, + k_AccessPolicy, + k_Start, + k_Expiry, + k_Permission, + k_Unknown, + }; + std::vector path; + while (true) + { + auto node = reader.Read(); + if (node.Type == _internal::XmlNodeType::End) + { + break; + } + else if (node.Type == _internal::XmlNodeType::EndTag) + { + if (path.size() > 0) + { + path.pop_back(); + } + else + { + break; + } + } + else if (node.Type == _internal::XmlNodeType::StartTag) + { + if (node.Name == "Id") + { + path.emplace_back(XmlTagName::k_Id); + } + else if (node.Name == "AccessPolicy") + { + path.emplace_back(XmlTagName::k_AccessPolicy); + } + else if (node.Name == "Start") + { + path.emplace_back(XmlTagName::k_Start); + } + else if (node.Name == "Expiry") + { + path.emplace_back(XmlTagName::k_Expiry); + } + else if (node.Name == "Permission") + { + path.emplace_back(XmlTagName::k_Permission); + } + else + { + path.emplace_back(XmlTagName::k_Unknown); + } + } + else if (node.Type == _internal::XmlNodeType::Text) + { + if (path.size() == 1 && path[0] == XmlTagName::k_Id) + { + ret.Id = node.Value; + } + else if ( + path.size() == 2 && path[0] == XmlTagName::k_AccessPolicy + && path[1] == XmlTagName::k_Start) + { + ret.StartsOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::k_AccessPolicy + && path[1] == XmlTagName::k_Expiry) + { + ret.ExpiresOn + = Azure::DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339); + } + else if ( + path.size() == 2 && path[0] == XmlTagName::k_AccessPolicy + && path[1] == XmlTagName::k_Permission) + { + ret.Permissions = node.Value; + } + } + } + return ret; + } + + static void SendMessageOptionsToXml( + _internal::XmlWriter& writer, + const SendMessageOptions& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "QueueMessage"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "MessageText"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Body}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + static void SetQueueAccessPolicyOptionsToXml( + _internal::XmlWriter& writer, + const SetQueueAccessPolicyOptions& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "SignedIdentifiers"}); + for (const auto& i : options.SignedIdentifiers) + { + SignedIdentifierToXml(writer, i); + } + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + static void UpdateMessageOptionsToXml( + _internal::XmlWriter& writer, + const UpdateMessageOptions& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "QueueMessage"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "MessageText"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Body}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + static void SignedIdentifierToXml( + _internal::XmlWriter& writer, + const SignedIdentifier& options) + { + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "SignedIdentifier"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Id"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Id}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "AccessPolicy"}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Start"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, + std::string(), + options.StartsOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, + Azure::DateTime::TimeFractionFormat::AllDigits)}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Expiry"}); + writer.Write(_internal::XmlNode{ + _internal::XmlNodeType::Text, + std::string(), + options.ExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, + Azure::DateTime::TimeFractionFormat::AllDigits)}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Permission"}); + writer.Write( + _internal::XmlNode{_internal::XmlNodeType::Text, std::string(), options.Permissions}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag}); + } + + }; // class Queue + + }; // class QueueRestClient + + } // namespace _detail + +}}} // namespace Azure::Storage::Queues diff --git a/sdk/storage/azure-storage-queues/sample/queue_getting_started.cpp b/sdk/storage/azure-storage-queues/sample/queue_getting_started.cpp new file mode 100644 index 000000000..bb21d19ff --- /dev/null +++ b/sdk/storage/azure-storage-queues/sample/queue_getting_started.cpp @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include + +#include "samples_common.hpp" + +SAMPLE(QueuesGettingStarted, QueuesGettingStarted) +void QueuesGettingStarted() {} diff --git a/sdk/storage/azure-storage-queues/src/private/package_version.hpp b/sdk/storage/azure-storage-queues/src/private/package_version.hpp new file mode 100644 index 000000000..817761f96 --- /dev/null +++ b/sdk/storage/azure-storage-queues/src/private/package_version.hpp @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +/** + * @file + * @brief Provides version information. + */ + +#pragma once + +#define AZURE_STORAGE_QUEUES_VERSION_MAJOR 12 +#define AZURE_STORAGE_QUEUES_VERSION_MINOR 1 +#define AZURE_STORAGE_QUEUES_VERSION_PATCH 0 +#define AZURE_STORAGE_QUEUES_VERSION_PRERELEASE "beta.1" + +#define AZURE_STORAGE_QUEUES_VERSION_ITOA_HELPER(i) #i +#define AZURE_STORAGE_QUEUES_VERSION_ITOA(i) AZURE_STORAGE_QUEUES_VERSION_ITOA_HELPER(i) + +namespace Azure { namespace Storage { namespace Queues { namespace _detail { + /** + * @brief Provides version information. + */ + class PackageVersion final { + public: + /// Major numeric identifier. + static constexpr int32_t Major = AZURE_STORAGE_QUEUES_VERSION_MAJOR; + + /// Minor numeric identifier. + static constexpr int32_t Minor = AZURE_STORAGE_QUEUES_VERSION_MINOR; + + /// Patch numeric identifier. + static constexpr int32_t Patch = AZURE_STORAGE_QUEUES_VERSION_PATCH; + + /// Indicates whether the SDK is in a pre-release state. + static constexpr bool IsPreRelease + = sizeof(AZURE_STORAGE_QUEUES_VERSION_PRERELEASE) != sizeof(""); + + /** + * @brief The version in string format used for telemetry following the `semver.org` standard + * (https://semver.org). + */ + static constexpr const char* ToString() + { + return IsPreRelease + ? AZURE_STORAGE_QUEUES_VERSION_ITOA(AZURE_STORAGE_QUEUES_VERSION_MAJOR) "." AZURE_STORAGE_QUEUES_VERSION_ITOA( + AZURE_STORAGE_QUEUES_VERSION_MINOR) "." AZURE_STORAGE_QUEUES_VERSION_ITOA(AZURE_STORAGE_QUEUES_VERSION_PATCH) "-" AZURE_STORAGE_QUEUES_VERSION_PRERELEASE + : AZURE_STORAGE_QUEUES_VERSION_ITOA(AZURE_STORAGE_QUEUES_VERSION_MAJOR) "." AZURE_STORAGE_QUEUES_VERSION_ITOA( + AZURE_STORAGE_QUEUES_VERSION_MINOR) "." AZURE_STORAGE_QUEUES_VERSION_ITOA(AZURE_STORAGE_QUEUES_VERSION_PATCH); + } + }; +}}}} // namespace Azure::Storage::Queues::_detail + +#undef AZURE_STORAGE_QUEUES_VERSION_ITOA_HELPER +#undef AZURE_STORAGE_QUEUES_VERSION_ITOA + +#undef AZURE_STORAGE_QUEUES_VERSION_MAJOR +#undef AZURE_STORAGE_QUEUES_VERSION_MINOR +#undef AZURE_STORAGE_QUEUES_VERSION_PATCH +#undef AZURE_STORAGE_QUEUES_VERSION_PRERELEASE diff --git a/sdk/storage/azure-storage-queues/src/queue_rest_client.cpp b/sdk/storage/azure-storage-queues/src/queue_rest_client.cpp new file mode 100644 index 000000000..b6e0e1229 --- /dev/null +++ b/sdk/storage/azure-storage-queues/src/queue_rest_client.cpp @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include "azure/storage/queues/protocol/queue_rest_client.hpp" + +namespace Azure { namespace Storage { namespace Queues { namespace Models { + + const GeoReplicationStatus GeoReplicationStatus::Live("live"); + const GeoReplicationStatus GeoReplicationStatus::Bootstrap("bootstrap"); + const GeoReplicationStatus GeoReplicationStatus::Unavailable("unavailable"); + +}}}} // namespace Azure::Storage::Queues::Models diff --git a/sdk/storage/azure-storage-queues/test/ut/macro_guard.cpp b/sdk/storage/azure-storage-queues/test/ut/macro_guard.cpp new file mode 100644 index 000000000..1a5f2c2d2 --- /dev/null +++ b/sdk/storage/azure-storage-queues/test/ut/macro_guard.cpp @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +// Define `min` and `max` as function-like macros before including all public +// headers to ensure that uses of those identifiers are defended against +// expansion as function-like macros. Define `small` as an object-like macro to +// ensure that identifier isn't used at all. Windows.h is badly behaved and +// defines similar macros with these names and we want to ensure the SDK headers +// function even when a naive user includes Windows.h first. +// +#define small FAIL> diff --git a/sdk/storage/azure-storage-queues/vcpkg/Config.cmake.in b/sdk/storage/azure-storage-queues/vcpkg/Config.cmake.in new file mode 100644 index 000000000..c4e0f7367 --- /dev/null +++ b/sdk/storage/azure-storage-queues/vcpkg/Config.cmake.in @@ -0,0 +1,11 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(azure-storage-common-cpp) + +include("${CMAKE_CURRENT_LIST_DIR}/azure-storage-queues-cppTargets.cmake") + +check_required_components("azure-storage-queues-cpp") diff --git a/sdk/storage/azure-storage-queues/vcpkg/portfile.cmake b/sdk/storage/azure-storage-queues/vcpkg/portfile.cmake new file mode 100644 index 000000000..6ebf04418 --- /dev/null +++ b/sdk/storage/azure-storage-queues/vcpkg/portfile.cmake @@ -0,0 +1,22 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO Azure/azure-sdk-for-cpp + REF azure-storage-queues_@AZ_LIBRARY_VERSION@ + SHA512 1 +) + +vcpkg_cmake_configure( + SOURCE_PATH ${SOURCE_PATH}/sdk/storage/azure-storage-queues/ + PREFER_NINJA + OPTIONS + -DWARNINGS_AS_ERRORS=OFF +) + +vcpkg_cmake_install() +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +vcpkg_cmake_config_fixup() +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share") +vcpkg_copy_pdbs() diff --git a/sdk/storage/azure-storage-queues/vcpkg/vcpkg.json b/sdk/storage/azure-storage-queues/vcpkg/vcpkg.json new file mode 100644 index 000000000..2933623e9 --- /dev/null +++ b/sdk/storage/azure-storage-queues/vcpkg/vcpkg.json @@ -0,0 +1,28 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +{ + "name": "azure-storage-queues-cpp", + "version-semver": "@AZ_LIBRARY_VERSION@", + "description": [ + "Microsoft Azure Storage Queues SDK for C++", + "This library provides Azure Storage Queues SDK." + ], + "homepage": "https://github.com/Azure/azure-sdk-for-cpp/tree/main/sdk/storage/azure-storage-queues", + "license": "MIT", + "dependencies": [ + { + "name": "azure-storage-common-cpp", + "default-features": false, + "version>=": "12.0.0" + }, + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} diff --git a/sdk/storage/ci.yml b/sdk/storage/ci.yml index c003f40ed..b931d800f 100644 --- a/sdk/storage/ci.yml +++ b/sdk/storage/ci.yml @@ -53,3 +53,6 @@ stages: - Name: azure-storage-files-shares Path: azure-storage-files-shares VcpkgPortName: azure-storage-files-shares-cpp + - Name: azure-storage-queues + Path: azure-storage-queues + VcpkgPortName: azure-storage-queues-cpp