3
0

AWSScriptBehaviorLambda.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/RTTI/BehaviorContext.h>
  9. #include <AzCore/Serialization/EditContext.h>
  10. #include <aws/lambda/LambdaClient.h>
  11. #include <aws/lambda/model/InvokeRequest.h>
  12. #include <aws/lambda/model/InvokeResult.h>
  13. #include <aws/core/utils/Outcome.h>
  14. #include <aws/core/auth/AWSCredentials.h>
  15. #include <aws/core/utils/memory/stl/AWSStringStream.h>
  16. #include <Framework/AWSApiRequestJob.h>
  17. #include <ResourceMapping/AWSResourceMappingBus.h>
  18. #include <ScriptCanvas/AWSScriptBehaviorLambda.h>
  19. namespace AWSCore
  20. {
  21. void AWSScriptBehaviorLambda::Reflect(AZ::ReflectContext* context)
  22. {
  23. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  24. {
  25. serializeContext->Class<AWSScriptBehaviorLambda>()
  26. ->Version(0);
  27. }
  28. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  29. {
  30. behaviorContext->Class<AWSScriptBehaviorLambda>("AWSScriptBehaviorLambda")
  31. ->Attribute(AZ::Script::Attributes::Category, "AWSCore")
  32. ->Method("Invoke", &AWSScriptBehaviorLambda::Invoke,
  33. {{{"Function Resource KeyName", "The resource key name of the lambda function in resource mapping config file."},
  34. {"Payload", "The JSON that you want to provide to your Lambda function as input."}}})
  35. ->Method("InvokeRaw", &AWSScriptBehaviorLambda::InvokeRaw,
  36. {{{"Function Name", "The name of the Lambda function, version, or alias."},
  37. {"Payload", "The JSON that you want to provide to your Lambda function as input."},
  38. {"Region Name", "The region of the lambda function located in."}}});
  39. behaviorContext->EBus<AWSScriptBehaviorLambdaNotificationBus>("AWSLambdaBehaviorNotificationBus")
  40. ->Attribute(AZ::Script::Attributes::Category, "AWSCore")
  41. ->Handler<AWSScriptBehaviorLambdaNotificationBusHandler>();
  42. }
  43. }
  44. void AWSScriptBehaviorLambda::Invoke(const AZStd::string& functionResourceKey, const AZStd::string& payload)
  45. {
  46. AZStd::string requestFunctionName = "";
  47. AWSResourceMappingRequestBus::BroadcastResult(requestFunctionName, &AWSResourceMappingRequests::GetResourceNameId, functionResourceKey);
  48. AZStd::string requestRegion = "";
  49. AWSResourceMappingRequestBus::BroadcastResult(requestRegion, &AWSResourceMappingRequests::GetResourceRegion, functionResourceKey);
  50. InvokeRaw(requestFunctionName, payload, requestRegion);
  51. }
  52. void AWSScriptBehaviorLambda::InvokeRaw(const AZStd::string& functionName, const AZStd::string& payload, const AZStd::string& region)
  53. {
  54. if (!ValidateInvokeRequest(functionName, region))
  55. {
  56. return;
  57. }
  58. using LambdaInvokeRequestJob = AWS_API_REQUEST_JOB(Lambda, Invoke);
  59. LambdaInvokeRequestJob::Config config(LambdaInvokeRequestJob::GetDefaultConfig());
  60. config.region = region.c_str();
  61. auto job = LambdaInvokeRequestJob::Create(
  62. [](LambdaInvokeRequestJob* job) // OnSuccess handler
  63. {
  64. Aws::IOStream& stream = job->result.GetPayload();
  65. std::istreambuf_iterator<AZStd::string::value_type> eos;
  66. AZStd::string content = AZStd::string{std::istreambuf_iterator<AZStd::string::value_type>(stream), eos};
  67. AWSScriptBehaviorLambdaNotificationBus::Broadcast(
  68. &AWSScriptBehaviorLambdaNotificationBus::Events::OnInvokeSuccess, content.c_str());
  69. },
  70. [](LambdaInvokeRequestJob* job) // OnError handler
  71. {
  72. Aws::String errorMessage = job->error.GetMessage();
  73. AWSScriptBehaviorLambdaNotificationBus::Broadcast(
  74. &AWSScriptBehaviorLambdaNotificationBus::Events::OnInvokeError, errorMessage.c_str());
  75. },
  76. &config);
  77. std::shared_ptr<Aws::StringStream> stream = std::make_shared<Aws::StringStream>();
  78. *stream << payload.c_str();
  79. job->request.SetFunctionName(functionName.c_str());
  80. job->request.SetBody(stream);
  81. job->Start();
  82. }
  83. bool AWSScriptBehaviorLambda::ValidateInvokeRequest(const AZStd::string& functionName, const AZStd::string& region)
  84. {
  85. if (functionName.empty())
  86. {
  87. AZ_Warning("AWSScriptBehaviorLambda", false, "Request validation failed, bucket name is required.");
  88. AWSScriptBehaviorLambdaNotificationBus::Broadcast(
  89. &AWSScriptBehaviorLambdaNotificationBus::Events::OnInvokeError, "Request validation failed, function name is required.");
  90. return false;
  91. }
  92. if (region.empty())
  93. {
  94. AZ_Warning("AWSScriptBehaviorLambda", false, "Request validation failed, region name is required.");
  95. AWSScriptBehaviorLambdaNotificationBus::Broadcast(
  96. &AWSScriptBehaviorLambdaNotificationBus::Events::OnInvokeError, "Request validation failed, region name is required.");
  97. return false;
  98. }
  99. return true;
  100. }
  101. } // namespace AWSCore