├── .actrc ├── .clang-format ├── .clang-tidy ├── .cmake-format.py ├── .codecov.yml ├── .dockerignore ├── .github ├── CODEOWNERS ├── renovate.json ├── snippet-bot.yml ├── trusted-contribution.yml └── workflows │ ├── build.yaml │ ├── coverage.yaml │ ├── install.yaml │ └── style.yaml ├── .gitignore ├── CHANGELOG.md ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build_scripts ├── Dockerfile ├── README.md ├── pack.Dockerfile └── vcpkg-overlays │ ├── portfile.cmake │ └── vcpkg.json ├── ci ├── README.md ├── abi-dumps │ └── functions_framework_cpp.expected.abi.dump.gz ├── build-examples.yaml ├── cloudbuild │ ├── README.md │ ├── build.sh │ ├── builds │ │ ├── check-api.sh │ │ ├── clang-16.0.sh │ │ ├── clang-tidy.sh │ │ ├── gcc-13.1.sh │ │ ├── lib │ │ │ ├── cmake.sh │ │ │ └── vcpkg.sh │ │ ├── sanitize-address.sh │ │ ├── sanitize-thread.sh │ │ └── sanitize-undefined.sh │ ├── cache.sh │ ├── cloudbuild.yaml │ ├── dockerfiles │ │ └── fedora-38.Dockerfile │ ├── trigger.sh │ └── triggers │ │ ├── check-api-ci.yaml │ │ ├── check-api-pr.yaml │ │ ├── clang-16-0-ci.yaml │ │ ├── clang-16-0-pr.yaml │ │ ├── clang-tidy-ci.yaml │ │ ├── clang-tidy-pr.yaml │ │ ├── gcc-13-1-ci.yaml │ │ ├── gcc-13-1-pr.yaml │ │ ├── pr.yaml │ │ ├── push.yaml │ │ ├── sanitize-address-ci.yaml │ │ ├── sanitize-address-pr.yaml │ │ ├── sanitize-thread-ci.yaml │ │ ├── sanitize-thread-pr.yaml │ │ ├── sanitize-undefined-ci.yaml │ │ └── sanitize-undefined-pr.yaml ├── etc │ └── vcpkg-config.sh ├── generate-build-examples.sh ├── lib │ ├── init.sh │ ├── io.sh │ └── module ├── pack │ ├── builder.toml │ └── buildpack │ │ ├── bin │ │ ├── build │ │ └── detect │ │ └── buildpack.toml ├── restore-vcpkg-from-cache.sh ├── test_install │ ├── CMakeLists.txt │ ├── README.md │ └── test_install.cc └── update-markdown-code-snippets.sh ├── cmake ├── BuildMetadata.cmake ├── FunctionsFrameworkCppHelpers.cmake └── InstallHeaders.cmake ├── docs └── code-of-conduct.md ├── examples ├── CMakeLists.txt ├── README.md ├── cloud_event_examples_test.cc ├── hello_cloud_event │ └── hello_cloud_event.cc ├── hello_from_namespace │ └── hello_from_namespace.cc ├── hello_from_nested_namespace │ └── hello_from_nested_namespace.cc ├── hello_gcs │ ├── CMakeLists.txt │ ├── hello_gcs.cc │ └── vcpkg.json ├── hello_multiple_sources │ ├── greeting.cc │ ├── greeting.h │ └── hello_multiple_sources.cc ├── hello_with_third_party │ ├── CMakeLists.txt │ ├── hello_with_third_party.cc │ └── vcpkg.json ├── hello_world │ └── hello_world.cc ├── howto-guides.md ├── howto_use_legacy_code │ ├── CMakeLists.txt │ ├── README.md │ ├── howto_use_legacy_code.cc │ ├── legacy │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── legacy.cc │ │ └── legacy.h │ ├── main.cc │ └── vcpkg.json ├── http_examples_test.cc ├── site │ ├── bearer_token │ │ ├── CMakeLists.txt │ │ ├── bearer_token.cc │ │ └── vcpkg.json │ ├── concepts_after_response │ │ └── concepts_after_response.cc │ ├── concepts_after_timeout │ │ └── concepts_after_timeout.cc │ ├── concepts_filesystem │ │ ├── CMakeLists.txt │ │ └── concepts_filesystem.cc │ ├── concepts_request │ │ └── concepts_request.cc │ ├── concepts_stateless │ │ └── concepts_stateless.cc │ ├── env_vars │ │ └── env_vars.cc │ ├── hello_world_error │ │ ├── hello_world_error.cc │ │ └── vcpkg.json │ ├── hello_world_get │ │ └── hello_world_get.cc │ ├── hello_world_http │ │ └── hello_world_http.cc │ ├── hello_world_pubsub │ │ ├── CMakeLists.txt │ │ ├── hello_world_pubsub.cc │ │ └── vcpkg.json │ ├── hello_world_storage │ │ ├── CMakeLists.txt │ │ ├── hello_world_storage.cc │ │ └── vcpkg.json │ ├── howto_create_container │ │ └── README.md │ ├── howto_deploy_cloud_event │ │ └── README.md │ ├── howto_deploy_to_cloud_run │ │ └── README.md │ ├── howto_local_development │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── local_server.cc │ │ └── vcpkg.json │ ├── http_content │ │ ├── http_content.cc │ │ └── vcpkg.json │ ├── http_cors │ │ └── http_cors.cc │ ├── http_cors_auth │ │ └── http_cors_auth.cc │ ├── http_form_data │ │ ├── CMakeLists.txt │ │ ├── http_form_data.cc │ │ └── vcpkg.json │ ├── http_method │ │ └── http_method.cc │ ├── http_xml │ │ ├── http_xml.cc │ │ └── vcpkg.json │ ├── log_helloworld │ │ ├── log_helloworld.cc │ │ └── vcpkg.json │ ├── log_stackdriver │ │ ├── log_stackdriver.cc │ │ └── vcpkg.json │ ├── pubsub_subscribe │ │ └── pubsub_subscribe.cc │ ├── testing_http │ │ ├── CMakeLists.txt │ │ ├── http_integration_server.cc │ │ ├── http_integration_test.cc │ │ └── http_unit_test.cc │ ├── testing_pubsub │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── pubsub_integration_server.cc │ │ ├── pubsub_integration_test.cc │ │ ├── pubsub_system_test.cc │ │ └── pubsub_unit_test.cc │ ├── testing_storage │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── storage_integration_server.cc │ │ ├── storage_integration_test.cc │ │ ├── storage_system_test.cc │ │ └── storage_unit_test.cc │ ├── tips_gcp_apis │ │ ├── CMakeLists.txt │ │ ├── tips_gcp_apis.cc │ │ └── vcpkg.json │ ├── tips_infinite_retries │ │ └── tips_infinite_retries.cc │ ├── tips_lazy_globals │ │ └── tips_lazy_globals.cc │ ├── tips_retry │ │ └── tips_retry.cc │ ├── tips_scopes │ │ └── tips_scopes.cc │ ├── tutorial_cloud_bigtable │ │ ├── CMakeLists.txt │ │ ├── tutorial_cloud_bigtable.cc │ │ └── vcpkg.json │ └── tutorial_cloud_spanner │ │ ├── CMakeLists.txt │ │ ├── tutorial_cloud_spanner.cc │ │ └── vcpkg.json └── site_test.cc ├── google └── cloud │ └── functions │ ├── CMakeLists.txt │ ├── cloud_event.cc │ ├── cloud_event.h │ ├── cloud_event_test.cc │ ├── config.cmake.in │ ├── config.pc.in │ ├── framework.h │ ├── function.cc │ ├── function.h │ ├── http_request.h │ ├── http_request_test.cc │ ├── http_response.cc │ ├── http_response.h │ ├── http_response_test.cc │ ├── integration_tests │ ├── CMakeLists.txt │ ├── basic_integration_test.cc │ ├── cloud_event_conformance.cc │ ├── cloud_event_handler.cc │ ├── cloud_event_integration_test.cc │ ├── echo_server.cc │ └── http_conformance.cc │ ├── internal │ ├── base64_decode.cc │ ├── base64_decode.h │ ├── base64_decode_test.cc │ ├── build_info.cc.in │ ├── build_info.h │ ├── call_user_function.cc │ ├── call_user_function.h │ ├── call_user_function_test.cc │ ├── compiler_info.cc │ ├── compiler_info.h │ ├── compiler_info_test.cc │ ├── framework_impl.cc │ ├── framework_impl.h │ ├── framework_impl_test.cc │ ├── function_impl.cc │ ├── function_impl.h │ ├── function_impl_test.cc │ ├── http_message_types.h │ ├── parse_cloud_event_http.cc │ ├── parse_cloud_event_http.h │ ├── parse_cloud_event_http_test.cc │ ├── parse_cloud_event_json.cc │ ├── parse_cloud_event_json.h │ ├── parse_cloud_event_json_test.cc │ ├── parse_cloud_event_legacy.cc │ ├── parse_cloud_event_legacy.h │ ├── parse_cloud_event_legacy_test.cc │ ├── parse_cloud_event_storage.cc │ ├── parse_cloud_event_storage.h │ ├── parse_cloud_event_storage_test.cc │ ├── parse_options.cc │ ├── parse_options.h │ ├── parse_options_test.cc │ ├── setenv.cc │ ├── setenv.h │ ├── version_info.h │ ├── version_info.h.in │ ├── wrap_request.cc │ ├── wrap_request.h │ ├── wrap_request_test.cc │ ├── wrap_response.cc │ └── wrap_response.h │ ├── user_functions.h │ ├── version.cc │ ├── version.h │ └── version_test.cc ├── release └── cutting-a-release.md └── vcpkg.json /.actrc: -------------------------------------------------------------------------------- 1 | # act is a tool to run GitHub actions locally. This 2 | # configuration file makes it easy to use with our code. 3 | -P ubuntu-latest=nektos/act-environments-ubuntu:18.04 4 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | # Use the Google style in this project. 2 | BasedOnStyle: Google 3 | 4 | # Some folks prefer to write "int& foo" while others prefer "int &foo". The 5 | # Google Style Guide only asks for consistency within a project, we chose 6 | # "int& foo" for this project: 7 | DerivePointerAlignment: false 8 | PointerAlignment: Left 9 | 10 | IncludeBlocks: Merge 11 | IncludeCategories: 12 | # Matches common headers first, but sorts them after project includes 13 | - Regex: '^\"google/cloud/functions/internal/' 14 | Priority: 100 15 | - Regex: '^\"google/cloud/functions/' 16 | Priority: 400 17 | - Regex: '^\"google/cloud/' # project includes should sort first 18 | Priority: 500 19 | - Regex: '^\"' 20 | Priority: 1500 21 | - Regex: '^' 28 | Priority: 5000 29 | 30 | # Format raw string literals with a `pb` or `proto` tag as proto. 31 | RawStringFormats: 32 | - Language: TextProto 33 | Delimiters: 34 | - 'pb' 35 | - 'proto' 36 | BasedOnStyle: Google 37 | 38 | CommentPragmas: '(@copydoc)' 39 | -------------------------------------------------------------------------------- /.cmake-format.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | tab_size = 4 16 | separate_ctrl_name_with_space = True 17 | enable_sort = True 18 | autosort = True 19 | 20 | additional_commands = { 21 | "externalproject_add": { 22 | "flags": [], 23 | "kwargs": { 24 | "BUILD_COMMAND": "+", 25 | "BUILD_BYPRODUCTS": "+", 26 | "CMAKE_ARGS": "+", 27 | "COMMAND": "+", 28 | "CONFIGURE_COMMAND": "+", 29 | "DEPENDS": "+", 30 | "DOWNLOAD_COMMAND": "+", 31 | "EXCLUDE_FROM_ALL": 1, 32 | "INSTALL_COMMAND": "+", 33 | "INSTALL_DIR": 1, 34 | "LIST_SEPARATOR": 1, 35 | "TEST_COMMAND": "+", 36 | "PATCH_COMMAND": "+", 37 | "LOG_BUILD": 1, 38 | "LOG_CONFIGURE": 1, 39 | "LOG_DOWNLOAD": 1, 40 | "LOG_INSTALL": 1, 41 | "PREFIX": 1, 42 | "URL": 1, 43 | "URL_HASH": 1, 44 | "BUILD_ALWAYS": 1, 45 | }, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | # Remove repository name from paths 2 | fixes: 3 | - "functions-framework-cpp/::" 4 | 5 | ignore: 6 | - "build/vcpkg_installed/**/*" 7 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Common build output directory names 2 | .build/ 3 | _build/ 4 | cmake-out/ 5 | build-out/ 6 | 7 | # Used by some IDEs and LSP plugins 8 | compile_commands.json 9 | 10 | # Backup files for Emacs 11 | *~ 12 | 13 | # Ignore IDEA / IntelliJ files 14 | .idea/ 15 | cmake-build-*/ 16 | 17 | # Ignore Visual Studio Code files 18 | .vsbuild/ 19 | .vscode/ 20 | 21 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners are automatically requested for review when someone opens a pull 2 | # request containing files matching the given path. The syntax for file paths 3 | # is the same as .gitignore. 4 | 5 | # The owners for all files in the repo. 6 | * @GoogleCloudPlatform/cloud-cxx-owners 7 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.github/snippet-bot.yml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.github/trusted-contribution.yml: -------------------------------------------------------------------------------- 1 | annotations: 2 | - type: comment 3 | text: "/gcbrun" 4 | -------------------------------------------------------------------------------- /.github/workflows/install.yaml: -------------------------------------------------------------------------------- 1 | name: install 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | 8 | jobs: 9 | static: 10 | name: ubuntu-22.04 11 | runs-on: ubuntu-22.04 12 | steps: 13 | - name: install-dependencies 14 | run: sudo apt install ninja-build libboost-dev libboost-program-options-dev nlohmann-json3-dev libabsl-dev 15 | - uses: actions/checkout@v4 16 | - name: configure 17 | run: > 18 | cmake -S . -B ${{runner.temp}}/build -GNinja -DBUILD_TESTING=OFF 19 | -DCMAKE_INSTALL_PREFIX=${{runner.temp}}/staging 20 | - name: build 21 | run: cmake --build ${{runner.temp}}/build 22 | - name: install 23 | run: cmake --build ${{runner.temp}}/build --target install 24 | - name: test-configure 25 | run: > 26 | cmake -S ci/test_install -B "${{runner.temp}}/test_install/build" -GNinja 27 | -DCMAKE_PREFIX_PATH="${{runner.temp}}/staging" 28 | - name: test-build 29 | run: cmake --build "${{runner.temp}}/test_install/build" 30 | - name: test 31 | run: "${{runner.temp}}/test_install/build/test_install" 32 | 33 | shared: 34 | name: ubuntu-22.04-shared 35 | runs-on: ubuntu-22.04 36 | steps: 37 | - name: install-dependencies 38 | run: > 39 | sudo apt install ninja-build libboost-dev libboost-program-options-dev nlohmann-json3-dev libabsl-dev 40 | - uses: actions/checkout@v4 41 | - name: configure 42 | run: > 43 | cmake -S . -B ${{runner.temp}}/build -GNinja 44 | -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=ON 45 | -DCMAKE_INSTALL_PREFIX=${{runner.temp}}/staging 46 | - name: build 47 | run: cmake --build ${{runner.temp}}/build 48 | - name: install 49 | run: cmake --build ${{runner.temp}}/build --target install 50 | - name: test-configure 51 | run: > 52 | cmake -S ci/test_install -B "${{runner.temp}}/test_install/build" -GNinja 53 | -DCMAKE_PREFIX_PATH="${{runner.temp}}/staging" 54 | - name: test-build 55 | run: cmake --build "${{runner.temp}}/test_install/build" 56 | - name: test 57 | run: "${{runner.temp}}/test_install/build/test_install" 58 | -------------------------------------------------------------------------------- /.github/workflows/style.yaml: -------------------------------------------------------------------------------- 1 | name: C++ Lint CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | 8 | env: 9 | vcpkg_SHA: "2024.09.30" 10 | 11 | jobs: 12 | clang-format: 13 | name: clang-format 14 | runs-on: ubuntu-22.04 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: clang-format 18 | run: > 19 | git ls-files -z -- '*.h' '*.cc' | 20 | xargs -P 2 -n 50 -0 clang-format-14 -i 21 | - name: check-diff 22 | run: git diff --ignore-submodules=all --color --exit-code . 23 | 24 | cmake-format: 25 | name: cmake-format 26 | runs-on: ubuntu-22.04 27 | steps: 28 | - uses: actions/checkout@v4 29 | - name: install cmake-format 30 | run: pip install cmakelang==0.6.13 31 | - name: cmake-format 32 | run: > 33 | git ls-files -z -- '*.cmake' '**/CMakeLists.txt' CMakeLists.txt | 34 | xargs -P 2 -n 1 -0 /home/runner/.local/bin/cmake-format -i 35 | - name: check-diff 36 | run: git diff --ignore-submodules=all --color --exit-code . 37 | 38 | generated-files: 39 | name: generated-files 40 | runs-on: ubuntu-22.04 41 | steps: 42 | - uses: actions/checkout@v4 43 | - name: install ninja 44 | run: sudo apt install moreutils 45 | - name: regenerate-build-examples 46 | run: > 47 | ./ci/generate-build-examples.sh >ci/build-examples.yaml 48 | - name: update-markdown-code-snippets 49 | run: > 50 | ./ci/update-markdown-code-snippets.sh 51 | - name: check-diff 52 | run: git diff --ignore-submodules=all --color --exit-code . 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Common build output directory names 2 | .build/ 3 | _build/ 4 | build-out/ 5 | cmake-out/ 6 | 7 | # Used by some IDEs and LSP plugins 8 | compile_commands.json 9 | 10 | # Backup files for Emacs 11 | *~ 12 | 13 | # Ignore IDEA / IntelliJ files 14 | .idea/ 15 | cmake-build-*/ 16 | 17 | # Ignore Visual Studio Code files 18 | .vsbuild/ 19 | .vscode/ 20 | build/ 21 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | cmake_minimum_required(VERSION 3.10...3.26) 18 | 19 | option(BUILD_TESTING "Enable tests" ON) 20 | if (BUILD_TESTING) 21 | list(APPEND VCPKG_MANIFEST_FEATURES "tests") 22 | endif () 23 | option(FUNCTIONS_FRAMEWORK_CPP_TEST_EXAMPLES "Enable testing for examples" ON) 24 | mark_as_advanced(FUNCTIONS_FRAMEWORK_CPP_TEST_EXAMPLES) 25 | if (FUNCTIONS_FRAMEWORK_CPP_TEST_EXAMPLES) 26 | list(APPEND VCPKG_MANIFEST_FEATURES "examples") 27 | endif () 28 | 29 | set(PACKAGE_BUGREPORT 30 | "http://github.com/GoogleCloudPlatform/functions-framework-cpp") 31 | project( 32 | functions-framework-cpp 33 | VERSION 1.3.0 34 | DESCRIPTION "Functions Framework for C++" 35 | LANGUAGES CXX) 36 | 37 | # Configure the compiler options, we will be using C++17 features. 38 | set(CMAKE_CXX_STANDARD 17) 39 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 40 | 41 | list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 42 | 43 | if (VCPKG_TARGET_TRIPLET MATCHES "-static$") 44 | set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 45 | else () 46 | set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") 47 | endif () 48 | 49 | include(CTest) 50 | include(FunctionsFrameworkCppHelpers) 51 | add_subdirectory(google/cloud/functions) 52 | 53 | if (BUILD_TESTING AND FUNCTIONS_FRAMEWORK_CPP_TEST_EXAMPLES) 54 | add_subdirectory(examples) 55 | endif () 56 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement (CLA). You (or your employer) retain the copyright to your 10 | contribution; this simply gives us permission to use and redistribute your 11 | contributions as part of the project. Head over to 12 | to see your current agreements on file or 13 | to sign a new one. 14 | 15 | You generally only need to submit a CLA once, so if you've already submitted one 16 | (even if it was for a different project), you probably don't need to do it 17 | again. 18 | 19 | ## Code reviews 20 | 21 | All submissions, including submissions by project members, require review. We 22 | use GitHub pull requests for this purpose. Consult 23 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 24 | information on using pull requests. 25 | 26 | ## Community Guidelines 27 | 28 | This project follows 29 | [Google's Open Source Community Guidelines](https://opensource.google/conduct/). 30 | 31 | -------------------------------------------------------------------------------- /build_scripts/README.md: -------------------------------------------------------------------------------- 1 | # Scripts to build Functions Framework-based applications 2 | 3 | This directory contains the scripts to 4 | 5 | 1. Create a Docker image with all the development tools to build applications based on the functions 6 | framework 7 | 1. Create the runtime image to execute applications built with said image 8 | 1. Support scripts to automatically create the `main()` entry point. 9 | 10 | ## Creating the Docker images 11 | 12 | ```sh 13 | docker build -t gcf-cpp-run-image --target gcf-cpp-runtime - ${VCPKG_ROOT_DIR}" 30 | if [[ ! -d "${VCPKG_ROOT_DIR}" ]]; then 31 | mkdir -p "${VCPKG_ROOT_DIR}" 32 | # vcpkg needs git history to support versioning, so we clone a recent 33 | # release tag rather than just extracting a tarball without history. 34 | git clone https://github.com/microsoft/vcpkg.git "${VCPKG_ROOT_DIR}" 35 | git -C "${VCPKG_ROOT_DIR}" checkout "${VCPKG_RELEASE_VERSION}" 36 | pwd 37 | fi 38 | env -C "${VCPKG_ROOT_DIR}" ./bootstrap-vcpkg.sh 39 | } 40 | 41 | # Outputs the root directory where vcpkg is installed (and bootstrapped) 42 | function vcpkg::root_dir() { 43 | echo "${VCPKG_ROOT_DIR}" 44 | } 45 | 46 | # Output common CMake configuration arguments 47 | function vcpkg::cmake_args() { 48 | local binary="cmake-out" 49 | if [[ $# -ge 1 ]]; then 50 | binary="$1" 51 | fi 52 | local args 53 | args=( 54 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 55 | -DCMAKE_TOOLCHAIN_FILE="${VCPKG_ROOT_DIR}/scripts/buildsystems/vcpkg.cmake" 56 | -DVCPKG_FEATURE_FLAGS="versions,manifest" 57 | ) 58 | printf "%s\n" "${args[@]}" 59 | } 60 | -------------------------------------------------------------------------------- /ci/cloudbuild/builds/sanitize-address.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2023 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -euo pipefail 18 | 19 | export CC=clang 20 | export CXX=clang++ 21 | 22 | source "$(dirname "$0")/../../lib/init.sh" 23 | source module ci/lib/io.sh 24 | source module ci/cloudbuild/builds/lib/vcpkg.sh 25 | source module ci/cloudbuild/builds/lib/cmake.sh 26 | 27 | io::log_h2 "Building with Address Sanitizer" 28 | mapfile -t cmake_args < <(cmake::common_args) 29 | mapfile -t vcpkg_args < <(vcpkg::cmake_args) 30 | io::run cmake "${cmake_args[@]}" "${vcpkg_args[@]}" \ 31 | -DCMAKE_BUILD_TYPE=Debug \ 32 | -DCMAKE_CXX_FLAGS="-fsanitize=address -DGRPC_TSAN_SUPPRESSED -DGRPC_ASAN_SUPPRESSED" 33 | io::run cmake --build cmake-out 34 | 35 | mapfile -t ctest_args < <(ctest::common_args) 36 | io::run env ASAN_OPTIONS=detect_leaks=1:color=always ctest "${ctest_args[@]}" 37 | -------------------------------------------------------------------------------- /ci/cloudbuild/builds/sanitize-thread.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2023 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -euo pipefail 18 | 19 | export CC=clang 20 | export CXX=clang++ 21 | 22 | source "$(dirname "$0")/../../lib/init.sh" 23 | source module ci/lib/io.sh 24 | source module ci/cloudbuild/builds/lib/vcpkg.sh 25 | source module ci/cloudbuild/builds/lib/cmake.sh 26 | 27 | io::log_h2 "Building with Thread Sanitizer" 28 | mapfile -t cmake_args < <(cmake::common_args) 29 | mapfile -t vcpkg_args < <(vcpkg::cmake_args) 30 | io::run cmake "${cmake_args[@]}" "${vcpkg_args[@]}" \ 31 | -DCMAKE_BUILD_TYPE=Debug \ 32 | -DCMAKE_CXX_FLAGS="-fsanitize=thread -DGRPC_TSAN_SUPPRESSED -DGRPC_ASAN_SUPPRESSED" 33 | io::run cmake --build cmake-out 34 | 35 | mapfile -t ctest_args < <(ctest::common_args) 36 | io::run env TSAN_OPTIONS=halt_on_error=1:second_deadlock_stack=1 ctest "${ctest_args[@]}" 37 | -------------------------------------------------------------------------------- /ci/cloudbuild/builds/sanitize-undefined.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2023 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -euo pipefail 18 | 19 | export CC=clang 20 | export CXX=clang++ 21 | 22 | source "$(dirname "$0")/../../lib/init.sh" 23 | source module ci/lib/io.sh 24 | source module ci/cloudbuild/builds/lib/vcpkg.sh 25 | source module ci/cloudbuild/builds/lib/cmake.sh 26 | 27 | io::log_h2 "Building with Undefined Behavior Sanitizer" 28 | mapfile -t cmake_args < <(cmake::common_args) 29 | mapfile -t vcpkg_args < <(vcpkg::cmake_args) 30 | io::run cmake "${cmake_args[@]}" "${vcpkg_args[@]}" \ 31 | -DCMAKE_BUILD_TYPE=Debug \ 32 | -DCMAKE_CXX_FLAGS="-fsanitize=undefined -DGRPC_TSAN_SUPPRESSED -DGRPC_ASAN_SUPPRESSED" 33 | io::run cmake --build cmake-out 34 | 35 | mapfile -t ctest_args < <(ctest::common_args) 36 | io::run env UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 ctest "${ctest_args[@]}" 37 | -------------------------------------------------------------------------------- /ci/cloudbuild/dockerfiles/fedora-38.Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM fedora:38 16 | ARG NCPU=4 17 | 18 | # Installs the development tools needed by functions-framework-cpp and its 19 | # dependencies. 20 | RUN dnf makecache && \ 21 | dnf install -y abi-compliance-checker autoconf automake \ 22 | ccache clang clang-analyzer clang-tools-extra \ 23 | cmake diffutils doxygen findutils gcc-c++ git \ 24 | lcov libcxx-devel libcxxabi-devel \ 25 | libasan libubsan libtsan llvm libcurl-devel make ninja-build \ 26 | openssl-devel patch python python3 \ 27 | python-pip tar unzip w3m wget which zip zlib-devel 28 | 29 | # This is needed to compile OpenSSL with vcpkg 30 | RUN dnf makecache && dnf install -y perl-IPC-Cmd 31 | 32 | # Installs Universal Ctags (which is different than the default "Exuberant 33 | # Ctags"), which is needed by the ABI checker. See https://ctags.io/ 34 | WORKDIR /var/tmp/build 35 | RUN curl -sSL https://github.com/universal-ctags/ctags/archive/refs/tags/p5.9.20210418.0.tar.gz | \ 36 | tar -xzf - --strip-components=1 && \ 37 | ./autogen.sh && \ 38 | ./configure --prefix=/usr/local && \ 39 | make && \ 40 | make install && \ 41 | cd /var/tmp && rm -fr build 42 | 43 | # Installs the abi-dumper with the integer overflow fix from 44 | # https://github.com/lvc/abi-dumper/pull/29. We can switch back to `dnf install 45 | # abi-dumper` once it has the fix. 46 | WORKDIR /var/tmp/build 47 | RUN curl -sSL https://github.com/lvc/abi-dumper/archive/16bb467cd7d343dd3a16782b151b56cf15509594.tar.gz | \ 48 | tar -xzf - --strip-components=1 && \ 49 | mv abi-dumper.pl /usr/local/bin/abi-dumper && \ 50 | chmod +x /usr/local/bin/abi-dumper 51 | 52 | WORKDIR /var/tmp/gcloud 53 | ARG GOOGLE_CLOUD_CPP_CLOUD_SDK_VERSION="428.0.0" 54 | ARG GOOGLE_CLOUD_CPP_SDK_SHA256="a665909d2ff9cd3a927d84670c5a8d11f0c5fbcda2540bbea44e0d6f77b82e27" 55 | ENV TARBALL="google-cloud-cli-${GOOGLE_CLOUD_CPP_CLOUD_SDK_VERSION}-linux-x86_64.tar.gz" 56 | RUN curl -fsSL "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/${TARBALL}" -o "${TARBALL}" 57 | RUN echo "${GOOGLE_CLOUD_CPP_SDK_SHA256} ${TARBALL}" | sha256sum --check - 58 | RUN tar x -C /usr/local -f "${TARBALL}" 59 | ENV PATH=${PATH}:/usr/local/google-cloud-sdk/bin 60 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/check-api-ci.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | push: 6 | branch: ^(master|main|v\d+\..*)$ 7 | name: check-api-ci 8 | substitutions: 9 | _BUILD_NAME: check-api 10 | _DISTRO: fedora-38 11 | _TRIGGER_TYPE: ci 12 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 13 | tags: 14 | - ci 15 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/check-api-pr.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | pullRequest: 6 | branch: ^(master|main|v\d+\..*)$ 7 | commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY 8 | name: check-api-pr 9 | substitutions: 10 | _BUILD_NAME: check-api 11 | _DISTRO: fedora-38 12 | _TRIGGER_TYPE: pr 13 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 14 | tags: 15 | - pr 16 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/clang-16-0-ci.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | push: 6 | branch: ^(main|v\d+\..*)$ 7 | name: clang-16-0-ci 8 | substitutions: 9 | _BUILD_NAME: clang-16.0 10 | _DISTRO: fedora-38 11 | _TRIGGER_TYPE: ci 12 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 13 | tags: 14 | - ci 15 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/clang-16-0-pr.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | pullRequest: 6 | branch: ^(main|v\d+\..*)$ 7 | commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY 8 | name: clang-16-0-pr 9 | substitutions: 10 | _BUILD_NAME: clang-16.0 11 | _DISTRO: fedora-38 12 | _TRIGGER_TYPE: pr 13 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 14 | tags: 15 | - pr 16 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/clang-tidy-ci.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | push: 6 | branch: ^(main|v\d+\..*)$ 7 | name: clang-tidy-ci 8 | substitutions: 9 | _BUILD_NAME: clang-tidy 10 | _DISTRO: fedora-38 11 | _TRIGGER_TYPE: ci 12 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 13 | tags: 14 | - ci 15 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/clang-tidy-pr.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | pullRequest: 6 | branch: ^(main|v\d+\..*)$ 7 | commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY 8 | name: clang-tidy-pr 9 | substitutions: 10 | _BUILD_NAME: clang-tidy 11 | _DISTRO: fedora-38 12 | _TRIGGER_TYPE: pr 13 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 14 | tags: 15 | - pr 16 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/gcc-13-1-ci.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | push: 6 | branch: ^(main|v\d+\..*)$ 7 | name: gcc-13-1-ci 8 | substitutions: 9 | _BUILD_NAME: gcc-13.1 10 | _DISTRO: fedora-38 11 | _TRIGGER_TYPE: ci 12 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 13 | tags: 14 | - ci 15 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/gcc-13-1-pr.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | pullRequest: 6 | branch: ^(main|v\d+\..*)$ 7 | commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY 8 | name: gcc-13-1-pr 9 | substitutions: 10 | _BUILD_NAME: gcc-13.1 11 | _DISTRO: fedora-38 12 | _TRIGGER_TYPE: pr 13 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 14 | tags: 15 | - pr 16 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/pr.yaml: -------------------------------------------------------------------------------- 1 | createTime: '2021-01-12T17:18:16.451278761Z' 2 | description: Pull Request to functions-framework-cpp 3 | filename: ci/build-examples.yaml 4 | github: 5 | name: functions-framework-cpp 6 | owner: GoogleCloudPlatform 7 | pullRequest: 8 | branch: ^main$ 9 | commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY 10 | id: 18ddf837-91e7-47c7-850e-d52d1e701d17 11 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 12 | name: pr 13 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/push.yaml: -------------------------------------------------------------------------------- 1 | createTime: '2021-01-12T17:19:25.822590886Z' 2 | description: Push to branch 3 | filename: ci/build-examples.yaml 4 | github: 5 | name: functions-framework-cpp 6 | owner: GoogleCloudPlatform 7 | push: 8 | branch: ^main$ 9 | id: c609a1b8-8acc-45ed-8aeb-c1ae7b070911 10 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 11 | name: push 12 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/sanitize-address-ci.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | push: 6 | branch: ^(main|v\d+\..*)$ 7 | name: sanitize-address-ci 8 | substitutions: 9 | _BUILD_NAME: sanitize-address 10 | _DISTRO: fedora-38 11 | _TRIGGER_TYPE: ci 12 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 13 | tags: 14 | - ci 15 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/sanitize-address-pr.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | pullRequest: 6 | branch: ^(main|v\d+\..*)$ 7 | commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY 8 | name: sanitize-address-pr 9 | substitutions: 10 | _BUILD_NAME: sanitize-address 11 | _DISTRO: fedora-38 12 | _TRIGGER_TYPE: pr 13 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 14 | tags: 15 | - pr 16 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/sanitize-thread-ci.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | push: 6 | branch: ^(main|v\d+\..*)$ 7 | name: sanitize-thread-ci 8 | substitutions: 9 | _BUILD_NAME: sanitize-thread 10 | _DISTRO: fedora-38 11 | _TRIGGER_TYPE: ci 12 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 13 | tags: 14 | - ci 15 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/sanitize-thread-pr.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | pullRequest: 6 | branch: ^(main|v\d+\..*)$ 7 | commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY 8 | name: sanitize-thread-pr 9 | substitutions: 10 | _BUILD_NAME: sanitize-thread 11 | _DISTRO: fedora-38 12 | _TRIGGER_TYPE: pr 13 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 14 | tags: 15 | - pr 16 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/sanitize-undefined-ci.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | push: 6 | branch: ^(main|v\d+\..*)$ 7 | name: sanitize-undefined-ci 8 | substitutions: 9 | _BUILD_NAME: sanitize-undefined 10 | _DISTRO: fedora-38 11 | _TRIGGER_TYPE: ci 12 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 13 | tags: 14 | - ci 15 | -------------------------------------------------------------------------------- /ci/cloudbuild/triggers/sanitize-undefined-pr.yaml: -------------------------------------------------------------------------------- 1 | filename: ci/cloudbuild/cloudbuild.yaml 2 | github: 3 | name: functions-framework-cpp 4 | owner: GoogleCloudPlatform 5 | pullRequest: 6 | branch: ^(main|v\d+\..*)$ 7 | commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY 8 | name: sanitize-undefined-pr 9 | substitutions: 10 | _BUILD_NAME: sanitize-undefined 11 | _DISTRO: fedora-38 12 | _TRIGGER_TYPE: pr 13 | includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS 14 | tags: 15 | - pr 16 | -------------------------------------------------------------------------------- /ci/etc/vcpkg-config.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright 2021 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Make our include guard clean against set -o nounset. 18 | test -n "${CI_ETC_VCPKG_CONFIG_SH__:-}" || declare -i CI_ETC_VCPKG_CONFIG_SH__=0 19 | if ((CI_ETC_VCPKG_CONFIG_SH__++ != 0)); then 20 | return 0 21 | fi # include guard 22 | 23 | # 24 | # Common configuration parameters. 25 | # 26 | export VCPKG_RELEASE_VERSION="2024.09.30" 27 | -------------------------------------------------------------------------------- /ci/lib/module: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright 2021 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This bash library (even though it doesn't have the .sh extension) will be 18 | # found when callers type `source module ` because init.sh added this 19 | # directory to the caller's PATH. The argument specified on the `source` 20 | # line will be passed to this library as '$1'. We'll look for the caller's 21 | # library by searching the MODULE_SEARCH_PATH array. 22 | # 23 | # This library does not use an include guard because it can, and should, be 24 | # sourced many times. Therefore, this library must not define any global 25 | # variables or functions. 26 | 27 | if [[ -z "${MODULE_SEARCH_PATH[0]:-}" ]]; then 28 | echo >&2 \ 29 | "No MODULE_SEARCH_PATH set. " \ 30 | "Did you forget to source init.sh, maybe from $0?" 31 | exit 1 32 | fi 33 | 34 | for dir in "${MODULE_SEARCH_PATH[@]}"; do 35 | if [[ -r "${dir}/$1" ]]; then 36 | source "${dir}/$1" 37 | return 0 38 | fi 39 | done 40 | 41 | echo >&2 "Unable to find module '$1' in search path: ${MODULE_SEARCH_PATH[@]}" 42 | exit 1 43 | -------------------------------------------------------------------------------- /ci/pack/builder.toml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | [[buildpacks]] 16 | uri = "buildpack" 17 | 18 | [[order]] 19 | [[order.group]] 20 | id = "com.google.buildpack.cpp" 21 | version = "0.6.0" 22 | 23 | # Stack that will be used by the builder 24 | [stack] 25 | id = "google" 26 | run-image = "ci-run-image:latest" 27 | build-image = "ci-build-image:latest" 28 | -------------------------------------------------------------------------------- /ci/pack/buildpack/bin/detect: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2021 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -eu 17 | 18 | if ! (compgen -G "*.cc" >/dev/null || 19 | compgen -G "*.cpp" >/dev/null || 20 | compgen -G "*.cxx" >/dev/null || 21 | [[ ! -f CMakeLists.txt ]]); then 22 | exit 100 23 | fi 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /ci/pack/buildpack/buildpack.toml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | api = "0.2" 16 | 17 | [buildpack] 18 | id = "com.google.buildpack.cpp" 19 | version = "0.6.0" 20 | name = "Functions Framework C++ Buildpack (prefix=ci-)" 21 | 22 | [[stacks]] 23 | id = "google" 24 | -------------------------------------------------------------------------------- /ci/restore-vcpkg-from-cache.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -eu 17 | 18 | if [[ $# -ne 1 ]]; then 19 | >&2 echo "Usage: $(basename "${0}") " 20 | exit 1 21 | fi 22 | 23 | readonly VCPKG_ROOT="${1}" 24 | 25 | if [[ -x "${HOME}/.cache/bin/vcpkg" ]]; then 26 | cp "${HOME}/.cache/bin/vcpkg" "${VCPKG_ROOT}/vcpkg" 27 | else 28 | (cd "${VCPKG_ROOT}" && ./bootstrap-vcpkg.sh -useSystemBinaries) 29 | mkdir -p "${HOME}/.cache/bin" 30 | cp "${VCPKG_ROOT}/vcpkg" "${HOME}/.cache/bin/vcpkg" 31 | fi 32 | -------------------------------------------------------------------------------- /ci/test_install/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | cmake_minimum_required(VERSION 3.5) 18 | project(functions-framework-cpp-test-install CXX C) 19 | 20 | set(CMAKE_CXX_STANDARD 17) 21 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 22 | 23 | find_package(Threads REQUIRED) 24 | find_package(functions_framework_cpp REQUIRED) 25 | 26 | add_executable(test_install test_install.cc) 27 | target_link_libraries(test_install functions-framework-cpp::framework) 28 | -------------------------------------------------------------------------------- /ci/test_install/README.md: -------------------------------------------------------------------------------- 1 | # Functions Framework for C++: Test Install Targets 2 | 3 | This program is used in the CI builds to verify `make install` produces usable 4 | artifacts. It is not enough that `make install` runs and exits without error, 5 | we also want to ensure the installed artifacts are usable by some program. 6 | -------------------------------------------------------------------------------- /ci/test_install/test_install.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | int main() { 19 | std::cout << google::cloud::functions::VersionString() << "\n"; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ci/update-markdown-code-snippets.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2022 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | declare -A files=( 19 | ["README.md"]="examples/hello_world/hello_world.cc" 20 | ["examples/site/howto_create_container/README.md"]="examples/site/hello_world_http/hello_world_http.cc" 21 | ["examples/site/howto_deploy_cloud_event/README.md"]="examples/site/hello_world_pubsub/hello_world_pubsub.cc" 22 | ["examples/site/howto_deploy_to_cloud_run/README.md"]="examples/site/hello_world_http/hello_world_http.cc" 23 | ["examples/site/testing_pubsub/README.md"]="examples/site/hello_world_pubsub/hello_world_pubsub.cc" 24 | ["examples/site/testing_storage/README.md"]="examples/site/hello_world_storage/hello_world_storage.cc" 25 | ) 26 | 27 | for markdown in "${!files[@]}"; do 28 | source="${files[$markdown]}" 29 | ( 30 | sed '//q' "${markdown}" 31 | echo "[snippet source]: /${source}" 32 | echo '```cc' 33 | # Dumps the contents of the source file starting at the first #include, so we 34 | # skip the license header comment. 35 | sed -n -e '/END .*quickstart/,$d' -e '/^#/,$p' "${source}" | sed -e '/^\/\//d' -e 's; // NOLINT;;' 36 | echo '```' 37 | sed -n '//,$p' "${markdown}" 38 | ) | sponge "${markdown}" 39 | done 40 | -------------------------------------------------------------------------------- /cmake/InstallHeaders.cmake: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | # 18 | # google_cloud_cpp_install_headers : install all the headers in a target 19 | # 20 | # Find all the headers in @p target and install them at @p destination, 21 | # preserving the directory structure. 22 | # 23 | # * target the name of the target. 24 | # * destination the destination directory, relative to . Typically this 25 | # starts with `include/google/cloud`, the function requires the full 26 | # destination in case some headers get installed elsewhere in the future. 27 | # 28 | function (google_cloud_cpp_install_headers target destination) 29 | get_target_property(target_type ${target} TYPE) 30 | if ("${target_type}" STREQUAL "INTERFACE_LIBRARY") 31 | # For interface libraries we use `INTERFACE_SOURCES` to get the list of 32 | # sources, which are actually just headers in this case. 33 | get_target_property(target_sources ${target} INTERFACE_SOURCES) 34 | else () 35 | get_target_property(target_sources ${target} SOURCES) 36 | endif () 37 | foreach (header ${target_sources}) 38 | if (NOT "${header}" MATCHES "\\.h$" AND NOT "${header}" MATCHES 39 | "\\.inc$") 40 | continue() 41 | endif () 42 | # Sometimes we generate header files into the binary directory, do not 43 | # forget to install those with their relative path. 44 | string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" relative "${header}") 45 | # INTERFACE libraries use absolute paths, yuck. 46 | string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" relative "${relative}") 47 | get_filename_component(dir "${relative}" DIRECTORY) 48 | install(FILES "${header}" DESTINATION "${destination}/${dir}") 49 | endforeach () 50 | endfunction () 51 | -------------------------------------------------------------------------------- /examples/cloud_event_examples_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/function_impl.h" 16 | #include "google/cloud/functions/function.h" 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | namespace gcf_internal = ::google::cloud::functions_internal; 21 | 22 | gcf::Function HelloCloudEvent(); 23 | 24 | namespace { 25 | 26 | auto constexpr kBody = R"js({ 27 | "specversion": "1.0", 28 | "type": "google.cloud.pubsub.topic.v1.messagePublished", 29 | "source": "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", 30 | "id": "aaaaaa-1111-bbbb-2222-cccccccccccc", 31 | "subject": "test-only", 32 | "time": "2020-09-29T11:32:00.000Z", 33 | "datacontenttype": "application/json", 34 | "data": { 35 | "subscription": "projects/sample-project/subscriptions/sample-subscription", 36 | "message": { 37 | "@type": "type.googleapis.com/google.pubsub.v1.PubsubMessage", 38 | "attributes": { 39 | "attr1":"attr1-value" 40 | }, 41 | "data": "" 42 | } 43 | } 44 | })js"; 45 | 46 | TEST(HttpExamplesTest, HelloCloudEvent) { 47 | auto function = HelloCloudEvent(); 48 | gcf_internal::BeastRequest request; 49 | request.insert("ce-type", "com.example.someevent"); 50 | request.insert("ce-source", "/mycontext"); 51 | request.insert("ce-id", "A234-1234-1234"); 52 | request.body() = kBody; 53 | auto handler = 54 | gcf_internal::FunctionImpl::GetImpl(function)->GetHandler("unused"); 55 | auto const response = handler(std::move(request)); 56 | EXPECT_EQ(response.result_int(), 200); 57 | } 58 | 59 | } // namespace 60 | -------------------------------------------------------------------------------- /examples/hello_cloud_event/hello_cloud_event.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function HelloCloudEvent() { 21 | return gcf::MakeFunction([](gcf::CloudEvent const& event) { 22 | std::cout << "Received event" 23 | << "\n id: " << event.id() 24 | << "\n subject: " << event.subject().value_or("") << std::endl; 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /examples/hello_from_namespace/hello_from_namespace.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace hello_from_namespace { 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | gcf::Function HelloWorld() { 22 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 23 | return gcf::HttpResponse{} 24 | .set_header("Content-Type", "text/plain") 25 | .set_payload("Hello from a C++ namespace!\n"); 26 | }); 27 | } 28 | 29 | } // namespace hello_from_namespace 30 | -------------------------------------------------------------------------------- /examples/hello_from_nested_namespace/hello_from_nested_namespace.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace hello_from_nested_namespace::ns0::ns1 { 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | gcf::Function HelloWorld() { 22 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 23 | return gcf::HttpResponse{} 24 | .set_header("Content-Type", "text/plain") 25 | .set_payload("Hello from a nested C++ namespace!\n"); 26 | }); 27 | } 28 | 29 | } // namespace hello_from_nested_namespace::ns0::ns1 30 | -------------------------------------------------------------------------------- /examples/hello_gcs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(google_cloud_cpp_storage REQUIRED) 18 | find_package(functions_framework_cpp REQUIRED) 19 | 20 | add_library(functions_framework_cpp_function hello_gcs.cc) 21 | target_link_libraries( 22 | functions_framework_cpp_function functions-framework-cpp::framework 23 | google-cloud-cpp::storage) 24 | -------------------------------------------------------------------------------- /examples/hello_gcs/hello_gcs.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | namespace gcs = ::google::cloud::storage; 21 | 22 | gcf::Function HelloGcs() { 23 | return gcf::MakeFunction([](gcf::HttpRequest const& request) { 24 | auto error = [] { 25 | return gcf::HttpResponse{}.set_result(gcf::HttpResponse::kBadRequest); 26 | }; 27 | 28 | std::vector components; 29 | std::istringstream split(request.target()); 30 | for (std::string c; std::getline(split, c, '/'); components.push_back(c)) { 31 | } 32 | 33 | if (components.size() != 2) return error(); 34 | auto const bucket = components[0]; 35 | auto const object = components[1]; 36 | auto client = gcs::Client::CreateDefaultClient().value(); 37 | auto reader = client.ReadObject(bucket, object); 38 | std::string contents(std::istreambuf_iterator{reader}, 39 | std::istreambuf_iterator{}); 40 | if (!reader.status().ok()) return error(); 41 | 42 | return gcf::HttpResponse{} 43 | .set_header("Content-Type", "application/octet-stream") 44 | .set_payload(std::move(contents)); 45 | }); 46 | } 47 | -------------------------------------------------------------------------------- /examples/hello_gcs/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-gcs", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "google-cloud-cpp", 6 | "functions-framework-cpp" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/hello_multiple_sources/greeting.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "greeting.h" 16 | 17 | std::string Greeting() { return "Hello World\n"; } 18 | -------------------------------------------------------------------------------- /examples/hello_multiple_sources/greeting.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_EXAMPLES_HELLO_MULTIPLE_SOURCES_GREETING_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_EXAMPLES_HELLO_MULTIPLE_SOURCES_GREETING_H 17 | 18 | #include 19 | 20 | extern std::string Greeting(); 21 | 22 | #endif // FUNCTIONS_FRAMEWORK_CPP_EXAMPLES_HELLO_MULTIPLE_SOURCES_GREETING_H 23 | -------------------------------------------------------------------------------- /examples/hello_multiple_sources/hello_multiple_sources.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "greeting.h" 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function HelloMultipleSources() { 21 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 22 | return gcf::HttpResponse{} 23 | .set_header("Content-Type", "text/plain") 24 | .set_payload(Greeting()); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /examples/hello_with_third_party/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(fmt REQUIRED) 18 | find_package(functions_framework_cpp REQUIRED) 19 | 20 | add_library(functions_framework_cpp_function hello_with_third_party.cc) 21 | target_link_libraries(functions_framework_cpp_function fmt::fmt 22 | functions-framework-cpp::framework) 23 | -------------------------------------------------------------------------------- /examples/hello_with_third_party/hello_with_third_party.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function HelloWithThirdParty() { 21 | return gcf::MakeFunction([](gcf::HttpRequest const& request) { 22 | return gcf::HttpResponse{} 23 | .set_header("Content-Type", "text/plain") 24 | .set_payload(fmt::format("Hello at {}\n", request.target())); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /examples/hello_with_third_party/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-with-third-party", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "fmt", 6 | "functions-framework-cpp" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/hello_world/hello_world.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace gcf = ::google::cloud::functions; 18 | 19 | gcf::Function HelloWorld() { 20 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 21 | return gcf::HttpResponse{} 22 | .set_header("Content-Type", "text/plain") 23 | .set_payload("Hello World\n"); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /examples/howto-guides.md: -------------------------------------------------------------------------------- 1 | # How-to Guides: Index 2 | 3 | * [Running your function as Docker container] - building and running your 4 | function into a Docker image and starting the function on your workstation. 5 | * [Deploy your function to Cloud Run] - continue by deploying a C++ function to 6 | Cloud Run. 7 | * [Deploy a C++ Pub/Sub function to Cloud Run] - deploy C++ functions handling 8 | Pub/Sub events to Cloud Run. 9 | * [Local Development] - use the Functions Framework without Docker, for faster 10 | local development, testing, and debugging. 11 | 12 | [Running your function as Docker container]: /examples/site/howto_create_container/README.md 13 | [Deploy your function to Cloud Run]: /examples/site/howto_deploy_to_cloud_run/README.md 14 | [Deploy a C++ Pub/Sub function to Cloud Run]: /examples/site/howto_deploy_cloud_event/README.md 15 | [Local Development]: /examples/site/howto_local_development/README.md 16 | -------------------------------------------------------------------------------- /examples/howto_use_legacy_code/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | cmake_minimum_required(VERSION 3.5) 18 | project(functions-framework-cpp-howto-local-development CXX C) 19 | 20 | set(CMAKE_CXX_STANDARD 17) 21 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 22 | 23 | find_package(Threads REQUIRED) 24 | find_package(functions_framework_cpp REQUIRED) 25 | 26 | include(ExternalProject) 27 | externalproject_add( 28 | legacy 29 | PREFIX "${CMAKE_CURRENT_BINARY_DIR}/legacy" 30 | DEPENDS "" SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/legacy" 31 | CONFIGURE_COMMAND "" 32 | BUILD_COMMAND "make" "CXX=${CMAKE_CXX_COMPILER}" "default" BUILD_IN_SOURCE 33 | ON 34 | BUILD_BYPRODUCTS "/liblegacy.a" 35 | INSTALL_COMMAND "") 36 | ExternalProject_Get_Property(legacy SOURCE_DIR) 37 | 38 | add_library(functions_framework_cpp_function howto_use_legacy_code.cc) 39 | add_dependencies(functions_framework_cpp_function legacy) 40 | target_link_libraries( 41 | functions_framework_cpp_function PUBLIC "${SOURCE_DIR}/liblegacy.a" 42 | functions-framework-cpp::framework) 43 | 44 | add_executable(main main.cc) 45 | target_link_libraries(main PRIVATE functions_framework_cpp_function) 46 | -------------------------------------------------------------------------------- /examples/howto_use_legacy_code/howto_use_legacy_code.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "legacy/legacy.h" 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function HowtoUseLegacyCode() { 21 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 22 | return gcf::HttpResponse{} 23 | .set_header("Content-Type", "text/plain") 24 | .set_payload(legacy::LegacyMessage()); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /examples/howto_use_legacy_code/legacy/.gitignore: -------------------------------------------------------------------------------- 1 | liblegacy.a 2 | legacy.o 3 | -------------------------------------------------------------------------------- /examples/howto_use_legacy_code/legacy/Makefile: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2021 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | default: liblegacy.a 18 | 19 | liblegacy.a: legacy.o 20 | $(AR) r $@ $< 21 | 22 | legacy.o: legacy.cc legacy.h 23 | $(CXX) $(CXXFLAGS) -c -o $@ $< 24 | -------------------------------------------------------------------------------- /examples/howto_use_legacy_code/legacy/legacy.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "legacy.h" 16 | #include 17 | 18 | namespace legacy { 19 | std::string LegacyMessage() { 20 | return "C++ version is " + std::to_string(__cplusplus) + "\n"; 21 | } 22 | } // namespace legacy 23 | -------------------------------------------------------------------------------- /examples/howto_use_legacy_code/legacy/legacy.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_EXAMPLES_HOWTO_USE_LEGACY_CODE_LEGACY_LEGACY_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_EXAMPLES_HOWTO_USE_LEGACY_CODE_LEGACY_LEGACY_H 17 | 18 | #include 19 | 20 | namespace legacy { 21 | std::string LegacyMessage(); 22 | } // namespace legacy 23 | 24 | #endif // FUNCTIONS_FRAMEWORK_CPP_EXAMPLES_HOWTO_USE_LEGACY_CODE_LEGACY_LEGACY_H 25 | -------------------------------------------------------------------------------- /examples/howto_use_legacy_code/main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function HowtoUseLegacyCode(); 21 | 22 | int main(int argc, char* argv[]) { 23 | return ::google::cloud::functions::Run(argc, argv, HowtoUseLegacyCode()); 24 | } 25 | -------------------------------------------------------------------------------- /examples/howto_use_legacy_code/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-with-third-party", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "fmt", 6 | "functions-framework-cpp" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/site/bearer_token/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2021 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(CURL CONFIG REQUIRED) 18 | find_package(google_cloud_cpp_storage REQUIRED) 19 | find_package(functions_framework_cpp REQUIRED) 20 | 21 | add_library(functions_framework_cpp_function bearer_token.cc) 22 | target_link_libraries( 23 | functions_framework_cpp_function functions-framework-cpp::framework 24 | google-cloud-cpp::storage CURL::libcurl) 25 | -------------------------------------------------------------------------------- /examples/site/bearer_token/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bearer-token", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "google-cloud-cpp", 6 | "functions-framework-cpp" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/site/concepts_after_response/concepts_after_response.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_concepts_after_response] 16 | #include 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | gcf::Function concepts_after_response() { 22 | return gcf::MakeFunction([](gcf::HttpRequest const&) { 23 | (void)std::async(std::launch::async, [] { 24 | // This code may fail to complete, or even fail to start at all. 25 | auto constexpr kIterations = 10; 26 | int sum = 0; 27 | for (int i = 0; i != kIterations; ++i) sum += i; 28 | return sum; 29 | }); 30 | return gcf::HttpResponse{}.set_payload("Hello World!"); 31 | }); 32 | } 33 | // [END functions_concepts_after_response] 34 | -------------------------------------------------------------------------------- /examples/site/concepts_after_timeout/concepts_after_timeout.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_concepts_after_timeout] 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace gcf = ::google::cloud::functions; 22 | 23 | gcf::Function concepts_after_timeout() { 24 | using std::chrono::minutes; 25 | return gcf::MakeFunction([](gcf::HttpRequest const& request) { 26 | std::cout << "Function running..." << std::endl; 27 | if (request.verb() == "GET") std::this_thread::sleep_for(minutes(2)); 28 | std::cout << "Function completed!" << std::endl; 29 | return gcf::HttpResponse{}.set_payload("Function completed!"); 30 | }); 31 | } 32 | // [END functions_concepts_after_timeout] 33 | -------------------------------------------------------------------------------- /examples/site/concepts_filesystem/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(functions_framework_cpp REQUIRED) 18 | 19 | add_library(functions_framework_cpp_function concepts_filesystem.cc) 20 | target_link_libraries(functions_framework_cpp_function 21 | functions-framework-cpp::framework stdc++fs) 22 | -------------------------------------------------------------------------------- /examples/site/concepts_filesystem/concepts_filesystem.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_concepts_filesystem] 16 | #include 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | gcf::Function concepts_filesystem() { 22 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 23 | std::string payload; 24 | for (auto const& p : std::filesystem::directory_iterator(".")) { 25 | payload += p.path().generic_string(); 26 | payload += "\n"; 27 | } 28 | return gcf::HttpResponse{} 29 | .set_header("content-type", "text/plain") 30 | .set_payload(payload); 31 | }); 32 | } 33 | // [END functions_concepts_filesystem] 34 | -------------------------------------------------------------------------------- /examples/site/concepts_request/concepts_request.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_concepts_requests] 16 | #include 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | namespace { 22 | // Use Boost.Beast to illustrate making HTTP requests, return the status code. 23 | unsigned int make_http_request(std::string const& host); 24 | } // namespace 25 | 26 | gcf::Function concepts_request() { 27 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 28 | std::string const host = "example.com"; 29 | auto const code = make_http_request(host); 30 | return gcf::HttpResponse{}.set_payload( 31 | "Received code " + std::to_string(code) + " from " + host); 32 | }); 33 | } 34 | // [END functions_concepts_requests] 35 | 36 | namespace { 37 | unsigned int make_http_request(std::string const& host) { 38 | namespace beast = boost::beast; 39 | namespace http = beast::http; 40 | using http_response = http::response; 41 | using tcp = boost::asio::ip::tcp; 42 | 43 | // Create a socket to make the HTTP request over 44 | boost::asio::io_context ioc; 45 | tcp::resolver resolver(ioc); 46 | beast::tcp_stream stream(ioc); 47 | auto const results = resolver.resolve(host, "80"); 48 | stream.connect(results); 49 | 50 | // Use Boost.Beast to make the HTTP request 51 | auto constexpr kHttpVersion = 10; // 1.0 as Boost.Beast spells it 52 | http::request req{http::verb::get, "/", kHttpVersion}; 53 | req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); 54 | req.set(http::field::host, host); 55 | http::write(stream, req); 56 | beast::flat_buffer buffer; 57 | http_response res; 58 | http::read(stream, buffer, res); 59 | boost::system::error_code ec; 60 | stream.socket().shutdown(tcp::socket::shutdown_both, ec); 61 | (void)ec; // ignore errors during shutdown() 62 | 63 | return res.result_int(); 64 | } 65 | } // namespace 66 | -------------------------------------------------------------------------------- /examples/site/concepts_stateless/concepts_stateless.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_concepts_stateless] 16 | #include 17 | #include 18 | #include 19 | 20 | namespace gcf = ::google::cloud::functions; 21 | 22 | namespace { 23 | std::atomic count{0}; 24 | } // namespace 25 | 26 | gcf::Function concepts_stateless() { 27 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 28 | return gcf::HttpResponse{}.set_payload("Instance execution count: " + 29 | std::to_string(++count)); 30 | }); 31 | } 32 | // [END functions_concepts_stateless] 33 | -------------------------------------------------------------------------------- /examples/site/env_vars/env_vars.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_env_vars] 16 | #include 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | gcf::Function env_vars() { 22 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 23 | char const* value = std::getenv("FOO"); 24 | if (value == nullptr) value = "FOO environment variable is not set"; 25 | return gcf::HttpResponse{}.set_payload(value); 26 | }); 27 | } 28 | // [END functions_env_vars] 29 | -------------------------------------------------------------------------------- /examples/site/hello_world_error/hello_world_error.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_helloworld_error] 16 | #include 17 | #include 18 | #include 19 | 20 | namespace gcf = ::google::cloud::functions; 21 | 22 | gcf::Function hello_world_error() { 23 | return gcf::MakeFunction([](gcf::HttpRequest const& request) { 24 | if (request.target() == "/return500") { 25 | // An error response code does NOT create entries in Error Reporting 26 | return gcf::HttpResponse{}.set_result( 27 | gcf::HttpResponse::kInternalServerError); 28 | } 29 | // Unstructured logs to stdout and/or stderr do NOT create entries in Error 30 | // Reporting 31 | std::cout << "An error occurred (stdout)\n"; 32 | std::cerr << "An error occurred (stderr)\n"; 33 | 34 | if (request.target() == "/throw/exception") { 35 | // Throwing an exception WILL create new entries in Error Reporting 36 | throw std::runtime_error("I failed you"); 37 | } 38 | 39 | // Structured logs MAY create entries in Error Reporting depending on their 40 | // severity. You can create structured logs manually (as shown here), or 41 | // using your favorite logging library with suitable formatting. 42 | std::cerr << nlohmann::json{{"severity", "info"}, 43 | {"message", "informational message"}} 44 | .dump() 45 | << std::endl; 46 | 47 | std::cerr << nlohmann::json{{"severity", "error"}, 48 | {"message", "an error message"}} 49 | .dump() 50 | << std::endl; 51 | 52 | return gcf::HttpResponse{} 53 | .set_header("content-type", "text/plain") 54 | .set_payload("Hello World!"); 55 | }); 56 | } 57 | // [END functions_helloworld_error] 58 | -------------------------------------------------------------------------------- /examples/site/hello_world_error/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world-error", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "functions-framework-cpp", 6 | "nlohmann-json" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/site/hello_world_get/hello_world_get.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_helloworld_get] 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function hello_world_get() { 21 | return gcf::MakeFunction([](gcf::HttpRequest const&) { 22 | return gcf::HttpResponse{} 23 | .set_header("content-type", "text/plain") 24 | .set_payload("Hello World!"); 25 | }); 26 | } 27 | // [END functions_helloworld_get] 28 | -------------------------------------------------------------------------------- /examples/site/hello_world_http/hello_world_http.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_helloworld_http] 16 | #include 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | gcf::HttpResponse hello_world_http_impl(gcf::HttpRequest request) { 22 | auto greeting = [r = std::move(request)] { 23 | auto request_json = nlohmann::json::parse(r.payload(), /*cb=*/nullptr, 24 | /*allow_exceptions=*/false); 25 | if (request_json.count("name") && request_json["name"].is_string()) { 26 | return "Hello " + request_json.value("name", "World") + "!"; 27 | } 28 | return std::string("Hello World!"); 29 | }; 30 | 31 | return gcf::HttpResponse{} 32 | .set_header("content-type", "text/plain") 33 | .set_payload(greeting()); 34 | } 35 | 36 | gcf::Function hello_world_http() { 37 | return gcf::MakeFunction(hello_world_http_impl); 38 | } 39 | // [END functions_helloworld_http] 40 | -------------------------------------------------------------------------------- /examples/site/hello_world_pubsub/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(functions_framework_cpp REQUIRED) 18 | find_package(Boost REQUIRED COMPONENTS log) 19 | 20 | add_library(functions_framework_cpp_function hello_world_pubsub.cc) 21 | target_link_libraries(functions_framework_cpp_function 22 | functions-framework-cpp::framework Boost::log) 23 | -------------------------------------------------------------------------------- /examples/site/hello_world_pubsub/hello_world_pubsub.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_helloworld_pubsub] 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace gcf = ::google::cloud::functions; 22 | 23 | void hello_world_pubsub_impl(gcf::CloudEvent const& event) { 24 | if (event.data_content_type().value_or("") != "application/json") { 25 | BOOST_LOG_TRIVIAL(error) << "expected application/json data"; 26 | return; 27 | } 28 | auto const payload = nlohmann::json::parse(event.data().value_or("{}")); 29 | auto const name = cppcodec::base64_rfc4648::decode( 30 | payload["message"]["data"].get()); 31 | BOOST_LOG_TRIVIAL(info) << "Hello " << (name.empty() ? "World" : name); 32 | } 33 | 34 | gcf::Function hello_world_pubsub() { 35 | return gcf::MakeFunction(hello_world_pubsub_impl); 36 | } 37 | // [END functions_helloworld_pubsub] 38 | -------------------------------------------------------------------------------- /examples/site/hello_world_pubsub/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world-pubsub", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "boost-log", 6 | "cppcodec", 7 | "functions-framework-cpp", 8 | "nlohmann-json" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/site/hello_world_storage/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(functions_framework_cpp REQUIRED) 18 | find_package(Boost REQUIRED COMPONENTS log) 19 | 20 | add_library(functions_framework_cpp_function hello_world_storage.cc) 21 | target_link_libraries(functions_framework_cpp_function 22 | functions-framework-cpp::framework Boost::log) 23 | -------------------------------------------------------------------------------- /examples/site/hello_world_storage/hello_world_storage.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_helloworld_storage] 16 | #include 17 | #include 18 | #include 19 | 20 | namespace gcf = ::google::cloud::functions; 21 | 22 | void hello_world_storage_impl(gcf::CloudEvent const& event) { 23 | if (event.data_content_type().value_or("") != "application/json") { 24 | BOOST_LOG_TRIVIAL(error) << "expected application/json data"; 25 | return; 26 | } 27 | auto const payload = nlohmann::json::parse(event.data().value_or("{}")); 28 | BOOST_LOG_TRIVIAL(info) << "Event: " << event.id(); 29 | BOOST_LOG_TRIVIAL(info) << "Event Type: " << event.type(); 30 | BOOST_LOG_TRIVIAL(info) << "Bucket: " << payload.value("bucket", ""); 31 | BOOST_LOG_TRIVIAL(info) << "Object: " << payload.value("name", ""); 32 | BOOST_LOG_TRIVIAL(info) << "Metageneration: " 33 | << payload.value("metageneration", ""); 34 | BOOST_LOG_TRIVIAL(info) << "Created: " << payload.value("timeCreated", ""); 35 | BOOST_LOG_TRIVIAL(info) << "Updated: " << payload.value("updated", ""); 36 | } 37 | 38 | gcf::Function hello_world_storage() { 39 | return gcf::MakeFunction(hello_world_storage_impl); 40 | } 41 | // [END functions_helloworld_storage] 42 | -------------------------------------------------------------------------------- /examples/site/hello_world_storage/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world-storage", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "boost-log", 6 | "functions-framework-cpp", 7 | "nlohmann-json" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /examples/site/howto_local_development/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2021 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | # A minimal CMakeList.txt showing how to use the Functions Framework for C++ in 18 | # CMake-based projects. 19 | 20 | cmake_minimum_required(VERSION 3.5) 21 | project(functions-framework-cpp-howto-local-development CXX) 22 | 23 | set(CMAKE_CXX_STANDARD 17) 24 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 25 | 26 | find_package(Threads REQUIRED) 27 | find_package(functions_framework_cpp REQUIRED) 28 | 29 | add_executable(local_server local_server.cc) 30 | target_link_libraries(local_server functions-framework-cpp::framework) 31 | -------------------------------------------------------------------------------- /examples/site/howto_local_development/local_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | namespace { 21 | 22 | gcf::Function HelloLocal() { 23 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 24 | return gcf::HttpResponse{} 25 | .set_header("Content-Type", "text/plain") 26 | .set_payload("Hello World\n"); 27 | }); 28 | } 29 | 30 | } // namespace 31 | 32 | int main(int argc, char* argv[]) { return gcf::Run(argc, argv, HelloLocal()); } 33 | -------------------------------------------------------------------------------- /examples/site/howto_local_development/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions-framework-cpp-local-development", 3 | "version-string": "0.5.0-dev", 4 | "port-version": 1, 5 | "homepage": "https://github.com/GoogleCloudPlatform/functions-framework-cpp/", 6 | "description": "How-to Guide: Local Development with the Functions Framework for C++.", 7 | "dependencies": [ 8 | "functions-framework-cpp" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/site/http_content/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-content", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "functions-framework-cpp", 6 | "nlohmann-json" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/site/http_cors/http_cors.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_http_cors] 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function http_cors() { 21 | return gcf::MakeFunction([](gcf::HttpRequest const& request) { 22 | // Set CORS headers for preflight request 23 | if (request.verb() == "OPTIONS") { 24 | // Allows GET requests from any origin with the Content-Type header and 25 | // caches preflight response for an 3600s 26 | return gcf::HttpResponse{} 27 | .set_result(gcf::HttpResponse::kNoContent) 28 | .set_header("Access-Control-Allow-Origin", "*") 29 | .set_header("Access-Control-Allow-Methods", "GET") 30 | .set_header("Access-Control-Allow-Headers", "Content-Type") 31 | .set_header("Access-Control-Max-Age", "3600"); 32 | } 33 | 34 | return gcf::HttpResponse{} 35 | .set_header("Access-Control-Allow-Origin", "*") 36 | .set_header("content-type", "text/plain") 37 | .set_payload("Hello World!"); 38 | }); 39 | } 40 | // [END functions_http_cors] 41 | -------------------------------------------------------------------------------- /examples/site/http_cors_auth/http_cors_auth.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_http_cors_auth] 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function http_cors_auth() { 21 | return gcf::MakeFunction([](gcf::HttpRequest const& request) { 22 | // Set CORS headers for preflight request 23 | if (request.verb() == "OPTIONS") { 24 | // Allows GET requests from any origin with the Content-Type header and 25 | // caches preflight response for an 3600s 26 | return gcf::HttpResponse{} 27 | .set_result(gcf::HttpResponse::kNoContent) 28 | .set_header("Access-Control-Allow-Origin", "https://mydomain.com") 29 | .set_header("Access-Control-Allow-Methods", "GET") 30 | .set_header("Access-Control-Allow-Headers", "Authorization") 31 | .set_header("Access-Control-Max-Age", "3600") 32 | .set_header("Access-Control-Allow-Credentials", "true"); 33 | } 34 | 35 | return gcf::HttpResponse{} 36 | .set_header("Access-Control-Allow-Origin", "https://mydomain.com") 37 | .set_header("Access-Control-Allow-Credentials", "true") 38 | .set_header("content-type", "text/plain") 39 | .set_payload("Hello World!"); 40 | }); 41 | } 42 | // [END functions_http_cors_auth] 43 | -------------------------------------------------------------------------------- /examples/site/http_form_data/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2021 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(absl CONFIG REQUIRED) 18 | find_package(functions_framework_cpp REQUIRED) 19 | 20 | add_library(functions_framework_cpp_function http_form_data.cc) 21 | target_link_libraries(functions_framework_cpp_function 22 | functions-framework-cpp::framework absl::strings) 23 | -------------------------------------------------------------------------------- /examples/site/http_form_data/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form-data", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "abseil", 6 | "functions-framework-cpp" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/site/http_method/http_method.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_http_method] 16 | #include 17 | 18 | namespace gcf = ::google::cloud::functions; 19 | 20 | gcf::Function http_method() { 21 | return gcf::MakeFunction([](gcf::HttpRequest const& request) { 22 | if (request.verb() == "GET") { 23 | return gcf::HttpResponse{} 24 | .set_header("content-type", "text/plain") 25 | .set_payload("Hello World!"); 26 | } 27 | 28 | return gcf::HttpResponse{}.set_result( 29 | request.verb() == "POST" ? gcf::HttpResponse::kForbidden 30 | : gcf::HttpResponse::kMethodNotAllowed); 31 | }); 32 | } 33 | // [END functions_http_method] 34 | -------------------------------------------------------------------------------- /examples/site/http_xml/http_xml.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_http_xml] 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace gcf = ::google::cloud::functions; 22 | 23 | gcf::Function http_xml() { 24 | return gcf::MakeFunction([](gcf::HttpRequest const& request) { 25 | std::istringstream is(request.payload()); 26 | // Use the Boost.PropertyTree XML parser, as this is adequate for a small 27 | // example. Application developers may want to consider a more robust 28 | // parser for production code. 29 | boost::property_tree::ptree data; 30 | boost::property_tree::read_xml(is, data); 31 | 32 | auto name = data.get("name", "World"); 33 | return gcf::HttpResponse{} 34 | .set_header("content-type", "text/plain") 35 | .set_payload("Hello " + name); 36 | }); 37 | } 38 | // [END functions_http_xml] 39 | -------------------------------------------------------------------------------- /examples/site/http_xml/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-xml", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "boost-property-tree", 6 | "functions-framework-cpp" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/site/log_helloworld/log_helloworld.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_log_helloworld] 16 | #include 17 | #include 18 | #include 19 | 20 | namespace gcf = ::google::cloud::functions; 21 | 22 | gcf::Function log_helloworld() { 23 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 24 | std::cout << "This is stdout\n"; 25 | std::cerr << "This is stderr\n"; 26 | 27 | std::cerr << nlohmann::json{{"message", "This has ERROR severity"}, 28 | {"severity", "error"}} 29 | .dump() 30 | << "\n"; 31 | return gcf::HttpResponse{} 32 | .set_header("content-type", "text/plain") 33 | .set_payload("Hello Logging!"); 34 | }); 35 | } 36 | // [END functions_log_helloworld] 37 | -------------------------------------------------------------------------------- /examples/site/log_helloworld/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-content", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "functions-framework-cpp", 6 | "nlohmann-json" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/site/log_stackdriver/log_stackdriver.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_log_stackdriver] 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace gcf = ::google::cloud::functions; 22 | 23 | gcf::Function log_stackdriver() { 24 | return gcf::MakeFunction([](gcf::CloudEvent const& event) { 25 | if (event.data_content_type().value_or("") != "application/json") { 26 | std::cerr << "expected application/json data\n"; 27 | return; 28 | } 29 | auto const payload = nlohmann::json::parse(event.data().value_or("{}")); 30 | auto const data = cppcodec::base64_rfc4648::decode( 31 | payload["message"]["data"].get()); 32 | auto const log_entry = nlohmann::json::parse(data); 33 | std::cout << "Log entry data: " << log_entry.dump(/*indent=*/2) << "\n"; 34 | }); 35 | } 36 | // [END functions_log_stackdriver] 37 | -------------------------------------------------------------------------------- /examples/site/log_stackdriver/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "log-stackdriver", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "cppcodec", 6 | "functions-framework-cpp", 7 | "nlohmann-json" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /examples/site/pubsub_subscribe/pubsub_subscribe.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_pubsub_subscribe] 16 | #include 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | gcf::Function pubsub_subscribe() { 22 | return gcf::MakeFunction([](gcf::CloudEvent const& event) { 23 | // The framework converts the data from base64 if needed. 24 | std::cout << event.data().value_or("") << "\n"; 25 | }); 26 | } 27 | // [END functions_pubsub_subscribe] 28 | -------------------------------------------------------------------------------- /examples/site/testing_http/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(CURL CONFIG REQUIRED) 18 | find_package(Boost REQUIRED COMPONENTS filesystem) 19 | 20 | if (BUILD_TESTING) 21 | find_package(GTest CONFIG REQUIRED) 22 | set(functions_framework_cpp_examples_unit_tests 23 | # cmake-format: sort 24 | http_integration_test.cc http_unit_test.cc) 25 | 26 | set(functions_framework_cpp_examples_programs # cmake-format: sort 27 | http_integration_server.cc) 28 | 29 | foreach (fname ${functions_framework_cpp_examples_unit_tests} 30 | ${functions_framework_cpp_examples_programs}) 31 | string(REPLACE "/" "_" target "${fname}") 32 | string(REPLACE ".cc" "" target "${target}") 33 | add_executable("${target}" ${fname}) 34 | functions_framework_cpp_add_common_options(${target}) 35 | if (MSVC) 36 | target_compile_definitions(${target} 37 | PRIVATE "_CRT_SECURE_NO_WARNINGS") 38 | endif () 39 | target_link_libraries( 40 | ${target} 41 | PRIVATE functions_framework_examples 42 | functions-framework-cpp::framework 43 | CURL::libcurl 44 | Boost::filesystem 45 | GTest::gmock_main 46 | GTest::gmock 47 | GTest::gtest) 48 | endforeach () 49 | 50 | foreach (fname ${functions_framework_cpp_examples_unit_tests}) 51 | string(REPLACE "/" "_" target "${fname}") 52 | string(REPLACE ".cc" "" target "${target}") 53 | functions_framework_cpp_add_common_options(${target}) 54 | add_test(NAME ${target} COMMAND ${target}) 55 | endforeach () 56 | endif () 57 | -------------------------------------------------------------------------------- /examples/site/testing_http/http_integration_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace gcf = ::google::cloud::functions; 18 | extern gcf::Function hello_world_http(); 19 | 20 | int main(int argc, char* argv[]) { 21 | return gcf::Run(argc, argv, hello_world_http()); 22 | } 23 | -------------------------------------------------------------------------------- /examples/site/testing_http/http_unit_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_http_unit_test] 16 | #include 17 | #include 18 | #include 19 | 20 | namespace gcf = ::google::cloud::functions; 21 | extern gcf::HttpResponse hello_world_http_impl(gcf::HttpRequest request); 22 | 23 | namespace { 24 | 25 | TEST(HttpUnitTest, Success) { 26 | auto actual = hello_world_http_impl( 27 | gcf::HttpRequest{}.set_payload(R"js({ "name": "Foo" })js")); 28 | EXPECT_EQ(actual.payload(), "Hello Foo!"); 29 | 30 | actual = hello_world_http_impl( 31 | gcf::HttpRequest{}.set_payload(R"js({ "unused": 7 })js")); 32 | EXPECT_EQ(actual.payload(), "Hello World!"); 33 | 34 | actual = hello_world_http_impl(gcf::HttpRequest{}.set_payload("Bar")); 35 | EXPECT_EQ(actual.payload(), "Hello World!"); 36 | } 37 | 38 | } // namespace 39 | // [END functions_http_unit_test] 40 | -------------------------------------------------------------------------------- /examples/site/testing_pubsub/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | if (BUILD_TESTING) 18 | find_package(GTest CONFIG REQUIRED) 19 | find_package(fmt CONFIG REQUIRED) 20 | find_package(google_cloud_cpp_pubsub REQUIRED) 21 | 22 | set(functions_framework_cpp_examples_unit_tests 23 | # cmake-format: sort 24 | pubsub_integration_test.cc pubsub_unit_test.cc) 25 | 26 | foreach (fname ${functions_framework_cpp_examples_unit_tests}) 27 | string(REPLACE "/" "_" target "${fname}") 28 | string(REPLACE ".cc" "" target "${target}") 29 | add_executable("${target}" ${fname}) 30 | functions_framework_cpp_add_common_options(${target}) 31 | target_link_libraries( 32 | ${target} 33 | PRIVATE functions_framework_examples 34 | functions-framework-cpp::framework 35 | Boost::filesystem 36 | Boost::log 37 | GTest::gmock_main 38 | GTest::gmock 39 | GTest::gtest) 40 | add_test(NAME ${target} COMMAND ${target}) 41 | endforeach () 42 | 43 | add_executable(pubsub_integration_server pubsub_integration_server.cc) 44 | target_link_libraries( 45 | pubsub_integration_server 46 | PRIVATE functions_framework_examples functions-framework-cpp::framework 47 | Boost::filesystem Boost::log) 48 | 49 | add_executable(pubsub_system_test pubsub_system_test.cc) 50 | target_link_libraries( 51 | pubsub_system_test PRIVATE google-cloud-cpp::pubsub fmt::fmt Boost::log 52 | GTest::gmock_main GTest::gmock GTest::gtest) 53 | if (MSVC) 54 | set_property( 55 | SOURCE pubsub_system_test.cc 56 | APPEND 57 | PROPERTY COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS) 58 | endif () 59 | endif () 60 | -------------------------------------------------------------------------------- /examples/site/testing_pubsub/pubsub_integration_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace gcf = ::google::cloud::functions; 18 | extern gcf::Function hello_world_pubsub(); 19 | 20 | int main(int argc, char* argv[]) { 21 | return gcf::Run(argc, argv, hello_world_pubsub()); 22 | } 23 | -------------------------------------------------------------------------------- /examples/site/testing_pubsub/pubsub_unit_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_pubsub_unit_test] 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace gcf = ::google::cloud::functions; 27 | extern void hello_world_pubsub_impl(gcf::CloudEvent const& event); 28 | 29 | namespace { 30 | 31 | using ::testing::HasSubstr; 32 | 33 | TEST(PubsubUnitTest, Basic) { 34 | auto core = boost::log::core::get(); 35 | auto stream = boost::make_shared(); 36 | auto be = [core, stream]() { 37 | auto backend = 38 | boost::make_shared(); 39 | backend->add_stream(stream); 40 | 41 | // Enable auto-flushing after each log record written 42 | backend->auto_flush(true); 43 | using sink_t = boost::log::sinks::synchronous_sink< 44 | boost::log::sinks::text_ostream_backend>; 45 | auto be = boost::make_shared(backend); 46 | core->add_sink(be); 47 | return be; 48 | }(); 49 | 50 | struct { 51 | std::string data; 52 | std::string expected; 53 | } const cases[]{ 54 | // The magic string was obtained using: 55 | // /bin/echo -n 'C++' | openssl base64 -e 56 | {R"js({"message": {"data": "Qysr"}})js", "Hello C++"}, 57 | {R"js({"message": {"data": ""}})js", "Hello World"}, 58 | }; 59 | 60 | for (auto const& test : cases) { 61 | SCOPED_TRACE("Testing for " + test.expected); 62 | gcf::CloudEvent event( 63 | /*id=*/"test-id-0001", /*source=*/"https://test-source.example.com", 64 | /*type=*/"google.cloud.pubsub.topic.v1.messagePublished"); 65 | event.set_data_content_type("application/json"); 66 | event.set_data(test.data); 67 | stream->str({}); 68 | EXPECT_NO_THROW(hello_world_pubsub_impl(event)); 69 | auto log_lines = stream->str(); 70 | EXPECT_THAT(log_lines, HasSubstr(test.expected)); 71 | } 72 | 73 | core->remove_sink(be); 74 | } 75 | 76 | } // namespace 77 | // [END functions_pubsub_unit_test] 78 | -------------------------------------------------------------------------------- /examples/site/testing_storage/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | if (BUILD_TESTING) 18 | find_package(GTest CONFIG REQUIRED) 19 | find_package(fmt CONFIG REQUIRED) 20 | find_package(google_cloud_cpp_storage REQUIRED) 21 | 22 | set(functions_framework_cpp_examples_unit_tests 23 | # cmake-format: sort 24 | storage_integration_test.cc storage_unit_test.cc) 25 | 26 | foreach (fname ${functions_framework_cpp_examples_unit_tests}) 27 | string(REPLACE "/" "_" target "${fname}") 28 | string(REPLACE ".cc" "" target "${target}") 29 | add_executable("${target}" ${fname}) 30 | functions_framework_cpp_add_common_options(${target}) 31 | target_link_libraries( 32 | ${target} 33 | PRIVATE functions_framework_examples 34 | functions-framework-cpp::framework 35 | Boost::filesystem 36 | Boost::log 37 | GTest::gmock_main 38 | GTest::gmock 39 | GTest::gtest) 40 | add_test(NAME ${target} COMMAND ${target}) 41 | endforeach () 42 | 43 | add_executable(storage_integration_server storage_integration_server.cc) 44 | target_link_libraries( 45 | storage_integration_server 46 | PRIVATE functions_framework_examples functions-framework-cpp::framework 47 | Boost::filesystem Boost::log) 48 | add_executable(storage_system_test storage_system_test.cc) 49 | target_link_libraries( 50 | storage_system_test 51 | PRIVATE google-cloud-cpp::storage fmt::fmt Boost::log GTest::gmock_main 52 | GTest::gmock GTest::gtest) 53 | if (MSVC) 54 | set_property( 55 | SOURCE storage_system_test.cc 56 | APPEND 57 | PROPERTY COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS) 58 | endif () 59 | endif () 60 | -------------------------------------------------------------------------------- /examples/site/testing_storage/storage_integration_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace gcf = ::google::cloud::functions; 18 | extern gcf::Function hello_world_storage(); 19 | 20 | int main(int argc, char* argv[]) { 21 | return gcf::Run(argc, argv, hello_world_storage()); 22 | } 23 | -------------------------------------------------------------------------------- /examples/site/tips_gcp_apis/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(google_cloud_cpp_pubsub REQUIRED) 18 | find_package(functions_framework_cpp REQUIRED) 19 | 20 | add_library(functions_framework_cpp_function tips_gcp_apis.cc) 21 | target_link_libraries( 22 | functions_framework_cpp_function functions-framework-cpp::framework 23 | google-cloud-cpp::pubsub) 24 | -------------------------------------------------------------------------------- /examples/site/tips_gcp_apis/tips_gcp_apis.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_pubsub_publish] 16 | // [START functions_tips_gcp_apis] 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace gcf = ::google::cloud::functions; 26 | namespace pubsub = ::google::cloud::pubsub; 27 | 28 | namespace { 29 | pubsub::BlockingPublisher GetPublisher() { 30 | static std::mutex mu; 31 | static std::shared_ptr connection; 32 | 33 | std::lock_guard const lk(mu); 34 | if (!connection) connection = pubsub::MakeBlockingPublisherConnection(); 35 | return pubsub::BlockingPublisher(connection); 36 | } 37 | } // namespace 38 | 39 | gcf::HttpResponse tips_gcp_apis_impl(gcf::HttpRequest const& request) { 40 | auto const* project = std::getenv("GCP_PROJECT"); 41 | if (project == nullptr) throw std::runtime_error("GCP_PROJECT is not set"); 42 | 43 | auto const body = nlohmann::json::parse(request.payload()); 44 | auto const topic_id = body.value("topic", ""); 45 | if (topic_id.empty()) throw std::runtime_error("Missing topic in request"); 46 | 47 | auto publisher = GetPublisher(); 48 | auto id = publisher.Publish( 49 | pubsub::Topic(project, topic_id), 50 | pubsub::MessageBuilder().SetData("Test message").Build()); 51 | 52 | if (!id) { 53 | return gcf::HttpResponse{}.set_result( 54 | gcf::HttpResponse::kInternalServerError); 55 | } 56 | return gcf::HttpResponse{} 57 | .set_payload("1 message published") 58 | .set_header("content-type", "text/plain"); 59 | } 60 | 61 | gcf::Function tips_gcp_apis() { return gcf::MakeFunction(tips_gcp_apis_impl); } 62 | // [END functions_tips_gcp_apis] 63 | // [END functions_pubsub_publish] 64 | -------------------------------------------------------------------------------- /examples/site/tips_gcp_apis/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tips-gcp-apis", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "google-cloud-cpp", 6 | "functions-framework-cpp" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/site/tips_infinite_retries/tips_infinite_retries.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_tips_infinite_retries] 16 | #include 17 | #include 18 | #include 19 | 20 | namespace gcf = ::google::cloud::functions; 21 | 22 | namespace { 23 | auto constexpr kMaxAge = std::chrono::seconds(10); 24 | } // namespace 25 | 26 | gcf::Function tips_infinite_retries() { 27 | return gcf::MakeFunction([](gcf::CloudEvent const& event) { 28 | using std::chrono::system_clock; 29 | auto const age = 30 | system_clock::now() - event.time().value_or(system_clock::time_point()); 31 | auto const seconds = 32 | std::chrono::duration_cast(age).count(); 33 | 34 | if (age >= kMaxAge) { 35 | std::cout << "Dropped " << event.id() << " (age " << seconds << "s)\n"; 36 | return; 37 | } 38 | std::cout << "Processed " << event.id() << " (age " << seconds << "s)\n"; 39 | }); 40 | } 41 | // [END functions_tips_infinite_retries] 42 | -------------------------------------------------------------------------------- /examples/site/tips_lazy_globals/tips_lazy_globals.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_tips_lazy_globals] 16 | #include 17 | #include 18 | #include 19 | 20 | namespace gcf = ::google::cloud::functions; 21 | 22 | namespace { 23 | // Placeholders to illustrate lazy global initialization. 24 | std::once_flag h_init_flag; 25 | std::string h; 26 | void h_init() { h = "heavy computation"; } 27 | } // namespace 28 | 29 | gcf::Function tips_lazy_globals() { 30 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 31 | std::call_once(h_init_flag, h_init); 32 | return gcf::HttpResponse{}.set_payload("Global: " + h); 33 | }); 34 | } 35 | // [END functions_tips_lazy_globals] 36 | -------------------------------------------------------------------------------- /examples/site/tips_retry/tips_retry.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_tips_retry] 16 | #include 17 | #include 18 | #include 19 | 20 | namespace gcf = ::google::cloud::functions; 21 | 22 | gcf::Function tips_retry() { 23 | return gcf::MakeFunction([](gcf::CloudEvent const& event) { 24 | if (event.data_content_type().value_or("") != "application/json") { 25 | std::cerr << "Error: expected application/json data\n"; 26 | return; 27 | } 28 | auto const payload = nlohmann::json::parse(event.data().value_or("{}")); 29 | auto const retry = payload.value("retry", false); 30 | if (retry) throw std::runtime_error("Throwing exception to force retry"); 31 | // Normal processing goes here. 32 | }); 33 | } 34 | // [END functions_tips_retry] 35 | -------------------------------------------------------------------------------- /examples/site/tips_scopes/tips_scopes.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START functions_tips_scopes] 16 | #include 17 | #include 18 | 19 | namespace gcf = ::google::cloud::functions; 20 | 21 | namespace { 22 | // Placeholders to illustrate global vs. local initialization 23 | std::string heavy_computation(); 24 | std::string light_computation(); 25 | 26 | std::string h = heavy_computation(); 27 | } // namespace 28 | 29 | gcf::Function tips_scopes() { 30 | return gcf::MakeFunction([](gcf::HttpRequest const& /*request*/) { 31 | auto l = light_computation(); 32 | return gcf::HttpResponse{}.set_payload("Global: " + h + ", Local: " + l); 33 | }); 34 | } 35 | // [END functions_tips_scopes] 36 | 37 | namespace { 38 | std::string heavy_computation() { return "slow"; } 39 | 40 | std::string light_computation() { return "fast"; } 41 | } // namespace 42 | -------------------------------------------------------------------------------- /examples/site/tutorial_cloud_bigtable/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2021 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(google_cloud_cpp_bigtable REQUIRED) 18 | find_package(functions_framework_cpp REQUIRED) 19 | 20 | add_library(functions_framework_cpp_function tutorial_cloud_bigtable.cc) 21 | target_link_libraries( 22 | functions_framework_cpp_function functions-framework-cpp::framework 23 | google-cloud-cpp::bigtable) 24 | -------------------------------------------------------------------------------- /examples/site/tutorial_cloud_bigtable/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tutorial-cloud-bigtable", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "fmt", 6 | "functions-framework-cpp", 7 | "google-cloud-cpp" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /examples/site/tutorial_cloud_spanner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2021 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(google_cloud_cpp_spanner REQUIRED) 18 | find_package(functions_framework_cpp REQUIRED) 19 | 20 | add_library(functions_framework_cpp_function tutorial_cloud_spanner.cc) 21 | target_link_libraries( 22 | functions_framework_cpp_function functions-framework-cpp::framework 23 | google-cloud-cpp::spanner) 24 | -------------------------------------------------------------------------------- /examples/site/tutorial_cloud_spanner/tutorial_cloud_spanner.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // [START spanner_functions_quickstart] 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace gcf = ::google::cloud::functions; 24 | namespace spanner = ::google::cloud::spanner; 25 | 26 | namespace { 27 | 28 | auto get_spanner_database() { 29 | auto getenv = [](char const* var) { 30 | auto const* value = std::getenv(var); 31 | if (value == nullptr) { 32 | throw std::runtime_error("Environment variable " + std::string(var) + 33 | " is not set"); 34 | } 35 | return std::string(value); 36 | }; 37 | return spanner::Database(getenv("GOOGLE_CLOUD_PROJECT"), 38 | getenv("SPANNER_INSTANCE"), 39 | getenv("SPANNER_DATABASE")); 40 | } 41 | 42 | gcf::HttpResponse handle_request(gcf::HttpRequest const& /*request*/) { 43 | static auto const kClient = 44 | spanner::Client(spanner::MakeConnection(get_spanner_database())); 45 | 46 | auto client = kClient; 47 | 48 | std::ostringstream os; 49 | os << "Albums:\n"; 50 | auto rows = client.ExecuteQuery(spanner::SqlStatement( 51 | "SELECT SingerId, AlbumId, AlbumTitle FROM Albums")); 52 | using RowType = std::tuple; 53 | for (auto const& row : spanner::StreamOf(rows)) { 54 | if (!row) throw std::runtime_error(row.status().message()); 55 | os << std::get<0>(*row) << " " << std::get<1>(*row) << " " 56 | << std::get<2>(*row) << "\n"; 57 | } 58 | 59 | return gcf::HttpResponse{} 60 | .set_header("content-type", "text/plain") 61 | .set_payload(std::move(os).str()); 62 | } 63 | 64 | } // namespace 65 | 66 | gcf::Function tutorial_cloud_spanner() { 67 | return gcf::MakeFunction(handle_request); 68 | } 69 | 70 | // [END spanner_functions_quickstart] 71 | -------------------------------------------------------------------------------- /examples/site/tutorial_cloud_spanner/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tutorial-cloud-spanner", 3 | "version-string": "unversioned", 4 | "dependencies": [ 5 | "functions-framework-cpp", 6 | "google-cloud-cpp" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /google/cloud/functions/cloud_event.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/cloud_event.h" 16 | #include // NOLINT(modernize-deprecated-headers) 17 | 18 | namespace google::cloud::functions { 19 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 20 | 21 | void CloudEvent::set_time(std::string const& timestamp) { 22 | std::string err; 23 | absl::Time time; 24 | if (!absl::ParseTime(absl::RFC3339_full, timestamp, &time, &err)) { 25 | throw std::invalid_argument(err); 26 | } 27 | set_time(absl::ToChronoTime(time)); 28 | } 29 | 30 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 31 | } // namespace google::cloud::functions 32 | -------------------------------------------------------------------------------- /google/cloud/functions/config.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | include(CMakeFindDependencyMacro) 16 | find_dependency(absl) 17 | find_dependency(Boost COMPONENTS program_options) 18 | find_dependency(Threads) 19 | find_dependency(nlohmann_json) 20 | 21 | set(FUNCTIONS_FRAMEWORK_CPP_VERSION @PROJECT_VERSION@) 22 | 23 | @PACKAGE_INIT@ 24 | 25 | include("${CMAKE_CURRENT_LIST_DIR}/functions-framework-cpp-targets.cmake") 26 | 27 | check_required_components(FUNCTIONS_FRAMEWORK_CPP_VERSION) 28 | -------------------------------------------------------------------------------- /google/cloud/functions/config.pc.in: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | prefix=${pcfiledir}/../.. 16 | exec_prefix=${prefix}/@CMAKE_INSTALL_BINDIR@ 17 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 18 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 19 | 20 | Name: Functions Framework for C++ 21 | Description: A framework to support C++ Google Cloud Functions 22 | Requires: 23 | Version: @PROJECT_VERSION@ 24 | 25 | Libs: -L${libdir} -lboost_program_options -lboost_beast 26 | Cflags: -I${includedir} 27 | -------------------------------------------------------------------------------- /google/cloud/functions/function.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/function.h" 16 | #include "google/cloud/functions/internal/function_impl.h" 17 | 18 | namespace google::cloud::functions { 19 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 20 | 21 | Function::~Function() = default; 22 | 23 | Function::Function(std::shared_ptr impl) 24 | : impl_(std::move(impl)) {} 25 | 26 | Function MakeFunction(UserHttpFunction function) { 27 | return functions_internal::FunctionImpl::MakeFunction( 28 | std::make_shared( 29 | std::move(function))); 30 | } 31 | 32 | Function MakeFunction(UserCloudEventFunction function) { 33 | return functions_internal::FunctionImpl::MakeFunction( 34 | std::make_shared( 35 | std::move(function))); 36 | } 37 | 38 | Function MakeFunction(std::map mapping) { 39 | return functions_internal::FunctionImpl::MakeFunction( 40 | std::make_shared( 41 | std::move(mapping))); 42 | } 43 | 44 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 45 | } // namespace google::cloud::functions 46 | -------------------------------------------------------------------------------- /google/cloud/functions/http_response.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/http_response.h" 16 | #include "google/cloud/functions/internal/wrap_response.h" 17 | 18 | namespace google::cloud::functions { 19 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 20 | 21 | HttpResponse::HttpResponse() : impl_(functions_internal::MakeHttpResponse()) {} 22 | 23 | HttpResponse::Impl::~Impl() = default; 24 | 25 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 26 | } // namespace google::cloud::functions 27 | -------------------------------------------------------------------------------- /google/cloud/functions/http_response_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/http_response.h" 16 | #include 17 | 18 | namespace google::cloud::functions_internal { 19 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 20 | namespace { 21 | 22 | using ::testing::ElementsAre; 23 | using ::testing::IsEmpty; 24 | 25 | TEST(WrapResponseTest, Payload) { 26 | functions::HttpResponse r; 27 | EXPECT_THAT(r.payload(), IsEmpty()); 28 | auto const hello = std::string("Hello"); 29 | auto response = std::move(r).set_payload(std::string(hello)); 30 | EXPECT_EQ(response.payload(), hello); 31 | auto const bye = std::string("Goodbye"); 32 | response.set_payload(bye); 33 | EXPECT_EQ(response.payload(), bye); 34 | } 35 | 36 | TEST(WrapResponseTest, Result) { 37 | functions::HttpResponse r; 38 | EXPECT_EQ(r.result(), functions::HttpResponse::kOkay); 39 | auto response = std::move(r).set_result(functions::HttpResponse::kNotFound); 40 | EXPECT_EQ(response.result(), functions::HttpResponse::kNotFound); 41 | response.set_result(functions::HttpResponse::kBadGateway); 42 | EXPECT_EQ(response.result(), functions::HttpResponse::kBadGateway); 43 | } 44 | 45 | TEST(WrapResponseTest, Headers) { 46 | auto r = functions::HttpResponse{}; 47 | EXPECT_THAT(r.headers(), IsEmpty()); 48 | auto response = std::move(r).set_header("Content-Type", "application/json"); 49 | EXPECT_THAT(response.headers(), 50 | ElementsAre(std::make_pair("Content-Type", "application/json"))); 51 | response.set_header("x-goog-test", "a"); 52 | response.set_header("x-goog-test", "b"); 53 | EXPECT_THAT(response.headers(), 54 | ElementsAre(std::make_pair("Content-Type", "application/json"), 55 | std::make_pair("x-goog-test", "b"))); 56 | } 57 | 58 | TEST(WrapResponseTest, Version) { 59 | auto r = functions::HttpResponse{}; 60 | EXPECT_EQ(r.version_major(), 1); 61 | EXPECT_EQ(r.version_minor(), 1); 62 | auto response = std::move(r).set_version(1, 0); 63 | EXPECT_EQ(response.version_major(), 1); 64 | EXPECT_EQ(response.version_minor(), 0); 65 | response.set_version(1, 1); 66 | EXPECT_EQ(response.version_major(), 1); 67 | EXPECT_EQ(response.version_minor(), 1); 68 | } 69 | 70 | } // namespace 71 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 72 | } // namespace google::cloud::functions_internal 73 | -------------------------------------------------------------------------------- /google/cloud/functions/integration_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ~~~ 16 | 17 | find_package(GTest CONFIG REQUIRED) 18 | find_package(Boost REQUIRED COMPONENTS filesystem) 19 | 20 | set(functions_framework_cpp_integration_tests 21 | # cmake-format: sort 22 | basic_integration_test.cc cloud_event_integration_test.cc) 23 | 24 | foreach (fname ${functions_framework_cpp_integration_tests}) 25 | string(REPLACE "/" "_" target "${fname}") 26 | string(REPLACE ".cc" "" target "${target}") 27 | add_executable("${target}" ${fname}) 28 | target_link_libraries( 29 | ${target} PRIVATE functions-framework-cpp::framework GTest::gmock 30 | GTest::gtest Boost::filesystem) 31 | functions_framework_cpp_add_common_options(${target}) 32 | # I (coryan) am not sure why this is needed, but it only affects the tests, 33 | # so I am more willing to tolerate it. I think normally Boost header-only 34 | # libraries automatically declare when they need additional libraries with 35 | # MSVC, but it does not seem to work here. 36 | target_compile_definitions("${target}" PRIVATE BOOST_UUID_FORCE_AUTO_LINK) 37 | add_test(NAME ${target} COMMAND ${target}) 38 | endforeach () 39 | 40 | set(functions_framework_cpp_integration_programs 41 | # cmake-format: sort 42 | cloud_event_conformance.cc cloud_event_handler.cc echo_server.cc 43 | http_conformance.cc) 44 | 45 | foreach (fname ${functions_framework_cpp_integration_programs}) 46 | string(REPLACE "/" "_" target "${fname}") 47 | string(REPLACE ".cc" "" target "${target}") 48 | add_executable("${target}" ${fname}) 49 | target_link_libraries(${target} PRIVATE functions-framework-cpp::framework) 50 | functions_framework_cpp_add_common_options(${target}) 51 | endforeach () 52 | -------------------------------------------------------------------------------- /google/cloud/functions/integration_tests/cloud_event_conformance.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/framework_impl.h" 16 | #include // NOLINT(modernize-deprecated-headers) 17 | #include 18 | #include 19 | #include 20 | 21 | namespace functions = ::google::cloud::functions; 22 | 23 | std::atomic shutdown_server{false}; 24 | 25 | void CloudEventConformance(functions::CloudEvent const& ev) { 26 | // This output name is hard requirement from the conformance testing 27 | // framework. 28 | auto constexpr kOutputFilename = "function_output.json"; 29 | nlohmann::json event{ 30 | {"id", ev.id()}, 31 | {"source", ev.source()}, 32 | {"type", ev.type()}, 33 | {"specversion", ev.spec_version()}, 34 | }; 35 | struct { 36 | std::string name; 37 | std::optional value; 38 | } const optional_fields[]{ 39 | {"datacontenttype", ev.data_content_type()}, 40 | {"dataschema", ev.data_schema()}, 41 | {"subject", ev.subject()}, 42 | }; 43 | for (auto const& of : optional_fields) { 44 | if (of.value) event[of.name] = *of.value; 45 | } 46 | if (ev.time()) { 47 | event["time"] = absl::FormatTime( 48 | absl::RFC3339_full, absl::FromChrono(*ev.time()), absl::UTCTimeZone()); 49 | } 50 | if (ev.data()) { 51 | if (ev.data_content_type().value_or("") == "application/json") { 52 | event["data"] = nlohmann::json::parse(*ev.data()); 53 | } else { 54 | event["data"] = *ev.data(); 55 | } 56 | } 57 | 58 | std::ofstream(kOutputFilename) << event.dump() << "\n"; 59 | 60 | // This is here just to gracefully shutdown and collect coverage data. 61 | if (ev.subject() == "/quit/program/0") shutdown_server.store(true); 62 | } 63 | 64 | int main(int argc, char* argv[]) { 65 | return google::cloud::functions_internal::RunForTest( 66 | argc, argv, functions::MakeFunction(CloudEventConformance), 67 | [] { return shutdown_server.load(); }, [](int /*port*/) {}); 68 | } 69 | -------------------------------------------------------------------------------- /google/cloud/functions/integration_tests/cloud_event_handler.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/framework_impl.h" 16 | #include 17 | #include 18 | 19 | using ::google::cloud::functions::CloudEvent; 20 | 21 | std::atomic shutdown_server{false}; 22 | 23 | void CloudEventHandler(CloudEvent const& event) { 24 | auto const& subject = event.subject().value_or(""); 25 | if (subject == "/quit/program/0") { 26 | shutdown_server.store(true); 27 | return; 28 | } 29 | if (subject.rfind("/exception/", 0) == 0) throw std::runtime_error(subject); 30 | if (subject.rfind("/unknown-exception/", 0) == 0) throw "uh-oh"; 31 | if (subject.rfind("/buffered-stdout/", 0) == 0) { 32 | std::cout << "stdout: " << subject << "\n"; 33 | } 34 | if (subject.rfind("/buffered-stderr/", 0) == 0) { 35 | std::clog << "stderr: " << subject << "\n"; 36 | } 37 | } 38 | 39 | int main(int argc, char* argv[]) { 40 | return google::cloud::functions_internal::RunForTest( 41 | argc, argv, google::cloud::functions::MakeFunction(CloudEventHandler), 42 | [] { return shutdown_server.load(); }, [](int /*port*/) {}); 43 | } 44 | -------------------------------------------------------------------------------- /google/cloud/functions/integration_tests/echo_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/framework_impl.h" 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace functions = ::google::cloud::functions; 22 | using functions::HttpRequest; 23 | using functions::HttpResponse; 24 | 25 | std::atomic shutdown_server{false}; 26 | 27 | HttpResponse EchoServer(HttpRequest const& request) { 28 | auto const& target = request.target(); 29 | if (target == "/quit/program/0") { 30 | shutdown_server = true; 31 | return HttpResponse{} 32 | .set_header("Content-Type", "text/plain") 33 | .set_payload("OK"); 34 | } 35 | if (target.rfind("/exception/", 0) == 0) throw std::runtime_error(target); 36 | if (target.rfind("/unknown-exception/", 0) == 0) throw "uh-oh"; 37 | 38 | if (target == "/ok") { 39 | return HttpResponse{} 40 | .set_header("Content-Type", "text/plain") 41 | .set_payload("OK"); 42 | } 43 | 44 | if (target.rfind("/error/", 0) == 0) { 45 | auto code = std::stoi(target.substr(std::strlen("/error/"))); 46 | return HttpResponse{}.set_result(code); 47 | } 48 | 49 | if (target.rfind("/buffered-stdout/", 0) == 0) { 50 | std::cout << "stdout: " << target << "\n"; 51 | } 52 | 53 | if (target.rfind("/buffered-stderr/", 0) == 0) { 54 | std::clog << "stderr: " << target << "\n"; 55 | } 56 | 57 | std::ostringstream payload; 58 | payload << "{\n" 59 | << R"js( "target": ")js" << target << "\"\n" 60 | << R"js( "verb": ")js" << request.verb() << "\"\n" 61 | << R"js( "headers": [)js"; 62 | for (auto [k, v] : request.headers()) { 63 | payload << '"' << k << ": " << v << '"' << "\n"; 64 | } 65 | payload << "}\n"; 66 | 67 | return HttpResponse{} 68 | .set_header("Content-Type", "application/json") 69 | .set_payload(std::move(payload).str()); 70 | } 71 | 72 | int main(int argc, char* argv[]) { 73 | return google::cloud::functions_internal::RunForTest( 74 | argc, argv, google::cloud::functions::MakeFunction(EchoServer), 75 | [] { return shutdown_server.load(); }, [](int /*port*/) {}); 76 | } 77 | -------------------------------------------------------------------------------- /google/cloud/functions/integration_tests/http_conformance.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/framework_impl.h" 16 | #include 17 | #include 18 | 19 | namespace functions = ::google::cloud::functions; 20 | 21 | std::atomic shutdown_server{false}; 22 | 23 | functions::HttpResponse HttpConformance(functions::HttpRequest const& request) { 24 | auto constexpr kOutputFilename = "function_output.json"; 25 | std::ofstream(kOutputFilename) << request.payload() << "\n"; 26 | // This is here just to gracefully shutdown and collect coverage data. 27 | if (request.target() == "/quit/program/0") shutdown_server = true; 28 | return functions::HttpResponse{}; 29 | } 30 | 31 | int main(int argc, char* argv[]) { 32 | return google::cloud::functions_internal::RunForTest( 33 | argc, argv, google::cloud::functions::MakeFunction(HttpConformance), 34 | [] { return shutdown_server.load(); }, [](int /*port*/) {}); 35 | } 36 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/base64_decode.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/base64_decode.h" 16 | #include 17 | #include 18 | #include 19 | 20 | namespace google::cloud::functions_internal { 21 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 22 | 23 | // NOLINTNEXTLINE(misc-no-recursion) 24 | std::string Base64Decode(std::string const& base64) { 25 | if (base64.size() % 4 != 0) { 26 | // This should be uncommon, to avoid copying every time, pad only when 27 | // needed and try again. 28 | auto padded = base64; 29 | padded.append((4 - padded.size() % 4) % 4, '='); 30 | return Base64Decode(padded); 31 | } 32 | 33 | namespace bai = boost::archive::iterators; 34 | auto constexpr kBase64RawBits = 6; 35 | auto constexpr kBase64EncodedBits = 8; 36 | using Decoder = 37 | bai::transform_width, 38 | kBase64EncodedBits, kBase64RawBits>; 39 | // While we know how much padding we added, there may have been some padding 40 | // there, just not enough. We need to determine the actual number of `=` 41 | // characters at the end of the string. 42 | auto pad_count = std::distance(base64.rbegin(), 43 | std::find_if(base64.rbegin(), base64.rend(), 44 | [](auto c) { return c != '='; })); 45 | if (pad_count > 2) { 46 | throw std::invalid_argument("Invalid base64 string <" + base64 + ">"); 47 | } 48 | 49 | auto data = std::string{Decoder(base64.begin()), Decoder(base64.end())}; 50 | for (; pad_count != 0; --pad_count) data.pop_back(); 51 | return data; 52 | } 53 | 54 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 55 | } // namespace google::cloud::functions_internal 56 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/base64_decode.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_BASE64_DECODE_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_BASE64_DECODE_H 17 | 18 | #include "google/cloud/functions/version.h" 19 | #include 20 | 21 | namespace google::cloud::functions_internal { 22 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 23 | 24 | std::string Base64Decode(std::string const& base64); 25 | 26 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 27 | } // namespace google::cloud::functions_internal 28 | 29 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_BASE64_DECODE_H 30 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/base64_decode_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/base64_decode.h" 16 | #include 17 | 18 | namespace google::cloud::functions_internal { 19 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 20 | namespace { 21 | 22 | struct TestData { 23 | std::string encoded_data; 24 | std::string expected_data; 25 | }; 26 | 27 | TEST(Base64DecodeTest, Basic) { 28 | // The magic strings were obtained using: 29 | // echo -n "" | openssl base64 -e 30 | // echo -n "a" | openssl base64 -e 31 | // echo -n "ab" | openssl base64 -e 32 | // echo -n "abc" | openssl base64 -e 33 | TestData const test_data[] = { 34 | {"", ""}, 35 | {"YQ==", "a"}, 36 | {"YWI=", "ab"}, 37 | {"YWJj", "abc"}, 38 | }; 39 | 40 | for (auto const& c : test_data) { 41 | auto const actual = Base64Decode(c.encoded_data); 42 | EXPECT_EQ(actual, c.expected_data); 43 | } 44 | } 45 | 46 | TEST(Base64DecodeTest, Underpadded) { 47 | TestData const test_data[] = { 48 | {"YQ=", "a"}, 49 | {"YQ", "a"}, 50 | {"YWI", "ab"}, 51 | }; 52 | for (auto const& c : test_data) { 53 | auto const actual = Base64Decode(c.encoded_data); 54 | EXPECT_EQ(actual, c.expected_data); 55 | } 56 | } 57 | 58 | TEST(Base64DecodeTest, Overpadded) { 59 | auto constexpr kExcessivePadding = "YWJj============"; 60 | EXPECT_THROW(Base64Decode(kExcessivePadding), std::invalid_argument); 61 | } 62 | 63 | } // namespace 64 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 65 | } // namespace google::cloud::functions_internal 66 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/build_info.cc.in: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/build_info.h" 16 | #include "google/cloud/functions/internal/compiler_info.h" 17 | #include 18 | 19 | namespace google::cloud::functions_internal { 20 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 21 | 22 | std::string Compiler() { 23 | return CompilerId() + " " + CompilerVersion(); 24 | } 25 | 26 | std::string CompilerFlags() { 27 | static char const kCompilerFlags[] = R"""(@CMAKE_CXX_FLAGS@)"""; 28 | return kCompilerFlags; 29 | } 30 | 31 | std::string BuildMetadata() { 32 | // Sometimes FUNCTIONS_FRAMEWORK_CPP_BUILD_METADATA string expands to nothing, and 33 | // then clang-tidy complains. 34 | // NOLINTNEXTLINE(readability-redundant-string-init) 35 | static char const kBuildMetadata[] = R"""(@FUNCTIONS_FRAMEWORK_CPP_BUILD_METADATA@)"""; 36 | return kBuildMetadata; 37 | } 38 | 39 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 40 | } // namespace google::cloud::functions_internal 41 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/build_info.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_BUILD_INFO_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_BUILD_INFO_H 17 | 18 | #include "google/cloud/functions/version.h" 19 | 20 | namespace google::cloud::functions_internal { 21 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 22 | 23 | /// The compiler version. 24 | std::string Compiler(); 25 | 26 | /// The compiler flags. 27 | std::string CompilerFlags(); 28 | 29 | /// Build metadata injected by the build system. 30 | std::string BuildMetadata(); 31 | 32 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 33 | } // namespace google::cloud::functions_internal 34 | 35 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_BUILD_INFO_H 36 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/call_user_function.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_CALL_USER_FUNCTION_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_CALL_USER_FUNCTION_H 17 | 18 | #include "google/cloud/functions/internal/http_message_types.h" 19 | #include "google/cloud/functions/user_functions.h" 20 | 21 | namespace google::cloud::functions_internal { 22 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 23 | 24 | BeastResponse CallUserFunction(functions::UserHttpFunction const& function, 25 | BeastRequest request); 26 | 27 | BeastResponse CallUserFunction( 28 | functions::UserCloudEventFunction const& function, 29 | BeastRequest const& request); 30 | 31 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 32 | } // namespace google::cloud::functions_internal 33 | 34 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_CALL_USER_FUNCTION_H 35 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/compiler_info.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_COMPILER_INFO_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_COMPILER_INFO_H 17 | 18 | #include "google/cloud/functions/version.h" 19 | 20 | namespace google::cloud::functions_internal { 21 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 22 | /** 23 | * Returns the compiler ID. 24 | * 25 | * The Compiler ID is a string like "GNU" or "Clang", as described by 26 | * https://cmake.org/cmake/help/v3.5/variable/CMAKE_LANG_COMPILER_ID.html 27 | */ 28 | std::string CompilerId(); 29 | 30 | /** 31 | * Returns the compiler version. 32 | * 33 | * This string will be something like "9.1.1". 34 | */ 35 | std::string CompilerVersion(); 36 | 37 | /** 38 | * Returns the 4-digit year of the C++ language standard. 39 | */ 40 | std::string LanguageVersion(); 41 | 42 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 43 | } // namespace google::cloud::functions_internal 44 | 45 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_COMPILER_INFO_H 46 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/compiler_info_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/compiler_info.h" 16 | #include 17 | #include 18 | 19 | namespace google::cloud::functions_internal { 20 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 21 | namespace { 22 | 23 | using ::testing::Contains; 24 | 25 | TEST(CompilerInfo, CompilerId) { 26 | auto const cn = CompilerId(); 27 | EXPECT_NE(cn, ""); 28 | EXPECT_EQ(std::string::npos, 29 | cn.find_first_not_of( 30 | "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")); 31 | } 32 | 33 | TEST(CompilerInfo, CompilerVersion) { 34 | auto const cv = CompilerVersion(); 35 | EXPECT_NE(cv, ""); 36 | // Look for something that looks vaguely like an X.Y version number. Cannot 37 | // use ::testing::ContainsRegex() because that does not work when GTest is 38 | // compiled under MSVC. 39 | EXPECT_THAT(cv, Contains('.')); 40 | EXPECT_TRUE(std::regex_search(cv, std::regex(R"([0-9]+\.[0-9]+)"))) 41 | << "version=" << cv; 42 | } 43 | 44 | TEST(CompilerInfo, LanguageVersion) { 45 | auto const lv = LanguageVersion(); 46 | EXPECT_NE(lv, ""); 47 | EXPECT_EQ(std::string::npos, lv.find_first_not_of("0123456789")); 48 | } 49 | 50 | } // namespace 51 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 52 | } // namespace google::cloud::functions_internal 53 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/framework_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_FRAMEWORK_IMPL_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_FRAMEWORK_IMPL_H 17 | 18 | #include "google/cloud/functions/function.h" 19 | #include "google/cloud/functions/user_functions.h" 20 | #include "google/cloud/functions/version.h" 21 | #include 22 | 23 | namespace google::cloud::functions_internal { 24 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 25 | 26 | /// Implement functions::Run(), with additional helpers for testing. 27 | int RunForTest(int argc, char const* const argv[], 28 | functions::Function const& handler, 29 | std::function const& shutdown, 30 | std::function const& actual_port); 31 | 32 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 33 | } // namespace google::cloud::functions_internal 34 | 35 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_FRAMEWORK_IMPL_H 36 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/function_impl.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/function_impl.h" 16 | #include "google/cloud/functions/internal/call_user_function.h" 17 | #include "google/cloud/functions/function.h" 18 | 19 | namespace google::cloud::functions_internal { 20 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 21 | 22 | std::shared_ptr FunctionImpl::GetImpl( 23 | functions::Function const& fun) { 24 | return fun.impl_; 25 | } 26 | 27 | functions::Function FunctionImpl::MakeFunction( 28 | std::shared_ptr impl) { 29 | return functions::Function(std::move(impl)); 30 | } 31 | 32 | BaseFunctionImpl::BaseFunctionImpl(functions::UserHttpFunction function) 33 | : handler_([fun = std::move(function)](BeastRequest request) { 34 | return CallUserFunction(fun, std::move(request)); 35 | }) {} 36 | 37 | BaseFunctionImpl::BaseFunctionImpl(functions::UserCloudEventFunction function) 38 | : handler_([fun = std::move(function)](BeastRequest const& request) { 39 | return CallUserFunction(fun, request); 40 | }) {} 41 | 42 | [[nodiscard]] Handler BaseFunctionImpl::GetHandler( 43 | std::string_view /*target*/) const { 44 | return handler_; 45 | } 46 | 47 | MapFunctionImpl::MapFunctionImpl( 48 | std::map mapping) 49 | : mapping_(std::move(mapping)) {} 50 | 51 | [[nodiscard]] Handler MapFunctionImpl::GetHandler( 52 | std::string_view target) const { 53 | auto const l = mapping_.find(std::string(target)); 54 | if (l == mapping_.end()) { 55 | throw std::runtime_error("Function not found " + std::string(target)); 56 | } 57 | return FunctionImpl::GetImpl(l->second)->GetHandler(target); 58 | } 59 | 60 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 61 | } // namespace google::cloud::functions_internal 62 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/function_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_FUNCTION_IMPL_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_FUNCTION_IMPL_H 17 | 18 | #include "google/cloud/functions/internal/http_message_types.h" 19 | #include "google/cloud/functions/user_functions.h" 20 | #include "google/cloud/functions/version.h" 21 | #include 22 | #include 23 | 24 | namespace google::cloud::functions { 25 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 26 | class Function; 27 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 28 | } // namespace google::cloud::functions 29 | 30 | namespace google::cloud::functions_internal { 31 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 32 | 33 | using Handler = std::function; 34 | 35 | class FunctionImpl { 36 | public: 37 | virtual ~FunctionImpl() = default; 38 | [[nodiscard]] virtual Handler GetHandler(std::string_view target) const = 0; 39 | 40 | static std::shared_ptr GetImpl(functions::Function const& fun); 41 | static functions::Function MakeFunction(std::shared_ptr impl); 42 | }; 43 | 44 | class BaseFunctionImpl : public FunctionImpl { 45 | public: 46 | explicit BaseFunctionImpl(functions::UserHttpFunction function); 47 | explicit BaseFunctionImpl(functions::UserCloudEventFunction function); 48 | ~BaseFunctionImpl() override = default; 49 | 50 | [[nodiscard]] Handler GetHandler(std::string_view /*target*/) const override; 51 | 52 | private: 53 | Handler handler_; 54 | }; 55 | 56 | class MapFunctionImpl : public FunctionImpl { 57 | public: 58 | explicit MapFunctionImpl(std::map mapping); 59 | ~MapFunctionImpl() override = default; 60 | 61 | [[nodiscard]] Handler GetHandler(std::string_view target) const override; 62 | 63 | private: 64 | std::map mapping_; 65 | }; 66 | 67 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 68 | } // namespace google::cloud::functions_internal 69 | 70 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_FUNCTION_IMPL_H 71 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/http_message_types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_HTTP_MESSAGE_TYPES_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_HTTP_MESSAGE_TYPES_H 17 | 18 | #include "google/cloud/functions/version.h" 19 | #include 20 | 21 | namespace google::cloud::functions_internal { 22 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 23 | 24 | using BeastRequest = 25 | boost::beast::http::request; 26 | 27 | using BeastResponse = 28 | boost::beast::http::response; 29 | 30 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 31 | } // namespace google::cloud::functions_internal 32 | 33 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_HTTP_MESSAGE_TYPES_H 34 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/parse_cloud_event_http.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_HTTP_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_HTTP_H 17 | 18 | #include "google/cloud/functions/internal/http_message_types.h" 19 | #include "google/cloud/functions/cloud_event.h" 20 | #include "google/cloud/functions/version.h" 21 | #include 22 | 23 | namespace google::cloud::functions_internal { 24 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 25 | 26 | /// Parse @p request as a Cloud Event, assuming the content type is binary. 27 | functions::CloudEvent ParseCloudEventHttpBinary(BeastRequest const& request); 28 | 29 | /// Parse @p request as a Cloud Event, using the request content type. 30 | std::vector ParseCloudEventHttp( 31 | BeastRequest const& request); 32 | 33 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 34 | } // namespace google::cloud::functions_internal 35 | 36 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_HTTP_H 37 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/parse_cloud_event_json.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_JSON_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_JSON_H 17 | 18 | #include "google/cloud/functions/cloud_event.h" 19 | #include "google/cloud/functions/version.h" 20 | #include 21 | #include 22 | 23 | namespace google::cloud::functions_internal { 24 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 25 | 26 | /// Parse @p json_string as a Cloud Event 27 | functions::CloudEvent ParseCloudEventJson(std::string_view json_string); 28 | 29 | /// Parse @p json_string as a batch of Cloud Events 30 | std::vector ParseCloudEventJsonBatch( 31 | std::string_view json_string); 32 | 33 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 34 | } // namespace google::cloud::functions_internal 35 | 36 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_JSON_H 37 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/parse_cloud_event_legacy.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_LEGACY_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_LEGACY_H 17 | 18 | #include "google/cloud/functions/cloud_event.h" 19 | #include "google/cloud/functions/version.h" 20 | #include 21 | 22 | namespace google::cloud::functions_internal { 23 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 24 | 25 | /// Parse @p json_string as one of the legacy GCF event formats. 26 | functions::CloudEvent ParseCloudEventLegacy(std::string_view json_string); 27 | 28 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 29 | } // namespace google::cloud::functions_internal 30 | 31 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_LEGACY_H 32 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/parse_cloud_event_storage.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_STORAGE_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_STORAGE_H 17 | 18 | #include "google/cloud/functions/cloud_event.h" 19 | #include "google/cloud/functions/version.h" 20 | 21 | namespace google::cloud::functions_internal { 22 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 23 | 24 | /// Parse @p e as a Cloud Storage event if possible, otherwise return @p e. 25 | functions::CloudEvent ParseCloudEventStorage(functions::CloudEvent e); 26 | 27 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 28 | } // namespace google::cloud::functions_internal 29 | 30 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_CLOUD_EVENT_STORAGE_H 31 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/parse_options.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_OPTIONS_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_OPTIONS_H 17 | 18 | #include "google/cloud/functions/version.h" 19 | #include 20 | 21 | namespace google::cloud::functions_internal { 22 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 23 | 24 | /// Parse the command-line options in @p argv 25 | boost::program_options::variables_map ParseOptions(int argc, 26 | char const* const argv[]); 27 | 28 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 29 | } // namespace google::cloud::functions_internal 30 | 31 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_PARSE_OPTIONS_H 32 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/setenv.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/setenv.h" 16 | // We need _putenv_s() on WIN32 and setenv()/unsetenv() on Posix. clang-tidy 17 | // recommends including . That seems wrong, as is not 18 | // guaranteed to define the Posix/WIN32 functions. 19 | #include // NOLINT(modernize-deprecated-headers) 20 | 21 | namespace google::cloud::functions_internal { 22 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 23 | 24 | namespace { 25 | void UnsetEnv(char const* variable) { 26 | #ifdef _WIN32 27 | (void)_putenv_s(variable, ""); 28 | #else 29 | unsetenv(variable); 30 | #endif // _WIN32 31 | } 32 | 33 | void SetEnv(char const* variable, char const* value) { 34 | #ifdef _WIN32 35 | (void)_putenv_s(variable, value); 36 | #else 37 | (void)setenv(variable, value, 1); 38 | #endif // _WIN32 39 | } 40 | 41 | } // namespace 42 | 43 | void SetEnv(std::string const& variable, 44 | std::optional const& value) { 45 | if (!value.has_value()) { 46 | UnsetEnv(variable.c_str()); 47 | return; 48 | } 49 | SetEnv(variable.c_str(), value->c_str()); 50 | } 51 | 52 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 53 | } // namespace google::cloud::functions_internal 54 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/setenv.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_SETENV_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_SETENV_H 17 | 18 | #include "google/cloud/functions/version.h" 19 | #include 20 | #include 21 | 22 | namespace google::cloud::functions_internal { 23 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 24 | 25 | /// Changes an environment variable in the current process. 26 | void SetEnv(std::string const& variable, 27 | std::optional const& value); 28 | 29 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 30 | } // namespace google::cloud::functions_internal 31 | 32 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_SETENV_H 33 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/version_info.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_VERSION_INFO_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_VERSION_INFO_H 17 | 18 | // clang-format off 19 | #define FUNCTIONS_FRAMEWORK_CPP_VERSION_MAJOR 1 // NOLINT(modernize-macro-to-enum) 20 | #define FUNCTIONS_FRAMEWORK_CPP_VERSION_MINOR 3 // NOLINT(modernize-macro-to-enum) 21 | #define FUNCTIONS_FRAMEWORK_CPP_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum) 22 | // clang-format on 23 | 24 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_VERSION_INFO_H 25 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/version_info.h.in: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_VERSION_INFO_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_VERSION_INFO_H 17 | 18 | // clang-format off 19 | #define FUNCTIONS_FRAMEWORK_CPP_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ // NOLINT(modernize-macro-to-enum) 20 | #define FUNCTIONS_FRAMEWORK_CPP_VERSION_MINOR @PROJECT_VERSION_MINOR@ // NOLINT(modernize-macro-to-enum) 21 | #define FUNCTIONS_FRAMEWORK_CPP_VERSION_PATCH @PROJECT_VERSION_PATCH@ // NOLINT(modernize-macro-to-enum) 22 | // clang-format on 23 | 24 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_VERSION_INFO_H 25 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/wrap_request.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/wrap_request.h" 16 | #include "google/cloud/functions/http_request.h" 17 | 18 | namespace google::cloud::functions_internal { 19 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 20 | 21 | ::google::cloud::functions::HttpRequest MakeHttpRequest(BeastRequest request) { 22 | auto constexpr kBeastHttpVersionFactor = 10; 23 | auto const version = static_cast(request.version()); 24 | auto r = ::google::cloud::functions::HttpRequest{} 25 | .set_verb(std::string(request.method_string())) 26 | .set_target(std::string(request.target())) 27 | .set_version(version / kBeastHttpVersionFactor, 28 | version % kBeastHttpVersionFactor); 29 | for (auto const& h : request.base()) { 30 | r.add_header(std::string(h.name_string()), std::string(h.value())); 31 | } 32 | r.set_payload(std::move(request).body()); 33 | return r; 34 | } 35 | 36 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 37 | } // namespace google::cloud::functions_internal 38 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/wrap_request.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_WRAP_REQUEST_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_WRAP_REQUEST_H 17 | 18 | #include "google/cloud/functions/internal/http_message_types.h" 19 | #include "google/cloud/functions/http_request.h" 20 | #include "google/cloud/functions/version.h" 21 | 22 | namespace google::cloud::functions_internal { 23 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 24 | 25 | /// Wrap a Boost.Beast request into a functions framework HTTP request. 26 | ::google::cloud::functions::HttpRequest MakeHttpRequest(BeastRequest request); 27 | 28 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 29 | } // namespace google::cloud::functions_internal 30 | 31 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_INTERNAL_WRAP_REQUEST_H 32 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/wrap_request_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/wrap_request.h" 16 | #include 17 | 18 | namespace google::cloud::functions_internal { 19 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 20 | namespace { 21 | 22 | using ::testing::ElementsAre; 23 | 24 | TEST(WrapRequestTest, Basic) { 25 | BeastRequest br; 26 | br.set("content-type", "application/json"); 27 | br.body() = "Hello World\n"; 28 | br.target("/some/random/target"); 29 | br.method(boost::beast::http::verb::put); 30 | auto constexpr kHttp11 = 11; 31 | br.version(kHttp11); 32 | 33 | auto actual = MakeHttpRequest(std::move(br)); 34 | EXPECT_EQ(actual.target(), "/some/random/target"); 35 | EXPECT_EQ(actual.verb(), "PUT"); 36 | EXPECT_EQ(actual.payload(), "Hello World\n"); 37 | EXPECT_THAT(actual.headers(), 38 | ElementsAre(std::make_pair("content-type", "application/json"))); 39 | EXPECT_EQ(actual.version_major(), 1); 40 | EXPECT_EQ(actual.version_minor(), 1); 41 | } 42 | 43 | } // namespace 44 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 45 | } // namespace google::cloud::functions_internal 46 | -------------------------------------------------------------------------------- /google/cloud/functions/internal/wrap_response.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/internal/wrap_response.h" 16 | 17 | namespace google::cloud::functions_internal { 18 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 19 | 20 | /// Wrap a Boost.Beast request into a functions framework HTTP request. 21 | std::shared_ptr MakeHttpResponse() { 22 | return std::make_shared(); 23 | } 24 | 25 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 26 | } // namespace google::cloud::functions_internal 27 | -------------------------------------------------------------------------------- /google/cloud/functions/user_functions.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_USER_FUNCTIONS_H 16 | #define FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_USER_FUNCTIONS_H 17 | 18 | #include "google/cloud/functions/cloud_event.h" 19 | #include "google/cloud/functions/http_request.h" 20 | #include "google/cloud/functions/http_response.h" 21 | #include "google/cloud/functions/version.h" 22 | #include 23 | 24 | namespace google::cloud::functions { 25 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 26 | 27 | using UserHttpFunction = 28 | std::function; 29 | 30 | using UserCloudEventFunction = std::function; 31 | 32 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 33 | } // namespace google::cloud::functions 34 | 35 | #endif // FUNCTIONS_FRAMEWORK_CPP_GOOGLE_CLOUD_FUNCTIONS_USER_FUNCTIONS_H 36 | -------------------------------------------------------------------------------- /google/cloud/functions/version.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/version.h" 16 | #include "google/cloud/functions/internal/build_info.h" 17 | #include 18 | 19 | namespace google::cloud::functions { 20 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 21 | 22 | std::string VersionString() { 23 | static std::string const kVersion = [] { 24 | std::ostringstream os; 25 | os << "v" << VersionMajor() << "." << VersionMinor() << "." 26 | << VersionPatch(); 27 | auto metadata = google::cloud::functions_internal::BuildMetadata(); 28 | if (!metadata.empty()) { 29 | os << "+" << metadata; 30 | } 31 | return os.str(); 32 | }(); 33 | return kVersion; 34 | } 35 | 36 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 37 | } // namespace google::cloud::functions 38 | -------------------------------------------------------------------------------- /google/cloud/functions/version_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "google/cloud/functions/version.h" 16 | #include "google/cloud/functions/internal/build_info.h" 17 | #include 18 | #include 19 | 20 | namespace google::cloud::functions { 21 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_BEGIN 22 | namespace { 23 | 24 | using ::testing::HasSubstr; 25 | using ::testing::Not; 26 | using ::testing::StartsWith; 27 | 28 | /// @test A trivial test for the Google Cloud Storage C++ Client 29 | TEST(VersionTest, Simple) { 30 | EXPECT_FALSE(VersionString().empty()); 31 | EXPECT_EQ(FUNCTIONS_FRAMEWORK_CPP_VERSION_MAJOR, VersionMajor()); 32 | EXPECT_EQ(FUNCTIONS_FRAMEWORK_CPP_VERSION_MINOR, VersionMinor()); 33 | EXPECT_EQ(FUNCTIONS_FRAMEWORK_CPP_VERSION_PATCH, VersionPatch()); 34 | } 35 | 36 | /// @test Verify the version string starts with the version numbers. 37 | TEST(VersionTest, Format) { 38 | std::ostringstream os; 39 | os << "v" << FUNCTIONS_FRAMEWORK_CPP_VERSION_MAJOR << "." 40 | << FUNCTIONS_FRAMEWORK_CPP_VERSION_MINOR << "." 41 | << FUNCTIONS_FRAMEWORK_CPP_VERSION_PATCH; 42 | EXPECT_THAT(VersionString(), StartsWith(os.str())); 43 | } 44 | 45 | /// @test Verify the version does not contain build info for release builds. 46 | TEST(VersionTest, NoBuildInfoInRelease) { 47 | if (!google::cloud::functions_internal::BuildMetadata().empty()) { 48 | EXPECT_THAT( 49 | VersionString(), 50 | HasSubstr("+" + google::cloud::functions_internal::BuildMetadata())); 51 | return; 52 | } 53 | EXPECT_THAT(VersionString(), Not(HasSubstr("+"))); 54 | } 55 | 56 | } // namespace 57 | FUNCTIONS_FRAMEWORK_CPP_INLINE_NAMESPACE_END 58 | } // namespace google::cloud::functions 59 | -------------------------------------------------------------------------------- /vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functions-framework-cpp-dev", 3 | "version-string": "1.2.0", 4 | "homepage": "https://github.com/GoogleCloudPlatform/functions-framework-cpp/", 5 | "description": [ 6 | "A functions as a service (FaaS) framework for writing portable C++ functions.", 7 | "Let's you write lightweight functions that run in many different environments,", 8 | "including local development, local containers, Knative, and Cloud Run." 9 | ], 10 | "default-features": ["framework"], 11 | "features": { 12 | "framework": { 13 | "description": "Everything needed to use the Functions Framework for C++", 14 | "dependencies": [ 15 | "abseil", 16 | "boost-beast", 17 | "boost-program-options", 18 | "boost-serialization", 19 | "nlohmann-json" 20 | ] 21 | }, 22 | "tests": { 23 | "description": "Unit and Integrations tests for functions-framework-cpp.", 24 | "dependencies": [ 25 | "boost-filesystem", 26 | "boost-log", 27 | "boost-process", 28 | "boost-uuid", 29 | "cppcodec", 30 | "fmt", 31 | "gtest" 32 | ] 33 | }, 34 | "examples": { 35 | "description": "Unit and Integration tests for the functions-framework-cpp examples.", 36 | "dependencies": [ 37 | "boost-property-tree", 38 | "google-cloud-cpp" 39 | ] 40 | } 41 | } 42 | } 43 | --------------------------------------------------------------------------------