diff --git a/.builder/actions/setup-eventstream-server.py b/.builder/actions/setup-eventstream-server.py new file mode 100644 index 000000000..4fedb67fd --- /dev/null +++ b/.builder/actions/setup-eventstream-server.py @@ -0,0 +1,124 @@ +import atexit +import Builder +import os +import shutil +import subprocess +import sys +import time + +class SetupEventstreamServer(Builder.Action): + + def _build_and_run_eventstream_echo_server(self, env): + java_sdk_dir = None + + try: + env.shell.exec(["mvn", "--version"], check=True) + + # maven is installed, so this is a configuration we can start an event stream echo server + java_sdk_dir = env.shell.mktemp() + + env.shell.exec(["git", "clone", "https://github.com/aws/aws-iot-device-sdk-java-v2"], working_dir=java_sdk_dir, check=True) + + sdk_dir = os.path.join(java_sdk_dir, "aws-iot-device-sdk-java-v2", "sdk") + env.shell.pushd(sdk_dir) + + try: + # The EchoTest server is in test-only code + env.shell.exec(["mvn", "test-compile"], check=True) + env.shell.exec(["mvn", "dependency:build-classpath", "-Dmdep.outputFile=classpath.txt"], check=True) + + time.sleep(1) + with open('classpath.txt', 'r') as file: + classpath = file.read() + + test_class_path = os.path.join(sdk_dir, "target", "test-classes") + target_class_path = os.path.join(sdk_dir, "target", "classes") + directory_separator = os.pathsep + + echo_server_probe_command = [ + "java", + "-classpath", + f"{test_class_path}{directory_separator}{target_class_path}{directory_separator}{classpath}", + "software.amazon.awssdk.eventstreamrpc.echotest.EchoTestServiceRunner"] + + probe_command_flat = " ".join(echo_server_probe_command) + print(f'Echo probe command: {probe_command_flat}') + + """ + Try to run the echo server in the foreground without required arguments. This always fails, but + the output can tell us whether or not the Java CRT is available on the platform (we have SDK CI + that runs on platforms that the Java CRT does not support). + + If the CRT supports the platform, we fail with an out-of-index exception (referencing non-existent + command line arguments) + + If the CRT does not support the platform, we fail with + 'java.io.IOException: Unable to open library in jar for AWS CRT' + """ + probe_output = "" + probe = subprocess.Popen( + echo_server_probe_command, + stderr=subprocess.PIPE) + with probe: + + # Convert all output to strings, which makes it much easier to both print + # and process, since all known uses of parsing output want strings anyway + line = probe.stderr.readline() + while (line): + # ignore weird characters coming back from the shell (colors, etc) + if not isinstance(line, str): + line = line.decode('ascii', 'ignore') + # We're reading in binary mode, so no automatic newline translation + if sys.platform == 'win32': + line = line.replace('\r\n', '\n') + probe_output += line + line = probe.stderr.readline() + probe.wait() + + print("Probe stderr:\n\n") + print(probe_output) + + if "java.io.IOException" in probe_output: + print("Skipping eventstream server unsupported platform") + raise Exception("Java CRT not supported by this platform") + + echo_server_command = [ + "java", + "-classpath", + f"{test_class_path}{directory_separator}{target_class_path}{directory_separator}{classpath}", + "software.amazon.awssdk.eventstreamrpc.echotest.EchoTestServiceRunner", + "127.0.0.1", + "8033"] + + print(f'Echo server command: {echo_server_command}') + + # bypass builder's exec wrapper since it doesn't allow for background execution + proc = subprocess.Popen(echo_server_command) + + @atexit.register + def _terminate_echo_server(): + proc.terminate() + proc.wait() + shutil.rmtree(java_sdk_dir) + + env.shell.setenv("AWS_TEST_EVENT_STREAM_ECHO_SERVER_HOST", "127.0.0.1", quiet=False) + env.shell.setenv("AWS_TEST_EVENT_STREAM_ECHO_SERVER_PORT", "8033", quiet=False) + finally: + env.shell.popd() + + except Exception as ex: + print('Failed to set up event stream server. Eventstream CI tests will not be run.') + print(ex) + + return + + def run(self, env): + + actions = [] + + try: + self._build_and_run_eventstream_echo_server(env) + except: + pass + + return Builder.Script(actions, name='setup-eventstream-server') diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96d329815..e9098792e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: - 'docs' env: - BUILDER_VERSION: v0.9.72 + BUILDER_VERSION: v0.9.79 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-iot-device-sdk-cpp-v2 @@ -57,7 +57,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -78,7 +78,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -90,7 +90,7 @@ jobs: aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh ./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ matrix.image }} build -p ${{ env.PACKAGE_NAME }} linux-compiler-compat: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: matrix: compiler: @@ -108,7 +108,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -123,7 +123,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -138,7 +138,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -153,7 +153,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -167,7 +167,7 @@ jobs: run: | python -m pip install boto3 - name: configure AWS credentials (PubSub) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_PUBSUB_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -180,7 +180,7 @@ jobs: cd ${{ env.CI_FOLDER }} python ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_windows_cert_connect_cfg.json - name: configure AWS credentials (MQTT5) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_MQTT5_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -189,7 +189,7 @@ jobs: cd ${{ env.CI_FOLDER }} python ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_mqtt5_pubsub_windows_cfg.json - name: configure AWS credentials (Device Advisor) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_DEVICE_ADVISOR }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -207,7 +207,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -221,7 +221,7 @@ jobs: run: | python -m pip install boto3 - name: configure AWS credentials (PubSub) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_PUBSUB_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -234,7 +234,7 @@ jobs: cd ${{ env.CI_FOLDER }} python ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_windows_cert_connect_cfg.json - name: configure AWS credentials (MQTT5) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_MQTT5_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -243,7 +243,7 @@ jobs: cd ${{ env.CI_FOLDER }} python ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_mqtt5_pubsub_windows_cfg.json - name: configure AWS credentials (Device Advisor) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_DEVICE_ADVISOR }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -257,7 +257,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -271,7 +271,7 @@ jobs: run: | python -m pip install boto3 - name: configure AWS credentials (PubSub) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_PUBSUB_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -284,7 +284,7 @@ jobs: cd ${{ env.CI_FOLDER }} python ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_windows_cert_connect_cfg.json - name: configure AWS credentials (MQTT5) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_MQTT5_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -293,7 +293,7 @@ jobs: cd ${{ env.CI_FOLDER }} python ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_mqtt5_pubsub_windows_cfg.json - name: configure AWS credentials (Device Advisor) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_DEVICE_ADVISOR }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -307,7 +307,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -321,7 +321,7 @@ jobs: run: | python -m pip install boto3 - name: configure AWS credentials (CyclePubSub) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_CYCLEPUBSUB_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -336,7 +336,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -359,7 +359,7 @@ jobs: security-events: write # This is required for pkcs12 sample to sign the key steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -374,7 +374,7 @@ jobs: source .venv/bin/activate python3 -m pip install boto3 - name: configure AWS credentials (PubSub) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_PUBSUB_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -401,7 +401,7 @@ jobs: /usr/bin/codesign --force -s $pkcs12_identity_name ./aws-iot-device-sdk-cpp-v2/build/samples/mqtt/pkcs12_connect/pkcs12-connect -v python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_pkcs12_connect_cfg.json - name: configure AWS credentials (MQTT5) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_MQTT5_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -410,7 +410,7 @@ jobs: source .venv/bin/activate python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_mqtt5_pubsub_cfg.json - name: configure AWS credentials (Device Advisor) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_DEVICE_ADVISOR }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -428,7 +428,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -440,7 +440,7 @@ jobs: run: | python3 -m pip install boto3 - name: configure AWS credentials (PubSub) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_PUBSUB_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -448,7 +448,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_pubsub_cfg.json - name: configure AWS credentials (MQTT5) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_MQTT5_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -456,7 +456,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_mqtt5_pubsub_cfg.json - name: configure AWS credentials (Device Advisor) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_DEVICE_ADVISOR }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -465,7 +465,7 @@ jobs: cd ./aws-iot-device-sdk-cpp-v2 python3 ./deviceadvisor/script/DATestRun.py - name: configure AWS credentials (Device Defender) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_DEVICE_DEFENDER }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -493,7 +493,7 @@ jobs: gcc --version cmake --version - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -512,7 +512,7 @@ jobs: softhsm2-util --version - name: configure AWS credentials (Fleet provisioning) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_FLEET_PROVISIONING_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -538,7 +538,7 @@ jobs: python3 ./test_cases/test_fleet_provisioning.py --config-file test_cases/mqtt5_fleet_provisioning_with_csr_cfg.json --thing-name-prefix Fleet_Thing_ - name: configure AWS credentials (Jobs) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_JOBS_SERVICE_CLIENT_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -553,7 +553,7 @@ jobs: export PYTHONPATH=${{ github.workspace }}/aws-iot-device-sdk-cpp-v2/utils python3 ./test_cases/test_jobs_execution.py --config-file ${{ env.CI_SERVICE_TESTS_CFG_FOLDER }}/mqtt5_jobs_cfg.json - name: configure AWS credentials (Shadow) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_SHADOW_SERVICE_CLIENT_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -578,7 +578,7 @@ jobs: export PYTHONPATH=${{ github.workspace }}/aws-iot-device-sdk-cpp-v2/utils python3 ./test_cases/test_shadow_update.py --config-file test_cases/mqtt5_named_shadow_cfg.json - name: configure AWS credentials (Connect and PubSub) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_PUBSUB_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -598,7 +598,7 @@ jobs: echo "directories.tokendir = /tmp/tokens" > /tmp/softhsm2.conf python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_pkcs11_connect_cfg.json - name: configure AWS credentials (MQTT5) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_MQTT5_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -609,7 +609,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_mqtt5_shared_subscription_cfg.json - name: configure AWS credentials (Jobs) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_JOBS_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -620,7 +620,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_jobs_mqtt5_cfg.json - name: configure AWS credentials (Cognito) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_COGNITO_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -628,7 +628,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_cognito_connect_cfg.json - name: configure AWS credentials (Custom Authorizer) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_CUSTOM_AUTHORIZER_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -636,7 +636,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_custom_authorizer_connect_cfg.json - name: configure AWS credentials (Shadow) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_SHADOW_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -647,7 +647,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_shadow_mqtt5_cfg.json - name: configure AWS credentials (Fleet provisioning) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_FLEET_PROVISIONING_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -664,7 +664,7 @@ jobs: python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_fleet_provisioning_mqtt5_cfg.json --input_uuid ${Sample_UUID} python3 ${{ env.CI_UTILS_FOLDER }}/delete_iot_thing_ci.py --thing_name "Fleet_Thing_${Sample_UUID}" --region "us-east-1" - name: configure AWS credentials (Secure tunneling) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_SECURE_TUNNEL }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -673,7 +673,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_secure_tunnel_ci.py --sample_file "./aws-iot-device-sdk-cpp-v2/build/samples/secure_tunneling/secure_tunnel/secure-tunnel" --sample_region ${{ env.AWS_DEFAULT_REGION }} - name: configure AWS credentials (X509) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_X509_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -734,7 +734,7 @@ jobs: id-token: write # This is required for requesting the JWT steps: - name: configure AWS credentials (containers) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_IOT_CONTAINERS }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -752,7 +752,7 @@ jobs: sudo apt-get install softhsm2 -y softhsm2-util --version - name: configure AWS credentials (Fleet provisioning) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_FLEET_PROVISIONING_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -777,7 +777,7 @@ jobs: export PYTHONPATH=${{ github.workspace }}/aws-iot-device-sdk-cpp-v2/utils python3 ./test_cases/test_fleet_provisioning.py --config-file test_cases/mqtt5_fleet_provisioning_with_csr_cfg.json --thing-name-prefix Fleet_Thing_ - name: configure AWS credentials (Jobs) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_JOBS_SERVICE_CLIENT_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -792,7 +792,7 @@ jobs: export PYTHONPATH=${{ github.workspace }}/aws-iot-device-sdk-cpp-v2/utils python3 ./test_cases/test_jobs_execution.py --config-file ${{ env.CI_SERVICE_TESTS_CFG_FOLDER }}/mqtt5_jobs_cfg.json - name: configure AWS credentials (Shadow) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_SHADOW_SERVICE_CLIENT_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -817,7 +817,7 @@ jobs: export PYTHONPATH=${{ github.workspace }}/aws-iot-device-sdk-cpp-v2/utils python3 ./test_cases/test_shadow_update.py --config-file test_cases/mqtt5_named_shadow_cfg.json - name: configure AWS credentials (Connect and PubSub) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_PUBSUB_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -837,7 +837,7 @@ jobs: echo "directories.tokendir = /tmp/tokens" > /tmp/softhsm2.conf python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_pkcs11_connect_cfg.json - name: configure AWS credentials (MQTT5) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_MQTT5_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -848,7 +848,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_mqtt5_shared_subscription_cfg.json - name: configure AWS credentials (Jobs) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_JOBS_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -859,7 +859,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_jobs_mqtt5_cfg.json - name: configure AWS credentials (Cognito) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_COGNITO_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -867,7 +867,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_cognito_connect_cfg.json - name: configure AWS credentials (Custom Authorizer) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_CUSTOM_AUTHORIZER_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -875,7 +875,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_custom_authorizer_connect_cfg.json - name: configure AWS credentials (Shadow) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_SHADOW_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -886,7 +886,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_shadow_mqtt5_cfg.json - name: configure AWS credentials (Fleet provisioning) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_FLEET_PROVISIONING_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -903,7 +903,7 @@ jobs: python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_fleet_provisioning_mqtt5_cfg.json --input_uuid ${Sample_UUID} python3 ${{ env.CI_UTILS_FOLDER }}/delete_iot_thing_ci.py --thing_name "Fleet_Thing_${Sample_UUID}" --region "us-east-1" - name: configure AWS credentials (Secure tunneling) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_SECURE_TUNNEL }} aws-region: ${{ env.AWS_DEFAULT_REGION }} @@ -912,7 +912,7 @@ jobs: run: | python3 ${{ env.CI_UTILS_FOLDER }}/run_secure_tunnel_ci.py --sample_file "./aws-iot-device-sdk-cpp-v2/build/samples/secure_tunneling/secure_tunnel/secure-tunnel" --sample_region ${{ env.AWS_DEFAULT_REGION }} - name: configure AWS credentials (X509) - uses: aws-actions/configure-aws-credentials@v3 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ env.CI_X509_ROLE }} aws-region: ${{ env.AWS_DEFAULT_REGION }} diff --git a/builder.json b/builder.json index 499b60927..0c00ca1de 100644 --- a/builder.json +++ b/builder.json @@ -1,5 +1,8 @@ { "name": "aws-iot-device-sdk-cpp-v2", + "packages": [ + "maven" + ], "!cmake_args": [ "-DPERFORM_HEADER_CHECK=OFF", "-DS2N_NO_PQ_ASM=ON" @@ -24,6 +27,7 @@ "build-samples" ], "test_steps": [ + "setup-eventstream-server", "sdk-ci-prep", "test" ], diff --git a/crt/aws-crt-cpp b/crt/aws-crt-cpp index 691979e3f..56dc6adb0 160000 --- a/crt/aws-crt-cpp +++ b/crt/aws-crt-cpp @@ -1 +1 @@ -Subproject commit 691979e3fc63b49e64948dc75d0880cfdcf437c7 +Subproject commit 56dc6adb0fcde401e18345849c6b459f8bc7dbb6 diff --git a/eventstream_rpc/include/aws/eventstreamrpc/EventStreamClient.h b/eventstream_rpc/include/aws/eventstreamrpc/EventStreamClient.h index a48bcc997..94adea5c7 100644 --- a/eventstream_rpc/include/aws/eventstreamrpc/EventStreamClient.h +++ b/eventstream_rpc/include/aws/eventstreamrpc/EventStreamClient.h @@ -10,20 +10,13 @@ #include #include #include -#include -#include #include #include -#include - #include -#include -#include #include #include -#include namespace Aws { @@ -40,14 +33,14 @@ namespace Aws class MessageAmendment; class ClientOperation; class ClientConnection; - class ClientContinuation; + class ClientContinuationHandler; using HeaderValueType = aws_event_stream_header_value_type; using MessageType = aws_event_stream_rpc_message_type; /** * A callback prototype that is called upon flushing a message over the wire. - * @param errorCode A non-zero value if an error occured while attempting to flush the message. + * @param errorCode A non-zero value if an error occurred while attempting to flush the message. */ using OnMessageFlushCallback = std::function; @@ -68,7 +61,7 @@ namespace Aws EventStreamHeader(EventStreamHeader &&rhs) noexcept; EventStreamHeader &operator=(const EventStreamHeader &lhs) noexcept; ~EventStreamHeader() noexcept; - EventStreamHeader( + explicit EventStreamHeader( const struct aws_event_stream_header_value_pair &header, Crt::Allocator *allocator = Crt::g_allocator); EventStreamHeader( @@ -82,8 +75,6 @@ namespace Aws const struct aws_event_stream_header_value_pair *GetUnderlyingHandle() const; - bool operator==(const EventStreamHeader &other) const noexcept; - private: Crt::Allocator *m_allocator; Crt::ByteBuf m_valueByteBuf; @@ -99,22 +90,24 @@ namespace Aws { public: MessageAmendment(const MessageAmendment &lhs); - MessageAmendment(MessageAmendment &&rhs); + MessageAmendment(MessageAmendment &&rhs) noexcept; MessageAmendment &operator=(const MessageAmendment &lhs); - MessageAmendment &operator=(MessageAmendment &&rhs); + MessageAmendment &operator=(MessageAmendment &&rhs) noexcept; ~MessageAmendment() noexcept; explicit MessageAmendment(Crt::Allocator *allocator = Crt::g_allocator) noexcept; MessageAmendment( const Crt::List &headers, Crt::Optional &payload, Crt::Allocator *allocator) noexcept; - MessageAmendment( + explicit MessageAmendment( const Crt::List &headers, Crt::Allocator *allocator = Crt::g_allocator) noexcept; - MessageAmendment( + explicit MessageAmendment( Crt::List &&headers, Crt::Allocator *allocator = Crt::g_allocator) noexcept; - MessageAmendment(const Crt::ByteBuf &payload, Crt::Allocator *allocator = Crt::g_allocator) noexcept; + explicit MessageAmendment( + const Crt::ByteBuf &payload, + Crt::Allocator *allocator = Crt::g_allocator) noexcept; /** * Add a given header to the end of the header list. @@ -138,6 +131,24 @@ namespace Aws Crt::Allocator *m_allocator; }; + enum EventStreamRpcStatusCode + { + EVENT_STREAM_RPC_SUCCESS = 0, + EVENT_STREAM_RPC_NULL_PARAMETER, + EVENT_STREAM_RPC_UNINITIALIZED, + EVENT_STREAM_RPC_ALLOCATION_ERROR, + EVENT_STREAM_RPC_CONNECTION_SETUP_FAILED, + EVENT_STREAM_RPC_CONNECTION_ACCESS_DENIED, + EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED, + EVENT_STREAM_RPC_CONNECTION_CLOSED, + EVENT_STREAM_RPC_CONTINUATION_CLOSED, + EVENT_STREAM_RPC_UNKNOWN_PROTOCOL_MESSAGE, + EVENT_STREAM_RPC_UNMAPPED_DATA, + EVENT_STREAM_RPC_UNSUPPORTED_CONTENT_TYPE, + EVENT_STREAM_RPC_CRT_ERROR, + EVENT_STREAM_RPC_CONTINUATION_NOT_YET_OPENED, + }; + /** * Configuration structure holding all configurations relating to eventstream RPC connection establishment */ @@ -157,10 +168,10 @@ namespace Aws OnMessageFlushCallback GetConnectRequestCallback() const noexcept { return m_connectRequestCallback; } ConnectMessageAmender GetConnectMessageAmender() const noexcept { - return [&](void) -> const MessageAmendment & { return m_connectAmendment; }; + return [&]() -> const MessageAmendment & { return m_connectAmendment; }; } - void SetHostName(Crt::String hostName) noexcept { m_hostName = hostName; } + void SetHostName(Crt::String hostName) noexcept { m_hostName = std::move(hostName); } void SetPort(uint32_t port) noexcept { m_port = port; } void SetSocketOptions(const Crt::Io::SocketOptions &socketOptions) noexcept { @@ -172,7 +183,7 @@ namespace Aws } void SetTlsConnectionOptions(Crt::Io::TlsConnectionOptions tlsConnectionOptions) noexcept { - m_tlsConnectionOptions = tlsConnectionOptions; + m_tlsConnectionOptions = std::move(tlsConnectionOptions); } void SetClientBootstrap(Crt::Io::ClientBootstrap *clientBootstrap) noexcept { @@ -180,9 +191,11 @@ namespace Aws } void SetConnectRequestCallback(OnMessageFlushCallback connectRequestCallback) noexcept { - m_connectRequestCallback = connectRequestCallback; + m_connectRequestCallback = std::move(connectRequestCallback); } + EventStreamRpcStatusCode Validate() const noexcept; + protected: Crt::Optional m_hostName; Crt::Optional m_port; @@ -193,29 +206,13 @@ namespace Aws OnMessageFlushCallback m_connectRequestCallback; }; - enum EventStreamRpcStatusCode - { - EVENT_STREAM_RPC_SUCCESS = 0, - EVENT_STREAM_RPC_NULL_PARAMETER, - EVENT_STREAM_RPC_UNINITIALIZED, - EVENT_STREAM_RPC_ALLOCATION_ERROR, - EVENT_STREAM_RPC_CONNECTION_SETUP_FAILED, - EVENT_STREAM_RPC_CONNECTION_ACCESS_DENIED, - EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED, - EVENT_STREAM_RPC_CONNECTION_CLOSED, - EVENT_STREAM_RPC_CONTINUATION_CLOSED, - EVENT_STREAM_RPC_UNKNOWN_PROTOCOL_MESSAGE, - EVENT_STREAM_RPC_UNMAPPED_DATA, - EVENT_STREAM_RPC_UNSUPPORTED_CONTENT_TYPE, - EVENT_STREAM_RPC_CRT_ERROR - }; - struct AWS_EVENTSTREAMRPC_API RpcError { + explicit operator bool() const noexcept { return baseStatus == EVENT_STREAM_RPC_SUCCESS; } + Crt::String StatusToString() const; + EventStreamRpcStatusCode baseStatus; int crtError; - operator bool() const noexcept { return baseStatus == EVENT_STREAM_RPC_SUCCESS; } - Crt::String StatusToString(); }; /** @@ -232,20 +229,21 @@ namespace Aws * is invoked, the `ClientConnection` is ready to be used for sending messages. */ virtual void OnConnectCallback(); + /** * Invoked upon connection shutdown. * @param status The status upon disconnection. It can be treated as a bool * with true implying a successful disconnection. */ virtual void OnDisconnectCallback(RpcError status); + /** * Invoked upon receiving an error. Use the return value to determine - * whether or not to force the connection to close. Keep in mind that once - * closed, the `ClientConnection` can no longer send messages. - * @param status The status upon disconnection. It can be treated as a bool - * with true implying a successful disconnection. + * whether or not to force the connection to close. + * @param status Details about the error encountered. */ virtual bool OnErrorCallback(RpcError status); + /** * Invoked upon receiving a ping from the server. The `headers` and `payload` * refer to what is contained in the ping message. @@ -255,132 +253,57 @@ namespace Aws const Crt::Optional &payload); }; - /** - * User data passed to callbacks for a new stream. - */ - class AWS_EVENTSTREAMRPC_API ContinuationCallbackData - { - public: - ContinuationCallbackData( - ClientContinuation *clientContinuation, - Crt::Allocator *allocator = Crt::g_allocator) noexcept - : clientContinuation(clientContinuation), allocator(allocator) - { - continuationDestroyed = false; - } - ContinuationCallbackData(const ContinuationCallbackData &lhs) noexcept = delete; - bool continuationDestroyed; - std::mutex callbackMutex; - ClientContinuation *clientContinuation; - Crt::Allocator *allocator; - }; + class ClientConnectionImpl; + class ClientContinuationImpl; /** - * Handler interface for continuation events. + * Class representing a connection to an RPC server. */ - class AWS_EVENTSTREAMRPC_API ClientContinuationHandler + class AWS_EVENTSTREAMRPC_API ClientConnection final { public: - /** - * Invoked when a message is received on this continuation. - */ - virtual void OnContinuationMessage( - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags) = 0; - /** - * Invoked when the continuation is closed. - * - * Once the continuation is closed, no more messages may be sent or received. - * The continuation is closed when a message is sent or received with - * the TERMINATE_STREAM flag, or when the connection shuts down. - */ - virtual void OnContinuationClosed() = 0; - virtual ~ClientContinuationHandler() noexcept = default; - - private: - friend class ClientContinuation; - ContinuationCallbackData *m_callbackData; - }; + ClientConnection(Crt::Allocator *allocator, aws_client_bootstrap *bootstrap) noexcept; + ~ClientConnection() noexcept; - /** - * A wrapper for event-stream-rpc client continuation. - */ - class AWS_EVENTSTREAMRPC_API ClientContinuation final - { - public: /** - * Create a new continuation. - * - * @note continuation_option's callbacks will not be invoked, and nothing will be sent across - * the wire until Activate() is invoked. - * @param connection Connection on which open a new stream. - * @param continuationHandler A set of callbacks that will be invoked for continuation events. - * @param allocator Allocator to use. + * Initiates a new outgoing event-stream-rpc connection. + * @param connectionOptions Connection options. + * @param connectionLifecycleHandler Handler to process connection lifecycle events. + * @return Future that will be resolved when connection either succeeds or fails. */ - ClientContinuation( - ClientConnection *connection, - ClientContinuationHandler &continuationHandler, - Crt::Allocator *allocator) noexcept; - ~ClientContinuation() noexcept; + std::future Connect( + const ConnectionConfig &connectionOptions, + ConnectionLifecycleHandler *connectionLifecycleHandler) noexcept; /** - * Initiate a new client stream. Send new message for the new stream. - * @param operation Name for the operation to be invoked by the peer endpoint. - * @param headers Headers for the eventstream message. - * @param payload Payload for the eventstream message. - * @param messageType Message type for the message. - * @param messageFlags Bitmask of aws_event_stream_rpc_message_flag values. - * @param onMessageFlushCallback Callback to be invoked upon the message being flushed to the underlying - * transport. - * @return Future that will be resolved when the message has either been written to the wire or it fails. + * Create a new stream (continuation). + * @return A newly created continuation. */ - std::future Activate( - const Crt::String &operation, - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags, - OnMessageFlushCallback onMessageFlushCallback) noexcept; + std::shared_ptr NewStream() noexcept; /** - * Check if the continuation has been closed. - * @return True if the continuation has been closed, false otherwise. + * Close the connection. */ - bool IsClosed() noexcept; + void Close() noexcept; /** - * Send message on the continuation. - * @param headers List of additional event stream headers to include on the message. - * @param payload Message payload. - * @param messageType Message type for the message. - * @param messageFlags Bitmask of aws_event_stream_rpc_message_flag values. - * @param onMessageFlushCallback Callback to be invoked upon the message being flushed to the underlying - * transport. - * @return Future that will be resolved when the message has either been written to the wire or it fails. + * Check if the connection is open. + * @return True if the connection is open, false otherwise. */ - std::future SendMessage( - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags, - OnMessageFlushCallback onMessageFlushCallback) noexcept; + bool IsOpen() const noexcept; private: - friend class ClientOperation; - Crt::Allocator *m_allocator; - ClientContinuationHandler &m_continuationHandler; - struct aws_event_stream_rpc_client_continuation_token *m_continuationToken; - ContinuationCallbackData *m_callbackData; - - static void s_onContinuationMessage( - struct aws_event_stream_rpc_client_continuation_token *continuationToken, - const struct aws_event_stream_rpc_message_args *messageArgs, - void *userData) noexcept; - static void s_onContinuationClosed( - struct aws_event_stream_rpc_client_continuation_token *continuationToken, - void *userData) noexcept; + std::shared_ptr m_impl; + }; + + /** + * Vestigial, do-nothing class that remains for backwards compatibility with the + * original, publicly-visible class hierarchy. + */ + class AWS_EVENTSTREAMRPC_API ClientContinuationHandler + { + public: + virtual ~ClientContinuationHandler() noexcept = default; }; /** @@ -407,8 +330,8 @@ namespace Aws public: explicit OperationError() noexcept = default; static void s_customDeleter(OperationError *shape) noexcept; - virtual void SerializeToJsonObject(Crt::JsonObject &payloadObject) const override; - virtual Crt::Optional GetMessage() noexcept = 0; + void SerializeToJsonObject(Crt::JsonObject &payloadObject) const override; + virtual Crt::Optional GetMessage() const noexcept = 0; }; /** @@ -427,7 +350,7 @@ namespace Aws virtual void OnStreamClosed(); protected: - friend class ClientOperation; + friend class ClientContinuationImpl; /** * Invoked when a message is received on this continuation. */ @@ -464,7 +387,7 @@ namespace Aws * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept; + explicit operator bool() const noexcept; /** * Get operation result. @@ -493,13 +416,16 @@ namespace Aws private: union AWS_EVENTSTREAMRPC_API OperationResult { - OperationResult(Crt::ScopedResource &&response) noexcept + explicit OperationResult(Crt::ScopedResource &&response) noexcept : m_response(std::move(response)) { } - OperationResult(Crt::ScopedResource &&error) noexcept : m_error(std::move(error)) {} + explicit OperationResult(Crt::ScopedResource &&error) noexcept + : m_error(std::move(error)) + { + } OperationResult() noexcept : m_response(nullptr) {} - ~OperationResult() noexcept {}; + ~OperationResult() noexcept {} Crt::ScopedResource m_response; Crt::ScopedResource m_error; }; @@ -546,7 +472,7 @@ namespace Aws class AWS_EVENTSTREAMRPC_API OperationModelContext { public: - OperationModelContext(const ServiceModel &serviceModel) noexcept; + explicit OperationModelContext(const ServiceModel &serviceModel) noexcept; virtual ~OperationModelContext() noexcept = default; @@ -624,9 +550,9 @@ namespace Aws ClientOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const OperationModelContext &operationModelContext, + const std::shared_ptr &operationModelContext, Crt::Allocator *allocator) noexcept; - ~ClientOperation() noexcept; + ~ClientOperation() noexcept override; ClientOperation(const ClientOperation &clientOperation) noexcept = delete; ClientOperation(ClientOperation &&clientOperation) noexcept = delete; @@ -643,12 +569,9 @@ namespace Aws std::future Close(OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; /** - * Get an operation result. - * @return Future which will be resolved when the corresponding RPC request completes. - */ - std::future GetOperationResult() noexcept; - - /** + * @deprecated This no longer does anything useful. Launch policy was added because of a + * mistake in the implementation that was attempting to chain two promises together. + * * Set the launch mode for executing operations. The mode is set to std::launch::deferred by default. * @param mode The launch mode to use. */ @@ -659,209 +582,38 @@ namespace Aws * Initiate a new client stream. Send the shape for the new stream. * @param shape A parameter for RPC operation. * @param onMessageFlushCallback Callback to invoke when the shape is flushed to the underlying transport. + * @param onResultCallback Callback to invoke with the untransformed activation result * @return Future which will be resolved once the message is sent. */ std::future Activate( const AbstractShapeBase *shape, - OnMessageFlushCallback onMessageFlushCallback) noexcept; + OnMessageFlushCallback &&onMessageFlushCallback, + std::function &&onResultCallback) noexcept; /** - * Returns the canonical model name associated with this operation across any client language. - * Namespace included. - * @return The model name. - */ - virtual Crt::String GetModelName() const noexcept = 0; - - const OperationModelContext &m_operationModelContext; - std::launch m_asyncLaunchMode; - - private: - EventStreamRpcStatusCode HandleData(const Crt::Optional &payload); - EventStreamRpcStatusCode HandleError( - const Crt::String &modelName, - const Crt::Optional &payload, - uint32_t messageFlags); - /** - * Invoked when a message is received on this continuation. - */ - void OnContinuationMessage( - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags) override; - /** - * Invoked when the continuation is closed. + * Sends a message on the stream * - * Once the continuation is closed, no more messages may be sent or received. - * The continuation is closed when a message is sent or received with - * the TERMINATE_STREAM flag, or when the connection shuts down. - */ - void OnContinuationClosed() override; - - const EventStreamHeader *GetHeaderByName( - const Crt::List &headers, - const Crt::String &name) noexcept; - - enum CloseState - { - WONT_CLOSE = 0, - WILL_CLOSE, - ALREADY_CLOSED - }; - - uint32_t m_messageCount; - Crt::Allocator *m_allocator; - std::shared_ptr m_streamHandler; - ClientContinuation m_clientContinuation; - /* This mutex protects m_resultReceived & m_closeState. */ - std::mutex m_continuationMutex; - bool m_resultReceived; - std::promise m_initialResponsePromise; - std::atomic_int m_expectedCloses; - std::atomic_bool m_streamClosedCalled; - std::condition_variable m_closeReady; - }; - - /** - * Class representing a connection to an RPC server. - */ - class AWS_EVENTSTREAMRPC_API ClientConnection final - { - public: - ClientConnection(Crt::Allocator *allocator = Crt::g_allocator) noexcept; - ~ClientConnection() noexcept; - ClientConnection(const ClientConnection &) noexcept = delete; - ClientConnection &operator=(const ClientConnection &) noexcept = delete; - ClientConnection(ClientConnection &&) noexcept; - ClientConnection &operator=(ClientConnection &&) noexcept; - - /** - * Initiates a new outgoing event-stream-rpc connection. - * @param connectionOptions Connection options. - * @param connectionLifecycleHandler Handler to process connection lifecycle events. - * @param clientBootstrap ClientBootstrap object to run the connection on. - * @return Future that will be resolved when connection either succeeds or fails. - */ - std::future Connect( - const ConnectionConfig &connectionOptions, - ConnectionLifecycleHandler *connectionLifecycleHandler, - Crt::Io::ClientBootstrap &clientBootstrap) noexcept; - - std::future SendPing( - const Crt::List &headers, - const Crt::Optional &payload, - OnMessageFlushCallback onMessageFlushCallback) noexcept; - - std::future SendPingResponse( - const Crt::List &headers, - const Crt::Optional &payload, - OnMessageFlushCallback onMessageFlushCallback) noexcept; - - /** - * Create a new stream. - * @note Activate() must be called on the stream for it to actually initiate the new stream. - * @param clientContinuationHandler Handler to process continuation events. - * @return A newly created continuation. - */ - ClientContinuation NewStream(ClientContinuationHandler &clientContinuationHandler) noexcept; - - /** - * Close the connection. - */ - void Close() noexcept; - - /** - * Check if the connection is open. - * @return True if the connection is open, false otherwise. + * @param shape Modeled representation of the message to send + * @param onMessageFlushCallback Optional callback to invoke when the message is written or fails to send + * + * @return Future which will be resolved once the message is sent. */ - bool IsOpen() const noexcept - { - if (this->m_underlyingConnection == nullptr) - { - return false; - } - else - { - return aws_event_stream_rpc_client_connection_is_open(this->m_underlyingConnection); - } - } + std::future SendStreamMessage( + const AbstractShapeBase *shape, + OnMessageFlushCallback &&onMessageFlushCallback) noexcept; /** - * @return true if the connection is open, false otherwise. + * Returns the canonical model name associated with this operation across any client language. + * Namespace included. + * @return The model name. */ - operator bool() const noexcept { return IsOpen(); } + virtual Crt::String GetModelName() const noexcept; private: - friend class ClientContinuation; - friend std::future ClientOperation::Close(OnMessageFlushCallback onMessageFlushCallback) noexcept; - enum ClientState - { - DISCONNECTED = 1, - CONNECTING_SOCKET, - WAITING_FOR_CONNECT_ACK, - CONNECTED, - DISCONNECTING, - }; - /* This recursive mutex protects m_clientState & m_connectionWillSetup */ - std::recursive_mutex m_stateMutex; - Crt::Allocator *m_allocator; - struct aws_event_stream_rpc_client_connection *m_underlyingConnection; - ClientState m_clientState; - ConnectionLifecycleHandler *m_lifecycleHandler; - ConnectMessageAmender m_connectMessageAmender; - std::promise m_connectionSetupPromise; - bool m_connectionWillSetup; - std::promise m_connectAckedPromise; - std::promise m_closedPromise; - bool m_onConnectCalled; - RpcError m_closeReason; - OnMessageFlushCallback m_onConnectRequestCallback; - Crt::Io::SocketOptions m_socketOptions; - ConnectionConfig m_connectionConfig; - std::future SendProtocolMessage( - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags, - OnMessageFlushCallback onMessageFlushCallback) noexcept; - - static void s_onConnectionShutdown( - struct aws_event_stream_rpc_client_connection *connection, - int errorCode, - void *userData) noexcept; - static void s_onConnectionSetup( - struct aws_event_stream_rpc_client_connection *connection, - int errorCode, - void *userData) noexcept; - static void s_onProtocolMessage( - struct aws_event_stream_rpc_client_connection *connection, - const struct aws_event_stream_rpc_message_args *messageArgs, - void *userData) noexcept; - - static void s_protocolMessageCallback(int errorCode, void *userData) noexcept; + Aws::Crt::Allocator *m_allocator; - /** - * Sends a message on the connection. These must be connection level messages (not application messages). - */ - static std::future s_sendProtocolMessage( - ClientConnection *connection, - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags, - OnMessageFlushCallback onMessageFlushCallback) noexcept; - - static std::future s_sendPing( - ClientConnection *connection, - const Crt::List &headers, - const Crt::Optional &payload, - OnMessageFlushCallback onMessageFlushCallback) noexcept; - - static std::future s_sendPingResponse( - ClientConnection *connection, - const Crt::List &headers, - const Crt::Optional &payload, - OnMessageFlushCallback onMessageFlushCallback) noexcept; + std::shared_ptr m_impl; }; + } // namespace Eventstreamrpc } // namespace Aws diff --git a/eventstream_rpc/source/EventStreamClient.cpp b/eventstream_rpc/source/EventStreamClient.cpp index b1f8ce8f2..f98d9780b 100644 --- a/eventstream_rpc/source/EventStreamClient.cpp +++ b/eventstream_rpc/source/EventStreamClient.cpp @@ -5,13 +5,11 @@ #include #include -#include #include -#include -#include - #include +#include +#include constexpr auto EVENTSTREAM_VERSION_HEADER = ":version"; constexpr auto EVENTSTREAM_VERSION_STRING = "0.1.0"; @@ -23,15 +21,158 @@ namespace Aws { namespace Eventstreamrpc { - /* Because `std::function` cannot be typecasted to void *, we must contain it in a struct. */ - struct OnMessageFlushCallbackContainer + /* + * User-data class for completing message flush callbacks. The C++ API supports both callbacks and + * promise completion and so in turn this must support both. + * + * Additionally, because we synthesize callbacks (in order to have non-blocking destruction), this class + * must also support multiple users trying to complete it (with the first one winning) in a thread-safe + * manner. + * + * The general pattern, when needed, results in two possibilities: + * + * (1) Create a (shared_ptr) instance and submit it to the C API via activate()/connect()/send_message() + * (2) Keep a shared_ptr back in the connection/continuation as needed + * (3) C client sends message and invokes completion. A later completion by the binding does nothing. + * + * or + * + * (1) Create a (shared_ptr) instance and submit it to the C API via activate()/connect()/send_message() + * (2) Keep a shared_ptr back in the connection/continuation as needed + * (3) Connection/continuation shutdown happens before the C client does the message flush, so the callbacks + * get triggered by the shutdown. When the C client goes to complete, the completion does nothing (but + * is memory-safe). + + */ + class OnMessageFlushCallbackContainer + { + public: + explicit OnMessageFlushCallbackContainer(OnMessageFlushCallback &&flushCallback) : m_sharedState({}) + { + m_sharedState.m_state = CallbackState::Incomplete; + m_sharedState.m_onMessageFlushCallback = std::move(flushCallback); + } + + OnMessageFlushCallbackContainer( + OnMessageFlushCallback &&flushCallback, + std::promise &&flushPromise) + : OnMessageFlushCallbackContainer(std::move(flushCallback)) + { + m_sharedState.m_onFlushPromise = std::move(flushPromise); + } + + ~OnMessageFlushCallbackContainer() = default; + + static void Complete(OnMessageFlushCallbackContainer *callback, RpcError error) + { + if (callback == nullptr) + { + return; + } + + bool performCallback = false; + OnMessageFlushCallback onMessageFlushCallback; + std::promise onFlushPromise; + { + std::lock_guard lock(callback->m_sharedStateLock); + + if (callback->m_sharedState.m_state == CallbackState::Incomplete) + { + performCallback = true; + callback->m_sharedState.m_state = CallbackState::Finished; + onMessageFlushCallback = std::move(callback->m_sharedState.m_onMessageFlushCallback); + onFlushPromise = std::move(callback->m_sharedState.m_onFlushPromise); + } + } + + if (performCallback) + { + if (error.crtError != AWS_ERROR_SUCCESS) + { + AWS_LOGF_ERROR( + AWS_LS_EVENT_STREAM_RPC_CLIENT, + "A CRT error occurred while attempting to send a message: %s", + Crt::ErrorDebugString(error.crtError)); + } + onFlushPromise.set_value(error); + if (onMessageFlushCallback) + { + onMessageFlushCallback(error.crtError); + } + } + } + + private: + enum class CallbackState + { + Incomplete, + Finished + }; + + std::mutex m_sharedStateLock; + struct + { + CallbackState m_state; + OnMessageFlushCallback m_onMessageFlushCallback; + std::promise m_onFlushPromise; + } m_sharedState; + }; + + /* + * We can't submit a shared_ptr to the C layer, only a raw pointer. So this class just wraps a shared_ptr + * to a callback container. + */ + class OnMessageFlushCallbackContainerWrapper { - explicit OnMessageFlushCallbackContainer(Crt::Allocator *allocator) : allocator(allocator) {} - Crt::Allocator *allocator; - OnMessageFlushCallback onMessageFlushCallback; - std::promise onFlushPromise; + public: + OnMessageFlushCallbackContainerWrapper(Crt::Allocator *allocator, OnMessageFlushCallback &&flushCallback) + : m_allocator(allocator), + m_container( + Aws::Crt::MakeShared(allocator, std::move(flushCallback))) + { + } + + OnMessageFlushCallbackContainerWrapper( + Crt::Allocator *allocator, + OnMessageFlushCallback &&flushCallback, + std::promise &&flushPromise) + : m_allocator(allocator), m_container(Aws::Crt::MakeShared( + allocator, + std::move(flushCallback), + std::move(flushPromise))) + { + } + + ~OnMessageFlushCallbackContainerWrapper() = default; + + static void Complete(OnMessageFlushCallbackContainerWrapper *wrapper, RpcError error) + { + if (wrapper == nullptr) + { + return; + } + + OnMessageFlushCallbackContainer::Complete(wrapper->GetContainer().get(), error); + } + + std::shared_ptr GetContainer() const { return m_container; } + Crt::Allocator *GetAllocator() { return m_allocator; } + + private: + Crt::Allocator *m_allocator; + std::shared_ptr m_container; }; + /* The flush completion callback function that the low-level C client will invoke */ + static void s_protocolMessageCallback(int errorCode, void *userData) noexcept + { + auto *wrapper = static_cast(userData); + + auto rpcStatus = (errorCode == AWS_ERROR_SUCCESS) ? EVENT_STREAM_RPC_SUCCESS : EVENT_STREAM_RPC_CRT_ERROR; + OnMessageFlushCallbackContainerWrapper::Complete(wrapper, {rpcStatus, errorCode}); + Aws::Crt::Delete(wrapper, wrapper->GetAllocator()); + } + MessageAmendment::MessageAmendment(Crt::Allocator *allocator) noexcept : m_headers(), m_payload(), m_allocator(allocator) { @@ -92,14 +233,14 @@ namespace Aws return *this; } - MessageAmendment::MessageAmendment(MessageAmendment &&rhs) - : m_headers(std::move(rhs.m_headers)), m_payload(rhs.m_payload), m_allocator(rhs.m_allocator) + MessageAmendment::MessageAmendment(MessageAmendment &&rhs) noexcept + : m_headers(std::move(rhs.m_headers)), m_payload(std::move(rhs.m_payload)), m_allocator(rhs.m_allocator) { rhs.m_allocator = nullptr; rhs.m_payload = Crt::Optional(); } - MessageAmendment &MessageAmendment::operator=(MessageAmendment &&rhs) + MessageAmendment &MessageAmendment::operator=(MessageAmendment &&rhs) noexcept { if (this != &rhs) { @@ -164,120 +305,23 @@ namespace Aws } } - class EventStreamCppToNativeCrtBuilder - { - private: - friend class ClientConnection; - friend class ClientContinuation; - static int s_fillNativeHeadersArray( - const Crt::List &headers, - struct aws_array_list *headersArray, - Crt::Allocator *m_allocator = Crt::g_allocator) - { - AWS_ZERO_STRUCT(*headersArray); - /* Check if the connection has expired before attempting to send. */ - int errorCode = aws_event_stream_headers_list_init(headersArray, m_allocator); - - if (!errorCode) - { - /* Populate the array with the underlying handle of each EventStreamHeader. */ - for (auto &i : headers) - { - errorCode = aws_array_list_push_back(headersArray, i.GetUnderlyingHandle()); - - if (errorCode) - { - break; - } - } - } - - return errorCode; - } - }; - - ClientConnection &ClientConnection::operator=(ClientConnection &&rhs) noexcept - { - m_allocator = std::move(rhs.m_allocator); - m_underlyingConnection = rhs.m_underlyingConnection; - rhs.m_stateMutex.lock(); - m_clientState = rhs.m_clientState; - rhs.m_stateMutex.unlock(); - m_lifecycleHandler = rhs.m_lifecycleHandler; - m_connectMessageAmender = rhs.m_connectMessageAmender; - m_connectAckedPromise = std::move(rhs.m_connectAckedPromise); - m_closedPromise = std::move(rhs.m_closedPromise); - m_onConnectRequestCallback = rhs.m_onConnectRequestCallback; - - /* Reset rhs. */ - rhs.m_allocator = nullptr; - rhs.m_underlyingConnection = nullptr; - rhs.m_clientState = DISCONNECTED; - rhs.m_lifecycleHandler = nullptr; - rhs.m_connectMessageAmender = nullptr; - rhs.m_closedPromise = {}; - rhs.m_onConnectRequestCallback = nullptr; - - return *this; - } - - ClientConnection::ClientConnection(ClientConnection &&rhs) noexcept : m_lifecycleHandler(rhs.m_lifecycleHandler) - { - *this = std::move(rhs); - } - - ClientConnection::ClientConnection(Crt::Allocator *allocator) noexcept - : m_allocator(allocator), m_underlyingConnection(nullptr), m_clientState(DISCONNECTED), - m_lifecycleHandler(nullptr), m_connectMessageAmender(nullptr), m_connectionWillSetup(false), - m_onConnectRequestCallback(nullptr) + static void s_fillNativeHeadersArray( + const Crt::List &headers, + struct aws_array_list *headersArray, + Crt::Allocator *m_allocator = Crt::g_allocator) { - } + AWS_ZERO_STRUCT(*headersArray); + /* Check if the connection has expired before attempting to send. */ + aws_event_stream_headers_list_init(headersArray, m_allocator); - ClientConnection::~ClientConnection() noexcept - { - m_stateMutex.lock(); - if (m_connectionWillSetup) - { - m_stateMutex.unlock(); - m_connectionSetupPromise.get_future().wait(); - } - m_stateMutex.lock(); - if (m_clientState != DISCONNECTED) + /* Populate the array with the underlying handle of each EventStreamHeader. */ + for (auto &i : headers) { - Close(); - m_stateMutex.unlock(); - m_closedPromise.get_future().wait(); + aws_array_list_push_back(headersArray, i.GetUnderlyingHandle()); } - /* Cover the case in which the if statements are not hit. */ - m_stateMutex.unlock(); - m_stateMutex.unlock(); - - m_underlyingConnection = nullptr; - } - - bool ConnectionLifecycleHandler::OnErrorCallback(RpcError error) - { - (void)error; - /* Returning true implies that the connection should close as a result of encountering this error. */ - return true; - } - - void ConnectionLifecycleHandler::OnPingCallback( - const Crt::List &headers, - const Crt::Optional &payload) - { - (void)headers; - (void)payload; } - void ConnectionLifecycleHandler::OnConnectCallback() {} - - void ConnectionLifecycleHandler::OnDisconnectCallback(RpcError error) - { - (void)error; - } - - Crt::String RpcError::StatusToString() + Crt::String RpcError::StatusToString() const { switch (baseStatus) { @@ -306,285 +350,47 @@ namespace Aws case EVENT_STREAM_RPC_UNSUPPORTED_CONTENT_TYPE: return "EVENT_STREAM_RPC_UNSUPPORTED_CONTENT_TYPE"; case EVENT_STREAM_RPC_CRT_ERROR: + { Crt::String ret = "Failed with EVENT_STREAM_RPC_CRT_ERROR, the CRT error was "; ret += Crt::ErrorDebugString(crtError); return ret; + } + case EVENT_STREAM_RPC_CONTINUATION_NOT_YET_OPENED: + return "EVENT_STREAM_RPC_CONTINUATION_NOT_YET_OPENED"; } return "Unknown status code"; } - std::future ClientConnection::Connect( - const ConnectionConfig &connectionConfig, - ConnectionLifecycleHandler *connectionLifecycleHandler, - Crt::Io::ClientBootstrap &clientBootstrap) noexcept + EventStreamRpcStatusCode ConnectionConfig::Validate() const noexcept { - EventStreamRpcStatusCode baseError = EVENT_STREAM_RPC_SUCCESS; - struct aws_event_stream_rpc_client_connection_options connOptions; - - { - const std::lock_guard lock(m_stateMutex); - if (m_clientState == DISCONNECTED) - { - m_clientState = CONNECTING_SOCKET; - m_onConnectCalled = false; - m_connectionSetupPromise = {}; - m_connectAckedPromise = {}; - m_closedPromise = {}; - m_closeReason = {EVENT_STREAM_RPC_UNINITIALIZED, 0}; - m_connectionConfig = connectionConfig; - m_lifecycleHandler = connectionLifecycleHandler; - } - else - { - baseError = EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED; - } - } - - m_onConnectRequestCallback = m_connectionConfig.GetConnectRequestCallback(); - Crt::String hostName; - - if (baseError == EVENT_STREAM_RPC_SUCCESS) - { - AWS_ZERO_STRUCT(connOptions); - if (m_connectionConfig.GetHostName().has_value()) - { - hostName = m_connectionConfig.GetHostName().value(); - connOptions.host_name = hostName.c_str(); - } - else - { - baseError = EVENT_STREAM_RPC_NULL_PARAMETER; - } - if (m_connectionConfig.GetPort().has_value()) - { - connOptions.port = m_connectionConfig.GetPort().value(); - } - else - { - baseError = EVENT_STREAM_RPC_NULL_PARAMETER; - } - - connOptions.bootstrap = clientBootstrap.GetUnderlyingHandle(); - } - - if (baseError) - { - std::promise errorPromise; - errorPromise.set_value({baseError, 0}); - if (baseError == EVENT_STREAM_RPC_NULL_PARAMETER) - { - const std::lock_guard lock(m_stateMutex); - m_clientState = DISCONNECTED; - } - return errorPromise.get_future(); - } - - if (m_connectionConfig.GetSocketOptions().has_value()) - { - m_socketOptions = m_connectionConfig.GetSocketOptions().value(); - } - connOptions.socket_options = &m_socketOptions.GetImpl(); - - connOptions.on_connection_setup = ClientConnection::s_onConnectionSetup; - connOptions.on_connection_protocol_message = ClientConnection::s_onProtocolMessage; - connOptions.on_connection_shutdown = ClientConnection::s_onConnectionShutdown; - connOptions.user_data = reinterpret_cast(this); - - m_lifecycleHandler = connectionLifecycleHandler; - m_connectMessageAmender = m_connectionConfig.GetConnectMessageAmender(); - - if (m_connectionConfig.GetTlsConnectionOptions().has_value()) - { - connOptions.tls_options = m_connectionConfig.GetTlsConnectionOptions()->GetUnderlyingHandle(); - } - - int crtError = aws_event_stream_rpc_client_connection_connect(m_allocator, &connOptions); - - if (crtError) - { - std::promise errorPromise; - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A CRT error occurred while attempting to establish the connection: %s", - Crt::ErrorDebugString(crtError)); - errorPromise.set_value({EVENT_STREAM_RPC_CRT_ERROR, crtError}); - const std::lock_guard lock(m_stateMutex); - m_clientState = DISCONNECTED; - return errorPromise.get_future(); - } - else + if (!m_hostName.has_value() || !m_port.has_value()) { - const std::lock_guard lock(m_stateMutex); - m_connectionWillSetup = true; + return EVENT_STREAM_RPC_NULL_PARAMETER; } - return m_connectAckedPromise.get_future(); - } - - std::future ClientConnection::SendPing( - const Crt::List &headers, - const Crt::Optional &payload, - OnMessageFlushCallback onMessageFlushCallback) noexcept - { - return s_sendPing(this, headers, payload, onMessageFlushCallback); - } - - std::future ClientConnection::SendPingResponse( - const Crt::List &headers, - const Crt::Optional &payload, - OnMessageFlushCallback onMessageFlushCallback) noexcept - { - return s_sendPingResponse(this, headers, payload, onMessageFlushCallback); - } - - std::future ClientConnection::s_sendPing( - ClientConnection *connection, - const Crt::List &headers, - const Crt::Optional &payload, - OnMessageFlushCallback onMessageFlushCallback) noexcept - { - return s_sendProtocolMessage( - connection, headers, payload, AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_PING, 0, onMessageFlushCallback); + return EVENT_STREAM_RPC_SUCCESS; } - std::future ClientConnection::s_sendPingResponse( - ClientConnection *connection, - const Crt::List &headers, - const Crt::Optional &payload, - OnMessageFlushCallback onMessageFlushCallback) noexcept + bool ConnectionLifecycleHandler::OnErrorCallback(RpcError error) { - return s_sendProtocolMessage( - connection, - headers, - payload, - AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_PING_RESPONSE, - 0, - onMessageFlushCallback); + (void)error; + /* Returning true implies that the connection should close as a result of encountering this error. */ + return true; } - std::future ClientConnection::SendProtocolMessage( + void ConnectionLifecycleHandler::OnPingCallback( const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags, - OnMessageFlushCallback onMessageFlushCallback) noexcept - { - return s_sendProtocolMessage(this, headers, payload, messageType, messageFlags, onMessageFlushCallback); - } - - void ClientConnection::s_protocolMessageCallback(int errorCode, void *userData) noexcept + const Crt::Optional &payload) { - auto *callbackData = static_cast(userData); - - if (errorCode) - { - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A CRT error occurred while attempting to send a message: %s", - Crt::ErrorDebugString(errorCode)); - callbackData->onFlushPromise.set_value({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); - } - else - { - callbackData->onFlushPromise.set_value({EVENT_STREAM_RPC_SUCCESS, 0}); - } - - /* Call the user-provided callback. */ - if (callbackData->onMessageFlushCallback) - { - callbackData->onMessageFlushCallback(errorCode); - } - - Crt::Delete(callbackData, callbackData->allocator); + (void)headers; + (void)payload; } - std::future ClientConnection::s_sendProtocolMessage( - ClientConnection *connection, - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags, - OnMessageFlushCallback onMessageFlushCallback) noexcept - { - std::promise onFlushPromise; - OnMessageFlushCallbackContainer *callbackContainer = nullptr; - struct aws_array_list headersArray; - - /* The caller should never pass a NULL connection. */ - AWS_PRECONDITION(connection != nullptr); - - int errorCode = EventStreamCppToNativeCrtBuilder::s_fillNativeHeadersArray( - headers, &headersArray, connection->m_allocator); - - if (!errorCode) - { - struct aws_event_stream_rpc_message_args msg_args; - msg_args.headers = (struct aws_event_stream_header_value_pair *)headersArray.data; - msg_args.headers_count = headers.size(); - msg_args.payload = payload.has_value() ? (aws_byte_buf *)(&(payload.value())) : nullptr; - msg_args.message_type = messageType; - msg_args.message_flags = messageFlags; - - /* This heap allocation is necessary so that the flush callback can still be invoked when this function - * returns. */ - callbackContainer = - Crt::New(connection->m_allocator, connection->m_allocator); - callbackContainer->onMessageFlushCallback = onMessageFlushCallback; - callbackContainer->onFlushPromise = std::move(onFlushPromise); - - errorCode = aws_event_stream_rpc_client_connection_send_protocol_message( - connection->m_underlyingConnection, - &msg_args, - ClientConnection::s_protocolMessageCallback, - reinterpret_cast(callbackContainer)); - } - - /* Cleanup. */ - if (aws_array_list_is_valid(&headersArray)) - { - aws_array_list_clean_up(&headersArray); - } - - if (errorCode) - { - onFlushPromise = std::move(callbackContainer->onFlushPromise); - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A CRT error occurred while queueing a message to be sent on the connection: %s", - Crt::ErrorDebugString(errorCode)); - onFlushPromise.set_value({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); - Crt::Delete(callbackContainer, connection->m_allocator); - } - else - { - return callbackContainer->onFlushPromise.get_future(); - } - - return onFlushPromise.get_future(); - } + void ConnectionLifecycleHandler::OnConnectCallback() {} - void ClientConnection::Close() noexcept + void ConnectionLifecycleHandler::OnDisconnectCallback(RpcError error) { - const std::lock_guard lock(m_stateMutex); - - if (IsOpen()) - { - aws_event_stream_rpc_client_connection_close(this->m_underlyingConnection, AWS_OP_SUCCESS); - } - else if (m_clientState == CONNECTING_SOCKET && !m_connectionWillSetup) - { - m_connectAckedPromise.set_value({EVENT_STREAM_RPC_CONNECTION_CLOSED, 0}); - } - - if (m_clientState != DISCONNECTING && m_clientState != DISCONNECTED) - { - m_clientState = DISCONNECTING; - } - - if (m_closeReason.baseStatus == EVENT_STREAM_RPC_UNINITIALIZED) - { - m_closeReason = {EVENT_STREAM_RPC_CONNECTION_CLOSED, 0}; - } + (void)error; } EventStreamHeader::EventStreamHeader( @@ -592,6 +398,21 @@ namespace Aws Crt::Allocator *allocator) : m_allocator(allocator), m_valueByteBuf({}), m_underlyingHandle(header) { + switch (header.header_value_type) + { + case AWS_EVENT_STREAM_HEADER_STRING: + case AWS_EVENT_STREAM_HEADER_BYTE_BUF: + // Unsafe to copy C struct by value. Copy the referenced buffer and fix up pointers. + m_valueByteBuf = + Crt::ByteBufNewCopy(allocator, header.header_value.variable_len_val, header.header_value_len); + m_underlyingHandle.header_value.variable_len_val = m_valueByteBuf.buffer; + m_underlyingHandle.header_value_len = static_cast(m_valueByteBuf.len); + break; + + default: + // C struct can be copied by value safely + break; + } } EventStreamHeader::EventStreamHeader( @@ -634,15 +455,23 @@ namespace Aws EventStreamHeader &EventStreamHeader::operator=(const EventStreamHeader &lhs) noexcept { - m_allocator = lhs.m_allocator; - m_valueByteBuf = Crt::ByteBufNewCopy(lhs.m_allocator, lhs.m_valueByteBuf.buffer, lhs.m_valueByteBuf.len); - m_underlyingHandle = lhs.m_underlyingHandle; - m_underlyingHandle.header_value.variable_len_val = m_valueByteBuf.buffer; - m_underlyingHandle.header_value_len = static_cast(m_valueByteBuf.len); - return *this; - } - - EventStreamHeader::EventStreamHeader(EventStreamHeader &&rhs) noexcept + if (this != &lhs) + { + m_allocator = lhs.m_allocator; + if (aws_byte_buf_is_valid(&m_valueByteBuf)) + { + Crt::ByteBufDelete(m_valueByteBuf); + } + m_valueByteBuf = + Crt::ByteBufNewCopy(lhs.m_allocator, lhs.m_valueByteBuf.buffer, lhs.m_valueByteBuf.len); + m_underlyingHandle = lhs.m_underlyingHandle; + m_underlyingHandle.header_value.variable_len_val = m_valueByteBuf.buffer; + m_underlyingHandle.header_value_len = static_cast(m_valueByteBuf.len); + } + return *this; + } + + EventStreamHeader::EventStreamHeader(EventStreamHeader &&rhs) noexcept : m_allocator(rhs.m_allocator), m_valueByteBuf(rhs.m_valueByteBuf), m_underlyingHandle(rhs.m_underlyingHandle) { @@ -674,500 +503,799 @@ namespace Aws return true; } - ClientContinuation ClientConnection::NewStream(ClientContinuationHandler &clientContinuationHandler) noexcept - { - return ClientContinuation(this, clientContinuationHandler, m_allocator); - } + /* + * Eventstream Connection Refactor + * + * For connections, we now enforce the following invariants for correctness: + * + * 1. No callback is made while a lock is held. We perform callbacks by having a transactional callback context + * that is moved out of shared state (under the lock), but the callback context does not perform its work until + * the lock is released. + * + * 2. No C API call is made while the lock is held. This prevents deadlock in degenerate cases where callbacks + * get invoked synchronously (for example, trying to send a message on a closed connection). + * + * 3. No destructor blocking or synchronization. In order to provide the best behavioral backwards + * compatibility, we "synthesize" the callbacks that would occur at destruction when we kick off the async + * cleanup process. Later, when the asynchronous events occur that would normally trigger a callback occur, we + * ignore them. + * + * 4. A self-reference (via shared_ptr member) guarantees the binding impl stays alive longer than the C + * objects. The public binding object also keeps a shared_ptr to the impl, so final destruction only occurs + * once both the public binding object's destructor has run and no C connection object is still alive. + * + * + * Invariant (2) lead to a common pattern throughout the bindings: + * + * (1) Lock the shared state + * (2) Optimistically update the shared state as if action-to-take was successful + * (3) Unlock the shared state + * (4) Invoke the C API + * (5) If the C API was unsuccessful (rare case), lock the shared state, rollback the optimistic update, unlock + * + * For this to be correct, the shared state update in (2) must exclude other pathways from trying to do the same + * action. For example, if a continuation is created but not activated, calling activate optimistically + * updates the state to PENDING_ACTIVATE, which prevents concurrent callers from doing anything. If the C + * call to activate() fails, then we roll back from PENDING_ACTIVATE, allowing future callers to again try + * and activate the continuation. + */ + + /* What kind of callback should this context trigger? */ + enum class ConnectionCallbackActionType + { + None, + CompleteConnectPromise, + DisconnectionCallback + }; - void ClientConnection::s_onConnectionSetup( - struct aws_event_stream_rpc_client_connection *connection, - int errorCode, - void *userData) noexcept + /* + * The purpose of this type is to hide much of the conditional complexity around callbacks that the + * connection implementation faces. Issues include: + * (1) When to complete a promise vs. calling a function + * (2) Tracking what promise to complete + * (3) Helping ensure callbacks always occur once and only once + * (4) Passing delayed state (like an error code) forward until the callback can safely be triggered + * + * We rely on move semantics to ensure (2) and (3) + */ + class ConnectionCallbackContext { - /* The `userData` pointer is used to pass `this` of a `ClientConnection` object. */ - auto *thisConnection = static_cast(userData); - - const std::lock_guard lock(thisConnection->m_stateMutex); - - if (errorCode) + public: + ConnectionCallbackContext() + : m_action(ConnectionCallbackActionType::None), m_error{EVENT_STREAM_RPC_SUCCESS, AWS_ERROR_SUCCESS} { - thisConnection->m_clientState = DISCONNECTED; - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A CRT error occurred while setting up the connection: %s", - Crt::ErrorDebugString(errorCode)); - thisConnection->m_connectAckedPromise.set_value({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); - aws_event_stream_rpc_client_connection_release(connection); - thisConnection->m_underlyingConnection = nullptr; - /* No connection to close on error, so no need to check return value of the callback. */ - (void)thisConnection->m_lifecycleHandler->OnErrorCallback({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); } - else if (thisConnection->m_clientState == DISCONNECTING || thisConnection->m_clientState == DISCONNECTED) + + ConnectionCallbackContext( + const std::function &disconnectionCallback, + const std::function &errorCallback, + const std::function &connectionSuccessCallback) + : m_action(ConnectionCallbackActionType::CompleteConnectPromise), + m_error{EVENT_STREAM_RPC_SUCCESS, AWS_ERROR_SUCCESS}, m_connectPromise(), + m_disconnectionCallback(disconnectionCallback), m_errorCallback(errorCallback), + m_connectionSuccessCallback(connectionSuccessCallback) { - thisConnection->m_underlyingConnection = connection; - thisConnection->m_closeReason = {EVENT_STREAM_RPC_CONNECTION_CLOSED, 0}; - thisConnection->Close(); } - else - { - thisConnection->m_clientState = WAITING_FOR_CONNECT_ACK; - thisConnection->m_underlyingConnection = connection; - MessageAmendment messageAmendment; - - if (thisConnection->m_connectMessageAmender) - { - MessageAmendment connectAmendment(thisConnection->m_connectMessageAmender()); - /* The version header is necessary for establishing the connection. */ - messageAmendment.AddHeader(EventStreamHeader( - Crt::String(EVENTSTREAM_VERSION_HEADER), - Crt::String(EVENTSTREAM_VERSION_STRING), - thisConnection->m_allocator)); - messageAmendment.PrependHeaders(std::move(connectAmendment).GetHeaders()); - messageAmendment.SetPayload(std::move(connectAmendment).GetPayload()); - } - /* Send a CONNECT packet to the server. */ - s_sendProtocolMessage( - thisConnection, - messageAmendment.GetHeaders(), - messageAmendment.GetPayload(), - AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_CONNECT, - 0U, - thisConnection->m_onConnectRequestCallback); + ConnectionCallbackContext(ConnectionCallbackContext &&rhs) noexcept + : m_action(rhs.m_action), m_error(rhs.m_error), m_connectPromise(std::move(rhs.m_connectPromise)), + m_disconnectionCallback(std::move(rhs.m_disconnectionCallback)), + m_errorCallback(std::move(rhs.m_errorCallback)), + m_connectionSuccessCallback(std::move(rhs.m_connectionSuccessCallback)) + { + rhs.ClearContext(); } - thisConnection->m_connectionSetupPromise.set_value(); - } - - void ClientConnection::s_onConnectionShutdown( - struct aws_event_stream_rpc_client_connection *connection, - int errorCode, - void *userData) noexcept - { - (void)connection; - /* The `userData` pointer is used to pass `this` of a `ClientConnection` object. */ - auto *thisConnection = static_cast(userData); - - const std::lock_guard lock(thisConnection->m_stateMutex); - - if (thisConnection->m_closeReason.baseStatus == EVENT_STREAM_RPC_UNINITIALIZED && errorCode) + ConnectionCallbackContext &operator=(ConnectionCallbackContext &&rhs) noexcept { - thisConnection->m_closeReason = {EVENT_STREAM_RPC_CRT_ERROR, errorCode}; - } + m_action = rhs.m_action; + m_error = rhs.m_error; + m_connectPromise = std::move(rhs.m_connectPromise); + m_disconnectionCallback = std::move(rhs.m_disconnectionCallback); + m_errorCallback = std::move(rhs.m_errorCallback); + m_connectionSuccessCallback = std::move(rhs.m_connectionSuccessCallback); - thisConnection->m_underlyingConnection = nullptr; + rhs.ClearContext(); - if (thisConnection->m_closeReason.baseStatus != EVENT_STREAM_RPC_UNINITIALIZED && - !thisConnection->m_onConnectCalled) - { - thisConnection->m_connectAckedPromise.set_value(thisConnection->m_closeReason); + return *this; } - thisConnection->m_clientState = DISCONNECTED; - - if (thisConnection->m_onConnectCalled) + void InvokeCallbacks() { - if (errorCode) - { - thisConnection->m_lifecycleHandler->OnDisconnectCallback({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); - } - else + switch (m_action) { - thisConnection->m_lifecycleHandler->OnDisconnectCallback({EVENT_STREAM_RPC_SUCCESS, 0}); + case ConnectionCallbackActionType::CompleteConnectPromise: + { + if (m_error.crtError != AWS_ERROR_SUCCESS) + { + if (m_errorCallback) + { + (void)m_errorCallback(m_error); + } + } + else + { + if (m_connectionSuccessCallback) + { + m_connectionSuccessCallback(); + } + } + m_connectPromise.set_value(m_error); + break; + } + case ConnectionCallbackActionType::DisconnectionCallback: + { + if (m_disconnectionCallback) + { + m_disconnectionCallback(m_error); + } + break; + } + default: + break; } - thisConnection->m_onConnectCalled = false; } - if (errorCode) + /* + * Returns a callback context that should be invoked now (indicating successful connection), and moves + * this context into a state that should be invoked when the connection is closed. + */ + ConnectionCallbackContext TransitionToConnected() { - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A CRT error occurred while shutting down the connection: %s", - Crt::ErrorDebugString(errorCode)); - thisConnection->m_closedPromise.set_value({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); + // connection success context caller should invoke + ConnectionCallbackContext context = {}; + context.m_action = ConnectionCallbackActionType::CompleteConnectPromise; + context.m_connectPromise = std::move(m_connectPromise); + context.m_connectionSuccessCallback = m_connectionSuccessCallback; + + // we're now a disconnect context + m_action = ConnectionCallbackActionType::DisconnectionCallback; + m_error = {EVENT_STREAM_RPC_SUCCESS, AWS_ERROR_SUCCESS}; + m_connectPromise = {}; + + return context; } - else + + void SetAction(ConnectionCallbackActionType action) { m_action = action; } + void SetError(RpcError error) { - thisConnection->m_closedPromise.set_value({EVENT_STREAM_RPC_SUCCESS, errorCode}); + if (m_error.baseStatus == EVENT_STREAM_RPC_SUCCESS) + { + m_error = error; + } } - } - void ClientConnection::s_onProtocolMessage( - struct aws_event_stream_rpc_client_connection *connection, - const struct aws_event_stream_rpc_message_args *messageArgs, - void *userData) noexcept + std::future GetConnectPromiseFuture() { return m_connectPromise.get_future(); } + + private: + /* Wipes out state in a context to guarantee it does nothing if someone tries to InvokeCallbacks on it */ + void ClearContext() + { + m_action = ConnectionCallbackActionType::None; + m_error = {EVENT_STREAM_RPC_SUCCESS, AWS_ERROR_SUCCESS}; + m_connectPromise = {}; + m_disconnectionCallback = {}; + m_errorCallback = {}; + m_connectionSuccessCallback = {}; + } + + ConnectionCallbackActionType m_action; + RpcError m_error; + std::promise m_connectPromise; + std::function m_disconnectionCallback; + std::function m_errorCallback; + std::function m_connectionSuccessCallback; + }; + + class ClientConnectionImpl final : public std::enable_shared_from_this { - AWS_PRECONDITION(messageArgs != nullptr); - (void)connection; + public: + explicit ClientConnectionImpl(Crt::Allocator *allocator, aws_client_bootstrap *bootstrap) noexcept; + ~ClientConnectionImpl() noexcept; - /* The `userData` pointer is used to pass `this` of a `ClientConnection` object. */ - auto *thisConnection = static_cast(userData); - Crt::List pingHeaders; + std::future Connect( + const ConnectionConfig &connectionOptions, + ConnectionLifecycleHandler *connectionLifecycleHandler) noexcept; - switch (messageArgs->message_type) + std::shared_ptr NewStream() noexcept; + + void Close() noexcept; + + bool IsOpen() const noexcept; + + // Exclusively called by ClientConnection's destructor. + void Shutdown() noexcept; + + private: + void CloseInternal(bool isShutdown) noexcept; + void MoveToDisconnected(RpcError error) noexcept; + + void ConstructConnectMessage( + struct aws_event_stream_rpc_message_args *msg_args, + struct aws_array_list *headersArray) noexcept; + + enum class ClientState { - case AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_CONNECT_ACK: - thisConnection->m_stateMutex.lock(); - if (thisConnection->m_clientState == WAITING_FOR_CONNECT_ACK) - { - if (messageArgs->message_flags & AWS_EVENT_STREAM_RPC_MESSAGE_FLAG_CONNECTION_ACCEPTED) - { - thisConnection->m_clientState = CONNECTED; - thisConnection->m_onConnectCalled = true; - thisConnection->m_connectAckedPromise.set_value({EVENT_STREAM_RPC_SUCCESS, 0}); - thisConnection->m_lifecycleHandler->OnConnectCallback(); - } - else - { - thisConnection->m_closeReason = {EVENT_STREAM_RPC_CONNECTION_ACCESS_DENIED, 0}; - thisConnection->Close(); - } - } - else - { - /* Unexpected CONNECT_ACK received. */ - } - thisConnection->m_stateMutex.unlock(); + // There is no C connection and no pending attempt to create one + Disconnected, - break; + // There is a pending attempt to create a C connection, but it has not completed yet + PendingConnect, - case AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_PING: + // We have a C connection, but the Connect->Connack handshake has not completed yet + PendingConnack, - for (size_t i = 0; i < messageArgs->headers_count; ++i) - { - pingHeaders.emplace_back( - EventStreamHeader(messageArgs->headers[i], thisConnection->m_allocator)); - } + // We have a C connection ready to be used + Connected, - if (messageArgs->payload) - { - thisConnection->m_lifecycleHandler->OnPingCallback(pingHeaders, *messageArgs->payload); - } - else - { - thisConnection->m_lifecycleHandler->OnPingCallback(pingHeaders, Crt::Optional()); - } + // Our formerly-connected C connection is in the process of shutting down + Disconnecting, + }; - break; + Crt::Allocator *m_allocator; - case AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_PING_RESPONSE: - return; - break; + ConnectionLifecycleHandler *m_lifecycleHandler; // cannot be made a shared_ptr sadly + ConnectMessageAmender m_connectMessageAmender; + ConnectionConfig m_connectionConfig; - case AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_PROTOCOL_ERROR: - case AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_INTERNAL_ERROR: + // Non-null as long as something connection-related is going on in the C layer. + std::shared_ptr m_selfReference; + aws_client_bootstrap *m_bootstrap; + aws_event_loop *m_eventLoop; - if (thisConnection->m_lifecycleHandler->OnErrorCallback( - {EVENT_STREAM_RPC_CRT_ERROR, AWS_ERROR_EVENT_STREAM_RPC_PROTOCOL_ERROR})) - { - thisConnection->Close(); - } + std::mutex m_sharedStateLock; + struct + { + aws_event_stream_rpc_client_connection *m_underlyingConnection; + ClientState m_currentState; + ClientState m_desiredState; + ConnectionCallbackContext m_callbackContext; + std::shared_ptr m_connectFlushContainer; + bool m_hasShutDown; + } m_sharedState; - break; + static void s_onConnectionShutdown( + struct aws_event_stream_rpc_client_connection *connection, + int errorCode, + void *userData) noexcept; - default: + static void s_onConnectionSetup( + struct aws_event_stream_rpc_client_connection *connection, + int errorCode, + void *userData) noexcept; - if (thisConnection->m_lifecycleHandler->OnErrorCallback( - {EVENT_STREAM_RPC_UNKNOWN_PROTOCOL_MESSAGE, 0})) - { - thisConnection->Close(); - } + static void s_onProtocolMessage( + struct aws_event_stream_rpc_client_connection *connection, + const struct aws_event_stream_rpc_message_args *messageArgs, + void *userData) noexcept; + }; - break; - } + ClientConnectionImpl::ClientConnectionImpl(Crt::Allocator *allocator, aws_client_bootstrap *bootstrap) noexcept + : m_allocator(allocator), m_lifecycleHandler(nullptr), m_connectMessageAmender(nullptr), + m_bootstrap(aws_client_bootstrap_acquire(bootstrap)), m_eventLoop(nullptr), + m_sharedState{nullptr, ClientState::Disconnected, ClientState::Disconnected, {}, nullptr, false} + { + m_eventLoop = aws_event_loop_group_get_next_loop(bootstrap->event_loop_group); } - void AbstractShapeBase::s_customDeleter(AbstractShapeBase *shape) noexcept + ClientConnectionImpl::~ClientConnectionImpl() noexcept { - if (shape->m_allocator != nullptr) - Crt::Delete(shape, shape->m_allocator); + aws_client_bootstrap_release(m_bootstrap); } - ClientContinuation::ClientContinuation( - ClientConnection *connection, - ClientContinuationHandler &continuationHandler, - Crt::Allocator *allocator) noexcept - : m_allocator(allocator), m_continuationHandler(continuationHandler), m_continuationToken(nullptr) + // We use a task to zero out the self reference to make sure we are not in a call stack that includes + // a member function of the connection impl itself when potentially releasing the final reference. + struct AwsEventstreamConnectionImplClearSharedTask + { + AwsEventstreamConnectionImplClearSharedTask( + Aws::Crt::Allocator *allocator, + ClientConnectionImpl *clientConnectionImpl) noexcept; + + struct aws_task m_task; + struct aws_allocator *m_allocator; + std::shared_ptr m_impl; + }; + + static void s_zeroSharedReference(struct aws_task *task, void *arg, enum aws_task_status status) { - struct aws_event_stream_rpc_client_stream_continuation_options options; - options.on_continuation = ClientContinuation::s_onContinuationMessage; - options.on_continuation_closed = ClientContinuation::s_onContinuationClosed; + (void)task; + (void)status; - m_callbackData = Crt::New(m_allocator, this, m_allocator); + auto clearSharedTask = static_cast(arg); + + // implicit destructor does all the work + Aws::Crt::Delete(clearSharedTask, clearSharedTask->m_allocator); + } - m_continuationHandler.m_callbackData = m_callbackData; - options.user_data = reinterpret_cast(m_callbackData); + AwsEventstreamConnectionImplClearSharedTask::AwsEventstreamConnectionImplClearSharedTask( + Aws::Crt::Allocator *allocator, + ClientConnectionImpl *clientConnectionImpl) noexcept + : m_task{}, m_allocator(allocator), m_impl(clientConnectionImpl->shared_from_this()) + { + aws_task_init(&m_task, s_zeroSharedReference, this, "AwsEventstreamConnectionImplClearSharedTask"); + } - if (connection->IsOpen()) + /* + * This gets called in the following cases: + * + * (1) Synchronous failure to initiate a connection + * (2) Connection setup failure (async callback) + * (3) Connnection (that was successfully established) shutdown completion (async callback) + */ + void ClientConnectionImpl::MoveToDisconnected(RpcError error) noexcept + { + auto *clearSharedTask = + Aws::Crt::New(m_allocator, m_allocator, this); + ConnectionCallbackContext localContext = {}; { - m_continuationToken = - aws_event_stream_rpc_client_connection_new_stream(connection->m_underlyingConnection, &options); - if (m_continuationToken == nullptr) + std::lock_guard lock(m_sharedStateLock); + + aws_event_stream_rpc_client_connection_release(m_sharedState.m_underlyingConnection); + m_sharedState.m_underlyingConnection = nullptr; + m_sharedState.m_currentState = ClientState::Disconnected; + m_sharedState.m_desiredState = ClientState::Disconnected; + m_sharedState.m_callbackContext.SetError(error); + m_selfReference = nullptr; // doesn't actually drop, since the clear shared task just took a ref + + // If we've called shutdown, then no further callbacks should be done + if (!m_sharedState.m_hasShutDown) { - Crt::Delete(m_callbackData, m_allocator); - m_continuationHandler.m_callbackData = nullptr; - m_callbackData = nullptr; + localContext = std::move(m_sharedState.m_callbackContext); } + m_sharedState.m_callbackContext = {}; + m_sharedState.m_connectFlushContainer = nullptr; } + + localContext.InvokeCallbacks(); + aws_event_loop_schedule_task_now(m_eventLoop, &clearSharedTask->m_task); } - ClientContinuation::~ClientContinuation() noexcept + /* + * Common logic to kick off the process of shutting down the connection + */ + void ClientConnectionImpl::CloseInternal(bool isShutdown) noexcept { - if (m_continuationToken) - { - aws_event_stream_rpc_client_continuation_release(m_continuationToken); - m_continuationToken = nullptr; - } - if (m_callbackData != nullptr) + struct aws_event_stream_rpc_client_connection *closeConnection = nullptr; + ConnectionCallbackContext localContext = {}; + std::shared_ptr connectFlushContainer = nullptr; { + std::lock_guard lock(m_sharedStateLock); + m_sharedState.m_desiredState = ClientState::Disconnected; + m_sharedState.m_callbackContext.SetError( + {EVENT_STREAM_RPC_CONNECTION_CLOSED, AWS_ERROR_EVENT_STREAM_RPC_CONNECTION_CLOSED}); + if (isShutdown) { - const std::lock_guard lock(m_callbackData->callbackMutex); - m_callbackData->continuationDestroyed = true; + m_sharedState.m_hasShutDown = true; } - Crt::Delete(m_callbackData, m_allocator); - } - } - void ClientContinuation::s_onContinuationMessage( - struct aws_event_stream_rpc_client_continuation_token *continuationToken, - const struct aws_event_stream_rpc_message_args *messageArgs, - void *userData) noexcept - { - (void)continuationToken; - /* The `userData` pointer is used to pass a `ContinuationCallbackData` object. */ - auto *callbackData = static_cast(userData); - auto *thisContinuation = callbackData->clientContinuation; + if (m_sharedState.m_currentState == ClientState::Connected || + m_sharedState.m_currentState == ClientState::PendingConnack) + { + m_sharedState.m_currentState = ClientState::Disconnecting; + closeConnection = m_sharedState.m_underlyingConnection; + aws_event_stream_rpc_client_connection_acquire(closeConnection); + } - Crt::List continuationMessageHeaders; - for (size_t i = 0; i < messageArgs->headers_count; ++i) - { - continuationMessageHeaders.emplace_back( - EventStreamHeader(messageArgs->headers[i], thisContinuation->m_allocator)); + if (isShutdown) + { + /* + * When shutting down (ClientConnection::~ClientConnection only) we synthesize any disconnect/ + * connection-failure callbacks that might happen in the future, and ignore them when they do. + * This gives us behavioral compatibility with the old implementation (that blocked in + * destructors) while still removing the blocking logic. + */ + localContext = std::move(m_sharedState.m_callbackContext); + connectFlushContainer = m_sharedState.m_connectFlushContainer; + m_sharedState.m_connectFlushContainer = nullptr; + } } - Crt::Optional payload; + // only does something on shutdown + localContext.InvokeCallbacks(); - if (messageArgs->payload) - { - payload = Crt::Optional(*messageArgs->payload); - } - else + // only does something on shutdown + OnMessageFlushCallbackContainer::Complete( + connectFlushContainer.get(), + {EVENT_STREAM_RPC_CONNECTION_CLOSED, AWS_ERROR_EVENT_STREAM_RPC_CONNECTION_CLOSED}); + + if (closeConnection != nullptr) { - payload = Crt::Optional(); + aws_event_stream_rpc_client_connection_close( + closeConnection, AWS_ERROR_EVENT_STREAM_RPC_CONNECTION_CLOSED); + aws_event_stream_rpc_client_connection_release(closeConnection); } - - const std::lock_guard lock(callbackData->callbackMutex); - if (callbackData->continuationDestroyed) - return; - thisContinuation->m_continuationHandler.OnContinuationMessage( - continuationMessageHeaders, payload, messageArgs->message_type, messageArgs->message_flags); } - void ClientContinuation::s_onContinuationClosed( - struct aws_event_stream_rpc_client_continuation_token *continuationToken, - void *userData) noexcept + /* + * Only called by the destructor of the public-facing ClientConnection object. When this returns, no + * further callbacks will be made. + */ + void ClientConnectionImpl::Shutdown() noexcept { - (void)continuationToken; - - /* The `userData` pointer is used to pass a `ContinuationCallbackData` object. */ - auto *callbackData = static_cast(userData); - - const std::lock_guard lock(callbackData->callbackMutex); - if (callbackData->continuationDestroyed) - return; + CloseInternal(true); + } - auto *thisContinuation = callbackData->clientContinuation; - thisContinuation->m_continuationHandler.OnContinuationClosed(); + void ClientConnectionImpl::Close() noexcept + { + CloseInternal(false); } - std::future ClientContinuation::Activate( - const Crt::String &operationName, - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags, - OnMessageFlushCallback onMessageFlushCallback) noexcept + std::future ClientConnectionImpl::Connect( + const ConnectionConfig &connectionConfig, + ConnectionLifecycleHandler *connectionLifecycleHandler) noexcept { - struct aws_array_list headersArray; - OnMessageFlushCallbackContainer *callbackContainer = nullptr; - std::promise onFlushPromise; + std::promise localPromise; + std::future localFuture = localPromise.get_future(); - if (m_continuationToken == nullptr) + EventStreamRpcStatusCode status = connectionConfig.Validate(); + if (status != EVENT_STREAM_RPC_SUCCESS) { - onFlushPromise.set_value({EVENT_STREAM_RPC_CONNECTION_CLOSED, 0}); - return onFlushPromise.get_future(); + localPromise.set_value({status, AWS_ERROR_INVALID_ARGUMENT}); + return localFuture; } - if (IsClosed()) { - onFlushPromise.set_value({EVENT_STREAM_RPC_CONTINUATION_CLOSED, 0}); - return onFlushPromise.get_future(); + std::lock_guard lock(m_sharedStateLock); + if (m_sharedState.m_currentState != ClientState::Disconnected) + { + localPromise.set_value({EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED, AWS_ERROR_SUCCESS}); + return localFuture; + } + + // Optimistic state update under the lock. Nothing can alter a PendingConnect (other than a + // connection callback). + m_lifecycleHandler = connectionLifecycleHandler; + std::function disconnectCallback = [connectionLifecycleHandler](RpcError error) + { connectionLifecycleHandler->OnDisconnectCallback(error); }; + std::function errorCallback = [connectionLifecycleHandler](RpcError error) + { return connectionLifecycleHandler->OnErrorCallback(error); }; + std::function connectionSuccessCallback = [connectionLifecycleHandler]() + { connectionLifecycleHandler->OnConnectCallback(); }; + + m_connectionConfig = connectionConfig; + m_selfReference = shared_from_this(); + m_sharedState.m_desiredState = ClientState::Connected; + m_sharedState.m_currentState = ClientState::PendingConnect; + m_sharedState.m_callbackContext = { + std::move(disconnectCallback), std::move(errorCallback), std::move(connectionSuccessCallback)}; + localFuture = m_sharedState.m_callbackContext.GetConnectPromiseFuture(); + } + + Crt::Io::SocketOptions socketOptions; + if (m_connectionConfig.GetSocketOptions().has_value()) + { + socketOptions = m_connectionConfig.GetSocketOptions().value(); } - int errorCode = - EventStreamCppToNativeCrtBuilder::s_fillNativeHeadersArray(headers, &headersArray, m_allocator); + auto hostName = connectionConfig.GetHostName().value(); + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EventStreamClient - Host name %d bytes long", (int)hostName.length()); + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EventStreamClient - Host name : %s", hostName.c_str()); - /* - * Regardless of how the promise gets moved around (or not), this future should stay valid as a return - * value. - * - * We pull it out early because the call to aws_event_stream_rpc_client_continuation_activate() may complete - * and delete the promise before we pull out the future afterwords. - */ - std::future retValue = onFlushPromise.get_future(); + struct aws_event_stream_rpc_client_connection_options connectOptions; + AWS_ZERO_STRUCT(connectOptions); - if (!errorCode) - { - struct aws_event_stream_rpc_message_args msg_args; - msg_args.headers = (struct aws_event_stream_header_value_pair *)headersArray.data; - msg_args.headers_count = headers.size(); - msg_args.payload = payload.has_value() ? (aws_byte_buf *)(&(payload.value())) : nullptr; - msg_args.message_type = messageType; - msg_args.message_flags = messageFlags; + connectOptions.host_name = hostName.c_str(); + connectOptions.port = connectionConfig.GetPort().value(); + connectOptions.bootstrap = m_bootstrap; + connectOptions.socket_options = &socketOptions.GetImpl(); + connectOptions.on_connection_setup = ClientConnectionImpl::s_onConnectionSetup; + connectOptions.on_connection_protocol_message = ClientConnectionImpl::s_onProtocolMessage; + connectOptions.on_connection_shutdown = ClientConnectionImpl::s_onConnectionShutdown; - /* This heap allocation is necessary so that the flush callback can still be invoked when this function - * returns. */ - callbackContainer = Crt::New(m_allocator, m_allocator); - callbackContainer->onMessageFlushCallback = onMessageFlushCallback; - callbackContainer->onFlushPromise = std::move(onFlushPromise); + connectOptions.user_data = reinterpret_cast(this); - errorCode = aws_event_stream_rpc_client_continuation_activate( - m_continuationToken, - Crt::ByteCursorFromCString(operationName.c_str()), - &msg_args, - ClientConnection::s_protocolMessageCallback, - reinterpret_cast(callbackContainer)); + if (m_connectionConfig.GetTlsConnectionOptions().has_value()) + { + connectOptions.tls_options = m_connectionConfig.GetTlsConnectionOptions()->GetUnderlyingHandle(); } - /* Cleanup. */ - if (aws_array_list_is_valid(&headersArray)) + if (aws_event_stream_rpc_client_connection_connect(m_allocator, &connectOptions)) { - aws_array_list_clean_up(&headersArray); + // Rollback our optimistic state update + MoveToDisconnected({EVENT_STREAM_RPC_CONNECTION_SETUP_FAILED, aws_last_error()}); } - if (errorCode) + AWS_LOGF_INFO( + AWS_LS_COMMON_GENERAL, "EventStreamClient2 - Host name %d bytes long", (int)hostName.length()); + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EventStreamClient2 - Host name : %s", hostName.c_str()); + + return localFuture; + } + + bool ClientConnectionImpl::IsOpen() const noexcept + { + std::lock_guard lock(const_cast(this)->m_sharedStateLock); + return m_sharedState.m_currentState == ClientState::Connected; + } + + void ClientConnectionImpl::ConstructConnectMessage( + struct aws_event_stream_rpc_message_args *msg_args, + struct aws_array_list *headersArray) noexcept + { + MessageAmendment messageAmendment; + // The version header is necessary for establishing the connection. + messageAmendment.AddHeader(EventStreamHeader( + Crt::String(EVENTSTREAM_VERSION_HEADER), Crt::String(EVENTSTREAM_VERSION_STRING), m_allocator)); + + if (m_connectionConfig.GetConnectAmendment().has_value()) { - onFlushPromise = std::move(callbackContainer->onFlushPromise); - onFlushPromise.set_value({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); - Crt::Delete(callbackContainer, m_allocator); + MessageAmendment connectAmendment(m_connectionConfig.GetConnectAmendment().value()); + messageAmendment.PrependHeaders(std::move(connectAmendment).GetHeaders()); + messageAmendment.SetPayload(std::move(connectAmendment).GetPayload()); } - return retValue; + s_fillNativeHeadersArray(messageAmendment.GetHeaders(), headersArray, m_allocator); + + msg_args->headers = (struct aws_event_stream_header_value_pair *)headersArray->data; + msg_args->headers_count = messageAmendment.GetHeaders().size(); + msg_args->payload = messageAmendment.GetPayload().has_value() + ? (aws_byte_buf *)(&(messageAmendment.GetPayload().value())) + : nullptr; + msg_args->message_type = AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_CONNECT; + msg_args->message_flags = 0U; } - std::future ClientContinuation::SendMessage( - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags, - OnMessageFlushCallback onMessageFlushCallback) noexcept + void ClientConnectionImpl::s_onConnectionSetup( + struct aws_event_stream_rpc_client_connection *connection, + int errorCode, + void *userData) noexcept { - struct aws_array_list headersArray; - OnMessageFlushCallbackContainer *callbackContainer = nullptr; - std::promise onFlushPromise; - - if (IsClosed()) + auto *impl = static_cast(userData); + if (errorCode != AWS_ERROR_SUCCESS) { - onFlushPromise.set_value({EVENT_STREAM_RPC_CONTINUATION_CLOSED, 0}); - return onFlushPromise.get_future(); + AWS_FATAL_ASSERT(connection == nullptr); + impl->MoveToDisconnected({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); + return; } - int errorCode = - EventStreamCppToNativeCrtBuilder::s_fillNativeHeadersArray(headers, &headersArray, m_allocator); + struct aws_event_stream_rpc_client_connection *closeConnection = nullptr; + struct aws_event_stream_rpc_client_connection *connectConnection = nullptr; + OnMessageFlushCallbackContainerWrapper *connectCallbackWrapper = nullptr; - if (!errorCode) + AWS_FATAL_ASSERT(connection != nullptr); { - struct aws_event_stream_rpc_message_args msg_args; - msg_args.headers = (struct aws_event_stream_header_value_pair *)headersArray.data; - msg_args.headers_count = headers.size(); - msg_args.payload = payload.has_value() ? (aws_byte_buf *)(&(payload.value())) : nullptr; - msg_args.message_type = messageType; - msg_args.message_flags = messageFlags; + std::lock_guard lock(impl->m_sharedStateLock); + AWS_FATAL_ASSERT(impl->m_sharedState.m_currentState == ClientState::PendingConnect); + AWS_FATAL_ASSERT(impl->m_sharedState.m_connectFlushContainer == nullptr); - /* This heap allocation is necessary so that the flush callback can still be invoked when this function - * returns. */ - callbackContainer = Crt::New(m_allocator, m_allocator); - callbackContainer->onMessageFlushCallback = onMessageFlushCallback; - callbackContainer->onFlushPromise = std::move(onFlushPromise); + // the channel owns the initial ref; we have to take our own + aws_event_stream_rpc_client_connection_acquire(connection); + impl->m_sharedState.m_underlyingConnection = connection; - if (m_continuationToken) + // we also temporarily take a reference because either closeConnection or clientConnection will + // also hold a local reference outside the lock. Not truly needed in this case due to event loop + // pinning, but do it anyways as a pattern to follow. + aws_event_stream_rpc_client_connection_acquire(connection); + + if (impl->m_sharedState.m_desiredState != ClientState::Connected) + { + // Someone called Close/Shutdown during the connection process. We couldn't do anything at the + // time, but now we can. So start the close process. + AWS_FATAL_ASSERT(impl->m_sharedState.m_desiredState == ClientState::Disconnected); + impl->m_sharedState.m_currentState = ClientState::Disconnecting; + closeConnection = connection; + } + else { - errorCode = aws_event_stream_rpc_client_continuation_send_message( - m_continuationToken, - &msg_args, - ClientConnection::s_protocolMessageCallback, - reinterpret_cast(callbackContainer)); + // optimistic state update to waiting on a connack from the server + impl->m_sharedState.m_currentState = ClientState::PendingConnack; + connectConnection = connection; + + auto callback = impl->m_connectionConfig.GetConnectRequestCallback(); + connectCallbackWrapper = Aws::Crt::New( + impl->m_allocator, impl->m_allocator, std::move(callback)); + impl->m_sharedState.m_connectFlushContainer = connectCallbackWrapper->GetContainer(); } } - /* Cleanup. */ - if (aws_array_list_is_valid(&headersArray)) + if (connectConnection) { - aws_array_list_clean_up(&headersArray); - } + AWS_FATAL_ASSERT(connectCallbackWrapper); - if (errorCode) - { - onFlushPromise = std::move(callbackContainer->onFlushPromise); - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A CRT error occurred while queueing a message to be sent on a stream: %s", - Crt::ErrorDebugString(errorCode)); - onFlushPromise.set_value({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); - Crt::Delete(callbackContainer, m_allocator); - } - else - { - return callbackContainer->onFlushPromise.get_future(); - } + struct aws_event_stream_rpc_message_args msgArgs; + struct aws_array_list headersArray; - return onFlushPromise.get_future(); - } + impl->ConstructConnectMessage(&msgArgs, &headersArray); - bool ClientContinuation::IsClosed() noexcept - { - if (!m_continuationToken) - { - return true; + int connectErrorCode = AWS_ERROR_SUCCESS; + if (aws_event_stream_rpc_client_connection_send_protocol_message( + connectConnection, + &msgArgs, + s_protocolMessageCallback, + reinterpret_cast(connectCallbackWrapper))) + { + connectErrorCode = aws_last_error(); + } + + if (aws_array_list_is_valid(&headersArray)) + { + aws_array_list_clean_up(&headersArray); + } + + if (connectErrorCode != AWS_ERROR_SUCCESS) + { + // rollback our optimistic connack update since we failed to send the connect. + // We dont need to release connectConnection because we're "transferring" it to closeConnection + std::lock_guard lock(impl->m_sharedStateLock); + + impl->m_sharedState.m_callbackContext.SetError({EVENT_STREAM_RPC_CRT_ERROR, connectErrorCode}); + impl->m_sharedState.m_currentState = ClientState::Disconnecting; + closeConnection = connection; + + impl->m_sharedState.m_connectFlushContainer = nullptr; + Aws::Crt::Delete(connectCallbackWrapper, connectCallbackWrapper->GetAllocator()); + } + else + { + aws_event_stream_rpc_client_connection_release(connectConnection); + } } - else + + if (closeConnection) { - return aws_event_stream_rpc_client_continuation_is_closed(m_continuationToken); + aws_event_stream_rpc_client_connection_close( + closeConnection, AWS_ERROR_EVENT_STREAM_RPC_CONNECTION_CLOSED); + aws_event_stream_rpc_client_connection_release(closeConnection); } } - OperationModelContext::OperationModelContext(const ServiceModel &serviceModel) noexcept - : m_serviceModel(serviceModel) + void ClientConnectionImpl::s_onConnectionShutdown( + struct aws_event_stream_rpc_client_connection *connection, + int errorCode, + void *userData) noexcept { - } + (void)connection; + auto *impl = static_cast(userData); - void OperationError::SerializeToJsonObject(Crt::JsonObject &payloadObject) const - { - (void)payloadObject; + impl->MoveToDisconnected({EVENT_STREAM_RPC_CONNECTION_CLOSED, errorCode}); } - AbstractShapeBase::AbstractShapeBase() noexcept : m_allocator(nullptr) {} - - ClientOperation::ClientOperation( - ClientConnection &connection, - std::shared_ptr streamHandler, - const OperationModelContext &operationModelContext, - Crt::Allocator *allocator) noexcept - : m_operationModelContext(operationModelContext), m_asyncLaunchMode(std::launch::deferred), - m_messageCount(0), m_allocator(allocator), m_streamHandler(streamHandler), - m_clientContinuation(connection.NewStream(*this)), m_expectedCloses(0), m_streamClosedCalled(false) + void ClientConnectionImpl::s_onProtocolMessage( + struct aws_event_stream_rpc_client_connection *connection, + const struct aws_event_stream_rpc_message_args *messageArgs, + void *userData) noexcept { - } + AWS_PRECONDITION(messageArgs != nullptr); + (void)connection; - ClientOperation::~ClientOperation() noexcept + struct aws_event_stream_rpc_client_connection *closeConnection = nullptr; + auto *impl = static_cast(userData); + switch (messageArgs->message_type) + { + case AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_CONNECT_ACK: + { + ConnectionCallbackContext localCallbackContext = {}; + bool successfulAck = + (messageArgs->message_flags & AWS_EVENT_STREAM_RPC_MESSAGE_FLAG_CONNECTION_ACCEPTED) != 0; + { + std::lock_guard lock(impl->m_sharedStateLock); + if (impl->m_sharedState.m_currentState != ClientState::PendingConnack || !successfulAck) + { + // triggered if closed/shutdown or failed the handshake + if (!impl->m_sharedState.m_hasShutDown) + { + impl->m_sharedState.m_callbackContext.SetError(RpcError{ + successfulAck ? EVENT_STREAM_RPC_CONNECTION_CLOSED + : EVENT_STREAM_RPC_CONNECTION_ACCESS_DENIED, + 0}); + } + impl->m_sharedState.m_desiredState = ClientState::Disconnected; + if (impl->m_sharedState.m_currentState != ClientState::Disconnecting) + { + impl->m_sharedState.m_currentState = ClientState::Disconnecting; + closeConnection = connection; + aws_event_stream_rpc_client_connection_acquire(closeConnection); + } + } + else + { + // everything's good; transition into the connected state + impl->m_sharedState.m_currentState = ClientState::Connected; + localCallbackContext = impl->m_sharedState.m_callbackContext.TransitionToConnected(); + } + } + localCallbackContext.InvokeCallbacks(); + + if (closeConnection) + { + aws_event_stream_rpc_client_connection_close( + closeConnection, AWS_ERROR_EVENT_STREAM_RPC_CONNECTION_CLOSED); + aws_event_stream_rpc_client_connection_release(closeConnection); + } + break; + } + + case AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_PING: + { + Crt::List pingHeaders; + for (size_t i = 0; i < messageArgs->headers_count; ++i) + { + pingHeaders.emplace_back(EventStreamHeader(messageArgs->headers[i], impl->m_allocator)); + } + + if (messageArgs->payload) + { + impl->m_lifecycleHandler->OnPingCallback(pingHeaders, *messageArgs->payload); + } + else + { + impl->m_lifecycleHandler->OnPingCallback(pingHeaders, Crt::Optional()); + } + + break; + } + + case AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_PING_RESPONSE: + break; + + default: + impl->m_lifecycleHandler->OnErrorCallback( + {EVENT_STREAM_RPC_CRT_ERROR, AWS_ERROR_EVENT_STREAM_RPC_PROTOCOL_ERROR}); + impl->Close(); + break; + } + } + + ClientConnection::ClientConnection(Crt::Allocator *allocator, aws_client_bootstrap *bootstrap) noexcept + : m_impl(Aws::Crt::MakeShared(allocator, allocator, bootstrap)) + { + } + + ClientConnection::~ClientConnection() noexcept + { + m_impl->Shutdown(); + m_impl = nullptr; + } + + std::future ClientConnection::Connect( + const ConnectionConfig &connectionOptions, + ConnectionLifecycleHandler *connectionLifecycleHandler) noexcept + { + return m_impl->Connect(connectionOptions, connectionLifecycleHandler); + } + + std::shared_ptr ClientConnection::NewStream() noexcept + { + return m_impl->NewStream(); + } + + void ClientConnection::Close() noexcept + { + m_impl->Close(); + } + + bool ClientConnection::IsOpen() const noexcept + { + return m_impl->IsOpen(); + } + + OperationModelContext::OperationModelContext(const ServiceModel &serviceModel) noexcept + : m_serviceModel(serviceModel) + { + } + + void OperationError::SerializeToJsonObject(Crt::JsonObject &payloadObject) const + { + (void)payloadObject; + } + + void OperationError::s_customDeleter(OperationError *shape) noexcept + { + AbstractShapeBase::s_customDeleter(shape); + } + + AbstractShapeBase::AbstractShapeBase() noexcept : m_allocator(nullptr) {} + + void AbstractShapeBase::s_customDeleter(AbstractShapeBase *shape) noexcept { - Close().wait(); - std::unique_lock lock(m_continuationMutex); - m_closeReady.wait(lock, [this] { return m_expectedCloses.load() == 0; }); + if (shape->m_allocator != nullptr) + { + Crt::Delete(shape, shape->m_allocator); + } } TaggedResult::TaggedResult(Crt::ScopedResource operationResponse) noexcept - : m_responseType(OPERATION_RESPONSE) + : m_responseType(OPERATION_RESPONSE), m_rpcError({}) { m_operationResult.m_response = std::move(operationResponse); } @@ -1260,329 +1388,651 @@ namespace Aws } } - std::future ClientOperation::GetOperationResult() noexcept + bool StreamResponseHandler::OnStreamError(Crt::ScopedResource operationError, RpcError rpcError) { - { - const std::lock_guard lock(m_continuationMutex); - - if (m_clientContinuation.IsClosed() && !m_resultReceived) - { - AWS_LOGF_ERROR(AWS_LS_EVENT_STREAM_RPC_CLIENT, "The underlying stream is already closed."); - m_initialResponsePromise.set_value(TaggedResult({EVENT_STREAM_RPC_CONNECTION_CLOSED, 0})); - m_resultReceived = true; - } - } + (void)operationError; + (void)rpcError; + /* Note: Always returning true implies that the stream should close + * as a result of encountering this error. */ + return true; + } - return m_initialResponsePromise.get_future(); + void StreamResponseHandler::OnStreamEvent(Crt::ScopedResource response) + { + (void)response; } - const EventStreamHeader *ClientOperation::GetHeaderByName( + void StreamResponseHandler::OnStreamClosed() {} + + static const EventStreamHeader *s_GetHeaderByName( const Crt::List &headers, const Crt::String &name) noexcept { - for (auto it = headers.begin(); it != headers.end(); ++it) + for (const auto &header : headers) { - if (name == it->GetHeaderName()) + if (name == header.GetHeaderName()) { - return &(*it); + return &header; } } return nullptr; } - EventStreamRpcStatusCode ClientOperation::HandleData(const Crt::Optional &payload) + // Depending on the current state of the continuation, each inbound message falls into one of three types + enum class EventStreamMessageRoutingType { - Crt::StringView payloadStringView; - if (payload.has_value()) - { - payloadStringView = Crt::ByteCursorToStringView(Crt::ByteCursorFromByteBuf(payload.value())); - } + // The inbound message should be turned into a modeled response for an Activate request + Response, - /* The value of this hashmap contains the function that allocates the response object from the - * payload. */ - /* Responses after the first message don't necessarily have the same shape as the first. */ - Crt::ScopedResource response; - if (m_messageCount == 1) - { - response = m_operationModelContext.AllocateInitialResponseFromPayload(payloadStringView, m_allocator); - } - else - { - response = m_operationModelContext.AllocateStreamingResponseFromPayload(payloadStringView, m_allocator); - } + // The inbound message should be turned into a modeled streaming event + Stream, - if (response.get() == nullptr) - { - AWS_LOGF_ERROR(AWS_LS_EVENT_STREAM_RPC_CLIENT, "Failed to allocate a response from the payload."); - return EVENT_STREAM_RPC_ALLOCATION_ERROR; - } + // The inbound message should be turned into a modeled error for an Activate request + Error + }; - if (m_messageCount == 1) - { - const std::lock_guard lock(m_continuationMutex); - m_resultReceived = true; - m_initialResponsePromise.set_value(TaggedResult(std::move(response))); - } - else + struct MessageDeserialization + { + MessageDeserialization() : m_route(EventStreamMessageRoutingType::Error) {} + + MessageDeserialization(EventStreamMessageRoutingType route, Crt::ScopedResource shape) + : m_route(route), m_shape(std::move(shape)) { - if (m_streamHandler) - m_streamHandler->OnStreamEvent(std::move(response)); } - return EVENT_STREAM_RPC_SUCCESS; + MessageDeserialization(MessageDeserialization &&) = default; + + MessageDeserialization &operator=(MessageDeserialization &&) = default; + + EventStreamMessageRoutingType m_route; + Crt::ScopedResource m_shape; + }; + + struct MessageResult + { + MessageResult() : m_statusCode(EVENT_STREAM_RPC_SUCCESS) {} + + MessageResult(MessageResult &&) = default; + + MessageResult &operator=(MessageResult &&) = default; + + EventStreamRpcStatusCode m_statusCode; + Crt::Optional m_message; + }; + + // One-way, sequential state sequence for continuations + enum class ContinuationStateType + { + // Continuation has been created, but Activate has not been called yet + None, + + // The continuation is in the process of being activated + PendingActivate, + + // The continuation has been successfully activated + Activated, + + // The continuation is closing + PendingClose, + + // The continuation is closed + Closed, + }; + + struct ContinuationSharedState + { + ContinuationSharedState(); + + ContinuationStateType m_currentState; + ContinuationStateType m_desiredState; + struct aws_event_stream_rpc_client_continuation_token *m_continuation; + std::shared_ptr m_activationCallbackContainer; + std::function m_activationResponseCallback; + std::shared_ptr m_closeCallbackContainer; + }; + + ContinuationSharedState::ContinuationSharedState() + : m_currentState(ContinuationStateType::None), m_desiredState(ContinuationStateType::None), + m_continuation(nullptr), m_activationCallbackContainer(nullptr), m_activationResponseCallback(), + m_closeCallbackContainer(nullptr) + { } - EventStreamRpcStatusCode ClientOperation::HandleError( - const Crt::String &modelName, - const Crt::Optional &payload, - uint32_t messageFlags) + class ClientContinuationImpl : public std::enable_shared_from_this { - bool streamAlreadyTerminated = (messageFlags & AWS_EVENT_STREAM_RPC_MESSAGE_FLAG_TERMINATE_STREAM) != 0; + public: + ClientContinuationImpl( + Aws::Crt::Allocator *allocator, + struct aws_client_bootstrap *bootstrap, + struct aws_event_stream_rpc_client_connection *connection) noexcept; + virtual ~ClientContinuationImpl(); - Crt::StringView payloadStringView; - if (payload.has_value()) - { - payloadStringView = Crt::ByteCursorToStringView(Crt::ByteCursorFromByteBuf(payload.value())); - } + // Only called by ClientContinuation::~ClientContinuation + void ShutDown() noexcept; - /* The value of this hashmap contains the function that allocates the error from the - * payload. */ - Crt::ScopedResource error = - m_operationModelContext.AllocateOperationErrorFromPayload(modelName, payloadStringView, m_allocator); - if (error.get() == nullptr) - return EVENT_STREAM_RPC_UNMAPPED_DATA; - if (error->GetMessage().has_value()) - { - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "An error was received from the server: %s", - error->GetMessage().value().c_str()); - } - TaggedResult taggedResult(std::move(error)); - if (m_messageCount == 1) + std::future Activate( + const Crt::String &operation, + const Crt::List &headers, + const Crt::Optional &payload, + MessageType messageType, + uint32_t messageFlags, + std::function &&onResultCallback, + OnMessageFlushCallback &&onMessageFlushCallback) noexcept; + + std::future SendStreamMessage( + const Crt::List &headers, + const Crt::Optional &payload, + MessageType messageType, + uint32_t messageFlags, + OnMessageFlushCallback &&onMessageFlushCallback); + + std::future Close(OnMessageFlushCallback &&onMessageFlushCallback = nullptr) noexcept; + + Crt::String GetModelName() const noexcept; + + void Initialize( + const std::shared_ptr &operationModelContext, + std::shared_ptr streamHandler) noexcept { + m_operationModelContext = operationModelContext; + m_streamHandler = std::move(streamHandler); + if (m_sharedState.m_continuation != nullptr) { - const std::lock_guard lock(m_continuationMutex); - m_resultReceived = true; - m_initialResponsePromise.set_value(std::move(taggedResult)); - } - /* Close the stream unless the server already closed it for us. This condition is checked - * so that TERMINATE_STREAM messages aren't resent by the client. */ - if (!streamAlreadyTerminated && !m_clientContinuation.IsClosed()) - { - Close().wait(); + m_selfReference = shared_from_this(); } } - else + + private: + MessageResult DeserializeRawMessage( + const struct aws_event_stream_rpc_message_args *rawMessage, + bool shouldBeActivationResponse) noexcept; + + void OnClosed() noexcept; + + void OnMessage(const struct aws_event_stream_rpc_message_args *messageArgs) noexcept; + + EventStreamRpcStatusCode GetEmptyContinuationStatusCode() const; + + static void s_OnContinuationClosed( + struct aws_event_stream_rpc_client_continuation_token *token, + void *user_data) noexcept; + + static void s_OnContinuationMessage( + struct aws_event_stream_rpc_client_continuation_token *token, + const struct aws_event_stream_rpc_message_args *message_args, + void *user_data) noexcept; + + static void s_OnContinuationTerminated(void *user_data) noexcept; + + static void ReleaseContinuation( + Aws::Crt::Allocator *allocator, + const struct aws_client_bootstrap *bootstrap, + struct aws_event_stream_rpc_client_continuation_token *continuation) noexcept; + + Aws::Crt::Allocator *m_allocator; + + struct aws_client_bootstrap *m_clientBootstrap; + struct aws_event_loop *m_connectionEventLoop; + + std::shared_ptr m_selfReference; + + std::mutex m_sharedStateLock; + ContinuationSharedState m_sharedState; + + std::shared_ptr m_operationModelContext; + + /* + * A small exception to our "never hold a lock while making callbacks" rule. + * + * The handler lock is "one-way"; it is held while invoking callbacks on the stream handler. We also + * conditionally hold it while zeroing the handler on shutdown. Because we do not need the lock for + * user-facing functions outside ShutDown, deadlock is not a risk. + * + * THis allows us to guarantee that streaming events/errors are not emitted after ShutDown is called, + * even while asynchronous C shutdown is in-progress. + */ + std::mutex m_streamHandlerLock; + std::shared_ptr m_streamHandler; + + /* + * An unfortunate bit of state needed to differentiate between two cases: + * (1) Failure to create the original continuation for any reason + * (2) A fully-closed continuation + * + * We want to differentiate these cases in order to communicate clear error codes when attempting + * to operate on the continuation. + * + * This is always true in case (2) and false in case (1) + */ + bool m_continuationValid; + }; + + ClientContinuationImpl::ClientContinuationImpl( + Aws::Crt::Allocator *allocator, + struct aws_client_bootstrap *bootstrap, + struct aws_event_stream_rpc_client_connection *connection) noexcept + : m_allocator(allocator), m_clientBootstrap(aws_client_bootstrap_acquire(bootstrap)), + m_connectionEventLoop(aws_event_stream_rpc_client_connection_get_event_loop(connection)), m_sharedState(), + m_operationModelContext(nullptr), m_continuationValid(true) + { + if (connection != nullptr) { - bool shouldCloseNow = true; - if (m_streamHandler) - shouldCloseNow = m_streamHandler->OnStreamError(std::move(error), {EVENT_STREAM_RPC_SUCCESS, 0}); - if (!streamAlreadyTerminated && shouldCloseNow && !m_clientContinuation.IsClosed()) - { - Close().wait(); - } + struct aws_event_stream_rpc_client_stream_continuation_options continuation_options; + AWS_ZERO_STRUCT(continuation_options); + continuation_options.on_continuation = s_OnContinuationMessage; + continuation_options.on_continuation_closed = s_OnContinuationClosed; + continuation_options.on_continuation_terminated = s_OnContinuationTerminated; + continuation_options.user_data = this; + + m_sharedState.m_continuation = + aws_event_stream_rpc_client_connection_new_stream(connection, &continuation_options); } - return EVENT_STREAM_RPC_SUCCESS; + if (!m_sharedState.m_continuation) + { + m_continuationValid = false; + m_sharedState.m_currentState = ContinuationStateType::Closed; + m_sharedState.m_desiredState = ContinuationStateType::Closed; + } } - bool StreamResponseHandler::OnStreamError(Crt::ScopedResource operationError, RpcError rpcError) + ClientContinuationImpl::~ClientContinuationImpl() { - (void)operationError; - (void)rpcError; - /* Note: Always returning true implies that the stream should close - * as a result of encountering this error. */ - return true; + aws_client_bootstrap_release(m_clientBootstrap); } - void StreamResponseHandler::OnStreamEvent(Crt::ScopedResource response) {} + // We use a task to release the C continuation to make it impossible to trigger the termination callback + // in a callstack that includes ClientContinationImpl methods or state. + // + // If we were the last ref holder then release would trigger the termination callback further down the + // callstack. This isn't necessarily unsafe, but for peace-of-mind, it's best for destruction to never + // get invoked on an object that has methods within the callstack. + struct AwsEventstreamContinuationReleaseTask + { + AwsEventstreamContinuationReleaseTask( + Aws::Crt::Allocator *allocator, + struct aws_event_stream_rpc_client_continuation_token *continuation) noexcept; - void StreamResponseHandler::OnStreamClosed() {} + struct aws_task m_task; + struct aws_allocator *m_allocator; + struct aws_event_stream_rpc_client_continuation_token *m_continuation; + }; - void ClientOperation::OnContinuationMessage( - const Crt::List &headers, - const Crt::Optional &payload, - MessageType messageType, - uint32_t messageFlags) + static void s_releaseContinuation(struct aws_task *task, void *arg, enum aws_task_status status) { - EventStreamRpcStatusCode errorCode = EVENT_STREAM_RPC_SUCCESS; - const EventStreamHeader *modelHeader = nullptr; - const EventStreamHeader *contentHeader = nullptr; - Crt::String modelName; + (void)task; + (void)status; - if (messageFlags & AWS_EVENT_STREAM_RPC_MESSAGE_FLAG_TERMINATE_STREAM) - { - const std::lock_guard lock(m_continuationMutex); - m_expectedCloses.fetch_add(1); - } + auto releaseTask = static_cast(arg); - m_messageCount += 1; + aws_event_stream_rpc_client_continuation_release(releaseTask->m_continuation); - modelHeader = GetHeaderByName(headers, Crt::String(SERVICE_MODEL_TYPE_HEADER)); - if (modelHeader == nullptr) + Aws::Crt::Delete(releaseTask, releaseTask->m_allocator); + } + + AwsEventstreamContinuationReleaseTask::AwsEventstreamContinuationReleaseTask( + Aws::Crt::Allocator *allocator, + struct aws_event_stream_rpc_client_continuation_token *continuation) noexcept + : m_task{}, m_allocator(allocator), m_continuation(continuation) + { + aws_task_init(&m_task, s_releaseContinuation, this, "AwsEventstreamContinuationReleaseTask"); + } + + void ClientContinuationImpl::ReleaseContinuation( + Aws::Crt::Allocator *allocator, + const struct aws_client_bootstrap *bootstrap, + struct aws_event_stream_rpc_client_continuation_token *continuation) noexcept + { + if (continuation == nullptr) { - /* Missing required service model type header. */ - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A required header (%s) could not be found in the message.", - SERVICE_MODEL_TYPE_HEADER); - errorCode = EVENT_STREAM_RPC_UNMAPPED_DATA; + return; } - /* Verify that the model name matches. */ - if (!errorCode) + AWS_FATAL_ASSERT(bootstrap != NULL); + + // We use the bootstrap rather than the connection's event loop because we might not have a connection + struct aws_event_loop *event_loop = aws_event_loop_group_get_next_loop(bootstrap->event_loop_group); + AWS_FATAL_ASSERT(event_loop != NULL); + + auto releaseTask = Aws::Crt::New(allocator, allocator, continuation); + aws_event_loop_schedule_task_now(event_loop, &releaseTask->m_task); + } + + void ClientContinuationImpl::ShutDown() noexcept + { + struct aws_event_stream_rpc_client_continuation_token *releaseContinuation = nullptr; + std::shared_ptr closeCallbackContainer = nullptr; + std::shared_ptr activationCallbackContainer = nullptr; + std::function activationResponseCallback = nullptr; + + // This block prevents streaming event callbacks from triggering after scope exit { - modelHeader->GetValueAsString(modelName); - if (messageType == AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_APPLICATION_MESSAGE) + if (m_connectionEventLoop != nullptr) { - if (m_messageCount == 1 && m_operationModelContext.GetInitialResponseModelName() != modelName) + // If we're on the connection's event loop thread then we risk deadlock by trying to use + // the handler lock. But in that case, it's safe not to use it, because we only use the lock from + // the event loop (or the single call to ShutDown) + bool useHandlerLock = !aws_event_loop_thread_is_callers_thread(m_connectionEventLoop); + if (useHandlerLock) { - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "The model name of the initial response did not match its expected model name."); - errorCode = EVENT_STREAM_RPC_UNMAPPED_DATA; + m_streamHandlerLock.lock(); } - else if ( - m_messageCount > 1 && m_operationModelContext.GetStreamingResponseModelName().has_value() && - m_operationModelContext.GetStreamingResponseModelName().value() != modelName) + + m_streamHandler = nullptr; + + if (useHandlerLock) { - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "The model name of a subsequent response did not match its expected model name."); - errorCode = EVENT_STREAM_RPC_UNMAPPED_DATA; + m_streamHandlerLock.unlock(); } } } - if (!errorCode) { - Crt::String contentType; - contentHeader = GetHeaderByName(headers, Crt::String(CONTENT_TYPE_HEADER)); - if (contentHeader == nullptr) + // update state and gather up all the callbacks we need to synthesize + std::lock_guard lock(m_sharedStateLock); + if (m_sharedState.m_currentState == ContinuationStateType::None) { - /* Missing required content type header. */ - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A required header (%s) could not be found in the message.", - CONTENT_TYPE_HEADER); - errorCode = EVENT_STREAM_RPC_UNSUPPORTED_CONTENT_TYPE; - } - else if (contentHeader->GetValueAsString(contentType) && contentType != CONTENT_TYPE_APPLICATION_JSON) - { - /* Missing required content type header. */ - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "The content type (%s) header was specified with an unsupported value (%s).", - CONTENT_TYPE_HEADER, - contentType.c_str()); - errorCode = EVENT_STREAM_RPC_UNSUPPORTED_CONTENT_TYPE; + releaseContinuation = m_sharedState.m_continuation; + m_sharedState.m_continuation = nullptr; + m_sharedState.m_currentState = ContinuationStateType::Closed; + m_sharedState.m_desiredState = ContinuationStateType::Closed; } + + activationCallbackContainer = m_sharedState.m_activationCallbackContainer; + m_sharedState.m_activationCallbackContainer = nullptr; + + closeCallbackContainer = m_sharedState.m_closeCallbackContainer; + m_sharedState.m_closeCallbackContainer = nullptr; + + activationResponseCallback = std::move(m_sharedState.m_activationResponseCallback); + m_sharedState.m_activationResponseCallback = nullptr; } - if (!errorCode) + // synthesize callbacks + + if (activationResponseCallback) { - if (messageType == AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_APPLICATION_MESSAGE) - { - errorCode = HandleData(payload); - } - else - { - errorCode = HandleError(modelName, payload, messageFlags); - } + activationResponseCallback( + TaggedResult(RpcError{EVENT_STREAM_RPC_CONTINUATION_CLOSED, AWS_ERROR_SUCCESS})); } - if (errorCode) + // Short-circuit and simulate both activate and close callbacks as necessary. + OnMessageFlushCallbackContainer::Complete( + activationCallbackContainer.get(), {EVENT_STREAM_RPC_CONTINUATION_CLOSED, AWS_ERROR_SUCCESS}); + + OnMessageFlushCallbackContainer::Complete( + closeCallbackContainer.get(), {EVENT_STREAM_RPC_CONTINUATION_CLOSED, AWS_ERROR_SUCCESS}); + + if (releaseContinuation != nullptr) { - if (m_messageCount == 1) - { - const std::lock_guard lock(m_continuationMutex); - m_resultReceived = true; - RpcError promiseValue = {(EventStreamRpcStatusCode)errorCode, 0}; - m_initialResponsePromise.set_value(TaggedResult(promiseValue)); - } - else - { - bool shouldClose = true; - if (m_streamHandler) - shouldClose = m_streamHandler->OnStreamError(nullptr, {errorCode, 0}); - if (!m_clientContinuation.IsClosed() && shouldClose) - { - Close().wait(); - } - } + // An unactivated continuation should be released directly + ReleaseContinuation(m_allocator, m_clientBootstrap, releaseContinuation); + } + else + { + // A continuation that has at least started the activation process should be closed first + Close(); } } - std::future ClientOperation::Activate( - const AbstractShapeBase *shape, - OnMessageFlushCallback onMessageFlushCallback) noexcept + EventStreamRpcStatusCode ClientContinuationImpl::GetEmptyContinuationStatusCode() const { - /* Promises must be reset in case the client would like to send a subsequent request with the same - * `ClientOperation`. */ - m_initialResponsePromise = {}; + if (m_continuationValid) { - const std::lock_guard lock(m_continuationMutex); - m_resultReceived = false; + return EVENT_STREAM_RPC_CONTINUATION_CLOSED; } - Crt::List headers; - headers.emplace_back(EventStreamHeader( - Crt::String(CONTENT_TYPE_HEADER), Crt::String(CONTENT_TYPE_APPLICATION_JSON), m_allocator)); - headers.emplace_back( - EventStreamHeader(Crt::String(SERVICE_MODEL_TYPE_HEADER), GetModelName(), m_allocator)); - Crt::JsonObject payloadObject; - shape->SerializeToJsonObject(payloadObject); - Crt::String payloadString = payloadObject.View().WriteCompact(); - return m_clientContinuation.Activate( - GetModelName(), - headers, - Crt::ByteBufFromCString(payloadString.c_str()), - AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_APPLICATION_MESSAGE, - 0, - onMessageFlushCallback); + return EVENT_STREAM_RPC_CONNECTION_CLOSED; } - void ClientOperation::OnContinuationClosed() + std::future ClientContinuationImpl::Activate( + const Crt::String &operation, + const Crt::List &headers, + const Crt::Optional &payload, + MessageType messageType, + uint32_t messageFlags, + std::function &&onResultCallback, + OnMessageFlushCallback &&onMessageFlushCallback) noexcept { - const std::lock_guard lock(m_continuationMutex); - if (!m_resultReceived) + AWS_FATAL_ASSERT(static_cast(onResultCallback)); + + int result = AWS_OP_ERR; + std::promise activationPromise; + std::future activationFuture = activationPromise.get_future(); + auto activationContainerWrapper = Crt::New( + m_allocator, m_allocator, std::move(onMessageFlushCallback), std::move(activationPromise)); + RpcError activationError = {}; + struct aws_event_stream_rpc_client_continuation_token *activateContinuation = nullptr; + { - m_initialResponsePromise.set_value(TaggedResult({EVENT_STREAM_RPC_CONTINUATION_CLOSED, 0})); - m_resultReceived = true; + std::lock_guard lock(m_sharedStateLock); + if (m_sharedState.m_continuation != nullptr) + { + if (m_sharedState.m_currentState == ContinuationStateType::None) + { + // optimistically update shared state to pending activate + activateContinuation = m_sharedState.m_continuation; + aws_event_stream_rpc_client_continuation_acquire(activateContinuation); + m_sharedState.m_currentState = ContinuationStateType::PendingActivate; + m_sharedState.m_desiredState = ContinuationStateType::Activated; + m_sharedState.m_activationCallbackContainer = activationContainerWrapper->GetContainer(); + m_sharedState.m_activationResponseCallback = std::move(onResultCallback); + } + else + { + // we're not in a state we can activate + switch (m_sharedState.m_currentState) + { + case ContinuationStateType::PendingActivate: + case ContinuationStateType::Activated: + // simulate what would be returned if we invoked the C API + activationError = {EVENT_STREAM_RPC_CRT_ERROR, AWS_ERROR_INVALID_STATE}; + break; + + case ContinuationStateType::PendingClose: + case ContinuationStateType::Closed: + activationError = {GetEmptyContinuationStatusCode(), 0}; + break; + + default: + AWS_FATAL_ASSERT(false); + break; + } + } + } + else + { + activationError = {GetEmptyContinuationStatusCode(), 0}; + } } - if (m_expectedCloses.load() > 0) + if (activateContinuation) { - m_expectedCloses.fetch_sub(1); - if (!m_streamClosedCalled.load() && m_streamHandler) + struct aws_array_list + headersArray; // guaranteed to be zeroed or valid if we reach the end of the function + + // cleanup requirements mean we can't early out from here on + s_fillNativeHeadersArray(headers, &headersArray, m_allocator); + + struct aws_event_stream_rpc_message_args msg_args; + msg_args.headers = static_cast(headersArray.data); + msg_args.headers_count = headers.size(); + msg_args.payload = payload.has_value() ? (aws_byte_buf *)(&(payload.value())) : nullptr; + msg_args.message_type = messageType; + msg_args.message_flags = messageFlags; + + result = aws_event_stream_rpc_client_continuation_activate( + activateContinuation, + Crt::ByteCursorFromCString(operation.c_str()), + &msg_args, + s_protocolMessageCallback, + reinterpret_cast(activationContainerWrapper)); + + if (result != AWS_OP_SUCCESS) { - m_streamHandler->OnStreamClosed(); - m_streamClosedCalled.store(true); + // ah shucks, we failed, rollback our optimistic shared state update + std::lock_guard lock(m_sharedStateLock); + m_sharedState.m_currentState = ContinuationStateType::None; + m_sharedState.m_desiredState = ContinuationStateType::None; + m_sharedState.m_activationCallbackContainer = nullptr; + m_sharedState.m_activationResponseCallback = nullptr; + + activationError = {EVENT_STREAM_RPC_CRT_ERROR, aws_last_error()}; } - m_closeReady.notify_one(); + + if (aws_array_list_is_valid(&headersArray)) + { + aws_array_list_clean_up(&headersArray); + } + + aws_event_stream_rpc_client_continuation_release(activateContinuation); } + + if (result != AWS_OP_SUCCESS) + { + AWS_FATAL_ASSERT(activationContainerWrapper != nullptr); + + OnMessageFlushCallbackContainerWrapper::Complete(activationContainerWrapper, activationError); + Aws::Crt::Delete(activationContainerWrapper, activationContainerWrapper->GetAllocator()); + } + + return activationFuture; } - void ClientOperation::WithLaunchMode(std::launch mode) noexcept - { - m_asyncLaunchMode = mode; + std::future ClientContinuationImpl::SendStreamMessage( + const Crt::List &headers, + const Crt::Optional &payload, + MessageType messageType, + uint32_t messageFlags, + OnMessageFlushCallback &&onMessageFlushCallback) + { + int result = AWS_OP_ERR; + std::promise sendPromise; + std::future sendFuture = sendPromise.get_future(); + auto sendContainerWrapper = Crt::New( + m_allocator, m_allocator, std::move(onMessageFlushCallback), std::move(sendPromise)); + RpcError sendError = {}; + struct aws_event_stream_rpc_client_continuation_token *sendContinuation = nullptr; + { + std::lock_guard lock(m_sharedStateLock); + if (m_sharedState.m_continuation != nullptr) + { + if (m_sharedState.m_currentState == ContinuationStateType::Activated) + { + // it's safe to send a stream message + sendContinuation = m_sharedState.m_continuation; + aws_event_stream_rpc_client_continuation_acquire(sendContinuation); + } + else + { + // we're not in a state to send a stream message + switch (m_sharedState.m_currentState) + { + case ContinuationStateType::PendingActivate: + case ContinuationStateType::None: + sendError = {EVENT_STREAM_RPC_CONTINUATION_NOT_YET_OPENED, 0}; + break; + + case ContinuationStateType::PendingClose: + case ContinuationStateType::Closed: + sendError = {EVENT_STREAM_RPC_CONTINUATION_CLOSED, 0}; + break; + + default: + AWS_FATAL_ASSERT(false); + break; + } + } + } + else + { + sendError = {GetEmptyContinuationStatusCode(), 0}; + } + } + + if (sendContinuation) + { + struct aws_array_list headersArray; + s_fillNativeHeadersArray(headers, &headersArray, m_allocator); + + struct aws_event_stream_rpc_message_args msg_args; + msg_args.headers = static_cast(headersArray.data); + msg_args.headers_count = headers.size(); + msg_args.payload = payload.has_value() ? (aws_byte_buf *)(&(payload.value())) : nullptr; + msg_args.message_type = messageType; + msg_args.message_flags = messageFlags; + + result = aws_event_stream_rpc_client_continuation_send_message( + sendContinuation, + &msg_args, + s_protocolMessageCallback, + reinterpret_cast(sendContainerWrapper)); + + if (result != AWS_OP_SUCCESS) + { + sendError = {EVENT_STREAM_RPC_CRT_ERROR, aws_last_error()}; + } + + if (aws_array_list_is_valid(&headersArray)) + { + aws_array_list_clean_up(&headersArray); + } + + aws_event_stream_rpc_client_continuation_release(sendContinuation); + } + + if (result == AWS_OP_ERR) + { + OnMessageFlushCallbackContainerWrapper::Complete(sendContainerWrapper, sendError); + Aws::Crt::Delete(sendContainerWrapper, sendContainerWrapper->GetAllocator()); + } + + return sendFuture; } - std::future ClientOperation::Close(OnMessageFlushCallback onMessageFlushCallback) noexcept + std::future ClientContinuationImpl::Close(OnMessageFlushCallback &&onMessageFlushCallback) noexcept { - const std::lock_guard lock(m_continuationMutex); - if (m_expectedCloses.load() > 0 || m_clientContinuation.IsClosed()) + int closeResult = AWS_OP_ERR; + std::promise closePromise; + std::future closeFuture = closePromise.get_future(); + auto closeCallbackContainerWrapper = Crt::New( + m_allocator, m_allocator, std::move(onMessageFlushCallback), std::move(closePromise)); + RpcError closeError = {}; + struct aws_event_stream_rpc_client_continuation_token *closeContinuation = nullptr; + + // needed to correctly roll back on failure to send the end-stream message + ContinuationStateType previousState = ContinuationStateType::PendingClose; + { - std::promise errorPromise; - errorPromise.set_value({EVENT_STREAM_RPC_CONTINUATION_CLOSED, 0}); - return errorPromise.get_future(); + std::lock_guard lock(m_sharedStateLock); + previousState = m_sharedState.m_currentState; + + if (m_sharedState.m_continuation != nullptr) + { + if (m_sharedState.m_currentState == ContinuationStateType::PendingActivate || + m_sharedState.m_currentState == ContinuationStateType::Activated) + { + m_sharedState.m_currentState = ContinuationStateType::PendingClose; + + closeContinuation = m_sharedState.m_continuation; + aws_event_stream_rpc_client_continuation_acquire(closeContinuation); + + m_sharedState.m_closeCallbackContainer = closeCallbackContainerWrapper->GetContainer(); + } + else + { + // not in a valid state to close + closeError = {EVENT_STREAM_RPC_CONTINUATION_CLOSED, 0}; + } + } + else + { + closeError = {GetEmptyContinuationStatusCode(), 0}; + } } - else - { - std::promise onTerminatePromise; - int errorCode = AWS_OP_ERR; + if (closeContinuation) + { struct aws_event_stream_rpc_message_args msg_args; msg_args.headers = nullptr; msg_args.headers_count = 0; @@ -1590,47 +2040,426 @@ namespace Aws msg_args.message_type = AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_APPLICATION_MESSAGE; msg_args.message_flags = AWS_EVENT_STREAM_RPC_MESSAGE_FLAG_TERMINATE_STREAM; - /* This heap allocation is necessary so that the flush callback can still be invoked when this function - * returns. */ - OnMessageFlushCallbackContainer *callbackContainer = - Crt::New(m_allocator, m_allocator); - callbackContainer->onMessageFlushCallback = onMessageFlushCallback; - callbackContainer->onFlushPromise = std::move(onTerminatePromise); + closeResult = aws_event_stream_rpc_client_continuation_send_message( + closeContinuation, + &msg_args, + s_protocolMessageCallback, + reinterpret_cast(closeCallbackContainerWrapper)); + + if (closeResult == AWS_OP_ERR) + { + closeError = {EVENT_STREAM_RPC_CRT_ERROR, aws_last_error()}; + + std::lock_guard lock(m_sharedStateLock); + m_sharedState.m_closeCallbackContainer = nullptr; + if (m_sharedState.m_currentState != ContinuationStateType::Closed) + { + // Rollback to previous state + m_sharedState.m_currentState = previousState; + } + } + + aws_event_stream_rpc_client_continuation_release(closeContinuation); + } + + if (closeResult != AWS_OP_SUCCESS) + { + OnMessageFlushCallbackContainerWrapper::Complete(closeCallbackContainerWrapper, closeError); + Aws::Crt::Delete(closeCallbackContainerWrapper, closeCallbackContainerWrapper->GetAllocator()); + } + + return closeFuture; + } + + void ClientContinuationImpl::OnClosed() noexcept + { + struct aws_event_stream_rpc_client_continuation_token *releaseContinuation = nullptr; + std::shared_ptr closeCallbackContainer = nullptr; + std::shared_ptr activationCallbackContainer = nullptr; + std::function activationResponseCallback; + + { + std::lock_guard lock(m_sharedStateLock); + + m_sharedState.m_currentState = ContinuationStateType::Closed; + m_sharedState.m_desiredState = ContinuationStateType::Closed; + releaseContinuation = m_sharedState.m_continuation; + m_sharedState.m_continuation = nullptr; + + activationCallbackContainer = m_sharedState.m_activationCallbackContainer; + m_sharedState.m_activationCallbackContainer = nullptr; + + closeCallbackContainer = m_sharedState.m_closeCallbackContainer; + m_sharedState.m_closeCallbackContainer = nullptr; + + activationResponseCallback = std::move(m_sharedState.m_activationResponseCallback); + m_sharedState.m_activationResponseCallback = nullptr; + } + + if (activationResponseCallback) + { + activationResponseCallback( + TaggedResult(RpcError{EVENT_STREAM_RPC_CONTINUATION_CLOSED, AWS_ERROR_SUCCESS})); + } + + OnMessageFlushCallbackContainer::Complete( + activationCallbackContainer.get(), {EVENT_STREAM_RPC_CONTINUATION_CLOSED, AWS_ERROR_SUCCESS}); + + OnMessageFlushCallbackContainer::Complete( + closeCallbackContainer.get(), {EVENT_STREAM_RPC_CONTINUATION_CLOSED, AWS_ERROR_SUCCESS}); + + ReleaseContinuation(m_allocator, m_clientBootstrap, releaseContinuation); + } + + MessageResult ClientContinuationImpl::DeserializeRawMessage( + const struct aws_event_stream_rpc_message_args *rawMessage, + bool shouldBeActivationResponse) noexcept + { + MessageResult result; + + Crt::List continuationMessageHeaders; + for (size_t i = 0; i < rawMessage->headers_count; ++i) + { + continuationMessageHeaders.emplace_back(EventStreamHeader(rawMessage->headers[i], m_allocator)); + } + + Crt::Optional payload; + if (rawMessage->payload) + { + payload = Crt::Optional(*rawMessage->payload); + } + else + { + payload = Crt::Optional(); + } + + const EventStreamHeader *modelHeader = + s_GetHeaderByName(continuationMessageHeaders, Crt::String(SERVICE_MODEL_TYPE_HEADER)); + if (modelHeader == nullptr) + { + AWS_LOGF_ERROR( + AWS_LS_EVENT_STREAM_RPC_CLIENT, + "A required header (%s) could not be found in the message.", + SERVICE_MODEL_TYPE_HEADER); + result.m_statusCode = EVENT_STREAM_RPC_UNMAPPED_DATA; + return result; + } + + Crt::String modelName; + modelHeader->GetValueAsString(modelName); + if (rawMessage->message_type == AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_APPLICATION_MESSAGE) + { + if (shouldBeActivationResponse) + { + if (m_operationModelContext->GetInitialResponseModelName() != modelName) + { + AWS_LOGF_ERROR( + AWS_LS_EVENT_STREAM_RPC_CLIENT, + "The model name of the initial response did not match its expected model name."); + result.m_statusCode = EVENT_STREAM_RPC_UNMAPPED_DATA; + return result; + } + } + else + { + if (m_operationModelContext->GetStreamingResponseModelName().has_value() && + m_operationModelContext->GetStreamingResponseModelName().value() != modelName) + { + AWS_LOGF_ERROR( + AWS_LS_EVENT_STREAM_RPC_CLIENT, + "The model name of a subsequent response did not match its expected model name."); + result.m_statusCode = EVENT_STREAM_RPC_UNMAPPED_DATA; + return result; + } + } + } + + const EventStreamHeader *contentHeader = + s_GetHeaderByName(continuationMessageHeaders, Crt::String(CONTENT_TYPE_HEADER)); + if (contentHeader == nullptr) + { + AWS_LOGF_ERROR( + AWS_LS_EVENT_STREAM_RPC_CLIENT, + "A required header (%s) could not be found in the message.", + CONTENT_TYPE_HEADER); + result.m_statusCode = EVENT_STREAM_RPC_UNSUPPORTED_CONTENT_TYPE; + return result; + } + + Crt::String contentType; + if (contentHeader->GetValueAsString(contentType) && contentType != CONTENT_TYPE_APPLICATION_JSON) + { + /* Missing required content type header. */ + AWS_LOGF_ERROR( + AWS_LS_EVENT_STREAM_RPC_CLIENT, + "The content type (%s) header was specified with an unsupported value (%s).", + CONTENT_TYPE_HEADER, + contentType.c_str()); + result.m_statusCode = EVENT_STREAM_RPC_UNSUPPORTED_CONTENT_TYPE; + return result; + } + + Crt::StringView payloadStringView; + if (payload.has_value()) + { + payloadStringView = Crt::ByteCursorToStringView(Crt::ByteCursorFromByteBuf(payload.value())); + } + + if (rawMessage->message_type == AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_APPLICATION_MESSAGE) + { + if (shouldBeActivationResponse) + { + result.m_message = MessageDeserialization{ + EventStreamMessageRoutingType::Response, + m_operationModelContext->AllocateInitialResponseFromPayload(payloadStringView, m_allocator)}; + } + else + { + result.m_message = MessageDeserialization{ + EventStreamMessageRoutingType::Stream, + m_operationModelContext->AllocateStreamingResponseFromPayload(payloadStringView, m_allocator)}; + } + } + else + { + auto errorShape = m_operationModelContext + ->AllocateOperationErrorFromPayload(modelName, payloadStringView, m_allocator) + .release(); + Crt::Allocator *allocator = m_allocator; + result.m_message = MessageDeserialization{ + EventStreamMessageRoutingType::Error, + Crt::ScopedResource( + errorShape, [allocator](AbstractShapeBase *shape) { Crt::Delete(shape, allocator); })}; + } - if (m_clientContinuation.m_continuationToken) + if (result.m_message.value().m_shape.get() == nullptr) + { + result.m_statusCode = EVENT_STREAM_RPC_UNMAPPED_DATA; + } + + return result; + } + + void ClientContinuationImpl::OnMessage(const struct aws_event_stream_rpc_message_args *messageArgs) noexcept + { + MessageResult result; + bool isResponse = false; + bool shouldClose = false; + std::function activationResultCallback = nullptr; + + { + std::lock_guard lock(m_sharedStateLock); + isResponse = static_cast(m_sharedState.m_currentState == ContinuationStateType::PendingActivate); + result = DeserializeRawMessage(messageArgs, isResponse); + + if (isResponse) { - errorCode = aws_event_stream_rpc_client_continuation_send_message( - m_clientContinuation.m_continuationToken, - &msg_args, - ClientConnection::s_protocolMessageCallback, - reinterpret_cast(callbackContainer)); + activationResultCallback = std::move(m_sharedState.m_activationResponseCallback); + m_sharedState.m_activationResponseCallback = nullptr; + m_sharedState.m_activationCallbackContainer = nullptr; + + if (result.m_statusCode == EVENT_STREAM_RPC_SUCCESS && + result.m_message.value().m_route == EventStreamMessageRoutingType::Response) + { + m_sharedState.m_currentState = ContinuationStateType::Activated; + } + else + { + shouldClose = true; + } } + } - if (errorCode) + if (activationResultCallback) + { + if (result.m_statusCode == EVENT_STREAM_RPC_SUCCESS) { - onTerminatePromise = std::move(callbackContainer->onFlushPromise); - std::promise errorPromise; - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_CLIENT, - "A CRT error occurred while closing the stream: %s", - Crt::ErrorDebugString(errorCode)); - onTerminatePromise.set_value({EVENT_STREAM_RPC_CRT_ERROR, errorCode}); - Crt::Delete(callbackContainer, m_allocator); + const auto &message = result.m_message.value(); + if (message.m_route == EventStreamMessageRoutingType::Response) + { + activationResultCallback(TaggedResult(std::move(result.m_message.value().m_shape))); + } + else + { + // Horribly awkward cast due to the infuriating original API design + Crt::Allocator *allocator = m_allocator; + auto errorResponse = Crt::ScopedResource( + static_cast(result.m_message.value().m_shape.release()), + [allocator](OperationError *shape) { Crt::Delete(shape, allocator); }); + + activationResultCallback(TaggedResult(std::move(errorResponse))); + } } else { - m_expectedCloses.fetch_add(1); - return callbackContainer->onFlushPromise.get_future(); + activationResultCallback(TaggedResult(RpcError{result.m_statusCode, 0})); + } + } + + if (!isResponse) + { + std::lock_guard handlerLock(m_streamHandlerLock); + + auto streamHandler = m_streamHandler; + if (streamHandler) + { + if (result.m_message.has_value()) + { + auto shape = std::move(result.m_message.value().m_shape); + auto route = result.m_message.value().m_route; + switch (route) + { + case EventStreamMessageRoutingType::Stream: + { + + streamHandler->OnStreamEvent(std::move(shape)); + break; + } + + case EventStreamMessageRoutingType::Error: + { + Crt::Allocator *allocator = m_allocator; + auto errorResponse = Crt::ScopedResource( + static_cast(shape.release()), + [allocator](OperationError *shape) { Crt::Delete(shape, allocator); }); + + shouldClose = streamHandler->OnStreamError( + std::move(errorResponse), {EVENT_STREAM_RPC_SUCCESS, 0}); + break; + } + + default: + AWS_FATAL_ASSERT(false); + } + } + else + { + shouldClose = streamHandler->OnStreamError(nullptr, {result.m_statusCode, 0}); + } } + } - return onTerminatePromise.get_future(); + if (shouldClose) + { + Close(); } } - void OperationError::s_customDeleter(OperationError *shape) noexcept + void ClientContinuationImpl::s_OnContinuationClosed( + struct aws_event_stream_rpc_client_continuation_token *token, + void *user_data) noexcept { - AbstractShapeBase::s_customDeleter(shape); + (void)token; + + auto impl = reinterpret_cast(user_data); + impl->OnClosed(); + } + + void ClientContinuationImpl::s_OnContinuationMessage( + struct aws_event_stream_rpc_client_continuation_token *token, + const struct aws_event_stream_rpc_message_args *message_args, + void *user_data) noexcept + { + (void)token; + + auto impl = reinterpret_cast(user_data); + impl->OnMessage(message_args); + } + + void ClientContinuationImpl::s_OnContinuationTerminated(void *user_data) noexcept + { + auto impl = reinterpret_cast(user_data); + + // We don't need to put this on an event loop task since we release the continuation on an event loop task + impl->m_selfReference = nullptr; + } + + Crt::String ClientContinuationImpl::GetModelName() const noexcept + { + return m_operationModelContext->GetOperationName(); + } + + std::shared_ptr ClientConnectionImpl::NewStream() noexcept + { + std::lock_guard lock(m_sharedStateLock); + return Aws::Crt::MakeShared( + m_allocator, m_allocator, m_bootstrap, m_sharedState.m_underlyingConnection); + } + + ClientOperation::ClientOperation( + ClientConnection &connection, + std::shared_ptr streamHandler, + const std::shared_ptr &operationModelContext, + Crt::Allocator *allocator) noexcept + : m_allocator(allocator), m_impl(connection.NewStream()) + { + m_impl->Initialize(operationModelContext, std::move(streamHandler)); + } + + ClientOperation::~ClientOperation() noexcept + { + m_impl->ShutDown(); + m_impl = nullptr; + } + + std::future ClientOperation::Close(OnMessageFlushCallback onMessageFlushCallback) noexcept + { + return m_impl->Close(std::move(onMessageFlushCallback)); + } + + void ClientOperation::WithLaunchMode(std::launch mode) noexcept + { + (void)mode; + } + + Crt::String ClientOperation::GetModelName() const noexcept + { + return m_impl->GetModelName(); } + std::future ClientOperation::Activate( + const AbstractShapeBase *shape, + OnMessageFlushCallback &&onMessageFlushCallback, + std::function &&onResultCallback) noexcept + { + Crt::List headers; + headers.emplace_back(EventStreamHeader( + Crt::String(CONTENT_TYPE_HEADER), Crt::String(CONTENT_TYPE_APPLICATION_JSON), m_allocator)); + headers.emplace_back( + EventStreamHeader(Crt::String(SERVICE_MODEL_TYPE_HEADER), GetModelName(), m_allocator)); + Crt::JsonObject payloadObject; + shape->SerializeToJsonObject(payloadObject); + Crt::String payloadString = payloadObject.View().WriteCompact(); + + return m_impl->Activate( + GetModelName(), + headers, + Crt::ByteBufFromCString(payloadString.c_str()), + AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_APPLICATION_MESSAGE, + 0, + std::move(onResultCallback), + std::move(onMessageFlushCallback)); + } + + std::future ClientOperation::SendStreamMessage( + const AbstractShapeBase *shape, + OnMessageFlushCallback &&onMessageFlushCallback) noexcept + { + Crt::List headers; + headers.emplace_back(EventStreamHeader( + Crt::String(CONTENT_TYPE_HEADER), Crt::String(CONTENT_TYPE_APPLICATION_JSON), m_allocator)); + headers.emplace_back( + EventStreamHeader(Crt::String(SERVICE_MODEL_TYPE_HEADER), GetModelName(), m_allocator)); + Crt::JsonObject payloadObject; + shape->SerializeToJsonObject(payloadObject); + Crt::String payloadString = payloadObject.View().WriteCompact(); + + return m_impl->SendStreamMessage( + headers, + Crt::ByteBufFromCString(payloadString.c_str()), + AWS_EVENT_STREAM_RPC_MESSAGE_TYPE_APPLICATION_MESSAGE, + 0, + std::move(onMessageFlushCallback)); + } } /* namespace Eventstreamrpc */ } // namespace Aws diff --git a/eventstream_rpc/tests/CMakeLists.txt b/eventstream_rpc/tests/CMakeLists.txt index 53ac62dc1..52e647bb4 100644 --- a/eventstream_rpc/tests/CMakeLists.txt +++ b/eventstream_rpc/tests/CMakeLists.txt @@ -30,11 +30,75 @@ file(GLOB TESTS ${TEST_HDRS} ${TEST_SRC}) set(TEST_BINARY_NAME ${PROJECT_NAME}-tests) -add_test_case(OperateWhileDisconnected) -# The tests below can be commented out when an EchoRPC Server is running on 127.0.0.1:8033 -#add_test_case(EventStreamConnect) -#add_test_case(EchoOperation) -#add_test_case(StressTestClient) +# Connectivity tests +add_test_case(EventStreamClientCreateFailureInvalidHost) +add_test_case(EventStreamClientCreateFailureInvalidPort) +add_test_case(EventStreamConnectSuccess) +add_test_case(EventStreamConnectFailureNoAuthHeader) +add_test_case(EventStreamConnectFailureBadAuthHeader) +add_test_case(EchoClientConnectSuccess) +add_test_case(EchoClientDoubleClose) +add_test_case(EchoClientMultiConnectSuccessFail) +add_test_case(EchoClientReconnect) +add_test_case(EchoClientCloseWhileConnecting) +add_test_case(EchoClientConnectWhileClosing) +add_test_case(EchoClientOpenCloseStress) + +# Basic non-streaming operation tests +add_test_case(EchoClientOperationEchoSuccessString) +add_test_case(EchoClientOperationEchoSuccessBoolean) +add_test_case(EchoClientOperationEchoSuccessTime) +add_test_case(EchoClientOperationEchoSuccessDocument) +add_test_case(EchoClientOperationEchoSuccessEnum) +add_test_case(EchoClientOperationEchoSuccessBlob) +add_test_case(EchoClientOperationEchoSuccessStringList) +add_test_case(EchoClientOperationEchoSuccessPairList) +add_test_case(EchoClientOperationEchoSuccessProductMap) +add_test_case(EchoClientOperationEchoSuccessMultiple) +add_test_case(EchoClientOperationGetAllProductsSuccess) +add_test_case(EchoClientOperationGetAllCustomersSuccess) +add_test_case(EchoClientOperationCauseServiceErrorSuccess) +add_test_case(EchoClientOperationEchoFailureNeverConnected) +add_test_case(EchoClientOperationEchoFailureDisconnected) + +# Non-streaming race condition tests +add_test_case(EchoClientOperationUnactivatedShutdown) +add_test_case(EchoClientOperationUnactivatedClose) +add_test_case(EchoClientOperationUnactivatedCloseDropFuture) +add_test_case(EchoClientOperationActivateActivate) +add_test_case(EchoClientOperationActivateWaitActivate) +add_test_case(EchoClientOperationActivateCloseActivate) +add_test_case(EchoClientOperationActivateClosedActivate) +add_test_case(EchoClientOperationActivateCloseConnection) +add_test_case(EchoClientOperationActivateDoubleCloseContinuation) +add_test_case(EchoClientOperationActivateWaitDoubleCloseContinuation) +add_test_case(EchoClientOperationActivateWaitCloseContinuationWaitCloseContinuation) +add_test_case(EchoClientOperationActivateShutdown) +add_test_case(EchoClientOperationActivateShutdownDropFuture) +add_test_case(EchoClientOperationActivateWaitCloseShutdown) +add_test_case(EchoClientOperationActivateWaitCloseShutdownDropFuture) + +# streaming echo messages tests +add_test_case(EchoClientStreamingOperationEchoSuccessString) +add_test_case(EchoClientStreamingOperationEchoSuccessBoolean) +add_test_case(EchoClientStreamingOperationEchoSuccessTime) +add_test_case(EchoClientStreamingOperationEchoSuccessDocument) +add_test_case(EchoClientStreamingOperationEchoSuccessEnum) +add_test_case(EchoClientStreamingOperationEchoSuccessBlob) +add_test_case(EchoClientStreamingOperationEchoSuccessStringList) +add_test_case(EchoClientStreamingOperationEchoSuccessPairList) +add_test_case(EchoClientStreamingOperationEchoSuccessProductMap) + +# streaming failure/error tests +add_test_case(EchoClientStreamingOperationCauseServiceError) + +# streaming race condition tests +add_test_case(EchoClientStreamingOperationSendCloseOperation) +add_test_case(EchoClientStreamingOperationSendDropOperation) +add_test_case(EchoClientStreamingOperationSendCloseConnection) +add_test_case(EchoClientStreamingOperationUnactivatedSend) +add_test_case(EchoClientOperationStress) + generate_cpp_test_driver(${TEST_BINARY_NAME}) aws_add_sanitizers(${TEST_BINARY_NAME}) target_include_directories(${TEST_BINARY_NAME} PUBLIC diff --git a/eventstream_rpc/tests/EchoTestRpcClient.cpp b/eventstream_rpc/tests/EchoTestRpcClient.cpp index 05fe07477..e0671dc26 100644 --- a/eventstream_rpc/tests/EchoTestRpcClient.cpp +++ b/eventstream_rpc/tests/EchoTestRpcClient.cpp @@ -11,11 +11,14 @@ namespace Awstest { + EchoTestRpcClient::EchoTestRpcClient( Aws::Crt::Io::ClientBootstrap &clientBootstrap, Aws::Crt::Allocator *allocator) noexcept - : m_connection(allocator), m_clientBootstrap(clientBootstrap), m_allocator(allocator), - m_asyncLaunchMode(std::launch::deferred) + : m_echoTestRpcServiceModel(allocator), + m_connection( + Aws::Crt::MakeShared(allocator, allocator, clientBootstrap.GetUnderlyingHandle())), + m_allocator(allocator), m_asyncLaunchMode(std::launch::deferred) { m_echoTestRpcServiceModel.AssignModelNameToErrorResponse( Aws::Crt::String("awstest#ServiceError"), ServiceError::s_allocateFromPayload); @@ -25,12 +28,12 @@ namespace Awstest ConnectionLifecycleHandler &lifecycleHandler, const ConnectionConfig &connectionConfig) noexcept { - return m_connection.Connect(connectionConfig, &lifecycleHandler, m_clientBootstrap); + return m_connection->Connect(connectionConfig, &lifecycleHandler); } void EchoTestRpcClient::Close() noexcept { - m_connection.Close(); + m_connection->Close(); } void EchoTestRpcClient::WithLaunchMode(std::launch mode) noexcept @@ -46,7 +49,7 @@ namespace Awstest std::shared_ptr EchoTestRpcClient::NewGetAllProducts() noexcept { auto operation = Aws::Crt::MakeShared( - m_allocator, m_connection, m_echoTestRpcServiceModel.m_getAllProductsOperationContext, m_allocator); + m_allocator, *m_connection, m_echoTestRpcServiceModel.m_getAllProductsOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); return operation; } @@ -54,7 +57,7 @@ namespace Awstest std::shared_ptr EchoTestRpcClient::NewCauseServiceError() noexcept { auto operation = Aws::Crt::MakeShared( - m_allocator, m_connection, m_echoTestRpcServiceModel.m_causeServiceErrorOperationContext, m_allocator); + m_allocator, *m_connection, m_echoTestRpcServiceModel.m_causeServiceErrorOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); return operation; } @@ -64,7 +67,7 @@ namespace Awstest { return Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, std::move(streamHandler), m_echoTestRpcServiceModel.m_causeStreamServiceToErrorOperationContext, m_allocator); @@ -75,7 +78,7 @@ namespace Awstest { return Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, std::move(streamHandler), m_echoTestRpcServiceModel.m_echoStreamMessagesOperationContext, m_allocator); @@ -84,7 +87,7 @@ namespace Awstest std::shared_ptr EchoTestRpcClient::NewEchoMessage() noexcept { auto operation = Aws::Crt::MakeShared( - m_allocator, m_connection, m_echoTestRpcServiceModel.m_echoMessageOperationContext, m_allocator); + m_allocator, *m_connection, m_echoTestRpcServiceModel.m_echoMessageOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); return operation; } @@ -92,7 +95,7 @@ namespace Awstest std::shared_ptr EchoTestRpcClient::NewGetAllCustomers() noexcept { auto operation = Aws::Crt::MakeShared( - m_allocator, m_connection, m_echoTestRpcServiceModel.m_getAllCustomersOperationContext, m_allocator); + m_allocator, *m_connection, m_echoTestRpcServiceModel.m_getAllCustomersOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); return operation; } diff --git a/eventstream_rpc/tests/EchoTestRpcModel.cpp b/eventstream_rpc/tests/EchoTestRpcModel.cpp index 3cb4f9c6b..c46008bec 100644 --- a/eventstream_rpc/tests/EchoTestRpcModel.cpp +++ b/eventstream_rpc/tests/EchoTestRpcModel.cpp @@ -326,7 +326,7 @@ namespace Awstest } } - Aws::Crt::Optional MessageData::GetEnumMessage() noexcept + Aws::Crt::Optional MessageData::GetEnumMessage() const noexcept { if (!m_enumMessage.has_value()) return Aws::Crt::Optional(); @@ -975,6 +975,22 @@ namespace Awstest AbstractShapeBase::s_customDeleter(static_cast(shape)); } + class GetAllProductsOperationContext : public OperationModelContext + { + public: + GetAllProductsOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + GetAllProductsOperationContext::GetAllProductsOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) { @@ -1018,14 +1034,15 @@ namespace Awstest std::future GetAllProductsOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return GetAllProductsResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } GetAllProductsOperation::GetAllProductsOperation( ClientConnection &connection, - const GetAllProductsOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -1033,13 +1050,32 @@ namespace Awstest const GetAllProductsRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(GetAllProductsResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String GetAllProductsOperation::GetModelName() const noexcept + class CauseServiceErrorOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + CauseServiceErrorOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; CauseServiceErrorOperationContext::CauseServiceErrorOperationContext( const EchoTestRpcServiceModel &serviceModel) noexcept @@ -1086,14 +1122,15 @@ namespace Awstest std::future CauseServiceErrorOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return CauseServiceErrorResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } CauseServiceErrorOperation::CauseServiceErrorOperation( ClientConnection &connection, - const CauseServiceErrorOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -1101,12 +1138,15 @@ namespace Awstest const CauseServiceErrorRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); - } + auto promiseReference = m_resultPromise; - Aws::Crt::String CauseServiceErrorOperation::GetModelName() const noexcept - { - return m_operationModelContext.GetOperationName(); + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(CauseServiceErrorResult(std::move(unmodeledResult))); }); + + return activateFuture; } void CauseStreamServiceToErrorStreamHandler::OnStreamEvent(Aws::Crt::ScopedResource response) @@ -1133,6 +1173,22 @@ namespace Awstest return streamShouldTerminate; } + class CauseStreamServiceToErrorOperationContext : public OperationModelContext + { + public: + CauseStreamServiceToErrorOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + CauseStreamServiceToErrorOperationContext::CauseStreamServiceToErrorOperationContext( const EchoTestRpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) @@ -1176,16 +1232,16 @@ namespace Awstest std::future CauseStreamServiceToErrorOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return CauseStreamServiceToErrorResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } CauseStreamServiceToErrorOperation::CauseStreamServiceToErrorOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const CauseStreamServiceToErrorOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, streamHandler, operationContext, allocator) + : ClientOperation(connection, streamHandler, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -1193,12 +1249,23 @@ namespace Awstest const EchoStreamingRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(CauseStreamServiceToErrorResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String CauseStreamServiceToErrorOperation::GetModelName() const noexcept + std::future CauseStreamServiceToErrorOperation::SendStreamMessage( + const EchoStreamingMessage &message, + OnMessageFlushCallback onMessageFlushCallback) { - return m_operationModelContext.GetOperationName(); + return ClientOperation::SendStreamMessage( + static_cast(&message), std::move(onMessageFlushCallback)); } void EchoStreamMessagesStreamHandler::OnStreamEvent(Aws::Crt::ScopedResource response) @@ -1220,6 +1287,22 @@ namespace Awstest return streamShouldTerminate; } + class EchoStreamMessagesOperationContext : public OperationModelContext + { + public: + EchoStreamMessagesOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + EchoStreamMessagesOperationContext::EchoStreamMessagesOperationContext( const EchoTestRpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) @@ -1263,15 +1346,16 @@ namespace Awstest std::future EchoStreamMessagesOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return EchoStreamMessagesResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } EchoStreamMessagesOperation::EchoStreamMessagesOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const EchoStreamMessagesOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, streamHandler, operationContext, allocator) + : ClientOperation(connection, streamHandler, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -1279,14 +1363,41 @@ namespace Awstest const EchoStreamingRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(EchoStreamMessagesResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String EchoStreamMessagesOperation::GetModelName() const noexcept + std::future EchoStreamMessagesOperation::SendStreamMessage( + const EchoStreamingMessage &message, + OnMessageFlushCallback onMessageFlushCallback) { - return m_operationModelContext.GetOperationName(); + return ClientOperation::SendStreamMessage( + static_cast(&message), std::move(onMessageFlushCallback)); } + class EchoMessageOperationContext : public OperationModelContext + { + public: + EchoMessageOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + EchoMessageOperationContext::EchoMessageOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) { @@ -1330,14 +1441,15 @@ namespace Awstest std::future EchoMessageOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return EchoMessageResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } EchoMessageOperation::EchoMessageOperation( ClientConnection &connection, - const EchoMessageOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -1345,13 +1457,32 @@ namespace Awstest const EchoMessageRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(EchoMessageResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String EchoMessageOperation::GetModelName() const noexcept + class GetAllCustomersOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + GetAllCustomersOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; GetAllCustomersOperationContext::GetAllCustomersOperationContext( const EchoTestRpcServiceModel &serviceModel) noexcept @@ -1397,14 +1528,15 @@ namespace Awstest std::future GetAllCustomersOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return GetAllCustomersResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } GetAllCustomersOperation::GetAllCustomersOperation( ClientConnection &connection, - const GetAllCustomersOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -1412,18 +1544,27 @@ namespace Awstest const GetAllCustomersRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); - } + auto promiseReference = m_resultPromise; - Aws::Crt::String GetAllCustomersOperation::GetModelName() const noexcept - { - return m_operationModelContext.GetOperationName(); + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(GetAllCustomersResult(std::move(unmodeledResult))); }); + + return activateFuture; } - EchoTestRpcServiceModel::EchoTestRpcServiceModel() noexcept - : m_getAllProductsOperationContext(*this), m_causeServiceErrorOperationContext(*this), - m_causeStreamServiceToErrorOperationContext(*this), m_echoStreamMessagesOperationContext(*this), - m_echoMessageOperationContext(*this), m_getAllCustomersOperationContext(*this) + EchoTestRpcServiceModel::EchoTestRpcServiceModel(Aws::Crt::Allocator *allocator) noexcept + : m_getAllProductsOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_causeServiceErrorOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_causeStreamServiceToErrorOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_echoStreamMessagesOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_echoMessageOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_getAllCustomersOperationContext(Aws::Crt::MakeShared(allocator, *this)) { } diff --git a/eventstream_rpc/tests/EventStreamClientTest.cpp b/eventstream_rpc/tests/EventStreamClientTest.cpp index b0301ab13..9ef25e9c8 100644 --- a/eventstream_rpc/tests/EventStreamClientTest.cpp +++ b/eventstream_rpc/tests/EventStreamClientTest.cpp @@ -14,63 +14,72 @@ # undef GetMessage #endif -#include -#include -#include +#include + +#include using namespace Aws::Crt; using namespace Aws::Eventstreamrpc; using namespace Awstest; +AWS_STATIC_STRING_FROM_LITERAL(s_env_name_echo_server_host, "AWS_TEST_EVENT_STREAM_ECHO_SERVER_HOST"); +AWS_STATIC_STRING_FROM_LITERAL(s_env_name_echo_server_port, "AWS_TEST_EVENT_STREAM_ECHO_SERVER_PORT"); + struct EventStreamClientTestContext { - std::unique_ptr apiHandle; - std::unique_ptr elGroup; - std::unique_ptr resolver; - std::unique_ptr clientBootstrap; -}; - -static EventStreamClientTestContext s_testContext; + explicit EventStreamClientTestContext(struct aws_allocator *allocator); + ~EventStreamClientTestContext() = default; -static int s_testSetup(struct aws_allocator *allocator, void *ctx) -{ - auto *testContext = static_cast(ctx); + bool isValidEnvironment() const; - testContext->apiHandle = std::unique_ptr(new ApiHandle(allocator)); - testContext->elGroup = std::unique_ptr(new Io::EventLoopGroup(0, allocator)); - testContext->resolver = - std::unique_ptr(new Io::DefaultHostResolver(*testContext->elGroup, 8, 30, allocator)); - testContext->clientBootstrap = std::unique_ptr( - new Io::ClientBootstrap(*testContext->elGroup, *testContext->resolver, allocator)); + std::shared_ptr elGroup; + std::shared_ptr resolver; + std::shared_ptr clientBootstrap; - return AWS_ERROR_SUCCESS; -} + uint16_t echoServerPort; + Aws::Crt::String echoServerHost; +}; -static int s_testTeardown(struct aws_allocator *allocator, int setup_result, void *ctx) +EventStreamClientTestContext::EventStreamClientTestContext(struct aws_allocator *allocator) : echoServerPort(0) { - auto *testContext = static_cast(ctx); + elGroup = Aws::Crt::MakeShared(allocator, 0, allocator); + resolver = Aws::Crt::MakeShared(allocator, *elGroup, 8, 30, allocator); + clientBootstrap = Aws::Crt::MakeShared(allocator, *elGroup, *resolver, allocator); + + aws_string *host_env_value = nullptr; + aws_get_environment_value(allocator, s_env_name_echo_server_host, &host_env_value); + if (host_env_value) + { + echoServerHost = aws_string_c_str(host_env_value); + } + + struct aws_string *port_env_value = nullptr; + if (!aws_get_environment_value(allocator, s_env_name_echo_server_port, &port_env_value) && + port_env_value != nullptr) + { + echoServerPort = static_cast(atoi(aws_string_c_str(port_env_value))); + } - testContext->elGroup.reset(); - testContext->resolver.reset(); - testContext->clientBootstrap.reset(); - /* The ApiHandle must be deallocated last or a deadlock occurs. */ - testContext->apiHandle.reset(); + aws_string_destroy(host_env_value); + aws_string_destroy(port_env_value); - return AWS_ERROR_SUCCESS; + AWS_LOGF_INFO( + AWS_LS_COMMON_GENERAL, "EventStreamClientTestContext - Host name %d bytes long", (int)echoServerHost.length()); + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EventStreamClientTestContext - Host name : %s", echoServerHost.c_str()); } -static int s_TestEventStreamConnect(struct aws_allocator *allocator, void *ctx); -static int s_TestEchoOperation(struct aws_allocator *allocator, void *ctx); -static int s_TestOperationWhileDisconnected(struct aws_allocator *allocator, void *ctx); +bool EventStreamClientTestContext::isValidEnvironment() const +{ + return !echoServerHost.empty() && echoServerPort > 0; +} class TestLifecycleHandler : public ConnectionLifecycleHandler { public: TestLifecycleHandler() + : isConnected(false), disconnectCrtErrorCode(AWS_ERROR_SUCCESS), + disconnectRpcStatusCode(EVENT_STREAM_RPC_SUCCESS) { - semaphoreULock = std::unique_lock(semaphoreLock); - isConnected = false; - lastErrorCode = AWS_OP_ERR; } void OnConnectCallback() override @@ -86,457 +95,2134 @@ class TestLifecycleHandler : public ConnectionLifecycleHandler { std::lock_guard lockGuard(semaphoreLock); - lastErrorCode = error.baseStatus; + disconnectCrtErrorCode = error.crtError; + disconnectRpcStatusCode = error.baseStatus; + isConnected = false; semaphore.notify_one(); } - void WaitOnCondition(std::function condition) { semaphore.wait(semaphoreULock, condition); } + void WaitOnCondition(std::function condition) + { + std::unique_lock semaphoreULock(semaphoreLock); + semaphore.wait(semaphoreULock, condition); + } + + void WaitOnDisconnected() + { + WaitOnCondition([this]() { return !isConnected; }); + } private: - friend int s_TestEventStreamConnect(struct aws_allocator *allocator, void *ctx); std::condition_variable semaphore; std::mutex semaphoreLock; - std::unique_lock semaphoreULock; - int isConnected; - int lastErrorCode; + + bool isConnected; + int disconnectCrtErrorCode; + EventStreamRpcStatusCode disconnectRpcStatusCode; }; -static void s_onMessageFlush(int errorCode) +static int s_TestEventStreamConnectSuccess(struct aws_allocator *allocator, void *ctx) { - (void)errorCode; + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + MessageAmendment connectionAmendment; + connectionAmendment.AddHeader(EventStreamHeader( + Aws::Crt::String("client-name"), Aws::Crt::String("accepted.testy_mc_testerson"), allocator)); + + ConnectionConfig connectionConfig; + connectionConfig.SetHostName(testContext.echoServerHost); + connectionConfig.SetPort(testContext.echoServerPort); + connectionConfig.SetConnectAmendment(connectionAmendment); + + TestLifecycleHandler lifecycleHandler; + ClientConnection connection(allocator, testContext.clientBootstrap->GetUnderlyingHandle()); + auto future = connection.Connect(connectionConfig, &lifecycleHandler); + EventStreamRpcStatusCode clientStatus = future.get().baseStatus; + + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, clientStatus); + } + + return AWS_OP_SUCCESS; } -AWS_TEST_CASE_FIXTURE(EventStreamConnect, s_testSetup, s_TestEventStreamConnect, s_testTeardown, &s_testContext); -static int s_TestEventStreamConnect(struct aws_allocator *allocator, void *ctx) +AWS_TEST_CASE(EventStreamConnectSuccess, s_TestEventStreamConnectSuccess); + +static int s_TestEventStreamConnectFailureNoAuthHeader(struct aws_allocator *allocator, void *ctx) { - auto *testContext = static_cast(ctx); + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } { - MessageAmendment connectionAmendment; - auto messageAmender = [&](void) -> const MessageAmendment & { return connectionAmendment; }; + ConnectionConfig connectionConfig; + connectionConfig.SetHostName(testContext.echoServerHost); + connectionConfig.SetPort(testContext.echoServerPort); - ConnectionConfig accessDeniedConfig; - accessDeniedConfig.SetHostName(Aws::Crt::String("127.0.0.1")); - accessDeniedConfig.SetPort(8033U); + TestLifecycleHandler lifecycleHandler; + ClientConnection connection(allocator, testContext.clientBootstrap->GetUnderlyingHandle()); + auto future = connection.Connect(connectionConfig, &lifecycleHandler); + EventStreamRpcStatusCode clientStatus = future.get().baseStatus; - /* Happy path case. */ - { - ConnectionLifecycleHandler lifecycleHandler; - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - client.Close(); - } + ASSERT_TRUE( + clientStatus == EVENT_STREAM_RPC_CRT_ERROR || clientStatus == EVENT_STREAM_RPC_CONNECTION_ACCESS_DENIED); + } - /* Empty amendment headers. */ - { - TestLifecycleHandler lifecycleHandler; - ClientConnection connection(allocator); - auto future = connection.Connect(accessDeniedConfig, &lifecycleHandler, *testContext->clientBootstrap); - ASSERT_TRUE(future.get().baseStatus == EVENT_STREAM_RPC_CONNECTION_ACCESS_DENIED); - } + return AWS_OP_SUCCESS; +} - /* Rejected client-name header. */ - { - TestLifecycleHandler lifecycleHandler; - ClientConnection connection(allocator); - connectionAmendment.AddHeader(EventStreamHeader( - Aws::Crt::String("client-name"), Aws::Crt::String("rejected.testy_mc_testerson"), allocator)); - auto future = connection.Connect(accessDeniedConfig, &lifecycleHandler, *testContext->clientBootstrap); - ASSERT_TRUE(future.get().baseStatus == EVENT_STREAM_RPC_CONNECTION_ACCESS_DENIED); - } +AWS_TEST_CASE(EventStreamConnectFailureNoAuthHeader, s_TestEventStreamConnectFailureNoAuthHeader); - /* Connect without taking its future then immediately close. */ - { - ConnectionLifecycleHandler lifecycleHandler; - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - client.Close(); - client.Close(); - ASSERT_FALSE(client.IsConnected()); - } +static int s_TestEventStreamConnectFailureBadAuthHeader(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + MessageAmendment connectionAmendment; + connectionAmendment.AddHeader(EventStreamHeader( + Aws::Crt::String("client-name"), Aws::Crt::String("rejected.testy_mc_testerson"), allocator)); + + ConnectionConfig connectionConfig; + connectionConfig.SetHostName(testContext.echoServerHost); + connectionConfig.SetPort(testContext.echoServerPort); + connectionConfig.SetConnectAmendment(connectionAmendment); + + TestLifecycleHandler lifecycleHandler; + ClientConnection connection(allocator, testContext.clientBootstrap->GetUnderlyingHandle()); + auto future = connection.Connect(connectionConfig, &lifecycleHandler); + EventStreamRpcStatusCode clientStatus = future.get().baseStatus; + + ASSERT_TRUE( + clientStatus == EVENT_STREAM_RPC_CRT_ERROR || clientStatus == EVENT_STREAM_RPC_CONNECTION_ACCESS_DENIED); } return AWS_OP_SUCCESS; } -AWS_TEST_CASE_FIXTURE( - OperateWhileDisconnected, - s_testSetup, - s_TestOperationWhileDisconnected, - s_testTeardown, - &s_testContext); -static int s_TestOperationWhileDisconnected(struct aws_allocator *allocator, void *ctx) -{ - auto *testContext = static_cast(ctx); +AWS_TEST_CASE(EventStreamConnectFailureBadAuthHeader, s_TestEventStreamConnectFailureBadAuthHeader); - /* Don't connect at all and try running operations as normal. */ +static int s_TestEchoClientConnectSuccess(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) { - ConnectionLifecycleHandler lifecycleHandler; - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto echoMessage = client.NewEchoMessage(); - EchoMessageRequest echoMessageRequest; - MessageData messageData; - Aws::Crt::String expectedMessage("l33t"); - messageData.SetStringMessage(expectedMessage); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - ASSERT_TRUE(requestFuture.get().baseStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED); - auto result = echoMessage->GetOperationResult().get(); - ASSERT_FALSE(result); - auto error = result.GetRpcError(); - ASSERT_TRUE(error.baseStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED); + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; } - /* Idempotent close and its safety. */ { ConnectionLifecycleHandler lifecycleHandler; - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - client.Close(); + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + EventStreamRpcStatusCode clientStatus = connectedStatus.get().baseStatus; + + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, clientStatus); client.Close(); } return AWS_OP_SUCCESS; } -AWS_TEST_CASE_FIXTURE(EchoOperation, s_testSetup, s_TestEchoOperation, s_testTeardown, &s_testContext); -static int s_TestEchoOperation(struct aws_allocator *allocator, void *ctx) -{ - auto *testContext = static_cast(ctx); - ConnectionLifecycleHandler lifecycleHandler; - Aws::Crt::String expectedMessage("Async I0 FTW"); - EchoMessageRequest echoMessageRequest; - MessageData messageData; - messageData.SetStringMessage(expectedMessage); +AWS_TEST_CASE(EchoClientConnectSuccess, s_TestEchoClientConnectSuccess); - /* Perform a regular echo operation. */ +static int s_TestEchoClientDoubleClose(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) { - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - auto echoMessage = client.NewEchoMessage(); - messageData.SetStringMessage(expectedMessage); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture.wait(); - auto result = echoMessage->GetResult().get(); - ASSERT_TRUE(result); - auto response = result.GetOperationResponse(); - ASSERT_NOT_NULL(response); - ASSERT_TRUE(response->GetMessage().value().GetStringMessage().value() == expectedMessage); + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; } - /* Attempt a connection, close it, then try running operations as normal. */ { ConnectionLifecycleHandler lifecycleHandler; - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + client.Close(); client.Close(); - auto echoMessage = client.NewEchoMessage(); - EchoMessageRequest echoMessageRequest; - MessageData messageData; - Aws::Crt::String expectedMessage("l33t"); - messageData.SetStringMessage(expectedMessage); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - ASSERT_TRUE(requestFuture.get().baseStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED); - auto result = echoMessage->GetOperationResult().get(); - ASSERT_FALSE(result); - auto error = result.GetRpcError(); - ASSERT_TRUE(error.baseStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED); } - /* Perform a regular echo operation but one after another without waiting. - * Only the response from the first operation will be received. */ + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EchoClientDoubleClose, s_TestEchoClientDoubleClose); + +static int s_TestEchoClientMultiConnectSuccessFail(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) { - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - auto echoMessage = client.NewEchoMessage(); - messageData.SetStringMessage(expectedMessage); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - MessageData differentMessage; - differentMessage.SetBooleanMessage(true); - echoMessageRequest.SetMessage(differentMessage); - requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture.wait(); - auto result = echoMessage->GetResult().get(); - ASSERT_TRUE(result); - auto response = result.GetOperationResponse(); - ASSERT_NOT_NULL(response); - ASSERT_TRUE(response->GetMessage().value().GetStringMessage().value() == expectedMessage); + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; } - /* Closing the stream should be idempotent. */ { - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - auto echoMessage = client.NewEchoMessage(); - messageData.SetStringMessage(expectedMessage); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - MessageData differentMessage; - differentMessage.SetBooleanMessage(true); - echoMessageRequest.SetMessage(differentMessage); - requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture.wait(); - echoMessage->Close().wait(); - echoMessage->Close().wait(); - echoMessage->Close().wait(); - echoMessage->Close().wait(); + + auto failedStatus1 = client.Connect(lifecycleHandler); + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED, failedStatus1.get().baseStatus); + + auto failedStatus2 = client.Connect(lifecycleHandler); + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED, failedStatus2.get().baseStatus); + + EventStreamRpcStatusCode clientStatus = connectedStatus.get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, clientStatus); + + client.Close(); } - /* Close without waiting on activation or close futures. */ + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EchoClientMultiConnectSuccessFail, s_TestEchoClientMultiConnectSuccessFail); + +static int s_TestEventStreamClientCreateFailureInvalidHost(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + { - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); + auto elGroup = Aws::Crt::MakeShared(allocator, 0, allocator); + auto resolver = Aws::Crt::MakeShared(allocator, *elGroup, 8, 30, allocator); + auto clientBootstrap = Aws::Crt::MakeShared(allocator, *elGroup, *resolver, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - auto echoMessage = client.NewEchoMessage(); - messageData.SetStringMessage(expectedMessage); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - MessageData differentMessage; - differentMessage.SetBooleanMessage(true); - echoMessageRequest.SetMessage(differentMessage); - echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - echoMessage->Close(); - echoMessage->Close(); - echoMessage->Close(); - echoMessage->Close(); + ConnectionLifecycleHandler lifecycleHandler; + ClientConnection client(allocator, clientBootstrap->GetUnderlyingHandle()); + + ConnectionConfig config; + config.SetPort(8033); + + auto connectFuture = client.Connect(config, &lifecycleHandler); + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_NULL_PARAMETER, connectFuture.get().baseStatus); } - /* Close without waiting for TERMINATE_STREAM to flush then immediately trying to activate. */ + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EventStreamClientCreateFailureInvalidHost, s_TestEventStreamClientCreateFailureInvalidHost); + +static int s_TestEventStreamClientCreateFailureInvalidPort(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + { - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); + auto elGroup = Aws::Crt::MakeShared(allocator, 0, allocator); + auto resolver = Aws::Crt::MakeShared(allocator, *elGroup, 8, 30, allocator); + auto clientBootstrap = Aws::Crt::MakeShared(allocator, *elGroup, *resolver, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - auto echoMessage = client.NewEchoMessage(); - messageData.SetStringMessage(expectedMessage); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - MessageData differentMessage; - differentMessage.SetBooleanMessage(true); - echoMessageRequest.SetMessage(differentMessage); - requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture.wait(); - auto closeFuture = echoMessage->Close(); - requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - closeFuture.wait(); - requestFuture.wait(); + ConnectionLifecycleHandler lifecycleHandler; + ClientConnection client(allocator, clientBootstrap->GetUnderlyingHandle()); + + ConnectionConfig config; + config.SetHostName("localhost"); + + auto connectFuture = client.Connect(config, &lifecycleHandler); + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_NULL_PARAMETER, connectFuture.get().baseStatus); } - /* Connect thrice and verify that the future of the first attempt succeeds. - * The rest of the attempts must fail with an error. - * Use the client to perform an operation and verify that the operation still succeeds. */ + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EventStreamClientCreateFailureInvalidPort, s_TestEventStreamClientCreateFailureInvalidPort); + +static int s_TestEchoClientReconnect(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) { - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - auto failedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(failedStatus.get().baseStatus == EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED); - failedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - ASSERT_TRUE(failedStatus.get().baseStatus == EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED); - auto echoMessage = client.NewEchoMessage(); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture.wait(); - auto result = echoMessage->GetResult().get(); - ASSERT_TRUE(result); - auto response = result.GetOperationResponse(); - ASSERT_NOT_NULL(response); - ASSERT_TRUE(response->GetMessage().value().GetStringMessage().value() == expectedMessage); + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; } - /* Connect twice sequentially. - * Use the client to perform an operation and verify that the operation still succeeds. */ { - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED); - auto echoMessage = client.NewEchoMessage(); - echoMessageRequest.SetMessage(messageData); - auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); - requestFuture.wait(); - auto result = echoMessage->GetResult().get(); - ASSERT_TRUE(result); - auto response = result.GetOperationResponse(); - ASSERT_NOT_NULL(response); - ASSERT_TRUE(response->GetMessage().value().GetStringMessage().value() == expectedMessage); + TestLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus1 = client.Connect(lifecycleHandler).get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, connectedStatus1); + + client.Close(); + lifecycleHandler.WaitOnDisconnected(); + + auto connectedStatus2 = client.Connect(lifecycleHandler).get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, connectedStatus2); + + client.Close(); } return AWS_OP_SUCCESS; } -class ThreadPool +AWS_TEST_CASE(EchoClientReconnect, s_TestEchoClientReconnect); + +static int s_TestEchoClientCloseWhileConnecting(struct aws_allocator *allocator, void *ctx) { - public: - ThreadPool(int numThreads = std::thread::hardware_concurrency()) noexcept - : m_numThreads(numThreads), m_stopped(false) + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) { - for (int i = 0; i < numThreads; i++) - { - m_threadPool.push_back(std::thread(&ThreadPool::TaskWorker, this)); - } - m_taskErrorCode = AWS_OP_SUCCESS; + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; } - void AddTask(std::function task) noexcept { - { - std::unique_lock lock(m_queueMutex); - m_queue.push(task); - } - m_taskReady.notify_one(); + TestLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedFuture = client.Connect(lifecycleHandler); + client.Close(); + + // Our primary concern is that + // we end up in a closed state, the connect future resolves, and nothing explodes in-between. + auto status = connectedFuture.get().baseStatus; + + // depending on race conditions, we may end up with a connection success (before the close gets triggered) + // or a connection closed + ASSERT_TRUE(status == EVENT_STREAM_RPC_CONNECTION_CLOSED || status == EVENT_STREAM_RPC_SUCCESS); + lifecycleHandler.WaitOnDisconnected(); } - void Shutdown() noexcept - { - /* Wake up all threads so that they can complete. */ - m_taskReady.notify_all(); + return AWS_OP_SUCCESS; +} - /* Wait for all threads to complete. */ - for (std::thread &thread : m_threadPool) - { - thread.join(); - } +AWS_TEST_CASE(EchoClientCloseWhileConnecting, s_TestEchoClientCloseWhileConnecting); - m_threadPool.clear(); - m_stopped = true; +static int s_TestEchoClientConnectWhileClosing(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; } - void BlockUntilTasksFinish() noexcept { - while (true) - { - if (m_queueMutex.try_lock()) - { - if (m_queue.empty()) - { - m_stopped = true; - m_queueMutex.unlock(); - /* Wait for all threads to complete. */ - m_taskReady.notify_all(); - for (std::thread &thread : m_threadPool) - { - thread.join(); - } - break; - } - else - { - m_queueMutex.unlock(); - std::this_thread::yield(); - } - } - } - } + TestLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedFuture = client.Connect(lifecycleHandler); + auto status = connectedFuture.get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, status); - int GetErrorCode() noexcept { return m_taskErrorCode; } + client.Close(); - ~ThreadPool() noexcept - { - if (!m_stopped) - Shutdown(); - } + auto reconnectFuture = client.Connect(lifecycleHandler); + auto reconnectStatus = reconnectFuture.get().baseStatus; - private: - int m_numThreads; - std::mutex m_poolMutex; - std::vector m_threadPool; - std::mutex m_queueMutex; - std::queue> m_queue; - std::condition_variable m_taskReady; - int m_taskErrorCode; - bool m_stopped; + // depending on race conditions, we may end up with a success (the close completed quickly) + // or an already established code (the connect arrived in the middle of close) + ASSERT_TRUE( + reconnectStatus == EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED || + reconnectStatus == EVENT_STREAM_RPC_SUCCESS); + client.Close(); - void TaskWorker() - { - while (true) - { - { - std::unique_lock lock(m_queueMutex); - - m_taskReady.wait(lock, [this] { return !m_queue.empty() || m_stopped; }); - if (!m_queue.empty()) - { - std::function currentJob = m_queue.front(); - m_queue.pop(); - lock.unlock(); - if (currentJob) - { - int errorCode = currentJob(); - if (errorCode) - m_taskErrorCode = errorCode; - } - } - else if (m_stopped) - { - break; - } - } - } + lifecycleHandler.WaitOnDisconnected(); } -}; -AWS_TEST_CASE_FIXTURE(StressTestClient, s_testSetup, s_TestStressClient, s_testTeardown, &s_testContext); -static int s_TestStressClient(struct aws_allocator *allocator, void *ctx) + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EchoClientConnectWhileClosing, s_TestEchoClientConnectWhileClosing); + +static int s_TestEchoClientOpenCloseStress(struct aws_allocator *allocator, void *ctx) { - auto *testContext = static_cast(ctx); - ThreadPool threadPool; - ConnectionLifecycleHandler lifecycleHandler; - Aws::Crt::String expectedMessage("Async I0 FTW"); - EchoMessageRequest echoMessageRequest; - MessageData messageData; - messageData.SetStringMessage(expectedMessage); + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } { - Awstest::EchoTestRpcClient client(*testContext->clientBootstrap, allocator); - auto connectedStatus = client.Connect(lifecycleHandler); - ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); - auto invokeOperation = [&](void) -> int + TestLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + + for (size_t i = 0; i < 1000; ++i) { - auto echoMessage = client.NewEchoMessage(); - messageData.SetStringMessage(expectedMessage); - echoMessageRequest.SetMessage(messageData); - auto requestStatus = echoMessage->Activate(echoMessageRequest, s_onMessageFlush).get(); - auto resultFuture = echoMessage->GetResult(); - /* The response may never arrive depending on how many ongoing requests are made - * so in case of timeout, assume success. */ - std::future_status status = resultFuture.wait_for(std::chrono::seconds(5)); - if (status != std::future_status::ready) + auto connectedFuture = client.Connect(lifecycleHandler); + + if (rand() % 2 == 0) { - return AWS_OP_SUCCESS; + std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10)); } - auto result = echoMessage->GetResult().get(); - ASSERT_TRUE(result); - auto response = result.GetOperationResponse(); - ASSERT_NOT_NULL(response); - ASSERT_TRUE(response->GetMessage().value().GetStringMessage().value() == expectedMessage); - - return AWS_OP_SUCCESS; - }; - for (int i = 0; i < 1000; i++) - threadPool.AddTask(invokeOperation); + client.Close(); - threadPool.BlockUntilTasksFinish(); + auto connectedStatus = connectedFuture.get().baseStatus; + ASSERT_TRUE( + connectedStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED || connectedStatus == EVENT_STREAM_RPC_SUCCESS || + connectedStatus == EVENT_STREAM_RPC_CONNECTION_ALREADY_ESTABLISHED); - if (threadPool.GetErrorCode() != AWS_OP_SUCCESS) - return threadPool.GetErrorCode(); + if (rand() % 2 == 0) + { + std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 10)); + } + } } return AWS_OP_SUCCESS; } + +AWS_TEST_CASE(EchoClientOpenCloseStress, s_TestEchoClientOpenCloseStress); + +static void s_onMessageFlush(int errorCode) +{ + (void)errorCode; +} + +template +static bool s_messageDataMembersAreEqual( + const Aws::Crt::Optional &expectedValue, + const Aws::Crt::Optional &actualValue) +{ + if (expectedValue.has_value() != actualValue.has_value()) + { + return false; + } + + if (expectedValue.has_value()) + { + return expectedValue.value() == actualValue.value(); + } + + return true; +} + +// Specialization for Vector since we don't codegen == for Shapes +static bool s_messageDataMembersAreEqual( + const Aws::Crt::Optional> &lhs, + const Aws::Crt::Optional> &rhs) +{ + if (lhs.has_value() != rhs.has_value()) + { + return false; + } + + if (!lhs.has_value()) + { + return true; + } + + if (lhs.value().size() != rhs.value().size()) + { + return false; + } + + for (size_t i = 0; i < lhs.value().size(); ++i) + { + const auto &lhs_pair = (lhs.value())[i]; + const auto &rhs_pair = (rhs.value())[i]; + + if (lhs_pair.GetKey().has_value() != rhs_pair.GetKey().has_value()) + { + return false; + } + + if (lhs_pair.GetValue().has_value() != rhs_pair.GetValue().has_value()) + { + return false; + } + + if (lhs_pair.GetKey().value() != rhs_pair.GetKey().value() || + lhs_pair.GetValue().value() != rhs_pair.GetValue().value()) + { + return false; + } + } + + return true; +} + +// Specialization for Map since we don't codegen == for Shapes +static bool s_messageDataMembersAreEqual( + const Aws::Crt::Optional> &lhs, + const Aws::Crt::Optional> &rhs) +{ + if (lhs.has_value() != rhs.has_value()) + { + return false; + } + + if (!lhs.has_value()) + { + return true; + } + + if (lhs.value().size() != rhs.value().size()) + { + return false; + } + + for (const auto &lhs_entry : lhs.value()) + { + const auto &rhs_entry = rhs.value().find(lhs_entry.first); + if (rhs_entry == rhs.value().end()) + { + return false; + } + + const auto &lhs_product = lhs_entry.second; + const auto &rhs_product = rhs_entry->second; + + if (lhs_product.GetName().has_value() != rhs_product.GetName().has_value()) + { + return false; + } + + if (lhs_product.GetPrice().has_value() != rhs_product.GetPrice().has_value()) + { + return false; + } + + if (lhs_product.GetName().value() != rhs_product.GetName().value() || + lhs_product.GetPrice().value() != rhs_product.GetPrice().value()) + { + return false; + } + } + + return true; +} + +static int s_checkMessageDataEquality(const MessageData &expectedData, const MessageData &actualData) +{ + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetStringMessage(), actualData.GetStringMessage())); + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetBooleanMessage(), actualData.GetBooleanMessage())); + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetTimeMessage(), actualData.GetTimeMessage())); + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetDocumentMessage(), actualData.GetDocumentMessage())); + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetEnumMessage(), actualData.GetEnumMessage())); + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetBlobMessage(), actualData.GetBlobMessage())); + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetStringListMessage(), actualData.GetStringListMessage())); + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetKeyValuePairList(), actualData.GetKeyValuePairList())); + ASSERT_TRUE(s_messageDataMembersAreEqual(expectedData.GetStringToValue(), actualData.GetStringToValue())); + + return AWS_OP_SUCCESS; +} + +static int s_DoTestEchoClientOperationEchoSuccess( + struct aws_allocator *allocator, + std::function messageDataBuilder) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + + auto echoMessage = client.NewEchoMessage(); + EchoMessageRequest echoMessageRequest; + MessageData messageData; + messageDataBuilder(messageData); + echoMessageRequest.SetMessage(messageData); + + auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); + requestFuture.wait(); + auto result = echoMessage->GetResult().get(); + ASSERT_TRUE(result); + auto response = result.GetOperationResponse(); + ASSERT_NOT_NULL(response); + + ASSERT_SUCCESS(s_checkMessageDataEquality(messageData, response->GetMessage().value())); + } + + return AWS_OP_SUCCESS; +} + +static int s_TestEchoClientOperationEchoSuccessString(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::String value = "Hello World"; + messageData.SetStringMessage(value); + }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessString, s_TestEchoClientOperationEchoSuccessString); + +static int s_TestEchoClientOperationEchoSuccessBoolean(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, [](MessageData &messageData) { messageData.SetBooleanMessage(true); }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessBoolean, s_TestEchoClientOperationEchoSuccessBoolean); + +static int s_TestEchoClientOperationEchoSuccessTime(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, [](MessageData &messageData) { messageData.SetTimeMessage(Aws::Crt::DateTime::Now()); }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessTime, s_TestEchoClientOperationEchoSuccessTime); + +static int s_TestEchoClientOperationEchoSuccessDocument(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::JsonObject subobject; + subobject.WithString("Hello", "There"); + Aws::Crt::JsonObject document; + document.WithInt64("Derp", 21); + document.WithObject("DailyAffirmations", subobject); + + messageData.SetDocumentMessage(document); + }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessDocument, s_TestEchoClientOperationEchoSuccessDocument); + +static int s_TestEchoClientOperationEchoSuccessEnum(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, [](MessageData &messageData) { messageData.SetEnumMessage(FruitEnum::FRUIT_ENUM_PINEAPPLE); }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessEnum, s_TestEchoClientOperationEchoSuccessEnum); + +static int s_TestEchoClientOperationEchoSuccessBlob(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::Vector blob = {1, 2, 3, 4, 5}; + messageData.SetBlobMessage(blob); + }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessBlob, s_TestEchoClientOperationEchoSuccessBlob); + +static int s_TestEchoClientOperationEchoSuccessStringList(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::Vector stringList = {"1", "2", "Toasty", "Mctoaster"}; + messageData.SetStringListMessage(stringList); + }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessStringList, s_TestEchoClientOperationEchoSuccessStringList); + +static int s_TestEchoClientOperationEchoSuccessPairList(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Pair pair1; + pair1.SetKey("Uff"); + pair1.SetValue("Dah"); + + Pair pair2; + pair2.SetKey("Hello"); + pair2.SetValue("World"); + + Aws::Crt::Vector pairList = {pair1, pair2}; + messageData.SetKeyValuePairList(pairList); + }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessPairList, s_TestEchoClientOperationEchoSuccessPairList); + +static int s_TestEchoClientOperationEchoSuccessProductMap(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::Map productMap = {}; + Product product1; + product1.SetName("Derp"); + product1.SetPrice(4.0); + + Product product2; + product2.SetName("Can Of Derp"); + product2.SetPrice(7.5); + + productMap[product1.GetName().value()] = product1; + productMap[product2.GetName().value()] = product2; + + messageData.SetStringToValue(productMap); + }); +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessProductMap, s_TestEchoClientOperationEchoSuccessProductMap); + +static int s_TestEchoClientOperationEchoSuccessMultiple(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + + for (size_t i = 0; i < 5; i++) + { + auto echoMessage = client.NewEchoMessage(); + EchoMessageRequest echoMessageRequest; + MessageData messageData; + Aws::Crt::StringStream ss; + ss << "Hello Echo #" << i + 1; + Aws::Crt::String expectedMessage(ss.str().c_str()); + messageData.SetStringMessage(expectedMessage); + echoMessageRequest.SetMessage(messageData); + + auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); + requestFuture.wait(); + auto result = echoMessage->GetResult().get(); + ASSERT_TRUE(result); + auto response = result.GetOperationResponse(); + ASSERT_NOT_NULL(response); + ASSERT_TRUE(response->GetMessage().value().GetStringMessage().value() == expectedMessage); + } + } + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EchoClientOperationEchoSuccessMultiple, s_TestEchoClientOperationEchoSuccessMultiple); + +static int s_DoSimpleRequestWhileConnectedTest( + struct aws_allocator *allocator, + std::function testFunction) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + + return testFunction(testContext, client); + } +} + +static int s_TestEchoClientOperationGetAllProductsSuccess(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestWhileConnectedTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllProducts = client.NewGetAllProducts(); + GetAllProductsRequest getAllProductsRequest; + + auto requestFuture = getAllProducts->Activate(getAllProductsRequest, s_onMessageFlush); + requestFuture.wait(); + auto result = getAllProducts->GetResult().get(); + ASSERT_TRUE(result); + auto response = result.GetOperationResponse(); + ASSERT_NOT_NULL(response); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationGetAllProductsSuccess, s_TestEchoClientOperationGetAllProductsSuccess); + +static int s_TestEchoClientOperationGetAllCustomersSuccess(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestWhileConnectedTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + requestFuture.wait(); + auto result = getAllCustomers->GetResult().get(); + ASSERT_TRUE(result); + auto response = result.GetOperationResponse(); + ASSERT_NOT_NULL(response); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationGetAllCustomersSuccess, s_TestEchoClientOperationGetAllCustomersSuccess); + +static int s_TestEchoClientOperationCauseServiceErrorSuccess(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestWhileConnectedTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto causeServiceError = client.NewCauseServiceError(); + CauseServiceErrorRequest causeServiceErrorRequest; + + auto requestFuture = causeServiceError->Activate(causeServiceErrorRequest, s_onMessageFlush); + requestFuture.wait(); + auto result = causeServiceError->GetResult().get(); + ASSERT_FALSE(result); + ASSERT_NOT_NULL(result.GetOperationError()); + auto error = result.GetOperationError(); + const auto &errorMessage = error->GetMessage().value(); + ASSERT_TRUE(errorMessage == "Intentionally thrown ServiceError"); + const auto &modelName = error->GetModelName(); + ASSERT_TRUE(modelName == "awstest#ServiceError"); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationCauseServiceErrorSuccess, s_TestEchoClientOperationCauseServiceErrorSuccess); + +static int s_TestEchoClientOperationEchoFailureNeverConnected(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + + auto echoMessage = client.NewEchoMessage(); + EchoMessageRequest echoMessageRequest; + MessageData messageData; + Aws::Crt::String expectedMessage("l33t"); + messageData.SetStringMessage(expectedMessage); + echoMessageRequest.SetMessage(messageData); + + auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_CONNECTION_CLOSED, requestFuture.get().baseStatus); + } + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EchoClientOperationEchoFailureNeverConnected, s_TestEchoClientOperationEchoFailureNeverConnected); + +static int s_TestEchoClientOperationEchoFailureDisconnected(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + + client.Close(); + + auto echoMessage = client.NewEchoMessage(); + EchoMessageRequest echoMessageRequest; + MessageData messageData; + Aws::Crt::String expectedMessage("l33t"); + messageData.SetStringMessage(expectedMessage); + echoMessageRequest.SetMessage(messageData); + + auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); + auto activateStatus = requestFuture.get().baseStatus; + ASSERT_TRUE( + activateStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED || activateStatus == EVENT_STREAM_RPC_CRT_ERROR); + } + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EchoClientOperationEchoFailureDisconnected, s_TestEchoClientOperationEchoFailureDisconnected); + +static int s_DoSimpleRequestRaceCheckTest( + struct aws_allocator *allocator, + std::function testFunction) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + + for (size_t i = 0; i < 1000; ++i) + { + ASSERT_SUCCESS(testFunction(testContext, client)); + } + + return AWS_OP_SUCCESS; + } +} + +static int s_TestEchoClientOperationUnactivatedShutdown(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto echoMessage = client.NewEchoMessage(); + + // Drop the operation, invoking shutdown + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationUnactivatedShutdown, s_TestEchoClientOperationUnactivatedShutdown); + +static int s_TestEchoClientOperationUnactivatedClose(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto echoMessage = client.NewEchoMessage(); + + auto closeFuture = echoMessage->Close(); + auto closeStatus = closeFuture.get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_CONTINUATION_CLOSED, closeStatus); + + // Drop the operation, invoking shutdown + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationUnactivatedClose, s_TestEchoClientOperationUnactivatedClose); + +static int s_TestEchoClientOperationUnactivatedCloseDropFuture(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto echoMessage = client.NewEchoMessage(); + + auto closeFuture = echoMessage->Close(); + + // Drop the operation and the close future, invoking shutdown + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationUnactivatedCloseDropFuture, s_TestEchoClientOperationUnactivatedCloseDropFuture); + +static int s_TestEchoClientOperationActivateActivate(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + auto requestFuture2 = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + requestFuture2.wait(); + requestFuture.wait(); + auto result = getAllCustomers->GetResult().get(); + ASSERT_TRUE(result); + auto response = result.GetOperationResponse(); + ASSERT_NOT_NULL(response); + + auto flush2Result = requestFuture2.get(); + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_CRT_ERROR, flush2Result.baseStatus); + ASSERT_INT_EQUALS(AWS_ERROR_INVALID_STATE, flush2Result.crtError); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationActivateActivate, s_TestEchoClientOperationActivateActivate); + +static int s_TestEchoClientOperationActivateWaitActivate(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + requestFuture.wait(); + auto result = getAllCustomers->GetResult().get(); + ASSERT_TRUE(result); + auto response = result.GetOperationResponse(); + ASSERT_NOT_NULL(response); + + auto requestFuture2 = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + requestFuture2.wait(); + + auto flush2ErrorStatus = requestFuture2.get().baseStatus; + ASSERT_TRUE( + flush2ErrorStatus == EVENT_STREAM_RPC_CRT_ERROR || + flush2ErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationActivateWaitActivate, s_TestEchoClientOperationActivateWaitActivate); + +static int s_TestEchoClientOperationActivateCloseActivate(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + + auto closeFuture = getAllCustomers->Close(); + + requestFuture.wait(); + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_TRUE( + flushErrorStatus == EVENT_STREAM_RPC_SUCCESS || + flushErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + auto requestFuture2 = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + requestFuture2.wait(); + + auto flush2ErrorStatus = requestFuture2.get().baseStatus; + ASSERT_TRUE( + flush2ErrorStatus == EVENT_STREAM_RPC_CRT_ERROR || + flush2ErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + closeFuture.wait(); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationActivateCloseActivate, s_TestEchoClientOperationActivateCloseActivate); + +static int s_TestEchoClientOperationActivateClosedActivate(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + + auto closeFuture = getAllCustomers->Close(); + closeFuture.wait(); + + requestFuture.wait(); + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_TRUE( + flushErrorStatus == EVENT_STREAM_RPC_SUCCESS || + flushErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + auto requestFuture2 = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + requestFuture2.wait(); + + auto flush2ErrorStatus = requestFuture2.get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_CONTINUATION_CLOSED, flush2ErrorStatus); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationActivateClosedActivate, s_TestEchoClientOperationActivateClosedActivate); + +static int s_DoClientScopedRaceCheckTest( + struct aws_allocator *allocator, + std::function testFunction) +{ + ApiHandle apiHandle(allocator); + for (size_t i = 0; i < 100; ++i) + { + + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + + ASSERT_SUCCESS(testFunction(testContext, client)); + } + } + + return AWS_OP_SUCCESS; +} + +static int s_TestEchoClientOperationActivateCloseConnection(struct aws_allocator *allocator, void *ctx) +{ + return s_DoClientScopedRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + + client.Close(); + + requestFuture.wait(); + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_TRUE( + flushErrorStatus == EVENT_STREAM_RPC_SUCCESS || flushErrorStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED); + + auto requestFuture2 = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + requestFuture2.wait(); + + auto flush2ErrorStatus = requestFuture2.get().baseStatus; + ASSERT_TRUE( + flush2ErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED || + flush2ErrorStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED || + flush2ErrorStatus == EVENT_STREAM_RPC_CRT_ERROR); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationActivateCloseConnection, s_TestEchoClientOperationActivateCloseConnection); + +static int s_TestEchoClientOperationActivateDoubleCloseContinuation(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + + auto closeFuture = getAllCustomers->Close(); + auto closeFuture2 = getAllCustomers->Close(); + + requestFuture.wait(); + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_TRUE( + flushErrorStatus == EVENT_STREAM_RPC_SUCCESS || + flushErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + closeFuture.wait(); + closeFuture2.wait(); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE( + EchoClientOperationActivateDoubleCloseContinuation, + s_TestEchoClientOperationActivateDoubleCloseContinuation); + +static int s_TestEchoClientOperationActivateWaitDoubleCloseContinuation(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + requestFuture.wait(); + + auto closeFuture = getAllCustomers->Close(); + auto closeFuture2 = getAllCustomers->Close(); + + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_TRUE( + flushErrorStatus == EVENT_STREAM_RPC_SUCCESS || + flushErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + closeFuture.wait(); + closeFuture2.wait(); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE( + EchoClientOperationActivateWaitDoubleCloseContinuation, + s_TestEchoClientOperationActivateWaitDoubleCloseContinuation); + +static int s_TestEchoClientOperationActivateWaitCloseContinuationWaitCloseContinuation( + struct aws_allocator *allocator, + void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_TRUE( + flushErrorStatus == EVENT_STREAM_RPC_SUCCESS || + flushErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + auto closeFuture = getAllCustomers->Close(); + closeFuture.wait(); + + auto closeFuture2 = getAllCustomers->Close(); + closeFuture2.wait(); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE( + EchoClientOperationActivateWaitCloseContinuationWaitCloseContinuation, + s_TestEchoClientOperationActivateWaitCloseContinuationWaitCloseContinuation); + +static int s_TestEchoClientOperationActivateShutdown(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + getAllCustomers = nullptr; + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_TRUE( + flushErrorStatus == EVENT_STREAM_RPC_SUCCESS || + flushErrorStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationActivateShutdown, s_TestEchoClientOperationActivateShutdown); + +static int s_TestEchoClientOperationActivateShutdownDropFuture(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + + GetAllCustomersRequest getAllCustomersRequest; + getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationActivateShutdownDropFuture, s_TestEchoClientOperationActivateShutdownDropFuture); + +static int s_TestEchoClientOperationActivateWaitCloseShutdown(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, flushErrorStatus); + + auto closeFuture = getAllCustomers->Close(); + getAllCustomers = nullptr; + + closeFuture.wait(); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientOperationActivateWaitCloseShutdown, s_TestEchoClientOperationActivateWaitCloseShutdown); + +static int s_TestEchoClientOperationActivateWaitCloseShutdownDropFuture(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto getAllCustomers = client.NewGetAllCustomers(); + GetAllCustomersRequest getAllCustomersRequest; + + auto requestFuture = getAllCustomers->Activate(getAllCustomersRequest, s_onMessageFlush); + auto flushErrorStatus = requestFuture.get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, flushErrorStatus); + + getAllCustomers->Close(); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE( + EchoClientOperationActivateWaitCloseShutdownDropFuture, + s_TestEchoClientOperationActivateWaitCloseShutdownDropFuture); + +class EchoStreamMessagesTestHandler : public EchoStreamMessagesStreamHandler +{ + public: + EchoStreamMessagesTestHandler(Aws::Crt::Allocator *allocator, bool closeOnError) + : m_allocator(allocator), m_closeOnError(closeOnError) + { + } + + void OnStreamEvent(EchoStreamingMessage *response) override + { + std::lock_guard lock(m_lock); + + m_messages.push_back(Aws::Crt::MakeShared(m_allocator, *response)); + m_signal.notify_all(); + } + + bool OnStreamError(RpcError rpcError) override + { + std::lock_guard lock(m_lock); + + m_rpcErrors.push_back(rpcError); + m_signal.notify_all(); + + return m_closeOnError; + } + + bool OnStreamError(OperationError *operationError) override + { + (void)operationError; + + return m_closeOnError; + } + + void WaitForMessages(size_t count) + { + std::unique_lock lock(m_lock); + m_signal.wait(lock, [this, count]() { return m_messages.size() == count; }); + } + + int ValidateMessages(MessageData &expectedData) + { + std::lock_guard lock(m_lock); + for (size_t i = 0; i < m_messages.size(); i++) + { + const auto &message = m_messages[i]; + ASSERT_SUCCESS(s_checkMessageDataEquality(expectedData, message->GetStreamMessage().value())); + } + + return AWS_OP_SUCCESS; + } + + private: + Aws::Crt::Allocator *m_allocator; + bool m_closeOnError; + + std::mutex m_lock; + std::condition_variable m_signal; + + Aws::Crt::Vector> m_messages; + Vector m_rpcErrors; +}; + +constexpr size_t STREAM_MESSAGE_COUNT = 10; + +static int s_DoTestEchoClientStreamingOperationEchoSuccess( + struct aws_allocator *allocator, + std::function messageDataBuilder) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + MessageData expecectedMessageData; + messageDataBuilder(expecectedMessageData); + + { + auto handler = Aws::Crt::MakeShared(allocator, allocator, false); + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + + auto echoStreamMessages = client.NewEchoStreamMessages(handler); + EchoStreamingRequest echoStreamingMessageRequest; + auto activateFuture = echoStreamMessages->Activate(echoStreamingMessageRequest, s_onMessageFlush); + activateFuture.wait(); + + auto result = echoStreamMessages->GetResult().get(); + ASSERT_TRUE(result); + + Aws::Crt::Vector> streamMessageFutures; + for (size_t i = 0; i < STREAM_MESSAGE_COUNT; ++i) + { + EchoStreamingMessage streamMessage; + MessageData messageData; + messageDataBuilder(messageData); + streamMessage.SetStreamMessage(messageData); + + auto streamFuture = echoStreamMessages->SendStreamMessage(streamMessage, s_onMessageFlush); + streamMessageFutures.emplace_back(std::move(streamFuture)); + } + + handler->WaitForMessages(STREAM_MESSAGE_COUNT); + ASSERT_INT_EQUALS(STREAM_MESSAGE_COUNT, streamMessageFutures.size()); + + for (size_t i = 0; i < streamMessageFutures.size(); i++) + { + auto streamResult = streamMessageFutures[i].get(); + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, streamResult.baseStatus); + } + + ASSERT_SUCCESS(handler->ValidateMessages(expecectedMessageData)); + } + + return AWS_OP_SUCCESS; +} + +static int s_TestEchoClientStreamingOperationEchoSuccessString(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::String value = "Hello World"; + messageData.SetStringMessage(value); + }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationEchoSuccessString, s_TestEchoClientStreamingOperationEchoSuccessString); + +static int s_TestEchoClientStreamingOperationEchoSuccessBoolean(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, [](MessageData &messageData) { messageData.SetBooleanMessage(true); }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationEchoSuccessBoolean, s_TestEchoClientStreamingOperationEchoSuccessBoolean); + +static int s_TestEchoClientStreamingOperationEchoSuccessTime(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, [](MessageData &messageData) { messageData.SetTimeMessage(Aws::Crt::DateTime::Now()); }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationEchoSuccessTime, s_TestEchoClientStreamingOperationEchoSuccessTime); + +static int s_TestEchoClientStreamingOperationEchoSuccessDocument(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::JsonObject subobject; + subobject.WithString("Hello", "There"); + Aws::Crt::JsonObject document; + document.WithInt64("Derp", 21); + document.WithObject("DailyAffirmations", subobject); + + messageData.SetDocumentMessage(document); + }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationEchoSuccessDocument, s_TestEchoClientStreamingOperationEchoSuccessDocument); + +static int s_TestEchoClientStreamingOperationEchoSuccessEnum(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, [](MessageData &messageData) { messageData.SetEnumMessage(FruitEnum::FRUIT_ENUM_PINEAPPLE); }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationEchoSuccessEnum, s_TestEchoClientStreamingOperationEchoSuccessEnum); + +static int s_TestEchoClientStreamingOperationEchoSuccessBlob(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::Vector blob = {1, 2, 3, 4, 5}; + messageData.SetBlobMessage(blob); + }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationEchoSuccessBlob, s_TestEchoClientStreamingOperationEchoSuccessBlob); + +static int s_TestEchoClientStreamingOperationEchoSuccessStringList(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::Vector stringList = {"1", "2", "Toasty", "Mctoaster"}; + messageData.SetStringListMessage(stringList); + }); +} + +AWS_TEST_CASE( + EchoClientStreamingOperationEchoSuccessStringList, + s_TestEchoClientStreamingOperationEchoSuccessStringList); + +static int s_TestEchoClientStreamingOperationEchoSuccessPairList(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Pair pair1; + pair1.SetKey("Uff"); + pair1.SetValue("Dah"); + + Pair pair2; + pair2.SetKey("Hello"); + pair2.SetValue("World"); + + Aws::Crt::Vector pairList = {pair1, pair2}; + messageData.SetKeyValuePairList(pairList); + }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationEchoSuccessPairList, s_TestEchoClientStreamingOperationEchoSuccessPairList); + +static int s_TestEchoClientStreamingOperationEchoSuccessProductMap(struct aws_allocator *allocator, void *ctx) +{ + return s_DoTestEchoClientStreamingOperationEchoSuccess( + allocator, + [](MessageData &messageData) + { + Aws::Crt::Map productMap = {}; + Product product1; + product1.SetName("Derp"); + product1.SetPrice(4.0); + + Product product2; + product2.SetName("Can Of Derp"); + product2.SetPrice(7.5); + + productMap[product1.GetName().value()] = product1; + productMap[product2.GetName().value()] = product2; + + messageData.SetStringToValue(productMap); + }); +} + +AWS_TEST_CASE( + EchoClientStreamingOperationEchoSuccessProductMap, + s_TestEchoClientStreamingOperationEchoSuccessProductMap); + +class CauseServiceErrorTestHandler : public CauseStreamServiceToErrorStreamHandler +{ + public: + CauseServiceErrorTestHandler(Aws::Crt::Allocator *allocator, bool closeOnError) + : m_allocator(allocator), m_closeOnError(closeOnError) + { + } + + void OnStreamEvent(EchoStreamingMessage *response) override { (void)response; } + + bool OnStreamError(RpcError rpcError) override + { + (void)rpcError; + + return m_closeOnError; + } + + bool OnStreamError(ServiceError *serviceError) override + { + std::lock_guard lock(m_lock); + + m_serviceErrors.push_back(Aws::Crt::MakeShared(m_allocator, *serviceError)); + m_signal.notify_all(); + + return m_closeOnError; + } + + bool OnStreamError(OperationError *operationError) override + { + (void)operationError; + + return m_closeOnError; + } + + void WaitForErrors(size_t count) + { + std::unique_lock lock(m_lock); + m_signal.wait(lock, [this, count]() { return m_serviceErrors.size() == count; }); + } + + int ValidateErrors(ServiceError &expectedError) + { + std::lock_guard lock(m_lock); + for (size_t i = 0; i < m_serviceErrors.size(); i++) + { + const auto &error = m_serviceErrors[i]; + + ASSERT_TRUE(error->GetMessage().has_value() == expectedError.GetMessage().has_value()); + ASSERT_TRUE(error->GetValue().has_value() == expectedError.GetValue().has_value()); + + if (expectedError.GetMessage().has_value()) + { + ASSERT_TRUE(expectedError.GetMessage().value() == error->GetMessage().value()); + } + + if (expectedError.GetValue().has_value()) + { + ASSERT_TRUE(expectedError.GetValue().value() == error->GetValue().value()); + } + } + + return AWS_OP_SUCCESS; + } + + private: + Aws::Crt::Allocator *m_allocator; + bool m_closeOnError; + + std::mutex m_lock; + std::condition_variable m_signal; + + Aws::Crt::Vector> m_serviceErrors; +}; + +static int s_TestEchoClientStreamingOperationCauseServiceError(struct aws_allocator *allocator, void *ctx) +{ + ApiHandle apiHandle(allocator); + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + { + auto handler = Aws::Crt::MakeShared(allocator, allocator, false); + ConnectionLifecycleHandler lifecycleHandler; + Awstest::EchoTestRpcClient client(*testContext.clientBootstrap, allocator); + auto connectedStatus = client.Connect(lifecycleHandler); + ASSERT_TRUE(connectedStatus.get().baseStatus == EVENT_STREAM_RPC_SUCCESS); + + auto causeStreamServiceError = client.NewCauseStreamServiceToError(handler); + EchoStreamingRequest request; + auto activateFuture = causeStreamServiceError->Activate(request, s_onMessageFlush); + activateFuture.wait(); + + auto result = causeStreamServiceError->GetResult().get(); + ASSERT_TRUE(result); + + EchoStreamingMessage streamMessage; + MessageData messageData; + Aws::Crt::String value = "Hello World"; + messageData.SetStringMessage(value); + streamMessage.SetStreamMessage(messageData); + + auto streamFuture = causeStreamServiceError->SendStreamMessage(streamMessage, s_onMessageFlush); + + handler->WaitForErrors(1); + + auto streamResult = streamFuture.get(); + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_SUCCESS, streamResult.baseStatus); + + ServiceError expectedError; + expectedError.SetMessage("Intentionally caused ServiceError on stream"); + + ASSERT_SUCCESS(handler->ValidateErrors(expectedError)); + } + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EchoClientStreamingOperationCauseServiceError, s_TestEchoClientStreamingOperationCauseServiceError); + +static int s_TestEchoClientStreamingOperationSendCloseOperation(struct aws_allocator *allocator, void *ctx) +{ + return s_DoSimpleRequestRaceCheckTest( + allocator, + [allocator](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto handler = Aws::Crt::MakeShared(allocator, allocator, false); + auto echoStreamMessages = client.NewEchoStreamMessages(handler); + EchoStreamingRequest echoStreamingMessageRequest; + auto activateFuture = echoStreamMessages->Activate(echoStreamingMessageRequest, s_onMessageFlush); + activateFuture.wait(); + + auto result = echoStreamMessages->GetResult().get(); + ASSERT_TRUE(result); + + EchoStreamingMessage streamMessage; + MessageData messageData; + Aws::Crt::String value = "Hello World"; + messageData.SetStringMessage(value); + + streamMessage.SetStreamMessage(messageData); + + auto streamFuture = echoStreamMessages->SendStreamMessage(streamMessage, s_onMessageFlush); + + auto closeFuture = echoStreamMessages->Close(); + closeFuture.wait(); + + auto streamResultStatus = streamFuture.get().baseStatus; + ASSERT_TRUE( + streamResultStatus == EVENT_STREAM_RPC_SUCCESS || + streamResultStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationSendCloseOperation, s_TestEchoClientStreamingOperationSendCloseOperation); + +static int s_TestEchoClientStreamingOperationSendDropOperation(struct aws_allocator *allocator, void *ctx) +{ + + return s_DoSimpleRequestRaceCheckTest( + allocator, + [allocator](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto handler = Aws::Crt::MakeShared(allocator, allocator, false); + auto echoStreamMessages = client.NewEchoStreamMessages(handler); + EchoStreamingRequest echoStreamingMessageRequest; + auto activateFuture = echoStreamMessages->Activate(echoStreamingMessageRequest, s_onMessageFlush); + activateFuture.wait(); + + auto result = echoStreamMessages->GetResult().get(); + ASSERT_TRUE(result); + + EchoStreamingMessage streamMessage; + MessageData messageData; + Aws::Crt::String value = "Hello World"; + messageData.SetStringMessage(value); + + streamMessage.SetStreamMessage(messageData); + + auto streamFuture = echoStreamMessages->SendStreamMessage(streamMessage, s_onMessageFlush); + + echoStreamMessages = nullptr; + + auto streamResultStatus = streamFuture.get().baseStatus; + ASSERT_TRUE( + streamResultStatus == EVENT_STREAM_RPC_SUCCESS || + streamResultStatus == EVENT_STREAM_RPC_CONTINUATION_CLOSED); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationSendDropOperation, s_TestEchoClientStreamingOperationSendDropOperation); + +static int s_TestEchoClientStreamingOperationSendCloseConnection(struct aws_allocator *allocator, void *ctx) +{ + return s_DoClientScopedRaceCheckTest( + allocator, + [allocator](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto handler = Aws::Crt::MakeShared(allocator, allocator, false); + auto echoStreamMessages = client.NewEchoStreamMessages(handler); + EchoStreamingRequest echoStreamingMessageRequest; + auto activateFuture = echoStreamMessages->Activate(echoStreamingMessageRequest, s_onMessageFlush); + activateFuture.wait(); + + auto result = echoStreamMessages->GetResult().get(); + ASSERT_TRUE(result); + + EchoStreamingMessage streamMessage; + MessageData messageData; + Aws::Crt::String value = "Hello World"; + messageData.SetStringMessage(value); + + streamMessage.SetStreamMessage(messageData); + + auto streamFuture = echoStreamMessages->SendStreamMessage(streamMessage, s_onMessageFlush); + + client.Close(); + + auto streamResultStatus = streamFuture.get().baseStatus; + ASSERT_TRUE( + streamResultStatus == EVENT_STREAM_RPC_SUCCESS || + streamResultStatus == EVENT_STREAM_RPC_CONNECTION_CLOSED); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationSendCloseConnection, s_TestEchoClientStreamingOperationSendCloseConnection); + +static int s_TestEchoClientStreamingOperationUnactivatedSend(struct aws_allocator *allocator, void *ctx) +{ + + return s_DoSimpleRequestRaceCheckTest( + allocator, + [allocator](EventStreamClientTestContext &testContext, EchoTestRpcClient &client) + { + auto handler = Aws::Crt::MakeShared(allocator, allocator, false); + auto echoStreamMessages = client.NewEchoStreamMessages(handler); + + EchoStreamingMessage streamMessage; + MessageData messageData; + Aws::Crt::String value = "Hello World"; + messageData.SetStringMessage(value); + + streamMessage.SetStreamMessage(messageData); + + auto streamFuture = echoStreamMessages->SendStreamMessage(streamMessage, s_onMessageFlush); + + auto streamResultStatus = streamFuture.get().baseStatus; + ASSERT_INT_EQUALS(EVENT_STREAM_RPC_CONTINUATION_NOT_YET_OPENED, streamResultStatus); + + return AWS_OP_SUCCESS; + }); +} + +AWS_TEST_CASE(EchoClientStreamingOperationUnactivatedSend, s_TestEchoClientStreamingOperationUnactivatedSend); + +class EchoStressContext +{ + public: + ~EchoStressContext() + { + m_client = nullptr; + m_stream = nullptr; + } + + std::shared_ptr m_client; + std::shared_ptr m_lifecycleHandler; + std::shared_ptr m_stream; + std::shared_ptr m_streamHandler; + Aws::Crt::Vector> m_oldLifecycleHandlers; + + Aws::Crt::Allocator *m_allocator; +}; + +using StressAction = std::function; + +struct WeightedAction +{ + StressAction m_action; + size_t m_weight; +}; + +class EchoStressActionDistribution +{ + public: + EchoStressActionDistribution(); + + void AddAction(StressAction &&action, size_t weight); + + void ApplyRandomAction(const EventStreamClientTestContext &testContext, EchoStressContext &stressContext); + + private: + Aws::Crt::Vector m_actions; + + size_t m_totalWeight; +}; + +EchoStressActionDistribution::EchoStressActionDistribution() : m_actions(), m_totalWeight(0) {} + +void EchoStressActionDistribution::AddAction(StressAction &&action, size_t weight) +{ + if (weight == 0) + { + return; + } + + m_actions.emplace_back(std::move(WeightedAction{std::move(action), weight})); + m_totalWeight += weight; +} + +void EchoStressActionDistribution::ApplyRandomAction( + const EventStreamClientTestContext &testContext, + EchoStressContext &stressContext) +{ + if (m_totalWeight == 0 || m_actions.empty()) + { + return; + } + + size_t accumulator = std::rand() % m_totalWeight; + for (size_t i = 0; i < m_actions.size(); ++i) + { + const auto &action = m_actions[i]; + + if (accumulator < action.m_weight) + { + action.m_action(testContext, stressContext); + break; + } + + accumulator -= action.m_weight; + } +} + +static void s_CreateClientIfNeeded(const EventStreamClientTestContext &testContext, EchoStressContext &stressContext) +{ + if (stressContext.m_client != nullptr) + { + return; + } + + stressContext.m_lifecycleHandler = Aws::Crt::MakeShared(stressContext.m_allocator); + stressContext.m_client = Aws::Crt::MakeShared( + stressContext.m_allocator, *testContext.clientBootstrap, stressContext.m_allocator); +} + +static void s_BeginClientAction(const EventStreamClientTestContext &testContext, EchoStressContext &stressContext) +{ + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - BeginClient"); + s_CreateClientIfNeeded(testContext, stressContext); + + auto connectFuture = stressContext.m_client->Connect(*stressContext.m_lifecycleHandler); + + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - BeginClient - waiting on connect future"); + connectFuture.wait(); + } +} + +static void s_EndClientAction(const EventStreamClientTestContext &testContext, EchoStressContext &stressContext) +{ + (void)testContext; + + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - EndClient"); + if (stressContext.m_client == nullptr) + { + return; + } + + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - EndClient - Closing"); + stressContext.m_client->Close(); + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - EndClient - Waiting On Close Completion"); + stressContext.m_lifecycleHandler->WaitOnDisconnected(); + } + } + else + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - EndClient - Dropping"); + stressContext.m_oldLifecycleHandlers.push_back(stressContext.m_lifecycleHandler); + stressContext.m_lifecycleHandler = nullptr; + stressContext.m_client = nullptr; + } +} + +static void s_RequestResponseAction(const EventStreamClientTestContext &testContext, EchoStressContext &stressContext) +{ + (void)testContext; + + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - RequestResponse"); + s_CreateClientIfNeeded(testContext, stressContext); + + auto echoMessage = stressContext.m_client->NewEchoMessage(); + + EchoMessageRequest echoMessageRequest; + MessageData messageData; + messageData.SetStringMessage("HelloWorld"); + echoMessageRequest.SetMessage(messageData); + + auto requestFuture = echoMessage->Activate(echoMessageRequest, s_onMessageFlush); + + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - RequestResponse - waiting on flush future"); + auto flushResult = requestFuture.get(); + + if (flushResult.baseStatus == EVENT_STREAM_RPC_SUCCESS) + { + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - RequestResponse - waiting on result"); + auto result = echoMessage->GetResult().get(); + } + } + } +} + +static void s_BeginStreamAction(const EventStreamClientTestContext &testContext, EchoStressContext &stressContext) +{ + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - BeginStream"); + s_CreateClientIfNeeded(testContext, stressContext); + + stressContext.m_stream = nullptr; + stressContext.m_streamHandler = nullptr; + + stressContext.m_streamHandler = Aws::Crt::MakeShared( + stressContext.m_allocator, stressContext.m_allocator, false); + auto echoStreamMessages = stressContext.m_client->NewEchoStreamMessages(stressContext.m_streamHandler); + + EchoStreamingRequest echoStreamingMessageRequest; + auto activateFuture = echoStreamMessages->Activate(echoStreamingMessageRequest, s_onMessageFlush); + + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - BeginStream - waiting on Activate flush future"); + auto flushResult = activateFuture.get(); + if (flushResult.baseStatus == EVENT_STREAM_RPC_SUCCESS) + { + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - BeginStream - waiting on Activate result"); + auto result = echoStreamMessages->GetResult().get(); + } + } + } +} + +static void s_SendStreamAction(const EventStreamClientTestContext &testContext, EchoStressContext &stressContext) +{ + (void)testContext; + + if (stressContext.m_stream == nullptr) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - SendStream - nothing to do"); + return; + } + + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - SendStream"); + EchoStreamingMessage streamMessage; + MessageData messageData; + Aws::Crt::String value = "Hello World"; + messageData.SetStringMessage(value); + + streamMessage.SetStreamMessage(messageData); + + auto streamFuture = stressContext.m_stream->SendStreamMessage(streamMessage, s_onMessageFlush); + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - SendStream - waiting on flush future"); + streamFuture.get(); + } +} + +static void s_EndStreamAction(const EventStreamClientTestContext &testContext, EchoStressContext &stressContext) +{ + (void)testContext; + + if (stressContext.m_stream == nullptr) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - EndStream - nothing to do"); + return; + } + + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - EndStream - Closing"); + auto closeFuture = stressContext.m_stream->Close(); + if (std::rand() % 2) + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - EndStream - Waiting on Close future"); + closeFuture.wait(); + } + } + else + { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "EchoStressTest - EndStream - Dropping"); + stressContext.m_stream = nullptr; + stressContext.m_streamHandler = nullptr; + } +} + +constexpr size_t STRESS_TEST_STEP_COUNT = 50000; + +static int s_TestEchoClientOperationStress(struct aws_allocator *allocator, void *ctx) +{ + (void)ctx; + + ApiHandle apiHandle(allocator); + + { + EchoStressContext stressContext; + stressContext.m_allocator = allocator; + + EventStreamClientTestContext testContext(allocator); + if (!testContext.isValidEnvironment()) + { + printf("Environment Variables are not set for the test, skipping..."); + return AWS_OP_SKIP; + } + + EchoStressActionDistribution actionDistribution; + actionDistribution.AddAction(s_BeginClientAction, 3); + actionDistribution.AddAction(s_EndClientAction, 1); + actionDistribution.AddAction(s_RequestResponseAction, 4); + actionDistribution.AddAction(s_BeginStreamAction, 2); + actionDistribution.AddAction(s_SendStreamAction, 4); + actionDistribution.AddAction(s_EndStreamAction, 1); + + for (size_t i = 0; i < STRESS_TEST_STEP_COUNT; ++i) + { + actionDistribution.ApplyRandomAction(testContext, stressContext); + } + } + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE(EchoClientOperationStress, s_TestEchoClientOperationStress); diff --git a/eventstream_rpc/tests/include/awstest/EchoTestRpcClient.h b/eventstream_rpc/tests/include/awstest/EchoTestRpcClient.h index 0afe066f1..231ff78e7 100644 --- a/eventstream_rpc/tests/include/awstest/EchoTestRpcClient.h +++ b/eventstream_rpc/tests/include/awstest/EchoTestRpcClient.h @@ -36,7 +36,7 @@ namespace Awstest std::future Connect( ConnectionLifecycleHandler &lifecycleHandler, const ConnectionConfig &connectionConfig = DefaultConnectionConfig()) noexcept; - bool IsConnected() const noexcept { return m_connection.IsOpen(); } + bool IsConnected() const noexcept { return m_connection->IsOpen(); } void Close() noexcept; void WithLaunchMode(std::launch mode) noexcept; @@ -76,8 +76,7 @@ namespace Awstest private: EchoTestRpcServiceModel m_echoTestRpcServiceModel; - ClientConnection m_connection; - Aws::Crt::Io::ClientBootstrap &m_clientBootstrap; + std::shared_ptr m_connection; Aws::Crt::Allocator *m_allocator; MessageAmendment m_connectAmendment; std::launch m_asyncLaunchMode; diff --git a/eventstream_rpc/tests/include/awstest/EchoTestRpcModel.h b/eventstream_rpc/tests/include/awstest/EchoTestRpcModel.h index b3eec4ce2..703c5fa9b 100644 --- a/eventstream_rpc/tests/include/awstest/EchoTestRpcModel.h +++ b/eventstream_rpc/tests/include/awstest/EchoTestRpcModel.h @@ -25,7 +25,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API Product : public AbstractShapeBase { public: - Product() noexcept {} + Product() noexcept = default; Product(const Product &) = default; /** * The product's name @@ -34,7 +34,7 @@ namespace Awstest /** * The product's name */ - Aws::Crt::Optional GetName() noexcept { return m_name; } + Aws::Crt::Optional GetName() const noexcept { return m_name; } /** * How much the product costs */ @@ -42,7 +42,7 @@ namespace Awstest /** * How much the product costs */ - Aws::Crt::Optional GetPrice() noexcept { return m_price; } + Aws::Crt::Optional GetPrice() const noexcept { return m_price; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(Product &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -67,7 +67,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API Pair : public AbstractShapeBase { public: - Pair() noexcept {} + Pair() noexcept = default; Pair(const Pair &) = default; /** * Pair.key as a string @@ -76,7 +76,7 @@ namespace Awstest /** * Pair.key as a string */ - Aws::Crt::Optional GetKey() noexcept { return m_key; } + Aws::Crt::Optional GetKey() const noexcept { return m_key; } /** * Pair.value also a string! */ @@ -84,7 +84,7 @@ namespace Awstest /** * Pair.value also a string! */ - Aws::Crt::Optional GetValue() noexcept { return m_value; } + Aws::Crt::Optional GetValue() const noexcept { return m_value; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(Pair &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -117,7 +117,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API Customer : public AbstractShapeBase { public: - Customer() noexcept {} + Customer() noexcept = default; Customer(const Customer &) = default; /** * Opaque customer identifier @@ -126,7 +126,7 @@ namespace Awstest /** * Opaque customer identifier */ - Aws::Crt::Optional GetId() noexcept { return m_id; } + Aws::Crt::Optional GetId() const noexcept { return m_id; } /** * First name of the customer */ @@ -134,7 +134,7 @@ namespace Awstest /** * First name of the customer */ - Aws::Crt::Optional GetFirstName() noexcept { return m_firstName; } + Aws::Crt::Optional GetFirstName() const noexcept { return m_firstName; } /** * Last name of the customer */ @@ -142,7 +142,7 @@ namespace Awstest /** * Last name of the customer */ - Aws::Crt::Optional GetLastName() noexcept { return m_lastName; } + Aws::Crt::Optional GetLastName() const noexcept { return m_lastName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(Customer &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -168,7 +168,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API MessageData : public AbstractShapeBase { public: - MessageData() noexcept {} + MessageData() noexcept = default; MessageData(const MessageData &) = default; /** * Some string data @@ -177,7 +177,7 @@ namespace Awstest /** * Some string data */ - Aws::Crt::Optional GetStringMessage() noexcept { return m_stringMessage; } + Aws::Crt::Optional GetStringMessage() const noexcept { return m_stringMessage; } /** * Some boolean data */ @@ -185,7 +185,7 @@ namespace Awstest /** * Some boolean data */ - Aws::Crt::Optional GetBooleanMessage() noexcept { return m_booleanMessage; } + Aws::Crt::Optional GetBooleanMessage() const noexcept { return m_booleanMessage; } /** * Some timestamp data */ @@ -193,7 +193,7 @@ namespace Awstest /** * Some timestamp data */ - Aws::Crt::Optional GetTimeMessage() noexcept { return m_timeMessage; } + Aws::Crt::Optional GetTimeMessage() const noexcept { return m_timeMessage; } /** * Some document data */ @@ -204,7 +204,7 @@ namespace Awstest /** * Some document data */ - Aws::Crt::Optional GetDocumentMessage() noexcept { return m_documentMessage; } + Aws::Crt::Optional GetDocumentMessage() const noexcept { return m_documentMessage; } /** * Some FruitEnum data */ @@ -212,7 +212,7 @@ namespace Awstest /** * Some FruitEnum data */ - Aws::Crt::Optional GetEnumMessage() noexcept; + Aws::Crt::Optional GetEnumMessage() const noexcept; /** * Some blob data */ @@ -220,7 +220,7 @@ namespace Awstest /** * Some blob data */ - Aws::Crt::Optional> GetBlobMessage() noexcept { return m_blobMessage; } + Aws::Crt::Optional> GetBlobMessage() const noexcept { return m_blobMessage; } /** * Some list of strings data */ @@ -231,7 +231,7 @@ namespace Awstest /** * Some list of strings data */ - Aws::Crt::Optional> GetStringListMessage() noexcept + Aws::Crt::Optional> GetStringListMessage() const noexcept { return m_stringListMessage; } @@ -245,7 +245,7 @@ namespace Awstest /** * A list of key-value pairs */ - Aws::Crt::Optional> GetKeyValuePairList() noexcept { return m_keyValuePairList; } + Aws::Crt::Optional> GetKeyValuePairList() const noexcept { return m_keyValuePairList; } /** * A map from strings to Product shapes */ @@ -256,7 +256,7 @@ namespace Awstest /** * A map from strings to Product shapes */ - Aws::Crt::Optional> GetStringToValue() noexcept + Aws::Crt::Optional> GetStringToValue() const noexcept { return m_stringToValue; } @@ -291,7 +291,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API EchoStreamingMessage : public AbstractShapeBase { public: - EchoStreamingMessage() noexcept {} + EchoStreamingMessage() noexcept = default; EchoStreamingMessage &operator=(const EchoStreamingMessage &) noexcept; EchoStreamingMessage(const EchoStreamingMessage &objectToCopy) { *this = objectToCopy; } /** @@ -305,7 +305,7 @@ namespace Awstest /** * A message data record */ - Aws::Crt::Optional GetStreamMessage() noexcept + Aws::Crt::Optional GetStreamMessage() const noexcept { if (m_chosenMember == TAG_STREAM_MESSAGE) { @@ -327,7 +327,7 @@ namespace Awstest /** * A key value pair */ - Aws::Crt::Optional GetKeyValuePair() noexcept + Aws::Crt::Optional GetKeyValuePair() const noexcept { if (m_chosenMember == TAG_KEY_VALUE_PAIR) { @@ -367,7 +367,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API ServiceError : public OperationError { public: - ServiceError() noexcept {} + ServiceError() noexcept = default; ServiceError(const ServiceError &) = default; /** * An error message @@ -376,7 +376,7 @@ namespace Awstest /** * An error message */ - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } /** * Some auxiliary value */ @@ -384,7 +384,7 @@ namespace Awstest /** * Some auxiliary value */ - Aws::Crt::Optional GetValue() noexcept { return m_value; } + Aws::Crt::Optional GetValue() const noexcept { return m_value; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ServiceError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -409,7 +409,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API GetAllProductsResponse : public AbstractShapeBase { public: - GetAllProductsResponse() noexcept {} + GetAllProductsResponse() noexcept = default; GetAllProductsResponse(const GetAllProductsResponse &) = default; /** * A map from strings to products @@ -418,7 +418,7 @@ namespace Awstest /** * A map from strings to products */ - Aws::Crt::Optional> GetProducts() noexcept { return m_products; } + Aws::Crt::Optional> GetProducts() const noexcept { return m_products; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetAllProductsResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -442,7 +442,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API GetAllProductsRequest : public AbstractShapeBase { public: - GetAllProductsRequest() noexcept {} + GetAllProductsRequest() noexcept = default; GetAllProductsRequest(const GetAllProductsRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetAllProductsRequest &, const Aws::Crt::JsonView &) noexcept; @@ -466,7 +466,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API GetAllCustomersResponse : public AbstractShapeBase { public: - GetAllCustomersResponse() noexcept {} + GetAllCustomersResponse() noexcept = default; GetAllCustomersResponse(const GetAllCustomersResponse &) = default; /** * A list of all known customers @@ -475,7 +475,7 @@ namespace Awstest /** * A list of all known customers */ - Aws::Crt::Optional> GetCustomers() noexcept { return m_customers; } + Aws::Crt::Optional> GetCustomers() const noexcept { return m_customers; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetAllCustomersResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -499,7 +499,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API GetAllCustomersRequest : public AbstractShapeBase { public: - GetAllCustomersRequest() noexcept {} + GetAllCustomersRequest() noexcept = default; GetAllCustomersRequest(const GetAllCustomersRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetAllCustomersRequest &, const Aws::Crt::JsonView &) noexcept; @@ -523,7 +523,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API EchoStreamingResponse : public AbstractShapeBase { public: - EchoStreamingResponse() noexcept {} + EchoStreamingResponse() noexcept = default; EchoStreamingResponse(const EchoStreamingResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(EchoStreamingResponse &, const Aws::Crt::JsonView &) noexcept; @@ -547,7 +547,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API EchoStreamingRequest : public AbstractShapeBase { public: - EchoStreamingRequest() noexcept {} + EchoStreamingRequest() noexcept = default; EchoStreamingRequest(const EchoStreamingRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(EchoStreamingRequest &, const Aws::Crt::JsonView &) noexcept; @@ -571,7 +571,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API EchoMessageResponse : public AbstractShapeBase { public: - EchoMessageResponse() noexcept {} + EchoMessageResponse() noexcept = default; EchoMessageResponse(const EchoMessageResponse &) = default; /** * Some message data @@ -580,7 +580,7 @@ namespace Awstest /** * Some message data */ - Aws::Crt::Optional GetMessage() noexcept { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(EchoMessageResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -604,7 +604,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API EchoMessageRequest : public AbstractShapeBase { public: - EchoMessageRequest() noexcept {} + EchoMessageRequest() noexcept = default; EchoMessageRequest(const EchoMessageRequest &) = default; /** * Some message data @@ -613,7 +613,7 @@ namespace Awstest /** * Some message data */ - Aws::Crt::Optional GetMessage() noexcept { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(EchoMessageRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -637,7 +637,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API CauseServiceErrorResponse : public AbstractShapeBase { public: - CauseServiceErrorResponse() noexcept {} + CauseServiceErrorResponse() noexcept = default; CauseServiceErrorResponse(const CauseServiceErrorResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CauseServiceErrorResponse &, const Aws::Crt::JsonView &) noexcept; @@ -661,7 +661,7 @@ namespace Awstest class AWS_ECHOTESTRPC_API CauseServiceErrorRequest : public AbstractShapeBase { public: - CauseServiceErrorRequest() noexcept {} + CauseServiceErrorRequest() noexcept = default; CauseServiceErrorRequest(const CauseServiceErrorRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CauseServiceErrorRequest &, const Aws::Crt::JsonView &) noexcept; @@ -679,22 +679,6 @@ namespace Awstest private: }; - class AWS_ECHOTESTRPC_API GetAllProductsOperationContext : public OperationModelContext - { - public: - GetAllProductsOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; - class AWS_ECHOTESTRPC_API GetAllProductsResult { public: @@ -704,11 +688,12 @@ namespace Awstest { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -722,8 +707,9 @@ namespace Awstest public: GetAllProductsOperation( ClientConnection &connection, - const GetAllProductsOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `GetAllProductsOperation` * @param request The request used for the `GetAllProductsOperation` @@ -733,29 +719,14 @@ namespace Awstest std::future Activate( const GetAllProductsRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_ECHOTESTRPC_API CauseServiceErrorOperationContext : public OperationModelContext - { - public: - CauseServiceErrorOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_ECHOTESTRPC_API CauseServiceErrorResult @@ -767,11 +738,12 @@ namespace Awstest { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -785,8 +757,9 @@ namespace Awstest public: CauseServiceErrorOperation( ClientConnection &connection, - const CauseServiceErrorOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `CauseServiceErrorOperation` * @param request The request used for the `CauseServiceErrorOperation` @@ -796,13 +769,14 @@ namespace Awstest std::future Activate( const CauseServiceErrorRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_ECHOTESTRPC_API CauseStreamServiceToErrorStreamHandler : public StreamResponseHandler @@ -845,6 +819,7 @@ namespace Awstest * Invoked when a message is received on this continuation. */ void OnStreamEvent(Aws::Crt::ScopedResource response) override; + /** * Invoked when a message is received on this continuation but results in an error. * @@ -852,21 +827,6 @@ namespace Awstest */ bool OnStreamError(Aws::Crt::ScopedResource error, RpcError rpcError) override; }; - class AWS_ECHOTESTRPC_API CauseStreamServiceToErrorOperationContext : public OperationModelContext - { - public: - CauseStreamServiceToErrorOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; class AWS_ECHOTESTRPC_API CauseStreamServiceToErrorResult { @@ -879,11 +839,12 @@ namespace Awstest { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -898,8 +859,9 @@ namespace Awstest CauseStreamServiceToErrorOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const CauseStreamServiceToErrorOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `CauseStreamServiceToErrorOperation` * @param request The request used for the `CauseStreamServiceToErrorOperation` @@ -909,13 +871,26 @@ namespace Awstest std::future Activate( const EchoStreamingRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + + /** + * Send a EchoStreamingMessage stream event. + * + * Activate() must have completed before calling SendMessage(). + * + * Returns a Future which completes with a value indicating message + * flush success or what went wrong. + **/ + std::future SendStreamMessage( + const EchoStreamingMessage &event, + OnMessageFlushCallback onMessageFlushCallback = nullptr); + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_ECHOTESTRPC_API EchoStreamMessagesStreamHandler : public StreamResponseHandler @@ -948,6 +923,7 @@ namespace Awstest * Invoked when a message is received on this continuation. */ void OnStreamEvent(Aws::Crt::ScopedResource response) override; + /** * Invoked when a message is received on this continuation but results in an error. * @@ -955,21 +931,6 @@ namespace Awstest */ bool OnStreamError(Aws::Crt::ScopedResource error, RpcError rpcError) override; }; - class AWS_ECHOTESTRPC_API EchoStreamMessagesOperationContext : public OperationModelContext - { - public: - EchoStreamMessagesOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; class AWS_ECHOTESTRPC_API EchoStreamMessagesResult { @@ -980,11 +941,12 @@ namespace Awstest { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -999,8 +961,9 @@ namespace Awstest EchoStreamMessagesOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const EchoStreamMessagesOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `EchoStreamMessagesOperation` * @param request The request used for the `EchoStreamMessagesOperation` @@ -1010,29 +973,26 @@ namespace Awstest std::future Activate( const EchoStreamingRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + + /** + * Send a EchoStreamingMessage stream event. + * + * Activate() must have completed before calling SendMessage(). + * + * Returns a Future which completes with a value indicating message + * flush success or what went wrong. + **/ + std::future SendStreamMessage( + const EchoStreamingMessage &event, + OnMessageFlushCallback onMessageFlushCallback = nullptr); + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_ECHOTESTRPC_API EchoMessageOperationContext : public OperationModelContext - { - public: - EchoMessageOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_ECHOTESTRPC_API EchoMessageResult @@ -1044,11 +1004,12 @@ namespace Awstest { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -1062,8 +1023,9 @@ namespace Awstest public: EchoMessageOperation( ClientConnection &connection, - const EchoMessageOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `EchoMessageOperation` * @param request The request used for the `EchoMessageOperation` @@ -1073,29 +1035,14 @@ namespace Awstest std::future Activate( const EchoMessageRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_ECHOTESTRPC_API GetAllCustomersOperationContext : public OperationModelContext - { - public: - GetAllCustomersOperationContext(const EchoTestRpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_ECHOTESTRPC_API GetAllCustomersResult @@ -1107,11 +1054,12 @@ namespace Awstest { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -1125,8 +1073,9 @@ namespace Awstest public: GetAllCustomersOperation( ClientConnection &connection, - const GetAllCustomersOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `GetAllCustomersOperation` * @param request The request used for the `GetAllCustomersOperation` @@ -1136,19 +1085,20 @@ namespace Awstest std::future Activate( const GetAllCustomersRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_ECHOTESTRPC_API EchoTestRpcServiceModel : public ServiceModel { public: - EchoTestRpcServiceModel() noexcept; + EchoTestRpcServiceModel(Aws::Crt::Allocator *allocator) noexcept; Aws::Crt::ScopedResource AllocateOperationErrorFromPayload( const Aws::Crt::String &errorModelName, Aws::Crt::StringView stringView, @@ -1157,12 +1107,12 @@ namespace Awstest private: friend class EchoTestRpcClient; - GetAllProductsOperationContext m_getAllProductsOperationContext; - CauseServiceErrorOperationContext m_causeServiceErrorOperationContext; - CauseStreamServiceToErrorOperationContext m_causeStreamServiceToErrorOperationContext; - EchoStreamMessagesOperationContext m_echoStreamMessagesOperationContext; - EchoMessageOperationContext m_echoMessageOperationContext; - GetAllCustomersOperationContext m_getAllCustomersOperationContext; + std::shared_ptr m_getAllProductsOperationContext; + std::shared_ptr m_causeServiceErrorOperationContext; + std::shared_ptr m_causeStreamServiceToErrorOperationContext; + std::shared_ptr m_echoStreamMessagesOperationContext; + std::shared_ptr m_echoMessageOperationContext; + std::shared_ptr m_getAllCustomersOperationContext; Aws::Crt::Map m_modelNameToErrorResponse; }; } // namespace Awstest diff --git a/greengrass_ipc/include/aws/greengrass/GreengrassCoreIpcClient.h b/greengrass_ipc/include/aws/greengrass/GreengrassCoreIpcClient.h index 502031d4f..4724e1bdc 100644 --- a/greengrass_ipc/include/aws/greengrass/GreengrassCoreIpcClient.h +++ b/greengrass_ipc/include/aws/greengrass/GreengrassCoreIpcClient.h @@ -38,7 +38,7 @@ namespace Aws std::future Connect( ConnectionLifecycleHandler &lifecycleHandler, const ConnectionConfig &connectionConfig = DefaultConnectionConfig()) noexcept; - bool IsConnected() const noexcept { return m_connection.IsOpen(); } + bool IsConnected() const noexcept { return m_connection->IsOpen(); } void Close() noexcept; void WithLaunchMode(std::launch mode) noexcept; @@ -235,8 +235,7 @@ namespace Aws private: GreengrassCoreIpcServiceModel m_greengrassCoreIpcServiceModel; - ClientConnection m_connection; - Aws::Crt::Io::ClientBootstrap &m_clientBootstrap; + std::shared_ptr m_connection; Aws::Crt::Allocator *m_allocator; MessageAmendment m_connectAmendment; std::launch m_asyncLaunchMode; diff --git a/greengrass_ipc/include/aws/greengrass/GreengrassCoreIpcModel.h b/greengrass_ipc/include/aws/greengrass/GreengrassCoreIpcModel.h index 652da3f4a..0644cd38e 100644 --- a/greengrass_ipc/include/aws/greengrass/GreengrassCoreIpcModel.h +++ b/greengrass_ipc/include/aws/greengrass/GreengrassCoreIpcModel.h @@ -24,16 +24,16 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API UserProperty : public AbstractShapeBase { public: - UserProperty() noexcept {} + UserProperty() noexcept = default; UserProperty(const UserProperty &) = default; void SetKey(const Aws::Crt::String &key) noexcept { m_key = key; } - Aws::Crt::Optional GetKey() noexcept { return m_key; } + Aws::Crt::Optional GetKey() const noexcept { return m_key; } void SetValue(const Aws::Crt::String &value) noexcept { m_value = value; } - Aws::Crt::Optional GetValue() noexcept { return m_value; } + Aws::Crt::Optional GetValue() const noexcept { return m_value; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(UserProperty &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -68,7 +68,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API MessageContext : public AbstractShapeBase { public: - MessageContext() noexcept {} + MessageContext() noexcept = default; MessageContext(const MessageContext &) = default; /** * The topic where the message was published. @@ -77,7 +77,7 @@ namespace Aws /** * The topic where the message was published. */ - Aws::Crt::Optional GetTopic() noexcept { return m_topic; } + Aws::Crt::Optional GetTopic() const noexcept { return m_topic; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(MessageContext &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -114,7 +114,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API DeploymentStatusDetails : public AbstractShapeBase { public: - DeploymentStatusDetails() noexcept {} + DeploymentStatusDetails() noexcept = default; DeploymentStatusDetails(const DeploymentStatusDetails &) = default; /** * The detailed deployment status of the local deployment. @@ -123,7 +123,7 @@ namespace Aws /** * The detailed deployment status of the local deployment. */ - Aws::Crt::Optional GetDetailedDeploymentStatus() noexcept; + Aws::Crt::Optional GetDetailedDeploymentStatus() const noexcept; /** * (Optional) The list of local deployment errors */ @@ -134,7 +134,7 @@ namespace Aws /** * (Optional) The list of local deployment errors */ - Aws::Crt::Optional> GetDeploymentErrorStack() noexcept + Aws::Crt::Optional> GetDeploymentErrorStack() const noexcept { return m_deploymentErrorStack; } @@ -148,7 +148,7 @@ namespace Aws /** * (Optional) The list of local deployment error types */ - Aws::Crt::Optional> GetDeploymentErrorTypes() noexcept + Aws::Crt::Optional> GetDeploymentErrorTypes() const noexcept { return m_deploymentErrorTypes; } @@ -162,7 +162,7 @@ namespace Aws /** * (Optional) The cause of local deployment failure */ - Aws::Crt::Optional GetDeploymentFailureCause() noexcept + Aws::Crt::Optional GetDeploymentFailureCause() const noexcept { return m_deploymentFailureCause; } @@ -210,7 +210,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SystemResourceLimits : public AbstractShapeBase { public: - SystemResourceLimits() noexcept {} + SystemResourceLimits() noexcept = default; SystemResourceLimits(const SystemResourceLimits &) = default; /** * (Optional) The maximum amount of RAM (in kilobytes) that this component's processes can use on the core @@ -221,7 +221,7 @@ namespace Aws * (Optional) The maximum amount of RAM (in kilobytes) that this component's processes can use on the core * device. */ - Aws::Crt::Optional GetMemory() noexcept { return m_memory; } + Aws::Crt::Optional GetMemory() const noexcept { return m_memory; } /** * (Optional) The maximum amount of CPU time that this component's processes can use on the core device. */ @@ -229,7 +229,7 @@ namespace Aws /** * (Optional) The maximum amount of CPU time that this component's processes can use on the core device. */ - Aws::Crt::Optional GetCpus() noexcept { return m_cpus; } + Aws::Crt::Optional GetCpus() const noexcept { return m_cpus; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(SystemResourceLimits &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -251,7 +251,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ValidateConfigurationUpdateEvent : public AbstractShapeBase { public: - ValidateConfigurationUpdateEvent() noexcept {} + ValidateConfigurationUpdateEvent() noexcept = default; ValidateConfigurationUpdateEvent(const ValidateConfigurationUpdateEvent &) = default; /** * The object that contains the new configuration. @@ -263,7 +263,7 @@ namespace Aws /** * The object that contains the new configuration. */ - Aws::Crt::Optional GetConfiguration() noexcept { return m_configuration; } + Aws::Crt::Optional GetConfiguration() const noexcept { return m_configuration; } /** * The ID of the AWS IoT Greengrass deployment that updates the component. */ @@ -271,7 +271,7 @@ namespace Aws /** * The ID of the AWS IoT Greengrass deployment that updates the component. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ValidateConfigurationUpdateEvent &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -293,7 +293,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API BinaryMessage : public AbstractShapeBase { public: - BinaryMessage() noexcept {} + BinaryMessage() noexcept = default; BinaryMessage(const BinaryMessage &) = default; /** * The binary message as a blob. @@ -302,7 +302,7 @@ namespace Aws /** * The binary message as a blob. */ - Aws::Crt::Optional> GetMessage() noexcept { return m_message; } + Aws::Crt::Optional> GetMessage() const noexcept { return m_message; } /** * The context of the message, such as the topic where the message was published. */ @@ -310,7 +310,7 @@ namespace Aws /** * The context of the message, such as the topic where the message was published. */ - Aws::Crt::Optional GetContext() noexcept { return m_context; } + Aws::Crt::Optional GetContext() const noexcept { return m_context; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(BinaryMessage &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -332,7 +332,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API JsonMessage : public AbstractShapeBase { public: - JsonMessage() noexcept {} + JsonMessage() noexcept = default; JsonMessage(const JsonMessage &) = default; /** * The JSON message as an object. @@ -341,7 +341,7 @@ namespace Aws /** * The JSON message as an object. */ - Aws::Crt::Optional GetMessage() noexcept { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept { return m_message; } /** * The context of the message, such as the topic where the message was published. */ @@ -349,7 +349,7 @@ namespace Aws /** * The context of the message, such as the topic where the message was published. */ - Aws::Crt::Optional GetContext() noexcept { return m_context; } + Aws::Crt::Optional GetContext() const noexcept { return m_context; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(JsonMessage &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -371,7 +371,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API MQTTMessage : public AbstractShapeBase { public: - MQTTMessage() noexcept {} + MQTTMessage() noexcept = default; MQTTMessage(const MQTTMessage &) = default; /** * The topic to which the message was published. @@ -380,7 +380,7 @@ namespace Aws /** * The topic to which the message was published. */ - Aws::Crt::Optional GetTopicName() noexcept { return m_topicName; } + Aws::Crt::Optional GetTopicName() const noexcept { return m_topicName; } /** * (Optional) The message payload as a blob. */ @@ -388,7 +388,7 @@ namespace Aws /** * (Optional) The message payload as a blob. */ - Aws::Crt::Optional> GetPayload() noexcept { return m_payload; } + Aws::Crt::Optional> GetPayload() const noexcept { return m_payload; } /** * (Optional) The value of the retain flag. */ @@ -396,7 +396,7 @@ namespace Aws /** * (Optional) The value of the retain flag. */ - Aws::Crt::Optional GetRetain() noexcept { return m_retain; } + Aws::Crt::Optional GetRetain() const noexcept { return m_retain; } /** * (Optional) MQTT user properties associated with the message. */ @@ -407,7 +407,10 @@ namespace Aws /** * (Optional) MQTT user properties associated with the message. */ - Aws::Crt::Optional> GetUserProperties() noexcept { return m_userProperties; } + Aws::Crt::Optional> GetUserProperties() const noexcept + { + return m_userProperties; + } /** * (Optional) Message expiry interval in seconds. */ @@ -418,7 +421,7 @@ namespace Aws /** * (Optional) Message expiry interval in seconds. */ - Aws::Crt::Optional GetMessageExpiryIntervalSeconds() noexcept + Aws::Crt::Optional GetMessageExpiryIntervalSeconds() const noexcept { return m_messageExpiryIntervalSeconds; } @@ -432,7 +435,10 @@ namespace Aws /** * (Optional) Correlation data blob for request/response. */ - Aws::Crt::Optional> GetCorrelationData() noexcept { return m_correlationData; } + Aws::Crt::Optional> GetCorrelationData() const noexcept + { + return m_correlationData; + } /** * (Optional) Response topic for request/response. */ @@ -440,7 +446,7 @@ namespace Aws /** * (Optional) Response topic for request/response. */ - Aws::Crt::Optional GetResponseTopic() noexcept { return m_responseTopic; } + Aws::Crt::Optional GetResponseTopic() const noexcept { return m_responseTopic; } /** * (Optional) Message payload format. */ @@ -448,7 +454,7 @@ namespace Aws /** * (Optional) Message payload format. */ - Aws::Crt::Optional GetPayloadFormat() noexcept; + Aws::Crt::Optional GetPayloadFormat() const noexcept; /** * (Optional) Message content type. */ @@ -456,7 +462,7 @@ namespace Aws /** * (Optional) Message content type. */ - Aws::Crt::Optional GetContentType() noexcept { return m_contentType; } + Aws::Crt::Optional GetContentType() const noexcept { return m_contentType; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(MQTTMessage &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -485,7 +491,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ConfigurationUpdateEvent : public AbstractShapeBase { public: - ConfigurationUpdateEvent() noexcept {} + ConfigurationUpdateEvent() noexcept = default; ConfigurationUpdateEvent(const ConfigurationUpdateEvent &) = default; /** * The name of the component. @@ -494,7 +500,7 @@ namespace Aws /** * The name of the component. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } /** * The key path to the configuration value that updated. */ @@ -502,7 +508,7 @@ namespace Aws /** * The key path to the configuration value that updated. */ - Aws::Crt::Optional> GetKeyPath() noexcept { return m_keyPath; } + Aws::Crt::Optional> GetKeyPath() const noexcept { return m_keyPath; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ConfigurationUpdateEvent &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -524,7 +530,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PostComponentUpdateEvent : public AbstractShapeBase { public: - PostComponentUpdateEvent() noexcept {} + PostComponentUpdateEvent() noexcept = default; PostComponentUpdateEvent(const PostComponentUpdateEvent &) = default; /** * The ID of the AWS IoT Greengrass deployment that updated the component. @@ -533,7 +539,7 @@ namespace Aws /** * The ID of the AWS IoT Greengrass deployment that updated the component. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PostComponentUpdateEvent &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -554,7 +560,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PreComponentUpdateEvent : public AbstractShapeBase { public: - PreComponentUpdateEvent() noexcept {} + PreComponentUpdateEvent() noexcept = default; PreComponentUpdateEvent(const PreComponentUpdateEvent &) = default; /** * The ID of the AWS IoT Greengrass deployment that updates the component. @@ -563,7 +569,7 @@ namespace Aws /** * The ID of the AWS IoT Greengrass deployment that updates the component. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } /** * Whether or not Greengrass needs to restart to apply the update. */ @@ -571,7 +577,7 @@ namespace Aws /** * Whether or not Greengrass needs to restart to apply the update. */ - Aws::Crt::Optional GetIsGgcRestarting() noexcept { return m_isGgcRestarting; } + Aws::Crt::Optional GetIsGgcRestarting() const noexcept { return m_isGgcRestarting; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PreComponentUpdateEvent &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -593,7 +599,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CertificateUpdate : public AbstractShapeBase { public: - CertificateUpdate() noexcept {} + CertificateUpdate() noexcept = default; CertificateUpdate(const CertificateUpdate &) = default; /** * The private key in pem format. @@ -602,7 +608,7 @@ namespace Aws /** * The private key in pem format. */ - Aws::Crt::Optional GetPrivateKey() noexcept { return m_privateKey; } + Aws::Crt::Optional GetPrivateKey() const noexcept { return m_privateKey; } /** * The public key in pem format. */ @@ -610,7 +616,7 @@ namespace Aws /** * The public key in pem format. */ - Aws::Crt::Optional GetPublicKey() noexcept { return m_publicKey; } + Aws::Crt::Optional GetPublicKey() const noexcept { return m_publicKey; } /** * The certificate in pem format. */ @@ -618,7 +624,7 @@ namespace Aws /** * The certificate in pem format. */ - Aws::Crt::Optional GetCertificate() noexcept { return m_certificate; } + Aws::Crt::Optional GetCertificate() const noexcept { return m_certificate; } /** * List of CA certificates in pem format. */ @@ -629,7 +635,7 @@ namespace Aws /** * List of CA certificates in pem format. */ - Aws::Crt::Optional> GetCaCertificates() noexcept + Aws::Crt::Optional> GetCaCertificates() const noexcept { return m_caCertificates; } @@ -667,20 +673,20 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API Metric : public AbstractShapeBase { public: - Metric() noexcept {} + Metric() noexcept = default; Metric(const Metric &) = default; void SetName(const Aws::Crt::String &name) noexcept { m_name = name; } - Aws::Crt::Optional GetName() noexcept { return m_name; } + Aws::Crt::Optional GetName() const noexcept { return m_name; } void SetUnit(MetricUnitType unit) noexcept; - Aws::Crt::Optional GetUnit() noexcept; + Aws::Crt::Optional GetUnit() const noexcept; void SetValue(const double &value) noexcept { m_value = value; } - Aws::Crt::Optional GetValue() noexcept { return m_value; } + Aws::Crt::Optional GetValue() const noexcept { return m_value; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(Metric &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -703,7 +709,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API LocalDeployment : public AbstractShapeBase { public: - LocalDeployment() noexcept {} + LocalDeployment() noexcept = default; LocalDeployment(const LocalDeployment &) = default; /** * The ID of the local deployment. @@ -712,7 +718,7 @@ namespace Aws /** * The ID of the local deployment. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } /** * The status of the local deployment. */ @@ -720,7 +726,7 @@ namespace Aws /** * The status of the local deployment. */ - Aws::Crt::Optional GetStatus() noexcept; + Aws::Crt::Optional GetStatus() const noexcept; /** * (Optional) The timestamp at which the local deployment was created in MM/dd/yyyy hh:mm:ss format */ @@ -728,7 +734,7 @@ namespace Aws /** * (Optional) The timestamp at which the local deployment was created in MM/dd/yyyy hh:mm:ss format */ - Aws::Crt::Optional GetCreatedOn() noexcept { return m_createdOn; } + Aws::Crt::Optional GetCreatedOn() const noexcept { return m_createdOn; } /** * (Optional) The status details of the local deployment. */ @@ -739,7 +745,7 @@ namespace Aws /** * (Optional) The status details of the local deployment. */ - Aws::Crt::Optional GetDeploymentStatusDetails() noexcept + Aws::Crt::Optional GetDeploymentStatusDetails() const noexcept { return m_deploymentStatusDetails; } @@ -766,7 +772,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ComponentDetails : public AbstractShapeBase { public: - ComponentDetails() noexcept {} + ComponentDetails() noexcept = default; ComponentDetails(const ComponentDetails &) = default; /** * The name of the component. @@ -775,7 +781,7 @@ namespace Aws /** * The name of the component. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } /** * The version of the component. */ @@ -783,7 +789,7 @@ namespace Aws /** * The version of the component. */ - Aws::Crt::Optional GetVersion() noexcept { return m_version; } + Aws::Crt::Optional GetVersion() const noexcept { return m_version; } /** * The state of the component. */ @@ -791,7 +797,7 @@ namespace Aws /** * The state of the component. */ - Aws::Crt::Optional GetState() noexcept; + Aws::Crt::Optional GetState() const noexcept; /** * The component's configuration as a JSON object. */ @@ -802,7 +808,7 @@ namespace Aws /** * The component's configuration as a JSON object. */ - Aws::Crt::Optional GetConfiguration() noexcept { return m_configuration; } + Aws::Crt::Optional GetConfiguration() const noexcept { return m_configuration; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ComponentDetails &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -826,7 +832,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API MQTTCredential : public AbstractShapeBase { public: - MQTTCredential() noexcept {} + MQTTCredential() noexcept = default; MQTTCredential(const MQTTCredential &) = default; /** * The client ID to used to connect. @@ -835,7 +841,7 @@ namespace Aws /** * The client ID to used to connect. */ - Aws::Crt::Optional GetClientId() noexcept { return m_clientId; } + Aws::Crt::Optional GetClientId() const noexcept { return m_clientId; } /** * The client certificate in pem format. */ @@ -846,7 +852,7 @@ namespace Aws /** * The client certificate in pem format. */ - Aws::Crt::Optional GetCertificatePem() noexcept { return m_certificatePem; } + Aws::Crt::Optional GetCertificatePem() const noexcept { return m_certificatePem; } /** * The username. (unused). */ @@ -854,7 +860,7 @@ namespace Aws /** * The username. (unused). */ - Aws::Crt::Optional GetUsername() noexcept { return m_username; } + Aws::Crt::Optional GetUsername() const noexcept { return m_username; } /** * The password. (unused). */ @@ -862,7 +868,7 @@ namespace Aws /** * The password. (unused). */ - Aws::Crt::Optional GetPassword() noexcept { return m_password; } + Aws::Crt::Optional GetPassword() const noexcept { return m_password; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(MQTTCredential &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -886,7 +892,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API RunWithInfo : public AbstractShapeBase { public: - RunWithInfo() noexcept {} + RunWithInfo() noexcept = default; RunWithInfo(const RunWithInfo &) = default; /** * (Optional) The POSIX system user and, optionally, group to use to run this component on Linux core @@ -897,7 +903,7 @@ namespace Aws * (Optional) The POSIX system user and, optionally, group to use to run this component on Linux core * devices. */ - Aws::Crt::Optional GetPosixUser() noexcept { return m_posixUser; } + Aws::Crt::Optional GetPosixUser() const noexcept { return m_posixUser; } /** * (Optional) The Windows user to use to run this component on Windows core devices. */ @@ -905,7 +911,7 @@ namespace Aws /** * (Optional) The Windows user to use to run this component on Windows core devices. */ - Aws::Crt::Optional GetWindowsUser() noexcept { return m_windowsUser; } + Aws::Crt::Optional GetWindowsUser() const noexcept { return m_windowsUser; } /** * (Optional) The system resource limits to apply to this component's processes. */ @@ -916,7 +922,7 @@ namespace Aws /** * (Optional) The system resource limits to apply to this component's processes. */ - Aws::Crt::Optional GetSystemResourceLimits() noexcept + Aws::Crt::Optional GetSystemResourceLimits() const noexcept { return m_systemResourceLimits; } @@ -942,7 +948,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ClientDeviceCredential : public AbstractShapeBase { public: - ClientDeviceCredential() noexcept {} + ClientDeviceCredential() noexcept = default; ClientDeviceCredential &operator=(const ClientDeviceCredential &) noexcept; ClientDeviceCredential(const ClientDeviceCredential &objectToCopy) { *this = objectToCopy; } /** @@ -956,7 +962,7 @@ namespace Aws /** * The client device's X.509 device certificate. */ - Aws::Crt::Optional GetClientDeviceCertificate() noexcept + Aws::Crt::Optional GetClientDeviceCertificate() const noexcept { if (m_chosenMember == TAG_CLIENT_DEVICE_CERTIFICATE) { @@ -997,7 +1003,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ValidateConfigurationUpdateEvents : public AbstractShapeBase { public: - ValidateConfigurationUpdateEvents() noexcept {} + ValidateConfigurationUpdateEvents() noexcept = default; ValidateConfigurationUpdateEvents &operator=(const ValidateConfigurationUpdateEvents &) noexcept; ValidateConfigurationUpdateEvents(const ValidateConfigurationUpdateEvents &objectToCopy) { @@ -1015,7 +1021,7 @@ namespace Aws /** * The configuration update event. */ - Aws::Crt::Optional GetValidateConfigurationUpdateEvent() noexcept + Aws::Crt::Optional GetValidateConfigurationUpdateEvent() const noexcept { if (m_chosenMember == TAG_VALIDATE_CONFIGURATION_UPDATE_EVENT) { @@ -1050,7 +1056,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscriptionResponseMessage : public AbstractShapeBase { public: - SubscriptionResponseMessage() noexcept {} + SubscriptionResponseMessage() noexcept = default; SubscriptionResponseMessage &operator=(const SubscriptionResponseMessage &) noexcept; SubscriptionResponseMessage(const SubscriptionResponseMessage &objectToCopy) { *this = objectToCopy; } /** @@ -1064,7 +1070,7 @@ namespace Aws /** * (Optional) A JSON message. */ - Aws::Crt::Optional GetJsonMessage() noexcept + Aws::Crt::Optional GetJsonMessage() const noexcept { if (m_chosenMember == TAG_JSON_MESSAGE) { @@ -1086,7 +1092,7 @@ namespace Aws /** * (Optional) A binary message. */ - Aws::Crt::Optional GetBinaryMessage() noexcept + Aws::Crt::Optional GetBinaryMessage() const noexcept { if (m_chosenMember == TAG_BINARY_MESSAGE) { @@ -1129,7 +1135,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API IoTCoreMessage : public AbstractShapeBase { public: - IoTCoreMessage() noexcept {} + IoTCoreMessage() noexcept = default; IoTCoreMessage &operator=(const IoTCoreMessage &) noexcept; IoTCoreMessage(const IoTCoreMessage &objectToCopy) { *this = objectToCopy; } /** @@ -1143,7 +1149,7 @@ namespace Aws /** * The MQTT message. */ - Aws::Crt::Optional GetMessage() noexcept + Aws::Crt::Optional GetMessage() const noexcept { if (m_chosenMember == TAG_MESSAGE) { @@ -1184,7 +1190,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ConfigurationUpdateEvents : public AbstractShapeBase { public: - ConfigurationUpdateEvents() noexcept {} + ConfigurationUpdateEvents() noexcept = default; ConfigurationUpdateEvents &operator=(const ConfigurationUpdateEvents &) noexcept; ConfigurationUpdateEvents(const ConfigurationUpdateEvents &objectToCopy) { *this = objectToCopy; } /** @@ -1198,7 +1204,7 @@ namespace Aws /** * The configuration update event. */ - Aws::Crt::Optional GetConfigurationUpdateEvent() noexcept + Aws::Crt::Optional GetConfigurationUpdateEvent() const noexcept { if (m_chosenMember == TAG_CONFIGURATION_UPDATE_EVENT) { @@ -1233,7 +1239,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ComponentUpdatePolicyEvents : public AbstractShapeBase { public: - ComponentUpdatePolicyEvents() noexcept {} + ComponentUpdatePolicyEvents() noexcept = default; ComponentUpdatePolicyEvents &operator=(const ComponentUpdatePolicyEvents &) noexcept; ComponentUpdatePolicyEvents(const ComponentUpdatePolicyEvents &objectToCopy) { *this = objectToCopy; } /** @@ -1247,7 +1253,7 @@ namespace Aws /** * An event that indicates that the Greengrass wants to update a component. */ - Aws::Crt::Optional GetPreUpdateEvent() noexcept + Aws::Crt::Optional GetPreUpdateEvent() const noexcept { if (m_chosenMember == TAG_PRE_UPDATE_EVENT) { @@ -1269,7 +1275,7 @@ namespace Aws /** * An event that indicates that the nucleus updated a component. */ - Aws::Crt::Optional GetPostUpdateEvent() noexcept + Aws::Crt::Optional GetPostUpdateEvent() const noexcept { if (m_chosenMember == TAG_POST_UPDATE_EVENT) { @@ -1306,7 +1312,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CertificateUpdateEvent : public AbstractShapeBase { public: - CertificateUpdateEvent() noexcept {} + CertificateUpdateEvent() noexcept = default; CertificateUpdateEvent &operator=(const CertificateUpdateEvent &) noexcept; CertificateUpdateEvent(const CertificateUpdateEvent &objectToCopy) { *this = objectToCopy; } /** @@ -1320,7 +1326,7 @@ namespace Aws /** * The information about the new certificate. */ - Aws::Crt::Optional GetCertificateUpdate() noexcept + Aws::Crt::Optional GetCertificateUpdate() const noexcept { if (m_chosenMember == TAG_CERTIFICATE_UPDATE) { @@ -1355,7 +1361,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CertificateOptions : public AbstractShapeBase { public: - CertificateOptions() noexcept {} + CertificateOptions() noexcept = default; CertificateOptions(const CertificateOptions &) = default; /** * The types of certificate updates to subscribe to. @@ -1364,7 +1370,7 @@ namespace Aws /** * The types of certificate updates to subscribe to. */ - Aws::Crt::Optional GetCertificateType() noexcept; + Aws::Crt::Optional GetCertificateType() const noexcept; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CertificateOptions &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1391,7 +1397,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ConfigurationValidityReport : public AbstractShapeBase { public: - ConfigurationValidityReport() noexcept {} + ConfigurationValidityReport() noexcept = default; ConfigurationValidityReport(const ConfigurationValidityReport &) = default; /** * The validity status. @@ -1400,7 +1406,7 @@ namespace Aws /** * The validity status. */ - Aws::Crt::Optional GetStatus() noexcept; + Aws::Crt::Optional GetStatus() const noexcept; /** * The ID of the AWS IoT Greengrass deployment that requested the configuration update. */ @@ -1408,7 +1414,7 @@ namespace Aws /** * The ID of the AWS IoT Greengrass deployment that requested the configuration update. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } /** * (Optional) A message that reports why the configuration isn't valid. */ @@ -1416,7 +1422,7 @@ namespace Aws /** * (Optional) A message that reports why the configuration isn't valid. */ - Aws::Crt::Optional GetMessage() noexcept { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ConfigurationValidityReport &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1439,7 +1445,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PublishMessage : public AbstractShapeBase { public: - PublishMessage() noexcept {} + PublishMessage() noexcept = default; PublishMessage &operator=(const PublishMessage &) noexcept; PublishMessage(const PublishMessage &objectToCopy) { *this = objectToCopy; } /** @@ -1453,7 +1459,7 @@ namespace Aws /** * (Optional) A JSON message. */ - Aws::Crt::Optional GetJsonMessage() noexcept + Aws::Crt::Optional GetJsonMessage() const noexcept { if (m_chosenMember == TAG_JSON_MESSAGE) { @@ -1475,7 +1481,7 @@ namespace Aws /** * (Optional) A binary message. */ - Aws::Crt::Optional GetBinaryMessage() noexcept + Aws::Crt::Optional GetBinaryMessage() const noexcept { if (m_chosenMember == TAG_BINARY_MESSAGE) { @@ -1512,7 +1518,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SecretValue : public AbstractShapeBase { public: - SecretValue() noexcept {} + SecretValue() noexcept = default; SecretValue &operator=(const SecretValue &) noexcept; SecretValue(const SecretValue &objectToCopy) { *this = objectToCopy; } /** @@ -1526,7 +1532,7 @@ namespace Aws /** * The decrypted part of the protected secret information that you provided to Secrets Manager as a string. */ - Aws::Crt::Optional GetSecretString() noexcept + Aws::Crt::Optional GetSecretString() const noexcept { if (m_chosenMember == TAG_SECRET_STRING) { @@ -1550,7 +1556,7 @@ namespace Aws * (Optional) The decrypted part of the protected secret information that you provided to Secrets Manager as * binary data in the form of a byte array. */ - Aws::Crt::Optional> GetSecretBinary() noexcept + Aws::Crt::Optional> GetSecretBinary() const noexcept { if (m_chosenMember == TAG_SECRET_BINARY) { @@ -1587,7 +1593,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CredentialDocument : public AbstractShapeBase { public: - CredentialDocument() noexcept {} + CredentialDocument() noexcept = default; CredentialDocument &operator=(const CredentialDocument &) noexcept; CredentialDocument(const CredentialDocument &objectToCopy) { *this = objectToCopy; } /** @@ -1603,7 +1609,7 @@ namespace Aws * The client device's MQTT credentials. Specify the client ID and certificate that the client device uses * to connect. */ - Aws::Crt::Optional GetMqttCredential() noexcept + Aws::Crt::Optional GetMqttCredential() const noexcept { if (m_chosenMember == TAG_MQTT_CREDENTIAL) { @@ -1644,12 +1650,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API InvalidArgumentsError : public OperationError { public: - InvalidArgumentsError() noexcept {} + InvalidArgumentsError() noexcept = default; InvalidArgumentsError(const InvalidArgumentsError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(InvalidArgumentsError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1670,16 +1676,16 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ServiceError : public OperationError { public: - ServiceError() noexcept {} + ServiceError() noexcept = default; ServiceError(const ServiceError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SetContext(const Aws::Crt::JsonObject &context) noexcept { m_context = context; } - Aws::Crt::Optional GetContext() noexcept { return m_context; } + Aws::Crt::Optional GetContext() const noexcept { return m_context; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ServiceError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1701,12 +1707,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API UnauthorizedError : public OperationError { public: - UnauthorizedError() noexcept {} + UnauthorizedError() noexcept = default; UnauthorizedError(const UnauthorizedError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(UnauthorizedError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1727,7 +1733,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API VerifyClientDeviceIdentityResponse : public AbstractShapeBase { public: - VerifyClientDeviceIdentityResponse() noexcept {} + VerifyClientDeviceIdentityResponse() noexcept = default; VerifyClientDeviceIdentityResponse(const VerifyClientDeviceIdentityResponse &) = default; /** * Whether the client device's identity is valid. @@ -1739,7 +1745,7 @@ namespace Aws /** * Whether the client device's identity is valid. */ - Aws::Crt::Optional GetIsValidClientDevice() noexcept { return m_isValidClientDevice; } + Aws::Crt::Optional GetIsValidClientDevice() const noexcept { return m_isValidClientDevice; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(VerifyClientDeviceIdentityResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1760,7 +1766,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API VerifyClientDeviceIdentityRequest : public AbstractShapeBase { public: - VerifyClientDeviceIdentityRequest() noexcept {} + VerifyClientDeviceIdentityRequest() noexcept = default; VerifyClientDeviceIdentityRequest(const VerifyClientDeviceIdentityRequest &) = default; /** * The client device's credentials. @@ -1769,7 +1775,7 @@ namespace Aws /** * The client device's credentials. */ - Aws::Crt::Optional GetCredential() noexcept { return m_credential; } + Aws::Crt::Optional GetCredential() const noexcept { return m_credential; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(VerifyClientDeviceIdentityRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1790,12 +1796,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API InvalidTokenError : public OperationError { public: - InvalidTokenError() noexcept {} + InvalidTokenError() noexcept = default; InvalidTokenError(const InvalidTokenError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(InvalidTokenError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1816,12 +1822,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ValidateAuthorizationTokenResponse : public AbstractShapeBase { public: - ValidateAuthorizationTokenResponse() noexcept {} + ValidateAuthorizationTokenResponse() noexcept = default; ValidateAuthorizationTokenResponse(const ValidateAuthorizationTokenResponse &) = default; void SetIsValid(const bool &isValid) noexcept { m_isValid = isValid; } - Aws::Crt::Optional GetIsValid() noexcept { return m_isValid; } + Aws::Crt::Optional GetIsValid() const noexcept { return m_isValid; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ValidateAuthorizationTokenResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1842,12 +1848,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ValidateAuthorizationTokenRequest : public AbstractShapeBase { public: - ValidateAuthorizationTokenRequest() noexcept {} + ValidateAuthorizationTokenRequest() noexcept = default; ValidateAuthorizationTokenRequest(const ValidateAuthorizationTokenRequest &) = default; void SetToken(const Aws::Crt::String &token) noexcept { m_token = token; } - Aws::Crt::Optional GetToken() noexcept { return m_token; } + Aws::Crt::Optional GetToken() const noexcept { return m_token; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ValidateAuthorizationTokenRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1868,12 +1874,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ConflictError : public OperationError { public: - ConflictError() noexcept {} + ConflictError() noexcept = default; ConflictError(const ConflictError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ConflictError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1894,7 +1900,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API UpdateThingShadowResponse : public AbstractShapeBase { public: - UpdateThingShadowResponse() noexcept {} + UpdateThingShadowResponse() noexcept = default; UpdateThingShadowResponse(const UpdateThingShadowResponse &) = default; /** * The response state document as a JSON encoded blob. @@ -1903,7 +1909,7 @@ namespace Aws /** * The response state document as a JSON encoded blob. */ - Aws::Crt::Optional> GetPayload() noexcept { return m_payload; } + Aws::Crt::Optional> GetPayload() const noexcept { return m_payload; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(UpdateThingShadowResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1924,7 +1930,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API UpdateThingShadowRequest : public AbstractShapeBase { public: - UpdateThingShadowRequest() noexcept {} + UpdateThingShadowRequest() noexcept = default; UpdateThingShadowRequest(const UpdateThingShadowRequest &) = default; /** * The name of the thing. @@ -1933,7 +1939,7 @@ namespace Aws /** * The name of the thing. */ - Aws::Crt::Optional GetThingName() noexcept { return m_thingName; } + Aws::Crt::Optional GetThingName() const noexcept { return m_thingName; } /** * The name of the shadow. To specify the thing's classic shadow, set this parameter to an empty string * (""). @@ -1943,7 +1949,7 @@ namespace Aws * The name of the shadow. To specify the thing's classic shadow, set this parameter to an empty string * (""). */ - Aws::Crt::Optional GetShadowName() noexcept { return m_shadowName; } + Aws::Crt::Optional GetShadowName() const noexcept { return m_shadowName; } /** * The request state document as a JSON encoded blob. */ @@ -1951,7 +1957,7 @@ namespace Aws /** * The request state document as a JSON encoded blob. */ - Aws::Crt::Optional> GetPayload() noexcept { return m_payload; } + Aws::Crt::Optional> GetPayload() const noexcept { return m_payload; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(UpdateThingShadowRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -1974,20 +1980,20 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ResourceNotFoundError : public OperationError { public: - ResourceNotFoundError() noexcept {} + ResourceNotFoundError() noexcept = default; ResourceNotFoundError(const ResourceNotFoundError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SetResourceType(const Aws::Crt::String &resourceType) noexcept { m_resourceType = resourceType; } - Aws::Crt::Optional GetResourceType() noexcept { return m_resourceType; } + Aws::Crt::Optional GetResourceType() const noexcept { return m_resourceType; } void SetResourceName(const Aws::Crt::String &resourceName) noexcept { m_resourceName = resourceName; } - Aws::Crt::Optional GetResourceName() noexcept { return m_resourceName; } + Aws::Crt::Optional GetResourceName() const noexcept { return m_resourceName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ResourceNotFoundError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2010,7 +2016,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API UpdateStateResponse : public AbstractShapeBase { public: - UpdateStateResponse() noexcept {} + UpdateStateResponse() noexcept = default; UpdateStateResponse(const UpdateStateResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(UpdateStateResponse &, const Aws::Crt::JsonView &) noexcept; @@ -2031,7 +2037,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API UpdateStateRequest : public AbstractShapeBase { public: - UpdateStateRequest() noexcept {} + UpdateStateRequest() noexcept = default; UpdateStateRequest(const UpdateStateRequest &) = default; /** * The state to set this component to. @@ -2040,7 +2046,7 @@ namespace Aws /** * The state to set this component to. */ - Aws::Crt::Optional GetState() noexcept; + Aws::Crt::Optional GetState() const noexcept; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(UpdateStateRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2061,12 +2067,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API FailedUpdateConditionCheckError : public OperationError { public: - FailedUpdateConditionCheckError() noexcept {} + FailedUpdateConditionCheckError() noexcept = default; FailedUpdateConditionCheckError(const FailedUpdateConditionCheckError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(FailedUpdateConditionCheckError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2087,7 +2093,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API UpdateConfigurationResponse : public AbstractShapeBase { public: - UpdateConfigurationResponse() noexcept {} + UpdateConfigurationResponse() noexcept = default; UpdateConfigurationResponse(const UpdateConfigurationResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(UpdateConfigurationResponse &, const Aws::Crt::JsonView &) noexcept; @@ -2108,7 +2114,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API UpdateConfigurationRequest : public AbstractShapeBase { public: - UpdateConfigurationRequest() noexcept {} + UpdateConfigurationRequest() noexcept = default; UpdateConfigurationRequest(const UpdateConfigurationRequest &) = default; /** * (Optional) The key path to the container node (the object) to update. Specify a list where each entry is @@ -2119,7 +2125,7 @@ namespace Aws * (Optional) The key path to the container node (the object) to update. Specify a list where each entry is * the key for a single level in the configuration object. Defaults to the root of the configuration object. */ - Aws::Crt::Optional> GetKeyPath() noexcept { return m_keyPath; } + Aws::Crt::Optional> GetKeyPath() const noexcept { return m_keyPath; } /** * The current Unix epoch time in milliseconds. This operation uses this timestamp to resolve concurrent * updates to the key. If the key in the component configuration has a greater timestamp than the timestamp @@ -2131,7 +2137,7 @@ namespace Aws * updates to the key. If the key in the component configuration has a greater timestamp than the timestamp * in the request, then the request fails. */ - Aws::Crt::Optional GetTimestamp() noexcept { return m_timestamp; } + Aws::Crt::Optional GetTimestamp() const noexcept { return m_timestamp; } /** * The configuration object to merge at the location that you specify in keyPath. */ @@ -2139,7 +2145,7 @@ namespace Aws /** * The configuration object to merge at the location that you specify in keyPath. */ - Aws::Crt::Optional GetValueToMerge() noexcept { return m_valueToMerge; } + Aws::Crt::Optional GetValueToMerge() const noexcept { return m_valueToMerge; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(UpdateConfigurationRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2162,7 +2168,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToValidateConfigurationUpdatesResponse : public AbstractShapeBase { public: - SubscribeToValidateConfigurationUpdatesResponse() noexcept {} + SubscribeToValidateConfigurationUpdatesResponse() noexcept = default; SubscribeToValidateConfigurationUpdatesResponse(const SubscribeToValidateConfigurationUpdatesResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; @@ -2187,7 +2193,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToValidateConfigurationUpdatesRequest : public AbstractShapeBase { public: - SubscribeToValidateConfigurationUpdatesRequest() noexcept {} + SubscribeToValidateConfigurationUpdatesRequest() noexcept = default; SubscribeToValidateConfigurationUpdatesRequest(const SubscribeToValidateConfigurationUpdatesRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; @@ -2212,7 +2218,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToTopicResponse : public AbstractShapeBase { public: - SubscribeToTopicResponse() noexcept {} + SubscribeToTopicResponse() noexcept = default; SubscribeToTopicResponse(const SubscribeToTopicResponse &) = default; /** * @deprecated No longer used @@ -2221,7 +2227,7 @@ namespace Aws /** * @deprecated No longer used */ - Aws::Crt::Optional GetTopicName() noexcept { return m_topicName; } + Aws::Crt::Optional GetTopicName() const noexcept { return m_topicName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(SubscribeToTopicResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2242,7 +2248,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToTopicRequest : public AbstractShapeBase { public: - SubscribeToTopicRequest() noexcept {} + SubscribeToTopicRequest() noexcept = default; SubscribeToTopicRequest(const SubscribeToTopicRequest &) = default; /** * The topic to subscribe to. Supports MQTT-style wildcards. @@ -2251,7 +2257,7 @@ namespace Aws /** * The topic to subscribe to. Supports MQTT-style wildcards. */ - Aws::Crt::Optional GetTopic() noexcept { return m_topic; } + Aws::Crt::Optional GetTopic() const noexcept { return m_topic; } /** * (Optional) The behavior that specifies whether the component receives messages from itself. */ @@ -2259,7 +2265,7 @@ namespace Aws /** * (Optional) The behavior that specifies whether the component receives messages from itself. */ - Aws::Crt::Optional GetReceiveMode() noexcept; + Aws::Crt::Optional GetReceiveMode() const noexcept; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(SubscribeToTopicRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2281,7 +2287,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToIoTCoreResponse : public AbstractShapeBase { public: - SubscribeToIoTCoreResponse() noexcept {} + SubscribeToIoTCoreResponse() noexcept = default; SubscribeToIoTCoreResponse(const SubscribeToIoTCoreResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(SubscribeToIoTCoreResponse &, const Aws::Crt::JsonView &) noexcept; @@ -2302,7 +2308,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToIoTCoreRequest : public AbstractShapeBase { public: - SubscribeToIoTCoreRequest() noexcept {} + SubscribeToIoTCoreRequest() noexcept = default; SubscribeToIoTCoreRequest(const SubscribeToIoTCoreRequest &) = default; /** * The topic to which to subscribe. Supports MQTT wildcards. @@ -2311,7 +2317,7 @@ namespace Aws /** * The topic to which to subscribe. Supports MQTT wildcards. */ - Aws::Crt::Optional GetTopicName() noexcept { return m_topicName; } + Aws::Crt::Optional GetTopicName() const noexcept { return m_topicName; } /** * The MQTT QoS to use. */ @@ -2319,7 +2325,7 @@ namespace Aws /** * The MQTT QoS to use. */ - Aws::Crt::Optional GetQos() noexcept; + Aws::Crt::Optional GetQos() const noexcept; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(SubscribeToIoTCoreRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2341,7 +2347,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToConfigurationUpdateResponse : public AbstractShapeBase { public: - SubscribeToConfigurationUpdateResponse() noexcept {} + SubscribeToConfigurationUpdateResponse() noexcept = default; SubscribeToConfigurationUpdateResponse(const SubscribeToConfigurationUpdateResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView( @@ -2365,7 +2371,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToConfigurationUpdateRequest : public AbstractShapeBase { public: - SubscribeToConfigurationUpdateRequest() noexcept {} + SubscribeToConfigurationUpdateRequest() noexcept = default; SubscribeToConfigurationUpdateRequest(const SubscribeToConfigurationUpdateRequest &) = default; /** * (Optional) The name of the component. Defaults to the name of the component that makes the request. @@ -2374,7 +2380,7 @@ namespace Aws /** * (Optional) The name of the component. Defaults to the name of the component that makes the request. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } /** * The key path to the configuration value for which to subscribe. Specify a list where each entry is the * key for a single level in the configuration object. @@ -2384,7 +2390,7 @@ namespace Aws * The key path to the configuration value for which to subscribe. Specify a list where each entry is the * key for a single level in the configuration object. */ - Aws::Crt::Optional> GetKeyPath() noexcept { return m_keyPath; } + Aws::Crt::Optional> GetKeyPath() const noexcept { return m_keyPath; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView( SubscribeToConfigurationUpdateRequest &, @@ -2408,7 +2414,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToComponentUpdatesResponse : public AbstractShapeBase { public: - SubscribeToComponentUpdatesResponse() noexcept {} + SubscribeToComponentUpdatesResponse() noexcept = default; SubscribeToComponentUpdatesResponse(const SubscribeToComponentUpdatesResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(SubscribeToComponentUpdatesResponse &, const Aws::Crt::JsonView &) noexcept; @@ -2429,7 +2435,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToComponentUpdatesRequest : public AbstractShapeBase { public: - SubscribeToComponentUpdatesRequest() noexcept {} + SubscribeToComponentUpdatesRequest() noexcept = default; SubscribeToComponentUpdatesRequest(const SubscribeToComponentUpdatesRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(SubscribeToComponentUpdatesRequest &, const Aws::Crt::JsonView &) noexcept; @@ -2450,7 +2456,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToCertificateUpdatesResponse : public AbstractShapeBase { public: - SubscribeToCertificateUpdatesResponse() noexcept {} + SubscribeToCertificateUpdatesResponse() noexcept = default; SubscribeToCertificateUpdatesResponse(const SubscribeToCertificateUpdatesResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView( @@ -2473,7 +2479,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SubscribeToCertificateUpdatesRequest : public AbstractShapeBase { public: - SubscribeToCertificateUpdatesRequest() noexcept {} + SubscribeToCertificateUpdatesRequest() noexcept = default; SubscribeToCertificateUpdatesRequest(const SubscribeToCertificateUpdatesRequest &) = default; void SetCertificateOptions(const CertificateOptions &certificateOptions) noexcept @@ -2481,7 +2487,10 @@ namespace Aws m_certificateOptions = certificateOptions; } - Aws::Crt::Optional GetCertificateOptions() noexcept { return m_certificateOptions; } + Aws::Crt::Optional GetCertificateOptions() const noexcept + { + return m_certificateOptions; + } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(SubscribeToCertificateUpdatesRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2502,12 +2511,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ComponentNotFoundError : public OperationError { public: - ComponentNotFoundError() noexcept {} + ComponentNotFoundError() noexcept = default; ComponentNotFoundError(const ComponentNotFoundError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ComponentNotFoundError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2528,7 +2537,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API StopComponentResponse : public AbstractShapeBase { public: - StopComponentResponse() noexcept {} + StopComponentResponse() noexcept = default; StopComponentResponse(const StopComponentResponse &) = default; /** * The status of the stop request. @@ -2537,7 +2546,7 @@ namespace Aws /** * The status of the stop request. */ - Aws::Crt::Optional GetStopStatus() noexcept; + Aws::Crt::Optional GetStopStatus() const noexcept; /** * A message about why the component failed to stop, if the request failed. */ @@ -2545,7 +2554,7 @@ namespace Aws /** * A message about why the component failed to stop, if the request failed. */ - Aws::Crt::Optional GetMessage() noexcept { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(StopComponentResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2567,7 +2576,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API StopComponentRequest : public AbstractShapeBase { public: - StopComponentRequest() noexcept {} + StopComponentRequest() noexcept = default; StopComponentRequest(const StopComponentRequest &) = default; /** * The name of the component. @@ -2576,7 +2585,7 @@ namespace Aws /** * The name of the component. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(StopComponentRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2597,7 +2606,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SendConfigurationValidityReportResponse : public AbstractShapeBase { public: - SendConfigurationValidityReportResponse() noexcept {} + SendConfigurationValidityReportResponse() noexcept = default; SendConfigurationValidityReportResponse(const SendConfigurationValidityReportResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView( @@ -2621,7 +2630,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API SendConfigurationValidityReportRequest : public AbstractShapeBase { public: - SendConfigurationValidityReportRequest() noexcept {} + SendConfigurationValidityReportRequest() noexcept = default; SendConfigurationValidityReportRequest(const SendConfigurationValidityReportRequest &) = default; /** * The report that tells Greengrass whether or not the configuration update is valid. @@ -2633,7 +2642,7 @@ namespace Aws /** * The report that tells Greengrass whether or not the configuration update is valid. */ - Aws::Crt::Optional GetConfigurationValidityReport() noexcept + Aws::Crt::Optional GetConfigurationValidityReport() const noexcept { return m_configurationValidityReport; } @@ -2660,7 +2669,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ResumeComponentResponse : public AbstractShapeBase { public: - ResumeComponentResponse() noexcept {} + ResumeComponentResponse() noexcept = default; ResumeComponentResponse(const ResumeComponentResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ResumeComponentResponse &, const Aws::Crt::JsonView &) noexcept; @@ -2681,7 +2690,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ResumeComponentRequest : public AbstractShapeBase { public: - ResumeComponentRequest() noexcept {} + ResumeComponentRequest() noexcept = default; ResumeComponentRequest(const ResumeComponentRequest &) = default; /** * The name of the component to resume. @@ -2690,7 +2699,7 @@ namespace Aws /** * The name of the component to resume. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ResumeComponentRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2711,7 +2720,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API RestartComponentResponse : public AbstractShapeBase { public: - RestartComponentResponse() noexcept {} + RestartComponentResponse() noexcept = default; RestartComponentResponse(const RestartComponentResponse &) = default; /** * The status of the restart request. @@ -2720,7 +2729,7 @@ namespace Aws /** * The status of the restart request. */ - Aws::Crt::Optional GetRestartStatus() noexcept; + Aws::Crt::Optional GetRestartStatus() const noexcept; /** * A message about why the component failed to restart, if the request failed. */ @@ -2728,7 +2737,7 @@ namespace Aws /** * A message about why the component failed to restart, if the request failed. */ - Aws::Crt::Optional GetMessage() noexcept { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(RestartComponentResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2750,7 +2759,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API RestartComponentRequest : public AbstractShapeBase { public: - RestartComponentRequest() noexcept {} + RestartComponentRequest() noexcept = default; RestartComponentRequest(const RestartComponentRequest &) = default; /** * The name of the component. @@ -2759,7 +2768,7 @@ namespace Aws /** * The name of the component. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(RestartComponentRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2780,7 +2789,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PutComponentMetricResponse : public AbstractShapeBase { public: - PutComponentMetricResponse() noexcept {} + PutComponentMetricResponse() noexcept = default; PutComponentMetricResponse(const PutComponentMetricResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PutComponentMetricResponse &, const Aws::Crt::JsonView &) noexcept; @@ -2801,12 +2810,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PutComponentMetricRequest : public AbstractShapeBase { public: - PutComponentMetricRequest() noexcept {} + PutComponentMetricRequest() noexcept = default; PutComponentMetricRequest(const PutComponentMetricRequest &) = default; void SetMetrics(const Aws::Crt::Vector &metrics) noexcept { m_metrics = metrics; } - Aws::Crt::Optional> GetMetrics() noexcept { return m_metrics; } + Aws::Crt::Optional> GetMetrics() const noexcept { return m_metrics; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PutComponentMetricRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2827,7 +2836,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PublishToTopicResponse : public AbstractShapeBase { public: - PublishToTopicResponse() noexcept {} + PublishToTopicResponse() noexcept = default; PublishToTopicResponse(const PublishToTopicResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PublishToTopicResponse &, const Aws::Crt::JsonView &) noexcept; @@ -2848,7 +2857,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PublishToTopicRequest : public AbstractShapeBase { public: - PublishToTopicRequest() noexcept {} + PublishToTopicRequest() noexcept = default; PublishToTopicRequest(const PublishToTopicRequest &) = default; /** * The topic to publish the message. @@ -2857,7 +2866,7 @@ namespace Aws /** * The topic to publish the message. */ - Aws::Crt::Optional GetTopic() noexcept { return m_topic; } + Aws::Crt::Optional GetTopic() const noexcept { return m_topic; } /** * The message to publish. */ @@ -2865,7 +2874,7 @@ namespace Aws /** * The message to publish. */ - Aws::Crt::Optional GetPublishMessage() noexcept { return m_publishMessage; } + Aws::Crt::Optional GetPublishMessage() const noexcept { return m_publishMessage; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PublishToTopicRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -2887,7 +2896,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PublishToIoTCoreResponse : public AbstractShapeBase { public: - PublishToIoTCoreResponse() noexcept {} + PublishToIoTCoreResponse() noexcept = default; PublishToIoTCoreResponse(const PublishToIoTCoreResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PublishToIoTCoreResponse &, const Aws::Crt::JsonView &) noexcept; @@ -2908,7 +2917,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PublishToIoTCoreRequest : public AbstractShapeBase { public: - PublishToIoTCoreRequest() noexcept {} + PublishToIoTCoreRequest() noexcept = default; PublishToIoTCoreRequest(const PublishToIoTCoreRequest &) = default; /** * The topic to which to publish the message. @@ -2917,7 +2926,7 @@ namespace Aws /** * The topic to which to publish the message. */ - Aws::Crt::Optional GetTopicName() noexcept { return m_topicName; } + Aws::Crt::Optional GetTopicName() const noexcept { return m_topicName; } /** * The MQTT QoS to use. */ @@ -2925,7 +2934,7 @@ namespace Aws /** * The MQTT QoS to use. */ - Aws::Crt::Optional GetQos() noexcept; + Aws::Crt::Optional GetQos() const noexcept; /** * (Optional) The message payload as a blob. */ @@ -2933,7 +2942,7 @@ namespace Aws /** * (Optional) The message payload as a blob. */ - Aws::Crt::Optional> GetPayload() noexcept { return m_payload; } + Aws::Crt::Optional> GetPayload() const noexcept { return m_payload; } /** * (Optional) Whether to set MQTT retain option to true when publishing. */ @@ -2941,7 +2950,7 @@ namespace Aws /** * (Optional) Whether to set MQTT retain option to true when publishing. */ - Aws::Crt::Optional GetRetain() noexcept { return m_retain; } + Aws::Crt::Optional GetRetain() const noexcept { return m_retain; } /** * (Optional) MQTT user properties associated with the message. */ @@ -2952,7 +2961,10 @@ namespace Aws /** * (Optional) MQTT user properties associated with the message. */ - Aws::Crt::Optional> GetUserProperties() noexcept { return m_userProperties; } + Aws::Crt::Optional> GetUserProperties() const noexcept + { + return m_userProperties; + } /** * (Optional) Message expiry interval in seconds. */ @@ -2963,7 +2975,7 @@ namespace Aws /** * (Optional) Message expiry interval in seconds. */ - Aws::Crt::Optional GetMessageExpiryIntervalSeconds() noexcept + Aws::Crt::Optional GetMessageExpiryIntervalSeconds() const noexcept { return m_messageExpiryIntervalSeconds; } @@ -2977,7 +2989,10 @@ namespace Aws /** * (Optional) Correlation data blob for request/response. */ - Aws::Crt::Optional> GetCorrelationData() noexcept { return m_correlationData; } + Aws::Crt::Optional> GetCorrelationData() const noexcept + { + return m_correlationData; + } /** * (Optional) Response topic for request/response. */ @@ -2985,7 +3000,7 @@ namespace Aws /** * (Optional) Response topic for request/response. */ - Aws::Crt::Optional GetResponseTopic() noexcept { return m_responseTopic; } + Aws::Crt::Optional GetResponseTopic() const noexcept { return m_responseTopic; } /** * (Optional) Message payload format. */ @@ -2993,7 +3008,7 @@ namespace Aws /** * (Optional) Message payload format. */ - Aws::Crt::Optional GetPayloadFormat() noexcept; + Aws::Crt::Optional GetPayloadFormat() const noexcept; /** * (Optional) Message content type. */ @@ -3001,7 +3016,7 @@ namespace Aws /** * (Optional) Message content type. */ - Aws::Crt::Optional GetContentType() noexcept { return m_contentType; } + Aws::Crt::Optional GetContentType() const noexcept { return m_contentType; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PublishToIoTCoreRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3031,7 +3046,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PauseComponentResponse : public AbstractShapeBase { public: - PauseComponentResponse() noexcept {} + PauseComponentResponse() noexcept = default; PauseComponentResponse(const PauseComponentResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PauseComponentResponse &, const Aws::Crt::JsonView &) noexcept; @@ -3052,7 +3067,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API PauseComponentRequest : public AbstractShapeBase { public: - PauseComponentRequest() noexcept {} + PauseComponentRequest() noexcept = default; PauseComponentRequest(const PauseComponentRequest &) = default; /** * The name of the component to pause, which must be a generic component. @@ -3061,7 +3076,7 @@ namespace Aws /** * The name of the component to pause, which must be a generic component. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(PauseComponentRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3082,7 +3097,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ListNamedShadowsForThingResponse : public AbstractShapeBase { public: - ListNamedShadowsForThingResponse() noexcept {} + ListNamedShadowsForThingResponse() noexcept = default; ListNamedShadowsForThingResponse(const ListNamedShadowsForThingResponse &) = default; /** * The list of shadow names. @@ -3091,7 +3106,7 @@ namespace Aws /** * The list of shadow names. */ - Aws::Crt::Optional> GetResults() noexcept { return m_results; } + Aws::Crt::Optional> GetResults() const noexcept { return m_results; } /** * (Optional) The date and time that the response was generated. */ @@ -3099,7 +3114,7 @@ namespace Aws /** * (Optional) The date and time that the response was generated. */ - Aws::Crt::Optional GetTimestamp() noexcept { return m_timestamp; } + Aws::Crt::Optional GetTimestamp() const noexcept { return m_timestamp; } /** * (Optional) The token value to use in paged requests to retrieve the next page in the sequence. This token * isn't present when there are no more shadow names to return. @@ -3109,7 +3124,7 @@ namespace Aws * (Optional) The token value to use in paged requests to retrieve the next page in the sequence. This token * isn't present when there are no more shadow names to return. */ - Aws::Crt::Optional GetNextToken() noexcept { return m_nextToken; } + Aws::Crt::Optional GetNextToken() const noexcept { return m_nextToken; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ListNamedShadowsForThingResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3132,7 +3147,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ListNamedShadowsForThingRequest : public AbstractShapeBase { public: - ListNamedShadowsForThingRequest() noexcept {} + ListNamedShadowsForThingRequest() noexcept = default; ListNamedShadowsForThingRequest(const ListNamedShadowsForThingRequest &) = default; /** * The name of the thing. @@ -3141,7 +3156,7 @@ namespace Aws /** * The name of the thing. */ - Aws::Crt::Optional GetThingName() noexcept { return m_thingName; } + Aws::Crt::Optional GetThingName() const noexcept { return m_thingName; } /** * (Optional) The token to retrieve the next set of results. This value is returned on paged results and is * used in the call that returns the next page. @@ -3151,7 +3166,7 @@ namespace Aws * (Optional) The token to retrieve the next set of results. This value is returned on paged results and is * used in the call that returns the next page. */ - Aws::Crt::Optional GetNextToken() noexcept { return m_nextToken; } + Aws::Crt::Optional GetNextToken() const noexcept { return m_nextToken; } /** * (Optional) The number of shadow names to return in each call. Value must be between 1 and 100. Default * is 25. @@ -3161,7 +3176,7 @@ namespace Aws * (Optional) The number of shadow names to return in each call. Value must be between 1 and 100. Default * is 25. */ - Aws::Crt::Optional GetPageSize() noexcept { return m_pageSize; } + Aws::Crt::Optional GetPageSize() const noexcept { return m_pageSize; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ListNamedShadowsForThingRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3184,7 +3199,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ListLocalDeploymentsResponse : public AbstractShapeBase { public: - ListLocalDeploymentsResponse() noexcept {} + ListLocalDeploymentsResponse() noexcept = default; ListLocalDeploymentsResponse(const ListLocalDeploymentsResponse &) = default; /** * The list of local deployments. @@ -3196,7 +3211,7 @@ namespace Aws /** * The list of local deployments. */ - Aws::Crt::Optional> GetLocalDeployments() noexcept + Aws::Crt::Optional> GetLocalDeployments() const noexcept { return m_localDeployments; } @@ -3220,7 +3235,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ListLocalDeploymentsRequest : public AbstractShapeBase { public: - ListLocalDeploymentsRequest() noexcept {} + ListLocalDeploymentsRequest() noexcept = default; ListLocalDeploymentsRequest(const ListLocalDeploymentsRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ListLocalDeploymentsRequest &, const Aws::Crt::JsonView &) noexcept; @@ -3241,7 +3256,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ListComponentsResponse : public AbstractShapeBase { public: - ListComponentsResponse() noexcept {} + ListComponentsResponse() noexcept = default; ListComponentsResponse(const ListComponentsResponse &) = default; /** * The list of components. @@ -3253,7 +3268,10 @@ namespace Aws /** * The list of components. */ - Aws::Crt::Optional> GetComponents() noexcept { return m_components; } + Aws::Crt::Optional> GetComponents() const noexcept + { + return m_components; + } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ListComponentsResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3274,7 +3292,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API ListComponentsRequest : public AbstractShapeBase { public: - ListComponentsRequest() noexcept {} + ListComponentsRequest() noexcept = default; ListComponentsRequest(const ListComponentsRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(ListComponentsRequest &, const Aws::Crt::JsonView &) noexcept; @@ -3295,7 +3313,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetThingShadowResponse : public AbstractShapeBase { public: - GetThingShadowResponse() noexcept {} + GetThingShadowResponse() noexcept = default; GetThingShadowResponse(const GetThingShadowResponse &) = default; /** * The response state document as a JSON encoded blob. @@ -3304,7 +3322,7 @@ namespace Aws /** * The response state document as a JSON encoded blob. */ - Aws::Crt::Optional> GetPayload() noexcept { return m_payload; } + Aws::Crt::Optional> GetPayload() const noexcept { return m_payload; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetThingShadowResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3325,7 +3343,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetThingShadowRequest : public AbstractShapeBase { public: - GetThingShadowRequest() noexcept {} + GetThingShadowRequest() noexcept = default; GetThingShadowRequest(const GetThingShadowRequest &) = default; /** * The name of the thing. @@ -3334,7 +3352,7 @@ namespace Aws /** * The name of the thing. */ - Aws::Crt::Optional GetThingName() noexcept { return m_thingName; } + Aws::Crt::Optional GetThingName() const noexcept { return m_thingName; } /** * The name of the shadow. To specify the thing's classic shadow, set this parameter to an empty string * (""). @@ -3344,7 +3362,7 @@ namespace Aws * The name of the shadow. To specify the thing's classic shadow, set this parameter to an empty string * (""). */ - Aws::Crt::Optional GetShadowName() noexcept { return m_shadowName; } + Aws::Crt::Optional GetShadowName() const noexcept { return m_shadowName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetThingShadowRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3366,7 +3384,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetSecretValueResponse : public AbstractShapeBase { public: - GetSecretValueResponse() noexcept {} + GetSecretValueResponse() noexcept = default; GetSecretValueResponse(const GetSecretValueResponse &) = default; /** * The ID of the secret. @@ -3375,7 +3393,7 @@ namespace Aws /** * The ID of the secret. */ - Aws::Crt::Optional GetSecretId() noexcept { return m_secretId; } + Aws::Crt::Optional GetSecretId() const noexcept { return m_secretId; } /** * The ID of this version of the secret. */ @@ -3383,7 +3401,7 @@ namespace Aws /** * The ID of this version of the secret. */ - Aws::Crt::Optional GetVersionId() noexcept { return m_versionId; } + Aws::Crt::Optional GetVersionId() const noexcept { return m_versionId; } /** * The list of staging labels attached to this version of the secret. */ @@ -3394,7 +3412,10 @@ namespace Aws /** * The list of staging labels attached to this version of the secret. */ - Aws::Crt::Optional> GetVersionStage() noexcept { return m_versionStage; } + Aws::Crt::Optional> GetVersionStage() const noexcept + { + return m_versionStage; + } /** * The value of this version of the secret. */ @@ -3402,7 +3423,7 @@ namespace Aws /** * The value of this version of the secret. */ - Aws::Crt::Optional GetSecretValue() noexcept { return m_secretValue; } + Aws::Crt::Optional GetSecretValue() const noexcept { return m_secretValue; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetSecretValueResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3426,7 +3447,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetSecretValueRequest : public AbstractShapeBase { public: - GetSecretValueRequest() noexcept {} + GetSecretValueRequest() noexcept = default; GetSecretValueRequest(const GetSecretValueRequest &) = default; /** * The name of the secret to get. You can specify either the Amazon Resource Name (ARN) or the friendly name @@ -3437,7 +3458,7 @@ namespace Aws * The name of the secret to get. You can specify either the Amazon Resource Name (ARN) or the friendly name * of the secret. */ - Aws::Crt::Optional GetSecretId() noexcept { return m_secretId; } + Aws::Crt::Optional GetSecretId() const noexcept { return m_secretId; } /** * (Optional) The ID of the version to get. If you don't specify versionId or versionStage, this operation * defaults to the version with the AWSCURRENT label. @@ -3447,7 +3468,7 @@ namespace Aws * (Optional) The ID of the version to get. If you don't specify versionId or versionStage, this operation * defaults to the version with the AWSCURRENT label. */ - Aws::Crt::Optional GetVersionId() noexcept { return m_versionId; } + Aws::Crt::Optional GetVersionId() const noexcept { return m_versionId; } /** * (Optional) The staging label of the version to get. If you don't specify versionId or versionStage, this * operation defaults to the version with the AWSCURRENT label. @@ -3457,7 +3478,7 @@ namespace Aws * (Optional) The staging label of the version to get. If you don't specify versionId or versionStage, this * operation defaults to the version with the AWSCURRENT label. */ - Aws::Crt::Optional GetVersionStage() noexcept { return m_versionStage; } + Aws::Crt::Optional GetVersionStage() const noexcept { return m_versionStage; } /** * (Optional) Whether to fetch the latest secret from cloud when the request is handled. Defaults to false. */ @@ -3465,7 +3486,7 @@ namespace Aws /** * (Optional) Whether to fetch the latest secret from cloud when the request is handled. Defaults to false. */ - Aws::Crt::Optional GetRefresh() noexcept { return m_refresh; } + Aws::Crt::Optional GetRefresh() const noexcept { return m_refresh; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetSecretValueRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3489,7 +3510,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetLocalDeploymentStatusResponse : public AbstractShapeBase { public: - GetLocalDeploymentStatusResponse() noexcept {} + GetLocalDeploymentStatusResponse() noexcept = default; GetLocalDeploymentStatusResponse(const GetLocalDeploymentStatusResponse &) = default; /** * The local deployment. @@ -3498,7 +3519,7 @@ namespace Aws /** * The local deployment. */ - Aws::Crt::Optional GetDeployment() noexcept { return m_deployment; } + Aws::Crt::Optional GetDeployment() const noexcept { return m_deployment; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetLocalDeploymentStatusResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3519,7 +3540,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetLocalDeploymentStatusRequest : public AbstractShapeBase { public: - GetLocalDeploymentStatusRequest() noexcept {} + GetLocalDeploymentStatusRequest() noexcept = default; GetLocalDeploymentStatusRequest(const GetLocalDeploymentStatusRequest &) = default; /** * The ID of the local deployment to get. @@ -3528,7 +3549,7 @@ namespace Aws /** * The ID of the local deployment to get. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetLocalDeploymentStatusRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3549,7 +3570,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetConfigurationResponse : public AbstractShapeBase { public: - GetConfigurationResponse() noexcept {} + GetConfigurationResponse() noexcept = default; GetConfigurationResponse(const GetConfigurationResponse &) = default; /** * The name of the component. @@ -3558,7 +3579,7 @@ namespace Aws /** * The name of the component. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } /** * The requested configuration as an object. */ @@ -3566,7 +3587,7 @@ namespace Aws /** * The requested configuration as an object. */ - Aws::Crt::Optional GetValue() noexcept { return m_value; } + Aws::Crt::Optional GetValue() const noexcept { return m_value; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetConfigurationResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3588,7 +3609,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetConfigurationRequest : public AbstractShapeBase { public: - GetConfigurationRequest() noexcept {} + GetConfigurationRequest() noexcept = default; GetConfigurationRequest(const GetConfigurationRequest &) = default; /** * (Optional) The name of the component. Defaults to the name of the component that makes the request. @@ -3597,7 +3618,7 @@ namespace Aws /** * (Optional) The name of the component. Defaults to the name of the component that makes the request. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } /** * The key path to the configuration value. Specify a list where each entry is the key for a single level in * the configuration object. @@ -3607,7 +3628,7 @@ namespace Aws * The key path to the configuration value. Specify a list where each entry is the key for a single level in * the configuration object. */ - Aws::Crt::Optional> GetKeyPath() noexcept { return m_keyPath; } + Aws::Crt::Optional> GetKeyPath() const noexcept { return m_keyPath; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetConfigurationRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3629,7 +3650,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetComponentDetailsResponse : public AbstractShapeBase { public: - GetComponentDetailsResponse() noexcept {} + GetComponentDetailsResponse() noexcept = default; GetComponentDetailsResponse(const GetComponentDetailsResponse &) = default; /** * The component's details. @@ -3641,7 +3662,7 @@ namespace Aws /** * The component's details. */ - Aws::Crt::Optional GetComponentDetails() noexcept { return m_componentDetails; } + Aws::Crt::Optional GetComponentDetails() const noexcept { return m_componentDetails; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetComponentDetailsResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3662,7 +3683,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetComponentDetailsRequest : public AbstractShapeBase { public: - GetComponentDetailsRequest() noexcept {} + GetComponentDetailsRequest() noexcept = default; GetComponentDetailsRequest(const GetComponentDetailsRequest &) = default; /** * The name of the component to get. @@ -3671,7 +3692,7 @@ namespace Aws /** * The name of the component to get. */ - Aws::Crt::Optional GetComponentName() noexcept { return m_componentName; } + Aws::Crt::Optional GetComponentName() const noexcept { return m_componentName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetComponentDetailsRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3692,12 +3713,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API InvalidCredentialError : public OperationError { public: - InvalidCredentialError() noexcept {} + InvalidCredentialError() noexcept = default; InvalidCredentialError(const InvalidCredentialError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(InvalidCredentialError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3718,7 +3739,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetClientDeviceAuthTokenResponse : public AbstractShapeBase { public: - GetClientDeviceAuthTokenResponse() noexcept {} + GetClientDeviceAuthTokenResponse() noexcept = default; GetClientDeviceAuthTokenResponse(const GetClientDeviceAuthTokenResponse &) = default; /** * The session token for the client device. You can use this session token in subsequent requests to @@ -3732,7 +3753,10 @@ namespace Aws * The session token for the client device. You can use this session token in subsequent requests to * authorize this client device's actions. */ - Aws::Crt::Optional GetClientDeviceAuthToken() noexcept { return m_clientDeviceAuthToken; } + Aws::Crt::Optional GetClientDeviceAuthToken() const noexcept + { + return m_clientDeviceAuthToken; + } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetClientDeviceAuthTokenResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3753,7 +3777,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API GetClientDeviceAuthTokenRequest : public AbstractShapeBase { public: - GetClientDeviceAuthTokenRequest() noexcept {} + GetClientDeviceAuthTokenRequest() noexcept = default; GetClientDeviceAuthTokenRequest(const GetClientDeviceAuthTokenRequest &) = default; /** * The client device's credentials. @@ -3762,7 +3786,7 @@ namespace Aws /** * The client device's credentials. */ - Aws::Crt::Optional GetCredential() noexcept { return m_credential; } + Aws::Crt::Optional GetCredential() const noexcept { return m_credential; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(GetClientDeviceAuthTokenRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3783,7 +3807,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API DeleteThingShadowResponse : public AbstractShapeBase { public: - DeleteThingShadowResponse() noexcept {} + DeleteThingShadowResponse() noexcept = default; DeleteThingShadowResponse(const DeleteThingShadowResponse &) = default; /** * An empty response state document. @@ -3792,7 +3816,7 @@ namespace Aws /** * An empty response state document. */ - Aws::Crt::Optional> GetPayload() noexcept { return m_payload; } + Aws::Crt::Optional> GetPayload() const noexcept { return m_payload; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(DeleteThingShadowResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3813,7 +3837,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API DeleteThingShadowRequest : public AbstractShapeBase { public: - DeleteThingShadowRequest() noexcept {} + DeleteThingShadowRequest() noexcept = default; DeleteThingShadowRequest(const DeleteThingShadowRequest &) = default; /** * The name of the thing. @@ -3822,7 +3846,7 @@ namespace Aws /** * The name of the thing. */ - Aws::Crt::Optional GetThingName() noexcept { return m_thingName; } + Aws::Crt::Optional GetThingName() const noexcept { return m_thingName; } /** * The name of the shadow. To specify the thing's classic shadow, set this parameter to an empty string * (""). @@ -3832,7 +3856,7 @@ namespace Aws * The name of the shadow. To specify the thing's classic shadow, set this parameter to an empty string * (""). */ - Aws::Crt::Optional GetShadowName() noexcept { return m_shadowName; } + Aws::Crt::Optional GetShadowName() const noexcept { return m_shadowName; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(DeleteThingShadowRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3854,7 +3878,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API DeferComponentUpdateResponse : public AbstractShapeBase { public: - DeferComponentUpdateResponse() noexcept {} + DeferComponentUpdateResponse() noexcept = default; DeferComponentUpdateResponse(const DeferComponentUpdateResponse &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(DeferComponentUpdateResponse &, const Aws::Crt::JsonView &) noexcept; @@ -3875,7 +3899,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API DeferComponentUpdateRequest : public AbstractShapeBase { public: - DeferComponentUpdateRequest() noexcept {} + DeferComponentUpdateRequest() noexcept = default; DeferComponentUpdateRequest(const DeferComponentUpdateRequest &) = default; /** * The ID of the AWS IoT Greengrass deployment to defer. @@ -3884,7 +3908,7 @@ namespace Aws /** * The ID of the AWS IoT Greengrass deployment to defer. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } /** * (Optional) The name of the component for which to defer updates. Defaults to the name of the component * that makes the request. @@ -3894,7 +3918,7 @@ namespace Aws * (Optional) The name of the component for which to defer updates. Defaults to the name of the component * that makes the request. */ - Aws::Crt::Optional GetMessage() noexcept { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept { return m_message; } /** * The amount of time in milliseconds for which to defer the update. Greengrass waits for this amount of * time and then sends another PreComponentUpdateEvent @@ -3904,7 +3928,7 @@ namespace Aws * The amount of time in milliseconds for which to defer the update. Greengrass waits for this amount of * time and then sends another PreComponentUpdateEvent */ - Aws::Crt::Optional GetRecheckAfterMs() noexcept { return m_recheckAfterMs; } + Aws::Crt::Optional GetRecheckAfterMs() const noexcept { return m_recheckAfterMs; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(DeferComponentUpdateRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3927,12 +3951,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API InvalidArtifactsDirectoryPathError : public OperationError { public: - InvalidArtifactsDirectoryPathError() noexcept {} + InvalidArtifactsDirectoryPathError() noexcept = default; InvalidArtifactsDirectoryPathError(const InvalidArtifactsDirectoryPathError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(InvalidArtifactsDirectoryPathError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3953,12 +3977,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API InvalidRecipeDirectoryPathError : public OperationError { public: - InvalidRecipeDirectoryPathError() noexcept {} + InvalidRecipeDirectoryPathError() noexcept = default; InvalidRecipeDirectoryPathError(const InvalidRecipeDirectoryPathError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(InvalidRecipeDirectoryPathError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -3979,7 +4003,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CreateLocalDeploymentResponse : public AbstractShapeBase { public: - CreateLocalDeploymentResponse() noexcept {} + CreateLocalDeploymentResponse() noexcept = default; CreateLocalDeploymentResponse(const CreateLocalDeploymentResponse &) = default; /** * The ID of the local deployment that the request created. @@ -3988,7 +4012,7 @@ namespace Aws /** * The ID of the local deployment that the request created. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CreateLocalDeploymentResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -4009,7 +4033,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CreateLocalDeploymentRequest : public AbstractShapeBase { public: - CreateLocalDeploymentRequest() noexcept {} + CreateLocalDeploymentRequest() noexcept = default; CreateLocalDeploymentRequest(const CreateLocalDeploymentRequest &) = default; /** * The thing group name the deployment is targeting. If the group name is not specified, "LOCAL_DEPLOYMENT" @@ -4020,7 +4044,7 @@ namespace Aws * The thing group name the deployment is targeting. If the group name is not specified, "LOCAL_DEPLOYMENT" * will be used. */ - Aws::Crt::Optional GetGroupName() noexcept { return m_groupName; } + Aws::Crt::Optional GetGroupName() const noexcept { return m_groupName; } /** * Map of component name to version. Components will be added to the group's existing root components. */ @@ -4032,8 +4056,8 @@ namespace Aws /** * Map of component name to version. Components will be added to the group's existing root components. */ - Aws::Crt::Optional> - GetRootComponentVersionsToAdd() noexcept + Aws::Crt::Optional> GetRootComponentVersionsToAdd() + const noexcept { return m_rootComponentVersionsToAdd; } @@ -4049,7 +4073,7 @@ namespace Aws * List of components that need to be removed from the group, for example if new artifacts were loaded in * this request but recipe version did not change. */ - Aws::Crt::Optional> GetRootComponentsToRemove() noexcept + Aws::Crt::Optional> GetRootComponentsToRemove() const noexcept { return m_rootComponentsToRemove; } @@ -4064,8 +4088,8 @@ namespace Aws /** * Map of component names to configuration. */ - Aws::Crt::Optional> - GetComponentToConfiguration() noexcept + Aws::Crt::Optional> GetComponentToConfiguration() + const noexcept { return m_componentToConfiguration; } @@ -4080,7 +4104,7 @@ namespace Aws /** * Map of component names to component run as info. */ - Aws::Crt::Optional> GetComponentToRunWithInfo() noexcept + Aws::Crt::Optional> GetComponentToRunWithInfo() const noexcept { return m_componentToRunWithInfo; } @@ -4094,7 +4118,10 @@ namespace Aws /** * All recipes files in this directory will be copied over to the Greengrass package store. */ - Aws::Crt::Optional GetRecipeDirectoryPath() noexcept { return m_recipeDirectoryPath; } + Aws::Crt::Optional GetRecipeDirectoryPath() const noexcept + { + return m_recipeDirectoryPath; + } /** * All artifact files in this directory will be copied over to the Greengrass package store. */ @@ -4105,7 +4132,7 @@ namespace Aws /** * All artifact files in this directory will be copied over to the Greengrass package store. */ - Aws::Crt::Optional GetArtifactsDirectoryPath() noexcept + Aws::Crt::Optional GetArtifactsDirectoryPath() const noexcept { return m_artifactsDirectoryPath; } @@ -4116,7 +4143,7 @@ namespace Aws /** * Deployment failure handling policy. */ - Aws::Crt::Optional GetFailureHandlingPolicy() noexcept; + Aws::Crt::Optional GetFailureHandlingPolicy() const noexcept; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CreateLocalDeploymentRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -4144,37 +4171,46 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CreateDebugPasswordResponse : public AbstractShapeBase { public: - CreateDebugPasswordResponse() noexcept {} + CreateDebugPasswordResponse() noexcept = default; CreateDebugPasswordResponse(const CreateDebugPasswordResponse &) = default; void SetPassword(const Aws::Crt::String &password) noexcept { m_password = password; } - Aws::Crt::Optional GetPassword() noexcept { return m_password; } + Aws::Crt::Optional GetPassword() const noexcept { return m_password; } void SetUsername(const Aws::Crt::String &username) noexcept { m_username = username; } - Aws::Crt::Optional GetUsername() noexcept { return m_username; } + Aws::Crt::Optional GetUsername() const noexcept { return m_username; } void SetPasswordExpiration(const Aws::Crt::DateTime &passwordExpiration) noexcept { m_passwordExpiration = passwordExpiration; } - Aws::Crt::Optional GetPasswordExpiration() noexcept { return m_passwordExpiration; } + Aws::Crt::Optional GetPasswordExpiration() const noexcept + { + return m_passwordExpiration; + } void SetCertificateSHA256Hash(const Aws::Crt::String &certificateSHA256Hash) noexcept { m_certificateSHA256Hash = certificateSHA256Hash; } - Aws::Crt::Optional GetCertificateSHA256Hash() noexcept { return m_certificateSHA256Hash; } + Aws::Crt::Optional GetCertificateSHA256Hash() const noexcept + { + return m_certificateSHA256Hash; + } void SetCertificateSHA1Hash(const Aws::Crt::String &certificateSHA1Hash) noexcept { m_certificateSHA1Hash = certificateSHA1Hash; } - Aws::Crt::Optional GetCertificateSHA1Hash() noexcept { return m_certificateSHA1Hash; } + Aws::Crt::Optional GetCertificateSHA1Hash() const noexcept + { + return m_certificateSHA1Hash; + } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CreateDebugPasswordResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -4199,7 +4235,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CreateDebugPasswordRequest : public AbstractShapeBase { public: - CreateDebugPasswordRequest() noexcept {} + CreateDebugPasswordRequest() noexcept = default; CreateDebugPasswordRequest(const CreateDebugPasswordRequest &) = default; void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CreateDebugPasswordRequest &, const Aws::Crt::JsonView &) noexcept; @@ -4220,12 +4256,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CancelLocalDeploymentResponse : public AbstractShapeBase { public: - CancelLocalDeploymentResponse() noexcept {} + CancelLocalDeploymentResponse() noexcept = default; CancelLocalDeploymentResponse(const CancelLocalDeploymentResponse &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CancelLocalDeploymentResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -4246,7 +4282,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API CancelLocalDeploymentRequest : public AbstractShapeBase { public: - CancelLocalDeploymentRequest() noexcept {} + CancelLocalDeploymentRequest() noexcept = default; CancelLocalDeploymentRequest(const CancelLocalDeploymentRequest &) = default; /** * (Optional) The ID of the local deployment to cancel. @@ -4255,7 +4291,7 @@ namespace Aws /** * (Optional) The ID of the local deployment to cancel. */ - Aws::Crt::Optional GetDeploymentId() noexcept { return m_deploymentId; } + Aws::Crt::Optional GetDeploymentId() const noexcept { return m_deploymentId; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(CancelLocalDeploymentRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -4276,12 +4312,12 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API InvalidClientDeviceAuthTokenError : public OperationError { public: - InvalidClientDeviceAuthTokenError() noexcept {} + InvalidClientDeviceAuthTokenError() noexcept = default; InvalidClientDeviceAuthTokenError(const InvalidClientDeviceAuthTokenError &) = default; void SetMessage(const Aws::Crt::String &message) noexcept { m_message = message; } - Aws::Crt::Optional GetMessage() noexcept override { return m_message; } + Aws::Crt::Optional GetMessage() const noexcept override { return m_message; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(InvalidClientDeviceAuthTokenError &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -4302,7 +4338,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API AuthorizeClientDeviceActionResponse : public AbstractShapeBase { public: - AuthorizeClientDeviceActionResponse() noexcept {} + AuthorizeClientDeviceActionResponse() noexcept = default; AuthorizeClientDeviceActionResponse(const AuthorizeClientDeviceActionResponse &) = default; /** * Whether the client device is authorized to perform the operation on the resource. @@ -4311,7 +4347,7 @@ namespace Aws /** * Whether the client device is authorized to perform the operation on the resource. */ - Aws::Crt::Optional GetIsAuthorized() noexcept { return m_isAuthorized; } + Aws::Crt::Optional GetIsAuthorized() const noexcept { return m_isAuthorized; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(AuthorizeClientDeviceActionResponse &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -4332,7 +4368,7 @@ namespace Aws class AWS_GREENGRASSCOREIPC_API AuthorizeClientDeviceActionRequest : public AbstractShapeBase { public: - AuthorizeClientDeviceActionRequest() noexcept {} + AuthorizeClientDeviceActionRequest() noexcept = default; AuthorizeClientDeviceActionRequest(const AuthorizeClientDeviceActionRequest &) = default; /** * The session token for the client device from GetClientDeviceAuthToken. @@ -4344,7 +4380,10 @@ namespace Aws /** * The session token for the client device from GetClientDeviceAuthToken. */ - Aws::Crt::Optional GetClientDeviceAuthToken() noexcept { return m_clientDeviceAuthToken; } + Aws::Crt::Optional GetClientDeviceAuthToken() const noexcept + { + return m_clientDeviceAuthToken; + } /** * The operation to authorize. */ @@ -4352,7 +4391,7 @@ namespace Aws /** * The operation to authorize. */ - Aws::Crt::Optional GetOperation() noexcept { return m_operation; } + Aws::Crt::Optional GetOperation() const noexcept { return m_operation; } /** * The resource the client device performs the operation on. */ @@ -4360,7 +4399,7 @@ namespace Aws /** * The resource the client device performs the operation on. */ - Aws::Crt::Optional GetResource() noexcept { return m_resource; } + Aws::Crt::Optional GetResource() const noexcept { return m_resource; } void SerializeToJsonObject(Aws::Crt::JsonObject &payloadObject) const noexcept override; static void s_loadFromJsonView(AuthorizeClientDeviceActionRequest &, const Aws::Crt::JsonView &) noexcept; static Aws::Crt::ScopedResource s_allocateFromPayload( @@ -4430,6 +4469,7 @@ namespace Aws * Invoked when a message is received on this continuation. */ void OnStreamEvent(Aws::Crt::ScopedResource response) override; + /** * Invoked when a message is received on this continuation but results in an error. * @@ -4437,21 +4477,6 @@ namespace Aws */ bool OnStreamError(Aws::Crt::ScopedResource error, RpcError rpcError) override; }; - class AWS_GREENGRASSCOREIPC_API SubscribeToIoTCoreOperationContext : public OperationModelContext - { - public: - SubscribeToIoTCoreOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; class AWS_GREENGRASSCOREIPC_API SubscribeToIoTCoreResult { @@ -4462,11 +4487,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -4481,8 +4507,9 @@ namespace Aws SubscribeToIoTCoreOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToIoTCoreOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `SubscribeToIoTCoreOperation` * @param request The request used for the `SubscribeToIoTCoreOperation` @@ -4492,29 +4519,14 @@ namespace Aws std::future Activate( const SubscribeToIoTCoreRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API ResumeComponentOperationContext : public OperationModelContext - { - public: - ResumeComponentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API ResumeComponentResult @@ -4526,11 +4538,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -4544,8 +4557,9 @@ namespace Aws public: ResumeComponentOperation( ClientConnection &connection, - const ResumeComponentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `ResumeComponentOperation` * @param request The request used for the `ResumeComponentOperation` @@ -4555,29 +4569,14 @@ namespace Aws std::future Activate( const ResumeComponentRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API PublishToIoTCoreOperationContext : public OperationModelContext - { - public: - PublishToIoTCoreOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API PublishToIoTCoreResult @@ -4589,11 +4588,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -4607,8 +4607,9 @@ namespace Aws public: PublishToIoTCoreOperation( ClientConnection &connection, - const PublishToIoTCoreOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `PublishToIoTCoreOperation` * @param request The request used for the `PublishToIoTCoreOperation` @@ -4618,13 +4619,14 @@ namespace Aws std::future Activate( const PublishToIoTCoreRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API SubscribeToConfigurationUpdateStreamHandler : public StreamResponseHandler @@ -4677,6 +4679,7 @@ namespace Aws * Invoked when a message is received on this continuation. */ void OnStreamEvent(Aws::Crt::ScopedResource response) override; + /** * Invoked when a message is received on this continuation but results in an error. * @@ -4684,21 +4687,6 @@ namespace Aws */ bool OnStreamError(Aws::Crt::ScopedResource error, RpcError rpcError) override; }; - class AWS_GREENGRASSCOREIPC_API SubscribeToConfigurationUpdateOperationContext : public OperationModelContext - { - public: - SubscribeToConfigurationUpdateOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; class AWS_GREENGRASSCOREIPC_API SubscribeToConfigurationUpdateResult { @@ -4712,11 +4700,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -4731,8 +4720,9 @@ namespace Aws SubscribeToConfigurationUpdateOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToConfigurationUpdateOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `SubscribeToConfigurationUpdateOperation` * @param request The request used for the `SubscribeToConfigurationUpdateOperation` @@ -4742,29 +4732,14 @@ namespace Aws std::future Activate( const SubscribeToConfigurationUpdateRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API DeleteThingShadowOperationContext : public OperationModelContext - { - public: - DeleteThingShadowOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API DeleteThingShadowResult @@ -4776,11 +4751,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -4794,8 +4770,9 @@ namespace Aws public: DeleteThingShadowOperation( ClientConnection &connection, - const DeleteThingShadowOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `DeleteThingShadowOperation` * @param request The request used for the `DeleteThingShadowOperation` @@ -4805,29 +4782,14 @@ namespace Aws std::future Activate( const DeleteThingShadowRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API PutComponentMetricOperationContext : public OperationModelContext - { - public: - PutComponentMetricOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API PutComponentMetricResult @@ -4839,11 +4801,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -4857,8 +4820,9 @@ namespace Aws public: PutComponentMetricOperation( ClientConnection &connection, - const PutComponentMetricOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `PutComponentMetricOperation` * @param request The request used for the `PutComponentMetricOperation` @@ -4868,29 +4832,14 @@ namespace Aws std::future Activate( const PutComponentMetricRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API DeferComponentUpdateOperationContext : public OperationModelContext - { - public: - DeferComponentUpdateOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API DeferComponentUpdateResult @@ -4904,11 +4853,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -4922,8 +4872,9 @@ namespace Aws public: DeferComponentUpdateOperation( ClientConnection &connection, - const DeferComponentUpdateOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `DeferComponentUpdateOperation` * @param request The request used for the `DeferComponentUpdateOperation` @@ -4933,13 +4884,14 @@ namespace Aws std::future Activate( const DeferComponentUpdateRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API SubscribeToValidateConfigurationUpdatesStreamHandler @@ -4983,6 +4935,7 @@ namespace Aws * Invoked when a message is received on this continuation. */ void OnStreamEvent(Aws::Crt::ScopedResource response) override; + /** * Invoked when a message is received on this continuation but results in an error. * @@ -4990,23 +4943,6 @@ namespace Aws */ bool OnStreamError(Aws::Crt::ScopedResource error, RpcError rpcError) override; }; - class AWS_GREENGRASSCOREIPC_API SubscribeToValidateConfigurationUpdatesOperationContext - : public OperationModelContext - { - public: - SubscribeToValidateConfigurationUpdatesOperationContext( - const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; class AWS_GREENGRASSCOREIPC_API SubscribeToValidateConfigurationUpdatesResult { @@ -5021,11 +4957,12 @@ namespace Aws return static_cast( m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5040,8 +4977,9 @@ namespace Aws SubscribeToValidateConfigurationUpdatesOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToValidateConfigurationUpdatesOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `SubscribeToValidateConfigurationUpdatesOperation` * @param request The request used for the `SubscribeToValidateConfigurationUpdatesOperation` @@ -5051,29 +4989,14 @@ namespace Aws std::future Activate( const SubscribeToValidateConfigurationUpdatesRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API GetConfigurationOperationContext : public OperationModelContext - { - public: - GetConfigurationOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API GetConfigurationResult @@ -5085,11 +5008,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5103,8 +5027,9 @@ namespace Aws public: GetConfigurationOperation( ClientConnection &connection, - const GetConfigurationOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `GetConfigurationOperation` * @param request The request used for the `GetConfigurationOperation` @@ -5114,13 +5039,14 @@ namespace Aws std::future Activate( const GetConfigurationRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API SubscribeToTopicStreamHandler : public StreamResponseHandler @@ -5183,6 +5109,7 @@ namespace Aws * Invoked when a message is received on this continuation. */ void OnStreamEvent(Aws::Crt::ScopedResource response) override; + /** * Invoked when a message is received on this continuation but results in an error. * @@ -5190,21 +5117,6 @@ namespace Aws */ bool OnStreamError(Aws::Crt::ScopedResource error, RpcError rpcError) override; }; - class AWS_GREENGRASSCOREIPC_API SubscribeToTopicOperationContext : public OperationModelContext - { - public: - SubscribeToTopicOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; class AWS_GREENGRASSCOREIPC_API SubscribeToTopicResult { @@ -5215,11 +5127,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5234,8 +5147,9 @@ namespace Aws SubscribeToTopicOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToTopicOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `SubscribeToTopicOperation` * @param request The request used for the `SubscribeToTopicOperation` @@ -5245,29 +5159,14 @@ namespace Aws std::future Activate( const SubscribeToTopicRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API GetComponentDetailsOperationContext : public OperationModelContext - { - public: - GetComponentDetailsOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API GetComponentDetailsResult @@ -5279,11 +5178,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5297,8 +5197,9 @@ namespace Aws public: GetComponentDetailsOperation( ClientConnection &connection, - const GetComponentDetailsOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `GetComponentDetailsOperation` * @param request The request used for the `GetComponentDetailsOperation` @@ -5308,29 +5209,14 @@ namespace Aws std::future Activate( const GetComponentDetailsRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API GetClientDeviceAuthTokenOperationContext : public OperationModelContext - { - public: - GetClientDeviceAuthTokenOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API GetClientDeviceAuthTokenResult @@ -5345,11 +5231,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5363,8 +5250,9 @@ namespace Aws public: GetClientDeviceAuthTokenOperation( ClientConnection &connection, - const GetClientDeviceAuthTokenOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `GetClientDeviceAuthTokenOperation` * @param request The request used for the `GetClientDeviceAuthTokenOperation` @@ -5374,29 +5262,14 @@ namespace Aws std::future Activate( const GetClientDeviceAuthTokenRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API PublishToTopicOperationContext : public OperationModelContext - { - public: - PublishToTopicOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API PublishToTopicResult @@ -5408,11 +5281,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5426,8 +5300,9 @@ namespace Aws public: PublishToTopicOperation( ClientConnection &connection, - const PublishToTopicOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `PublishToTopicOperation` * @param request The request used for the `PublishToTopicOperation` @@ -5437,13 +5312,14 @@ namespace Aws std::future Activate( const PublishToTopicRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API SubscribeToCertificateUpdatesStreamHandler : public StreamResponseHandler @@ -5506,6 +5382,7 @@ namespace Aws * Invoked when a message is received on this continuation. */ void OnStreamEvent(Aws::Crt::ScopedResource response) override; + /** * Invoked when a message is received on this continuation but results in an error. * @@ -5513,21 +5390,6 @@ namespace Aws */ bool OnStreamError(Aws::Crt::ScopedResource error, RpcError rpcError) override; }; - class AWS_GREENGRASSCOREIPC_API SubscribeToCertificateUpdatesOperationContext : public OperationModelContext - { - public: - SubscribeToCertificateUpdatesOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; class AWS_GREENGRASSCOREIPC_API SubscribeToCertificateUpdatesResult { @@ -5541,11 +5403,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5560,8 +5423,9 @@ namespace Aws SubscribeToCertificateUpdatesOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToCertificateUpdatesOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `SubscribeToCertificateUpdatesOperation` * @param request The request used for the `SubscribeToCertificateUpdatesOperation` @@ -5571,29 +5435,14 @@ namespace Aws std::future Activate( const SubscribeToCertificateUpdatesRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API VerifyClientDeviceIdentityOperationContext : public OperationModelContext - { - public: - VerifyClientDeviceIdentityOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API VerifyClientDeviceIdentityResult @@ -5608,11 +5457,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5626,8 +5476,9 @@ namespace Aws public: VerifyClientDeviceIdentityOperation( ClientConnection &connection, - const VerifyClientDeviceIdentityOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `VerifyClientDeviceIdentityOperation` * @param request The request used for the `VerifyClientDeviceIdentityOperation` @@ -5637,29 +5488,14 @@ namespace Aws std::future Activate( const VerifyClientDeviceIdentityRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API AuthorizeClientDeviceActionOperationContext : public OperationModelContext - { - public: - AuthorizeClientDeviceActionOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API AuthorizeClientDeviceActionResult @@ -5674,11 +5510,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5692,8 +5529,9 @@ namespace Aws public: AuthorizeClientDeviceActionOperation( ClientConnection &connection, - const AuthorizeClientDeviceActionOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `AuthorizeClientDeviceActionOperation` * @param request The request used for the `AuthorizeClientDeviceActionOperation` @@ -5703,29 +5541,14 @@ namespace Aws std::future Activate( const AuthorizeClientDeviceActionRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API ListComponentsOperationContext : public OperationModelContext - { - public: - ListComponentsOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API ListComponentsResult @@ -5737,11 +5560,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5755,8 +5579,9 @@ namespace Aws public: ListComponentsOperation( ClientConnection &connection, - const ListComponentsOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `ListComponentsOperation` * @param request The request used for the `ListComponentsOperation` @@ -5766,29 +5591,14 @@ namespace Aws std::future Activate( const ListComponentsRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API CreateDebugPasswordOperationContext : public OperationModelContext - { - public: - CreateDebugPasswordOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API CreateDebugPasswordResult @@ -5800,11 +5610,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5818,8 +5629,9 @@ namespace Aws public: CreateDebugPasswordOperation( ClientConnection &connection, - const CreateDebugPasswordOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `CreateDebugPasswordOperation` * @param request The request used for the `CreateDebugPasswordOperation` @@ -5829,29 +5641,14 @@ namespace Aws std::future Activate( const CreateDebugPasswordRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API GetThingShadowOperationContext : public OperationModelContext - { - public: - GetThingShadowOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API GetThingShadowResult @@ -5863,11 +5660,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5881,8 +5679,9 @@ namespace Aws public: GetThingShadowOperation( ClientConnection &connection, - const GetThingShadowOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `GetThingShadowOperation` * @param request The request used for the `GetThingShadowOperation` @@ -5892,29 +5691,14 @@ namespace Aws std::future Activate( const GetThingShadowRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API SendConfigurationValidityReportOperationContext : public OperationModelContext - { - public: - SendConfigurationValidityReportOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API SendConfigurationValidityReportResult @@ -5929,11 +5713,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -5947,8 +5732,9 @@ namespace Aws public: SendConfigurationValidityReportOperation( ClientConnection &connection, - const SendConfigurationValidityReportOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `SendConfigurationValidityReportOperation` * @param request The request used for the `SendConfigurationValidityReportOperation` @@ -5958,29 +5744,14 @@ namespace Aws std::future Activate( const SendConfigurationValidityReportRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API UpdateThingShadowOperationContext : public OperationModelContext - { - public: - UpdateThingShadowOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API UpdateThingShadowResult @@ -5992,11 +5763,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6010,8 +5782,9 @@ namespace Aws public: UpdateThingShadowOperation( ClientConnection &connection, - const UpdateThingShadowOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `UpdateThingShadowOperation` * @param request The request used for the `UpdateThingShadowOperation` @@ -6021,29 +5794,14 @@ namespace Aws std::future Activate( const UpdateThingShadowRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API UpdateConfigurationOperationContext : public OperationModelContext - { - public: - UpdateConfigurationOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API UpdateConfigurationResult @@ -6055,11 +5813,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6073,8 +5832,9 @@ namespace Aws public: UpdateConfigurationOperation( ClientConnection &connection, - const UpdateConfigurationOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `UpdateConfigurationOperation` * @param request The request used for the `UpdateConfigurationOperation` @@ -6084,29 +5844,14 @@ namespace Aws std::future Activate( const UpdateConfigurationRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API ValidateAuthorizationTokenOperationContext : public OperationModelContext - { - public: - ValidateAuthorizationTokenOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API ValidateAuthorizationTokenResult @@ -6121,11 +5866,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6139,8 +5885,9 @@ namespace Aws public: ValidateAuthorizationTokenOperation( ClientConnection &connection, - const ValidateAuthorizationTokenOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `ValidateAuthorizationTokenOperation` * @param request The request used for the `ValidateAuthorizationTokenOperation` @@ -6150,29 +5897,14 @@ namespace Aws std::future Activate( const ValidateAuthorizationTokenRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API RestartComponentOperationContext : public OperationModelContext - { - public: - RestartComponentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API RestartComponentResult @@ -6184,11 +5916,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6202,8 +5935,9 @@ namespace Aws public: RestartComponentOperation( ClientConnection &connection, - const RestartComponentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `RestartComponentOperation` * @param request The request used for the `RestartComponentOperation` @@ -6213,29 +5947,14 @@ namespace Aws std::future Activate( const RestartComponentRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API GetLocalDeploymentStatusOperationContext : public OperationModelContext - { - public: - GetLocalDeploymentStatusOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API GetLocalDeploymentStatusResult @@ -6250,11 +5969,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6268,8 +5988,9 @@ namespace Aws public: GetLocalDeploymentStatusOperation( ClientConnection &connection, - const GetLocalDeploymentStatusOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `GetLocalDeploymentStatusOperation` * @param request The request used for the `GetLocalDeploymentStatusOperation` @@ -6279,29 +6000,14 @@ namespace Aws std::future Activate( const GetLocalDeploymentStatusRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API GetSecretValueOperationContext : public OperationModelContext - { - public: - GetSecretValueOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API GetSecretValueResult @@ -6313,11 +6019,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6331,8 +6038,9 @@ namespace Aws public: GetSecretValueOperation( ClientConnection &connection, - const GetSecretValueOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `GetSecretValueOperation` * @param request The request used for the `GetSecretValueOperation` @@ -6342,29 +6050,14 @@ namespace Aws std::future Activate( const GetSecretValueRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API UpdateStateOperationContext : public OperationModelContext - { - public: - UpdateStateOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API UpdateStateResult @@ -6376,11 +6069,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6394,8 +6088,9 @@ namespace Aws public: UpdateStateOperation( ClientConnection &connection, - const UpdateStateOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `UpdateStateOperation` * @param request The request used for the `UpdateStateOperation` @@ -6405,29 +6100,14 @@ namespace Aws std::future Activate( const UpdateStateRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API CancelLocalDeploymentOperationContext : public OperationModelContext - { - public: - CancelLocalDeploymentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API CancelLocalDeploymentResult @@ -6441,11 +6121,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6459,8 +6140,9 @@ namespace Aws public: CancelLocalDeploymentOperation( ClientConnection &connection, - const CancelLocalDeploymentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `CancelLocalDeploymentOperation` * @param request The request used for the `CancelLocalDeploymentOperation` @@ -6470,29 +6152,14 @@ namespace Aws std::future Activate( const CancelLocalDeploymentRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API ListNamedShadowsForThingOperationContext : public OperationModelContext - { - public: - ListNamedShadowsForThingOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API ListNamedShadowsForThingResult @@ -6507,11 +6174,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6525,8 +6193,9 @@ namespace Aws public: ListNamedShadowsForThingOperation( ClientConnection &connection, - const ListNamedShadowsForThingOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `ListNamedShadowsForThingOperation` * @param request The request used for the `ListNamedShadowsForThingOperation` @@ -6536,13 +6205,14 @@ namespace Aws std::future Activate( const ListNamedShadowsForThingRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API SubscribeToComponentUpdatesStreamHandler : public StreamResponseHandler @@ -6595,6 +6265,7 @@ namespace Aws * Invoked when a message is received on this continuation. */ void OnStreamEvent(Aws::Crt::ScopedResource response) override; + /** * Invoked when a message is received on this continuation but results in an error. * @@ -6602,21 +6273,6 @@ namespace Aws */ bool OnStreamError(Aws::Crt::ScopedResource error, RpcError rpcError) override; }; - class AWS_GREENGRASSCOREIPC_API SubscribeToComponentUpdatesOperationContext : public OperationModelContext - { - public: - SubscribeToComponentUpdatesOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; - }; class AWS_GREENGRASSCOREIPC_API SubscribeToComponentUpdatesResult { @@ -6630,11 +6286,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6649,8 +6306,9 @@ namespace Aws SubscribeToComponentUpdatesOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToComponentUpdatesOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `SubscribeToComponentUpdatesOperation` * @param request The request used for the `SubscribeToComponentUpdatesOperation` @@ -6660,29 +6318,14 @@ namespace Aws std::future Activate( const SubscribeToComponentUpdatesRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API ListLocalDeploymentsOperationContext : public OperationModelContext - { - public: - ListLocalDeploymentsOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API ListLocalDeploymentsResult @@ -6696,11 +6339,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6714,8 +6358,9 @@ namespace Aws public: ListLocalDeploymentsOperation( ClientConnection &connection, - const ListLocalDeploymentsOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `ListLocalDeploymentsOperation` * @param request The request used for the `ListLocalDeploymentsOperation` @@ -6725,29 +6370,14 @@ namespace Aws std::future Activate( const ListLocalDeploymentsRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API StopComponentOperationContext : public OperationModelContext - { - public: - StopComponentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API StopComponentResult @@ -6759,11 +6389,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6777,8 +6408,9 @@ namespace Aws public: StopComponentOperation( ClientConnection &connection, - const StopComponentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `StopComponentOperation` * @param request The request used for the `StopComponentOperation` @@ -6788,29 +6420,14 @@ namespace Aws std::future Activate( const StopComponentRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API PauseComponentOperationContext : public OperationModelContext - { - public: - PauseComponentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API PauseComponentResult @@ -6822,11 +6439,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6840,8 +6458,9 @@ namespace Aws public: PauseComponentOperation( ClientConnection &connection, - const PauseComponentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `PauseComponentOperation` * @param request The request used for the `PauseComponentOperation` @@ -6851,29 +6470,14 @@ namespace Aws std::future Activate( const PauseComponentRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; - }; - - class AWS_GREENGRASSCOREIPC_API CreateLocalDeploymentOperationContext : public OperationModelContext - { - public: - CreateLocalDeploymentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; - Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( - Aws::Crt::StringView stringView, - Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; - Aws::Crt::String GetRequestModelName() const noexcept override; - Aws::Crt::String GetInitialResponseModelName() const noexcept override; - Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; - Aws::Crt::String GetOperationName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API CreateLocalDeploymentResult @@ -6887,11 +6491,12 @@ namespace Aws { return static_cast(m_taggedResult.GetOperationResponse()); } + /** * @return true if the response is associated with an expected response; * false if the response is associated with an error. */ - operator bool() const noexcept { return m_taggedResult == true; } + operator bool() const noexcept { return static_cast(m_taggedResult) == true; } OperationError *GetOperationError() const noexcept { return m_taggedResult.GetOperationError(); } RpcError GetRpcError() const noexcept { return m_taggedResult.GetRpcError(); } ResultType GetResultType() const noexcept { return m_taggedResult.GetResultType(); } @@ -6905,8 +6510,9 @@ namespace Aws public: CreateLocalDeploymentOperation( ClientConnection &connection, - const CreateLocalDeploymentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) noexcept; + /** * Used to activate a stream for the `CreateLocalDeploymentOperation` * @param request The request used for the `CreateLocalDeploymentOperation` @@ -6916,19 +6522,20 @@ namespace Aws std::future Activate( const CreateLocalDeploymentRequest &request, OnMessageFlushCallback onMessageFlushCallback = nullptr) noexcept; + /** * Retrieve the result from activating the stream. */ std::future GetResult() noexcept; - protected: - Aws::Crt::String GetModelName() const noexcept override; + private: + std::shared_ptr> m_resultPromise; }; class AWS_GREENGRASSCOREIPC_API GreengrassCoreIpcServiceModel : public ServiceModel { public: - GreengrassCoreIpcServiceModel() noexcept; + GreengrassCoreIpcServiceModel(Aws::Crt::Allocator *allocator) noexcept; Aws::Crt::ScopedResource AllocateOperationErrorFromPayload( const Aws::Crt::String &errorModelName, Aws::Crt::StringView stringView, @@ -6937,41 +6544,40 @@ namespace Aws private: friend class GreengrassCoreIpcClient; - SubscribeToIoTCoreOperationContext m_subscribeToIoTCoreOperationContext; - ResumeComponentOperationContext m_resumeComponentOperationContext; - PublishToIoTCoreOperationContext m_publishToIoTCoreOperationContext; - SubscribeToConfigurationUpdateOperationContext m_subscribeToConfigurationUpdateOperationContext; - DeleteThingShadowOperationContext m_deleteThingShadowOperationContext; - PutComponentMetricOperationContext m_putComponentMetricOperationContext; - DeferComponentUpdateOperationContext m_deferComponentUpdateOperationContext; - SubscribeToValidateConfigurationUpdatesOperationContext - m_subscribeToValidateConfigurationUpdatesOperationContext; - GetConfigurationOperationContext m_getConfigurationOperationContext; - SubscribeToTopicOperationContext m_subscribeToTopicOperationContext; - GetComponentDetailsOperationContext m_getComponentDetailsOperationContext; - GetClientDeviceAuthTokenOperationContext m_getClientDeviceAuthTokenOperationContext; - PublishToTopicOperationContext m_publishToTopicOperationContext; - SubscribeToCertificateUpdatesOperationContext m_subscribeToCertificateUpdatesOperationContext; - VerifyClientDeviceIdentityOperationContext m_verifyClientDeviceIdentityOperationContext; - AuthorizeClientDeviceActionOperationContext m_authorizeClientDeviceActionOperationContext; - ListComponentsOperationContext m_listComponentsOperationContext; - CreateDebugPasswordOperationContext m_createDebugPasswordOperationContext; - GetThingShadowOperationContext m_getThingShadowOperationContext; - SendConfigurationValidityReportOperationContext m_sendConfigurationValidityReportOperationContext; - UpdateThingShadowOperationContext m_updateThingShadowOperationContext; - UpdateConfigurationOperationContext m_updateConfigurationOperationContext; - ValidateAuthorizationTokenOperationContext m_validateAuthorizationTokenOperationContext; - RestartComponentOperationContext m_restartComponentOperationContext; - GetLocalDeploymentStatusOperationContext m_getLocalDeploymentStatusOperationContext; - GetSecretValueOperationContext m_getSecretValueOperationContext; - UpdateStateOperationContext m_updateStateOperationContext; - CancelLocalDeploymentOperationContext m_cancelLocalDeploymentOperationContext; - ListNamedShadowsForThingOperationContext m_listNamedShadowsForThingOperationContext; - SubscribeToComponentUpdatesOperationContext m_subscribeToComponentUpdatesOperationContext; - ListLocalDeploymentsOperationContext m_listLocalDeploymentsOperationContext; - StopComponentOperationContext m_stopComponentOperationContext; - PauseComponentOperationContext m_pauseComponentOperationContext; - CreateLocalDeploymentOperationContext m_createLocalDeploymentOperationContext; + std::shared_ptr m_subscribeToIoTCoreOperationContext; + std::shared_ptr m_resumeComponentOperationContext; + std::shared_ptr m_publishToIoTCoreOperationContext; + std::shared_ptr m_subscribeToConfigurationUpdateOperationContext; + std::shared_ptr m_deleteThingShadowOperationContext; + std::shared_ptr m_putComponentMetricOperationContext; + std::shared_ptr m_deferComponentUpdateOperationContext; + std::shared_ptr m_subscribeToValidateConfigurationUpdatesOperationContext; + std::shared_ptr m_getConfigurationOperationContext; + std::shared_ptr m_subscribeToTopicOperationContext; + std::shared_ptr m_getComponentDetailsOperationContext; + std::shared_ptr m_getClientDeviceAuthTokenOperationContext; + std::shared_ptr m_publishToTopicOperationContext; + std::shared_ptr m_subscribeToCertificateUpdatesOperationContext; + std::shared_ptr m_verifyClientDeviceIdentityOperationContext; + std::shared_ptr m_authorizeClientDeviceActionOperationContext; + std::shared_ptr m_listComponentsOperationContext; + std::shared_ptr m_createDebugPasswordOperationContext; + std::shared_ptr m_getThingShadowOperationContext; + std::shared_ptr m_sendConfigurationValidityReportOperationContext; + std::shared_ptr m_updateThingShadowOperationContext; + std::shared_ptr m_updateConfigurationOperationContext; + std::shared_ptr m_validateAuthorizationTokenOperationContext; + std::shared_ptr m_restartComponentOperationContext; + std::shared_ptr m_getLocalDeploymentStatusOperationContext; + std::shared_ptr m_getSecretValueOperationContext; + std::shared_ptr m_updateStateOperationContext; + std::shared_ptr m_cancelLocalDeploymentOperationContext; + std::shared_ptr m_listNamedShadowsForThingOperationContext; + std::shared_ptr m_subscribeToComponentUpdatesOperationContext; + std::shared_ptr m_listLocalDeploymentsOperationContext; + std::shared_ptr m_stopComponentOperationContext; + std::shared_ptr m_pauseComponentOperationContext; + std::shared_ptr m_createLocalDeploymentOperationContext; Aws::Crt::Map m_modelNameToErrorResponse; }; } // namespace Greengrass diff --git a/greengrass_ipc/source/GreengrassCoreIpcClient.cpp b/greengrass_ipc/source/GreengrassCoreIpcClient.cpp index a1db24d5a..765156874 100644 --- a/greengrass_ipc/source/GreengrassCoreIpcClient.cpp +++ b/greengrass_ipc/source/GreengrassCoreIpcClient.cpp @@ -13,11 +13,14 @@ namespace Aws { namespace Greengrass { + GreengrassCoreIpcClient::GreengrassCoreIpcClient( Aws::Crt::Io::ClientBootstrap &clientBootstrap, Aws::Crt::Allocator *allocator) noexcept - : m_connection(allocator), m_clientBootstrap(clientBootstrap), m_allocator(allocator), - m_asyncLaunchMode(std::launch::deferred) + : m_greengrassCoreIpcServiceModel(allocator), + m_connection( + Aws::Crt::MakeShared(allocator, allocator, clientBootstrap.GetUnderlyingHandle())), + m_allocator(allocator), m_asyncLaunchMode(std::launch::deferred) { m_greengrassCoreIpcServiceModel.AssignModelNameToErrorResponse( Aws::Crt::String("aws.greengrass#InvalidArgumentsError"), InvalidArgumentsError::s_allocateFromPayload); @@ -55,12 +58,12 @@ namespace Aws ConnectionLifecycleHandler &lifecycleHandler, const ConnectionConfig &connectionConfig) noexcept { - return m_connection.Connect(connectionConfig, &lifecycleHandler, m_clientBootstrap); + return m_connection->Connect(connectionConfig, &lifecycleHandler); } void GreengrassCoreIpcClient::Close() noexcept { - m_connection.Close(); + m_connection->Close(); } void GreengrassCoreIpcClient::WithLaunchMode(std::launch mode) noexcept @@ -78,7 +81,7 @@ namespace Aws { return Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, std::move(streamHandler), m_greengrassCoreIpcServiceModel.m_subscribeToIoTCoreOperationContext, m_allocator); @@ -88,7 +91,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_resumeComponentOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -99,7 +102,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_publishToIoTCoreOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -112,7 +115,7 @@ namespace Aws { return Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, std::move(streamHandler), m_greengrassCoreIpcServiceModel.m_subscribeToConfigurationUpdateOperationContext, m_allocator); @@ -122,7 +125,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_deleteThingShadowOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -133,7 +136,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_putComponentMetricOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -144,7 +147,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_deferComponentUpdateOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -157,7 +160,7 @@ namespace Aws { return Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, std::move(streamHandler), m_greengrassCoreIpcServiceModel.m_subscribeToValidateConfigurationUpdatesOperationContext, m_allocator); @@ -167,7 +170,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_getConfigurationOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -179,7 +182,7 @@ namespace Aws { return Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, std::move(streamHandler), m_greengrassCoreIpcServiceModel.m_subscribeToTopicOperationContext, m_allocator); @@ -189,7 +192,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_getComponentDetailsOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -201,7 +204,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_getClientDeviceAuthTokenOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -212,7 +215,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_publishToTopicOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -225,7 +228,7 @@ namespace Aws { return Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, std::move(streamHandler), m_greengrassCoreIpcServiceModel.m_subscribeToCertificateUpdatesOperationContext, m_allocator); @@ -236,7 +239,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_verifyClientDeviceIdentityOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -248,7 +251,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_authorizeClientDeviceActionOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -259,7 +262,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_listComponentsOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -270,7 +273,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_createDebugPasswordOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -281,7 +284,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_getThingShadowOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -293,7 +296,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_sendConfigurationValidityReportOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -304,7 +307,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_updateThingShadowOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -315,7 +318,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_updateConfigurationOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -327,7 +330,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_validateAuthorizationTokenOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -338,7 +341,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_restartComponentOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -350,7 +353,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_getLocalDeploymentStatusOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -361,7 +364,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_getSecretValueOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -371,7 +374,7 @@ namespace Aws std::shared_ptr GreengrassCoreIpcClient::NewUpdateState() noexcept { auto operation = Aws::Crt::MakeShared( - m_allocator, m_connection, m_greengrassCoreIpcServiceModel.m_updateStateOperationContext, m_allocator); + m_allocator, *m_connection, m_greengrassCoreIpcServiceModel.m_updateStateOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); return operation; } @@ -380,7 +383,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_cancelLocalDeploymentOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -392,7 +395,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_listNamedShadowsForThingOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -404,7 +407,7 @@ namespace Aws { return Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, std::move(streamHandler), m_greengrassCoreIpcServiceModel.m_subscribeToComponentUpdatesOperationContext, m_allocator); @@ -414,7 +417,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_listLocalDeploymentsOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -425,7 +428,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_stopComponentOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -436,7 +439,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_pauseComponentOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); @@ -447,7 +450,7 @@ namespace Aws { auto operation = Aws::Crt::MakeShared( m_allocator, - m_connection, + *m_connection, m_greengrassCoreIpcServiceModel.m_createLocalDeploymentOperationContext, m_allocator); operation->WithLaunchMode(m_asyncLaunchMode); diff --git a/greengrass_ipc/source/GreengrassCoreIpcModel.cpp b/greengrass_ipc/source/GreengrassCoreIpcModel.cpp index 10d686a57..d91723063 100644 --- a/greengrass_ipc/source/GreengrassCoreIpcModel.cpp +++ b/greengrass_ipc/source/GreengrassCoreIpcModel.cpp @@ -211,7 +211,8 @@ namespace Aws } } - Aws::Crt::Optional DeploymentStatusDetails::GetDetailedDeploymentStatus() noexcept + Aws::Crt::Optional DeploymentStatusDetails::GetDetailedDeploymentStatus() + const noexcept { if (!m_detailedDeploymentStatus.has_value()) return Aws::Crt::Optional(); @@ -626,7 +627,7 @@ namespace Aws } } - Aws::Crt::Optional MQTTMessage::GetPayloadFormat() noexcept + Aws::Crt::Optional MQTTMessage::GetPayloadFormat() const noexcept { if (!m_payloadFormat.has_value()) return Aws::Crt::Optional(); @@ -988,7 +989,7 @@ namespace Aws } } - Aws::Crt::Optional Metric::GetUnit() noexcept + Aws::Crt::Optional Metric::GetUnit() const noexcept { if (!m_unit.has_value()) return Aws::Crt::Optional(); @@ -1119,7 +1120,7 @@ namespace Aws } } - Aws::Crt::Optional LocalDeployment::GetStatus() noexcept + Aws::Crt::Optional LocalDeployment::GetStatus() const noexcept { if (!m_status.has_value()) return Aws::Crt::Optional(); @@ -1252,7 +1253,7 @@ namespace Aws } } - Aws::Crt::Optional ComponentDetails::GetState() noexcept + Aws::Crt::Optional ComponentDetails::GetState() const noexcept { if (!m_state.has_value()) return Aws::Crt::Optional(); @@ -1956,7 +1957,7 @@ namespace Aws } } - Aws::Crt::Optional CertificateOptions::GetCertificateType() noexcept + Aws::Crt::Optional CertificateOptions::GetCertificateType() const noexcept { if (!m_certificateType.has_value()) return Aws::Crt::Optional(); @@ -2048,7 +2049,7 @@ namespace Aws } } - Aws::Crt::Optional ConfigurationValidityReport::GetStatus() noexcept + Aws::Crt::Optional ConfigurationValidityReport::GetStatus() const noexcept { if (!m_status.has_value()) return Aws::Crt::Optional(); @@ -3007,7 +3008,7 @@ namespace Aws } } - Aws::Crt::Optional UpdateStateRequest::GetState() noexcept + Aws::Crt::Optional UpdateStateRequest::GetState() const noexcept { if (!m_state.has_value()) return Aws::Crt::Optional(); @@ -3396,7 +3397,7 @@ namespace Aws } } - Aws::Crt::Optional SubscribeToTopicRequest::GetReceiveMode() noexcept + Aws::Crt::Optional SubscribeToTopicRequest::GetReceiveMode() const noexcept { if (!m_receiveMode.has_value()) return Aws::Crt::Optional(); @@ -3523,7 +3524,7 @@ namespace Aws } } - Aws::Crt::Optional SubscribeToIoTCoreRequest::GetQos() noexcept + Aws::Crt::Optional SubscribeToIoTCoreRequest::GetQos() const noexcept { if (!m_qos.has_value()) return Aws::Crt::Optional(); @@ -3961,7 +3962,7 @@ namespace Aws } } - Aws::Crt::Optional StopComponentResponse::GetStopStatus() noexcept + Aws::Crt::Optional StopComponentResponse::GetStopStatus() const noexcept { if (!m_stopStatus.has_value()) return Aws::Crt::Optional(); @@ -4283,7 +4284,7 @@ namespace Aws } } - Aws::Crt::Optional RestartComponentResponse::GetRestartStatus() noexcept + Aws::Crt::Optional RestartComponentResponse::GetRestartStatus() const noexcept { if (!m_restartStatus.has_value()) return Aws::Crt::Optional(); @@ -4757,7 +4758,7 @@ namespace Aws } } - Aws::Crt::Optional PublishToIoTCoreRequest::GetQos() noexcept + Aws::Crt::Optional PublishToIoTCoreRequest::GetQos() const noexcept { if (!m_qos.has_value()) return Aws::Crt::Optional(); @@ -4787,7 +4788,7 @@ namespace Aws } } - Aws::Crt::Optional PublishToIoTCoreRequest::GetPayloadFormat() noexcept + Aws::Crt::Optional PublishToIoTCoreRequest::GetPayloadFormat() const noexcept { if (!m_payloadFormat.has_value()) return Aws::Crt::Optional(); @@ -6535,7 +6536,8 @@ namespace Aws } } - Aws::Crt::Optional CreateLocalDeploymentRequest::GetFailureHandlingPolicy() noexcept + Aws::Crt::Optional CreateLocalDeploymentRequest::GetFailureHandlingPolicy() + const noexcept { if (!m_failureHandlingPolicy.has_value()) return Aws::Crt::Optional(); @@ -6996,6 +6998,22 @@ namespace Aws return streamShouldTerminate; } + class SubscribeToIoTCoreOperationContext : public OperationModelContext + { + public: + SubscribeToIoTCoreOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + SubscribeToIoTCoreOperationContext::SubscribeToIoTCoreOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) @@ -7039,16 +7057,16 @@ namespace Aws std::future SubscribeToIoTCoreOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return SubscribeToIoTCoreResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } SubscribeToIoTCoreOperation::SubscribeToIoTCoreOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToIoTCoreOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, streamHandler, operationContext, allocator) + : ClientOperation(connection, streamHandler, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7056,13 +7074,32 @@ namespace Aws const SubscribeToIoTCoreRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(SubscribeToIoTCoreResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String SubscribeToIoTCoreOperation::GetModelName() const noexcept + class ResumeComponentOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + ResumeComponentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; ResumeComponentOperationContext::ResumeComponentOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7109,15 +7146,15 @@ namespace Aws std::future ResumeComponentOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return ResumeComponentResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } ResumeComponentOperation::ResumeComponentOperation( ClientConnection &connection, - const ResumeComponentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7125,13 +7162,32 @@ namespace Aws const ResumeComponentRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(ResumeComponentResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String ResumeComponentOperation::GetModelName() const noexcept + class PublishToIoTCoreOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + PublishToIoTCoreOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; PublishToIoTCoreOperationContext::PublishToIoTCoreOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7178,15 +7234,15 @@ namespace Aws std::future PublishToIoTCoreOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return PublishToIoTCoreResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } PublishToIoTCoreOperation::PublishToIoTCoreOperation( ClientConnection &connection, - const PublishToIoTCoreOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7194,12 +7250,15 @@ namespace Aws const PublishToIoTCoreRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); - } + auto promiseReference = m_resultPromise; - Aws::Crt::String PublishToIoTCoreOperation::GetModelName() const noexcept - { - return m_operationModelContext.GetOperationName(); + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(PublishToIoTCoreResult(std::move(unmodeledResult))); }); + + return activateFuture; } void SubscribeToConfigurationUpdateStreamHandler::OnStreamEvent( @@ -7234,6 +7293,22 @@ namespace Aws return streamShouldTerminate; } + class SubscribeToConfigurationUpdateOperationContext : public OperationModelContext + { + public: + SubscribeToConfigurationUpdateOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + SubscribeToConfigurationUpdateOperationContext::SubscribeToConfigurationUpdateOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) @@ -7277,17 +7352,16 @@ namespace Aws std::future SubscribeToConfigurationUpdateOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, - [this]() { return SubscribeToConfigurationUpdateResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } SubscribeToConfigurationUpdateOperation::SubscribeToConfigurationUpdateOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToConfigurationUpdateOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, streamHandler, operationContext, allocator) + : ClientOperation(connection, streamHandler, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7295,13 +7369,32 @@ namespace Aws const SubscribeToConfigurationUpdateRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(SubscribeToConfigurationUpdateResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String SubscribeToConfigurationUpdateOperation::GetModelName() const noexcept + class DeleteThingShadowOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + DeleteThingShadowOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; DeleteThingShadowOperationContext::DeleteThingShadowOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7348,15 +7441,15 @@ namespace Aws std::future DeleteThingShadowOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return DeleteThingShadowResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } DeleteThingShadowOperation::DeleteThingShadowOperation( ClientConnection &connection, - const DeleteThingShadowOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7364,13 +7457,32 @@ namespace Aws const DeleteThingShadowRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(DeleteThingShadowResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String DeleteThingShadowOperation::GetModelName() const noexcept + class PutComponentMetricOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + PutComponentMetricOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; PutComponentMetricOperationContext::PutComponentMetricOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7417,15 +7529,15 @@ namespace Aws std::future PutComponentMetricOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return PutComponentMetricResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } PutComponentMetricOperation::PutComponentMetricOperation( ClientConnection &connection, - const PutComponentMetricOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7433,13 +7545,32 @@ namespace Aws const PutComponentMetricRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(PutComponentMetricResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String PutComponentMetricOperation::GetModelName() const noexcept + class DeferComponentUpdateOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + DeferComponentUpdateOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; DeferComponentUpdateOperationContext::DeferComponentUpdateOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7486,15 +7617,15 @@ namespace Aws std::future DeferComponentUpdateOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return DeferComponentUpdateResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } DeferComponentUpdateOperation::DeferComponentUpdateOperation( ClientConnection &connection, - const DeferComponentUpdateOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7502,12 +7633,15 @@ namespace Aws const DeferComponentUpdateRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); - } + auto promiseReference = m_resultPromise; - Aws::Crt::String DeferComponentUpdateOperation::GetModelName() const noexcept - { - return m_operationModelContext.GetOperationName(); + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(DeferComponentUpdateResult(std::move(unmodeledResult))); }); + + return activateFuture; } void SubscribeToValidateConfigurationUpdatesStreamHandler::OnStreamEvent( @@ -7536,6 +7670,23 @@ namespace Aws return streamShouldTerminate; } + class SubscribeToValidateConfigurationUpdatesOperationContext : public OperationModelContext + { + public: + SubscribeToValidateConfigurationUpdatesOperationContext( + const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + SubscribeToValidateConfigurationUpdatesOperationContext:: SubscribeToValidateConfigurationUpdatesOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7582,17 +7733,17 @@ namespace Aws std::future SubscribeToValidateConfigurationUpdatesOperation:: GetResult() noexcept { - return std::async( - m_asyncLaunchMode, - [this]() { return SubscribeToValidateConfigurationUpdatesResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } SubscribeToValidateConfigurationUpdatesOperation::SubscribeToValidateConfigurationUpdatesOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToValidateConfigurationUpdatesOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, streamHandler, operationContext, allocator) + : ClientOperation(connection, streamHandler, operationContext, allocator), + m_resultPromise( + Aws::Crt::MakeShared>(allocator)) { } @@ -7600,13 +7751,34 @@ namespace Aws const SubscribeToValidateConfigurationUpdatesRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) { + promiseReference->set_value( + SubscribeToValidateConfigurationUpdatesResult(std::move(unmodeledResult))); + }); + + return activateFuture; } - Aws::Crt::String SubscribeToValidateConfigurationUpdatesOperation::GetModelName() const noexcept + class GetConfigurationOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + GetConfigurationOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; GetConfigurationOperationContext::GetConfigurationOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7653,15 +7825,15 @@ namespace Aws std::future GetConfigurationOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return GetConfigurationResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } GetConfigurationOperation::GetConfigurationOperation( ClientConnection &connection, - const GetConfigurationOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7669,12 +7841,15 @@ namespace Aws const GetConfigurationRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); - } + auto promiseReference = m_resultPromise; - Aws::Crt::String GetConfigurationOperation::GetModelName() const noexcept - { - return m_operationModelContext.GetOperationName(); + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(GetConfigurationResult(std::move(unmodeledResult))); }); + + return activateFuture; } void SubscribeToTopicStreamHandler::OnStreamEvent(Aws::Crt::ScopedResource response) @@ -7714,6 +7889,22 @@ namespace Aws return streamShouldTerminate; } + class SubscribeToTopicOperationContext : public OperationModelContext + { + public: + SubscribeToTopicOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + SubscribeToTopicOperationContext::SubscribeToTopicOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) @@ -7757,16 +7948,16 @@ namespace Aws std::future SubscribeToTopicOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return SubscribeToTopicResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } SubscribeToTopicOperation::SubscribeToTopicOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToTopicOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, streamHandler, operationContext, allocator) + : ClientOperation(connection, streamHandler, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7774,13 +7965,32 @@ namespace Aws const SubscribeToTopicRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(SubscribeToTopicResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String SubscribeToTopicOperation::GetModelName() const noexcept + class GetComponentDetailsOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + GetComponentDetailsOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; GetComponentDetailsOperationContext::GetComponentDetailsOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7827,15 +8037,15 @@ namespace Aws std::future GetComponentDetailsOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return GetComponentDetailsResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } GetComponentDetailsOperation::GetComponentDetailsOperation( ClientConnection &connection, - const GetComponentDetailsOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7843,13 +8053,32 @@ namespace Aws const GetComponentDetailsRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(GetComponentDetailsResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String GetComponentDetailsOperation::GetModelName() const noexcept + class GetClientDeviceAuthTokenOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + GetClientDeviceAuthTokenOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; GetClientDeviceAuthTokenOperationContext::GetClientDeviceAuthTokenOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7896,15 +8125,15 @@ namespace Aws std::future GetClientDeviceAuthTokenOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return GetClientDeviceAuthTokenResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } GetClientDeviceAuthTokenOperation::GetClientDeviceAuthTokenOperation( ClientConnection &connection, - const GetClientDeviceAuthTokenOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7912,13 +8141,32 @@ namespace Aws const GetClientDeviceAuthTokenRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(GetClientDeviceAuthTokenResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String GetClientDeviceAuthTokenOperation::GetModelName() const noexcept + class PublishToTopicOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + PublishToTopicOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; PublishToTopicOperationContext::PublishToTopicOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -7965,14 +8213,15 @@ namespace Aws std::future PublishToTopicOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return PublishToTopicResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } PublishToTopicOperation::PublishToTopicOperation( ClientConnection &connection, - const PublishToTopicOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -7980,12 +8229,15 @@ namespace Aws const PublishToTopicRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); - } + auto promiseReference = m_resultPromise; - Aws::Crt::String PublishToTopicOperation::GetModelName() const noexcept - { - return m_operationModelContext.GetOperationName(); + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(PublishToTopicResult(std::move(unmodeledResult))); }); + + return activateFuture; } void SubscribeToCertificateUpdatesStreamHandler::OnStreamEvent( @@ -8026,6 +8278,22 @@ namespace Aws return streamShouldTerminate; } + class SubscribeToCertificateUpdatesOperationContext : public OperationModelContext + { + public: + SubscribeToCertificateUpdatesOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + SubscribeToCertificateUpdatesOperationContext::SubscribeToCertificateUpdatesOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) @@ -8069,17 +8337,16 @@ namespace Aws std::future SubscribeToCertificateUpdatesOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, - [this]() { return SubscribeToCertificateUpdatesResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } SubscribeToCertificateUpdatesOperation::SubscribeToCertificateUpdatesOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToCertificateUpdatesOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, streamHandler, operationContext, allocator) + : ClientOperation(connection, streamHandler, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8087,13 +8354,32 @@ namespace Aws const SubscribeToCertificateUpdatesRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(SubscribeToCertificateUpdatesResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String SubscribeToCertificateUpdatesOperation::GetModelName() const noexcept + class VerifyClientDeviceIdentityOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + VerifyClientDeviceIdentityOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; VerifyClientDeviceIdentityOperationContext::VerifyClientDeviceIdentityOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8140,15 +8426,15 @@ namespace Aws std::future VerifyClientDeviceIdentityOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return VerifyClientDeviceIdentityResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } VerifyClientDeviceIdentityOperation::VerifyClientDeviceIdentityOperation( ClientConnection &connection, - const VerifyClientDeviceIdentityOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8156,13 +8442,32 @@ namespace Aws const VerifyClientDeviceIdentityRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(VerifyClientDeviceIdentityResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String VerifyClientDeviceIdentityOperation::GetModelName() const noexcept + class AuthorizeClientDeviceActionOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + AuthorizeClientDeviceActionOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; AuthorizeClientDeviceActionOperationContext::AuthorizeClientDeviceActionOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8209,15 +8514,15 @@ namespace Aws std::future AuthorizeClientDeviceActionOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return AuthorizeClientDeviceActionResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } AuthorizeClientDeviceActionOperation::AuthorizeClientDeviceActionOperation( ClientConnection &connection, - const AuthorizeClientDeviceActionOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8225,13 +8530,32 @@ namespace Aws const AuthorizeClientDeviceActionRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(AuthorizeClientDeviceActionResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String AuthorizeClientDeviceActionOperation::GetModelName() const noexcept + class ListComponentsOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + ListComponentsOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; ListComponentsOperationContext::ListComponentsOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8278,14 +8602,15 @@ namespace Aws std::future ListComponentsOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return ListComponentsResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } ListComponentsOperation::ListComponentsOperation( ClientConnection &connection, - const ListComponentsOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8293,13 +8618,32 @@ namespace Aws const ListComponentsRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(ListComponentsResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String ListComponentsOperation::GetModelName() const noexcept + class CreateDebugPasswordOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + CreateDebugPasswordOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; CreateDebugPasswordOperationContext::CreateDebugPasswordOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8346,15 +8690,15 @@ namespace Aws std::future CreateDebugPasswordOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return CreateDebugPasswordResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } CreateDebugPasswordOperation::CreateDebugPasswordOperation( ClientConnection &connection, - const CreateDebugPasswordOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8362,13 +8706,32 @@ namespace Aws const CreateDebugPasswordRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(CreateDebugPasswordResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String CreateDebugPasswordOperation::GetModelName() const noexcept + class GetThingShadowOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + GetThingShadowOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; GetThingShadowOperationContext::GetThingShadowOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8415,14 +8778,15 @@ namespace Aws std::future GetThingShadowOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return GetThingShadowResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } GetThingShadowOperation::GetThingShadowOperation( ClientConnection &connection, - const GetThingShadowOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8430,13 +8794,32 @@ namespace Aws const GetThingShadowRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(GetThingShadowResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String GetThingShadowOperation::GetModelName() const noexcept + class SendConfigurationValidityReportOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + SendConfigurationValidityReportOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; SendConfigurationValidityReportOperationContext::SendConfigurationValidityReportOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8484,16 +8867,15 @@ namespace Aws std::future SendConfigurationValidityReportOperation:: GetResult() noexcept { - return std::async( - m_asyncLaunchMode, - [this]() { return SendConfigurationValidityReportResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } SendConfigurationValidityReportOperation::SendConfigurationValidityReportOperation( ClientConnection &connection, - const SendConfigurationValidityReportOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8501,13 +8883,32 @@ namespace Aws const SendConfigurationValidityReportRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(SendConfigurationValidityReportResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String SendConfigurationValidityReportOperation::GetModelName() const noexcept + class UpdateThingShadowOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + UpdateThingShadowOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; UpdateThingShadowOperationContext::UpdateThingShadowOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8554,15 +8955,15 @@ namespace Aws std::future UpdateThingShadowOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return UpdateThingShadowResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } UpdateThingShadowOperation::UpdateThingShadowOperation( ClientConnection &connection, - const UpdateThingShadowOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8570,13 +8971,32 @@ namespace Aws const UpdateThingShadowRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(UpdateThingShadowResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String UpdateThingShadowOperation::GetModelName() const noexcept + class UpdateConfigurationOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + UpdateConfigurationOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; UpdateConfigurationOperationContext::UpdateConfigurationOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8623,15 +9043,15 @@ namespace Aws std::future UpdateConfigurationOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return UpdateConfigurationResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } UpdateConfigurationOperation::UpdateConfigurationOperation( ClientConnection &connection, - const UpdateConfigurationOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8639,13 +9059,32 @@ namespace Aws const UpdateConfigurationRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(UpdateConfigurationResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String UpdateConfigurationOperation::GetModelName() const noexcept + class ValidateAuthorizationTokenOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + ValidateAuthorizationTokenOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; ValidateAuthorizationTokenOperationContext::ValidateAuthorizationTokenOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8692,15 +9131,15 @@ namespace Aws std::future ValidateAuthorizationTokenOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return ValidateAuthorizationTokenResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } ValidateAuthorizationTokenOperation::ValidateAuthorizationTokenOperation( ClientConnection &connection, - const ValidateAuthorizationTokenOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8708,13 +9147,32 @@ namespace Aws const ValidateAuthorizationTokenRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(ValidateAuthorizationTokenResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String ValidateAuthorizationTokenOperation::GetModelName() const noexcept + class RestartComponentOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + RestartComponentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; RestartComponentOperationContext::RestartComponentOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8761,15 +9219,15 @@ namespace Aws std::future RestartComponentOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return RestartComponentResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } RestartComponentOperation::RestartComponentOperation( ClientConnection &connection, - const RestartComponentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8777,13 +9235,32 @@ namespace Aws const RestartComponentRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(RestartComponentResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String RestartComponentOperation::GetModelName() const noexcept + class GetLocalDeploymentStatusOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + GetLocalDeploymentStatusOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; GetLocalDeploymentStatusOperationContext::GetLocalDeploymentStatusOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8830,15 +9307,15 @@ namespace Aws std::future GetLocalDeploymentStatusOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return GetLocalDeploymentStatusResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } GetLocalDeploymentStatusOperation::GetLocalDeploymentStatusOperation( ClientConnection &connection, - const GetLocalDeploymentStatusOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8846,13 +9323,32 @@ namespace Aws const GetLocalDeploymentStatusRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(GetLocalDeploymentStatusResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String GetLocalDeploymentStatusOperation::GetModelName() const noexcept + class GetSecretValueOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + GetSecretValueOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; GetSecretValueOperationContext::GetSecretValueOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8899,14 +9395,15 @@ namespace Aws std::future GetSecretValueOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return GetSecretValueResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } GetSecretValueOperation::GetSecretValueOperation( ClientConnection &connection, - const GetSecretValueOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8914,13 +9411,32 @@ namespace Aws const GetSecretValueRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(GetSecretValueResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String GetSecretValueOperation::GetModelName() const noexcept + class UpdateStateOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + UpdateStateOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; UpdateStateOperationContext::UpdateStateOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -8966,14 +9482,15 @@ namespace Aws std::future UpdateStateOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return UpdateStateResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } UpdateStateOperation::UpdateStateOperation( ClientConnection &connection, - const UpdateStateOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -8981,13 +9498,32 @@ namespace Aws const UpdateStateRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(UpdateStateResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String UpdateStateOperation::GetModelName() const noexcept + class CancelLocalDeploymentOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + CancelLocalDeploymentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; CancelLocalDeploymentOperationContext::CancelLocalDeploymentOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -9034,15 +9570,15 @@ namespace Aws std::future CancelLocalDeploymentOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return CancelLocalDeploymentResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } CancelLocalDeploymentOperation::CancelLocalDeploymentOperation( ClientConnection &connection, - const CancelLocalDeploymentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -9050,13 +9586,32 @@ namespace Aws const CancelLocalDeploymentRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(CancelLocalDeploymentResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String CancelLocalDeploymentOperation::GetModelName() const noexcept + class ListNamedShadowsForThingOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + ListNamedShadowsForThingOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; ListNamedShadowsForThingOperationContext::ListNamedShadowsForThingOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -9103,15 +9658,15 @@ namespace Aws std::future ListNamedShadowsForThingOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return ListNamedShadowsForThingResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } ListNamedShadowsForThingOperation::ListNamedShadowsForThingOperation( ClientConnection &connection, - const ListNamedShadowsForThingOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -9119,12 +9674,15 @@ namespace Aws const ListNamedShadowsForThingRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); - } + auto promiseReference = m_resultPromise; - Aws::Crt::String ListNamedShadowsForThingOperation::GetModelName() const noexcept - { - return m_operationModelContext.GetOperationName(); + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(ListNamedShadowsForThingResult(std::move(unmodeledResult))); }); + + return activateFuture; } void SubscribeToComponentUpdatesStreamHandler::OnStreamEvent( @@ -9159,6 +9717,22 @@ namespace Aws return streamShouldTerminate; } + class SubscribeToComponentUpdatesOperationContext : public OperationModelContext + { + public: + SubscribeToComponentUpdatesOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; + SubscribeToComponentUpdatesOperationContext::SubscribeToComponentUpdatesOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept : OperationModelContext(serviceModel) @@ -9202,16 +9776,16 @@ namespace Aws std::future SubscribeToComponentUpdatesOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return SubscribeToComponentUpdatesResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } SubscribeToComponentUpdatesOperation::SubscribeToComponentUpdatesOperation( ClientConnection &connection, std::shared_ptr streamHandler, - const SubscribeToComponentUpdatesOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, streamHandler, operationContext, allocator) + : ClientOperation(connection, streamHandler, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -9219,13 +9793,32 @@ namespace Aws const SubscribeToComponentUpdatesRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(SubscribeToComponentUpdatesResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String SubscribeToComponentUpdatesOperation::GetModelName() const noexcept + class ListLocalDeploymentsOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + ListLocalDeploymentsOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; ListLocalDeploymentsOperationContext::ListLocalDeploymentsOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -9272,15 +9865,15 @@ namespace Aws std::future ListLocalDeploymentsOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return ListLocalDeploymentsResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } ListLocalDeploymentsOperation::ListLocalDeploymentsOperation( ClientConnection &connection, - const ListLocalDeploymentsOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -9288,13 +9881,32 @@ namespace Aws const ListLocalDeploymentsRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(ListLocalDeploymentsResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String ListLocalDeploymentsOperation::GetModelName() const noexcept + class StopComponentOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + StopComponentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; StopComponentOperationContext::StopComponentOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -9341,14 +9953,15 @@ namespace Aws std::future StopComponentOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return StopComponentResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } StopComponentOperation::StopComponentOperation( ClientConnection &connection, - const StopComponentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -9356,13 +9969,32 @@ namespace Aws const StopComponentRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(StopComponentResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String StopComponentOperation::GetModelName() const noexcept + class PauseComponentOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + PauseComponentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; PauseComponentOperationContext::PauseComponentOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -9409,14 +10041,15 @@ namespace Aws std::future PauseComponentOperation::GetResult() noexcept { - return std::async(m_asyncLaunchMode, [this]() { return PauseComponentResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } PauseComponentOperation::PauseComponentOperation( ClientConnection &connection, - const PauseComponentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -9424,13 +10057,32 @@ namespace Aws const PauseComponentRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(PauseComponentResult(std::move(unmodeledResult))); }); + + return activateFuture; } - Aws::Crt::String PauseComponentOperation::GetModelName() const noexcept + class CreateLocalDeploymentOperationContext : public OperationModelContext { - return m_operationModelContext.GetOperationName(); - } + public: + CreateLocalDeploymentOperationContext(const GreengrassCoreIpcServiceModel &serviceModel) noexcept; + Aws::Crt::ScopedResource AllocateInitialResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::ScopedResource AllocateStreamingResponseFromPayload( + Aws::Crt::StringView stringView, + Aws::Crt::Allocator *allocator = Aws::Crt::g_allocator) const noexcept override; + Aws::Crt::String GetRequestModelName() const noexcept override; + Aws::Crt::String GetInitialResponseModelName() const noexcept override; + Aws::Crt::Optional GetStreamingResponseModelName() const noexcept override; + Aws::Crt::String GetOperationName() const noexcept override; + }; CreateLocalDeploymentOperationContext::CreateLocalDeploymentOperationContext( const GreengrassCoreIpcServiceModel &serviceModel) noexcept @@ -9477,15 +10129,15 @@ namespace Aws std::future CreateLocalDeploymentOperation::GetResult() noexcept { - return std::async( - m_asyncLaunchMode, [this]() { return CreateLocalDeploymentResult(GetOperationResult().get()); }); + return m_resultPromise->get_future(); } CreateLocalDeploymentOperation::CreateLocalDeploymentOperation( ClientConnection &connection, - const CreateLocalDeploymentOperationContext &operationContext, + const std::shared_ptr &operationContext, Aws::Crt::Allocator *allocator) noexcept - : ClientOperation(connection, nullptr, operationContext, allocator) + : ClientOperation(connection, nullptr, operationContext, allocator), + m_resultPromise(Aws::Crt::MakeShared>(allocator)) { } @@ -9493,33 +10145,79 @@ namespace Aws const CreateLocalDeploymentRequest &request, OnMessageFlushCallback onMessageFlushCallback) noexcept { - return ClientOperation::Activate(static_cast(&request), onMessageFlushCallback); - } - - Aws::Crt::String CreateLocalDeploymentOperation::GetModelName() const noexcept - { - return m_operationModelContext.GetOperationName(); - } - - GreengrassCoreIpcServiceModel::GreengrassCoreIpcServiceModel() noexcept - : m_subscribeToIoTCoreOperationContext(*this), m_resumeComponentOperationContext(*this), - m_publishToIoTCoreOperationContext(*this), m_subscribeToConfigurationUpdateOperationContext(*this), - m_deleteThingShadowOperationContext(*this), m_putComponentMetricOperationContext(*this), - m_deferComponentUpdateOperationContext(*this), - m_subscribeToValidateConfigurationUpdatesOperationContext(*this), - m_getConfigurationOperationContext(*this), m_subscribeToTopicOperationContext(*this), - m_getComponentDetailsOperationContext(*this), m_getClientDeviceAuthTokenOperationContext(*this), - m_publishToTopicOperationContext(*this), m_subscribeToCertificateUpdatesOperationContext(*this), - m_verifyClientDeviceIdentityOperationContext(*this), m_authorizeClientDeviceActionOperationContext(*this), - m_listComponentsOperationContext(*this), m_createDebugPasswordOperationContext(*this), - m_getThingShadowOperationContext(*this), m_sendConfigurationValidityReportOperationContext(*this), - m_updateThingShadowOperationContext(*this), m_updateConfigurationOperationContext(*this), - m_validateAuthorizationTokenOperationContext(*this), m_restartComponentOperationContext(*this), - m_getLocalDeploymentStatusOperationContext(*this), m_getSecretValueOperationContext(*this), - m_updateStateOperationContext(*this), m_cancelLocalDeploymentOperationContext(*this), - m_listNamedShadowsForThingOperationContext(*this), m_subscribeToComponentUpdatesOperationContext(*this), - m_listLocalDeploymentsOperationContext(*this), m_stopComponentOperationContext(*this), - m_pauseComponentOperationContext(*this), m_createLocalDeploymentOperationContext(*this) + auto promiseReference = m_resultPromise; + + auto activateFuture = ClientOperation::Activate( + static_cast(&request), + std::move(onMessageFlushCallback), + [promiseReference](TaggedResult &&unmodeledResult) + { promiseReference->set_value(CreateLocalDeploymentResult(std::move(unmodeledResult))); }); + + return activateFuture; + } + + GreengrassCoreIpcServiceModel::GreengrassCoreIpcServiceModel(Aws::Crt::Allocator *allocator) noexcept + : m_subscribeToIoTCoreOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_resumeComponentOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_publishToIoTCoreOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_subscribeToConfigurationUpdateOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_deleteThingShadowOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_putComponentMetricOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_deferComponentUpdateOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_subscribeToValidateConfigurationUpdatesOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_getConfigurationOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_subscribeToTopicOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_getComponentDetailsOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_getClientDeviceAuthTokenOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_publishToTopicOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_subscribeToCertificateUpdatesOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_verifyClientDeviceIdentityOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_authorizeClientDeviceActionOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_listComponentsOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_createDebugPasswordOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_getThingShadowOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_sendConfigurationValidityReportOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_updateThingShadowOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_updateConfigurationOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_validateAuthorizationTokenOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_restartComponentOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_getLocalDeploymentStatusOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_getSecretValueOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_updateStateOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_cancelLocalDeploymentOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_listNamedShadowsForThingOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_subscribeToComponentUpdatesOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_listLocalDeploymentsOperationContext( + Aws::Crt::MakeShared(allocator, *this)), + m_stopComponentOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_pauseComponentOperationContext(Aws::Crt::MakeShared(allocator, *this)), + m_createLocalDeploymentOperationContext( + Aws::Crt::MakeShared(allocator, *this)) { }