/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include #include "AWSBehaviorLambda.h" #include /// To use a specific AWS API request you have to include each of these. #include AZ_PUSH_DISABLE_WARNING(4251 4355 4996, "-Wunknown-warning-option") #include #include #include #include #include #include #include AZ_POP_DISABLE_WARNING namespace CloudGemAWSScriptBehaviors { AWSBehaviorLambda::AWSBehaviorLambda() : m_inFunctionName(), m_inRequestBody() { } void AWSBehaviorLambda::ReflectSerialization(AZ::SerializeContext* serializeContext) { if (serializeContext) { serializeContext->Class() ->Field("functionName", &AWSBehaviorLambda::m_inFunctionName) ->Field("requestBody", &AWSBehaviorLambda::m_inRequestBody) ->Version(3); } } void AWSBehaviorLambda::ReflectBehaviors(AZ::BehaviorContext* behaviorContext) { behaviorContext->Class("AWSLambda") ->Method("InvokeAWSLambda", &AWSBehaviorLambda::Invoke, nullptr, "Invokes the method on AWS") ->Property("functionName", nullptr, BehaviorValueSetter(&AWSBehaviorLambda::m_inFunctionName)) ->Property("requestBody", nullptr, BehaviorValueSetter(&AWSBehaviorLambda::m_inRequestBody)); behaviorContext->EBus("AWSLambdaHandler") ->Handler(); } void AWSBehaviorLambda::ReflectEditParameters(AZ::EditContext* editContext) { editContext->Class("AWSLambda", "Wraps AWS Lambda functionality") ->DataElement(AZ::Edit::UIHandlers::ComboBox, &AWSBehaviorLambda::m_inFunctionName, "functionName", "Name of the AWS Lambda function to invoke") ->Attribute(AZ::Edit::Attributes::StringList, &AWSBehaviorLambda::GetFunctionNames) ->DataElement(AZ::Edit::UIHandlers::Default, &AWSBehaviorLambda::m_inRequestBody, "requestBody", "The data that will be sent to the lambda function call as arguments in JSON format."); } AZStd::vector AWSBehaviorLambda::GetFunctionNames() { AZStd::vector functionNames; CloudGemFramework::CloudCanvasMappingsBus::BroadcastResult(functionNames, &CloudGemFramework::CloudCanvasMappingsBus::Events::GetMappingsOfType, "AWS::Lambda::Function"); if (AZStd::find(functionNames.begin(), functionNames.end(), m_inFunctionName) == functionNames.end()) { m_inFunctionName = functionNames.size() > 0 ? functionNames[0] : ""; } return functionNames; } void AWSBehaviorLambda::Invoke() { if (m_inFunctionName.empty()) { EBUS_EVENT(AWSBehaviorLambdaNotificationsBus, OnError, "AWS Lambda Invoke: No function name provided"); return; } using LambdaInvokeRequestJob = AWS_API_REQUEST_JOB(Lambda, Invoke); LambdaInvokeRequestJob::Config config(LambdaInvokeRequestJob::GetDefaultConfig()); AZStd::string region; EBUS_EVENT_RESULT(region, CloudGemFramework::CloudCanvasMappingsBus, GetLogicalToPhysicalResourceMapping, "region"); config.region = region.c_str(); auto job = LambdaInvokeRequestJob::Create( [](LambdaInvokeRequestJob* job) // OnSuccess handler { Aws::IOStream& stream = job->result.GetPayload(); std::istreambuf_iterator eos; AZStd::string content = AZStd::string{ std::istreambuf_iterator(stream),eos }; AZStd::function notifyOnMainThread = [content]() { AWSBehaviorLambdaNotificationsBus::Broadcast(&AWSBehaviorLambdaNotificationsBus::Events::OnSuccess, content.c_str()); }; AZ::TickBus::QueueFunction(notifyOnMainThread); }, [](LambdaInvokeRequestJob* job) // OnError handler { Aws::String errorMessage = job->error.GetMessage(); AZStd::function notifyOnMainThread = [errorMessage]() { AWSBehaviorLambdaNotificationsBus::Broadcast(&AWSBehaviorLambdaNotificationsBus::Events::OnError, errorMessage.c_str()); }; AZ::TickBus::QueueFunction(notifyOnMainThread); }, &config ); std::shared_ptr stream = std::make_shared(); *stream << m_inRequestBody.c_str(); AZStd::string resourceFunctionName; EBUS_EVENT_RESULT(resourceFunctionName, CloudGemFramework::CloudCanvasMappingsBus, GetLogicalToPhysicalResourceMapping, m_inFunctionName.c_str()); if (resourceFunctionName.empty()) { // if there is no logical resource, user may have put in a physical resource, so try that // of course it could have been a typo too // future version of this will request available lambda names in to the edit context // so a list may be presented to the user, but that's not available yet resourceFunctionName = m_inFunctionName; } job->request.SetFunctionName(resourceFunctionName.c_str()); job->request.SetBody(stream); job->Start(); } }