Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,16 @@
/*
* 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 "HttpRequestor_precompiled.h"
#include <AzCore/Module/Module.h>
AZ_DECLARE_MODULE_CLASS(Gem_HttpRequestor, AZ::Module)
@@ -0,0 +1,201 @@
/*
* 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 "HttpRequestor_precompiled.h"
#include <AzFramework/AzFramework_Traits_Platform.h>
// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly.
// AWSAllocator.h(70): warning C4996: 'std::allocator<T>::pointer': warning STL4010: Various members of std::allocator are deprecated in C++17.
// Use std::allocator_traits instead of accessing these members directly.
// You can define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.
AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option")
#include <aws/core/http/HttpClient.h>
#include <aws/core/http/HttpClientFactory.h>
#include <aws/core/http/HttpRequest.h>
#include <aws/core/http/HttpResponse.h>
#include <aws/core/client/ClientConfiguration.h>
AZ_POP_DISABLE_WARNING
#include <AWSNativeSDKInit/AWSNativeSDKInit.h>
#include <AzCore/std/string/conversions.h>
#include "HttpRequestManager.h"
namespace HttpRequestor
{
const char* Manager::s_loggingName = "GemHttpRequestManager";
Manager::Manager()
{
AZStd::thread_desc desc;
desc.m_name = s_loggingName;
desc.m_cpuId = AFFINITY_MASK_USERTHREADS;
m_runThread = true;
// Shutdown will be handled by the InitializationManager - no need to call in the destructor
AWSNativeSDKInit::InitializationManager::InitAwsApi();
auto function = AZStd::bind(&Manager::ThreadFunction, this);
m_thread = AZStd::thread(function, &desc);
}
Manager::~Manager()
{
// NativeSDK Shutdown does not need to be called here - will be taken care of by the InitializationManager
m_runThread = false;
m_requestConditionVar.notify_all();
if (m_thread.joinable())
{
m_thread.join();
}
}
void Manager::AddRequest(Parameters && httpRequestParameters)
{
{
AZStd::lock_guard<AZStd::mutex> lock(m_requestMutex);
m_requestsToHandle.push(AZStd::move(httpRequestParameters));
}
m_requestConditionVar.notify_all();
}
void Manager::AddTextRequest(TextParameters && httpTextRequestParameters)
{
{
AZStd::lock_guard<AZStd::mutex> lock(m_requestMutex);
m_textRequestsToHandle.push(AZStd::move(httpTextRequestParameters));
}
m_requestConditionVar.notify_all();
}
void Manager::ThreadFunction()
{
// Run the thread as long as directed
while (m_runThread)
{
HandleRequestBatch();
}
}
void Manager::HandleRequestBatch()
{
// Lock mutex and wait for work to be signalled via the condition variable
AZStd::unique_lock<AZStd::mutex> lock(m_requestMutex);
m_requestConditionVar.wait(lock, [&] { return !m_runThread || !m_requestsToHandle.empty() || !m_textRequestsToHandle.empty(); });
// Swap queues
AZStd::queue<Parameters> requestsToHandle;
requestsToHandle.swap(m_requestsToHandle);
AZStd::queue<TextParameters> textRequestsToHandle;
textRequestsToHandle.swap(m_textRequestsToHandle);
// Release lock
lock.unlock();
// Handle requests
while (!requestsToHandle.empty())
{
HandleRequest(requestsToHandle.front());
requestsToHandle.pop();
}
while (!textRequestsToHandle.empty())
{
HandleTextRequest(textRequestsToHandle.front());
textRequestsToHandle.pop();
}
}
void Manager::HandleRequest(const Parameters& httpRequestParameters)
{
Aws::Client::ClientConfiguration config;
config.enableTcpKeepAlive = AZ_TRAIT_AZFRAMEWORK_AWS_ENABLE_TCP_KEEP_ALIVE_SUPPORTED;
std::shared_ptr<Aws::Http::HttpClient> httpClient = Aws::Http::CreateHttpClient(config);
auto httpRequest = Aws::Http::CreateHttpRequest(httpRequestParameters.GetURI(), httpRequestParameters.GetMethod(), Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
AZ_Assert(httpRequest, "HttpRequest not created!");
for (const auto & it : httpRequestParameters.GetHeaders())
{
httpRequest->SetHeaderValue(it.first.c_str(), it.second.c_str());
}
if( httpRequestParameters.GetBodyStream() != nullptr)
{
httpRequest->AddContentBody(httpRequestParameters.GetBodyStream());
httpRequest->SetContentLength(AZStd::to_string(httpRequestParameters.GetBodyStream()->str().length()).c_str());
}
auto httpResponse = httpClient->MakeRequest(httpRequest);
if (!httpResponse)
{
httpRequestParameters.GetCallback()(Aws::Utils::Json::JsonValue(), Aws::Http::HttpResponseCode::INTERNAL_SERVER_ERROR);
return;
}
if (httpResponse->GetResponseCode() != Aws::Http::HttpResponseCode::OK)
{
httpRequestParameters.GetCallback()(Aws::Utils::Json::JsonValue(), httpResponse->GetResponseCode());
return;
}
Aws::Utils::Json::JsonValue json(httpResponse->GetResponseBody());
if (json.WasParseSuccessful())
{
httpRequestParameters.GetCallback()(AZStd::move(json), httpResponse->GetResponseCode());
}
else
{
httpRequestParameters.GetCallback()(Aws::Utils::Json::JsonValue(), Aws::Http::HttpResponseCode::INTERNAL_SERVER_ERROR);
}
}
void Manager::HandleTextRequest(const TextParameters & httpRequestParameters)
{
Aws::Client::ClientConfiguration config;
config.enableTcpKeepAlive = AZ_TRAIT_AZFRAMEWORK_AWS_ENABLE_TCP_KEEP_ALIVE_SUPPORTED;
std::shared_ptr<Aws::Http::HttpClient> httpClient = Aws::Http::CreateHttpClient(config);
auto httpRequest = Aws::Http::CreateHttpRequest(httpRequestParameters.GetURI(), httpRequestParameters.GetMethod(), Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
for (const auto & it : httpRequestParameters.GetHeaders())
{
httpRequest->SetHeaderValue(it.first.c_str(), it.second.c_str());
}
if (httpRequestParameters.GetBodyStream() != nullptr)
{
httpRequest->AddContentBody(httpRequestParameters.GetBodyStream());
}
auto httpResponse = httpClient->MakeRequest(httpRequest);
if (!httpResponse)
{
httpRequestParameters.GetCallback()(AZStd::string(), Aws::Http::HttpResponseCode::INTERNAL_SERVER_ERROR);
return;
}
if (httpResponse->GetResponseCode() != Aws::Http::HttpResponseCode::OK)
{
httpRequestParameters.GetCallback()(AZStd::string(), httpResponse->GetResponseCode());
return;
}
// load up the raw output into a string
// TODO(aaj): it feels like there should be some limit maybe 1 MB?
std::istreambuf_iterator<char> eos;
AZStd::string data(std::istreambuf_iterator<char>(httpResponse->GetResponseBody()), eos);
httpRequestParameters.GetCallback()(AZStd::move(data), httpResponse->GetResponseCode());
}
}
@@ -0,0 +1,63 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/std/containers/queue.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/std/parallel/atomic.h>
#include <AzCore/std/parallel/mutex.h>
#include <AzCore/std/parallel/condition_variable.h>
#include <AzCore/std/parallel/thread.h>
#include <HttpRequestor/HttpRequestParameters.h>
#include <HttpRequestor/HttpTextRequestParameters.h>
namespace HttpRequestor
{
class Manager
{
public:
Manager();
virtual ~Manager();
// Add these parameters to a queue of request parameters to send off as an HTTP request as soon as they reach the head of the queue
void AddRequest(Parameters && httpRequestParameters);
// Add these parameters to a queue of request parameters to send off as an HTTP TEXT request as soon as they reach the head of the queue
void AddTextRequest(TextParameters && httpTextRequestParameters);
private:
// RequestManager thread loop.
void ThreadFunction();
// Called by ThreadFunction. Waits for timeout or until notified and processes any requests queued up.
void HandleRequestBatch();
// Perform an HTTP request, block until a response is received, then give the returned JSON to the callback to parse. Returns the HTTPResponseCode to the callback to handle any errors.
void HandleRequest(const Parameters & httpRequestParameters);
// Perform an HTTP request, block until a response is received, then give the returned TEXT to the callback to parse. Returns the HTTPResponseCode to the callback to handle any errors.
void HandleTextRequest(const TextParameters & httpTextRequestParameters);
private:
AZStd::queue<Parameters> m_requestsToHandle; // Queue of requests that will be made in order of time received
AZStd::queue<TextParameters> m_textRequestsToHandle; // Queue of requests for TEXT blobs that will be made in order of time received
AZStd::mutex m_requestMutex; // Member variables for synchronization
AZStd::condition_variable m_requestConditionVar;
AZStd::atomic<bool> m_runThread; // Run flag used to signal the worker thread
AZStd::thread m_thread; // This is the thread that will be used for all async operations
static const char* s_loggingName; // Name to use for log messages etc...
};
using ManagerPtr = AZStd::shared_ptr<Manager>;
}
@@ -0,0 +1,49 @@
/*
* 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 "HttpRequestor_precompiled.h"
#include "HttpRequestorSystemComponent.h"
#include <AzCore/Module/Module.h>
namespace HttpRequestor
{
class HttpRequestorModule
: public AZ::Module
{
public:
AZ_RTTI(HttpRequestorModule, "{FD411E40-AF83-4F6B-A5A3-F59AB71150BF}", AZ::Module);
HttpRequestorModule()
: AZ::Module()
{
// Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
m_descriptors.insert(m_descriptors.end(), {
HttpRequestorSystemComponent::CreateDescriptor(),
});
}
/**
* Add required SystemComponents to the SystemEntity.
*/
AZ::ComponentTypeList GetRequiredSystemComponents() const override
{
return AZ::ComponentTypeList{
azrtti_typeid<HttpRequestorSystemComponent>(),
};
}
};
}
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
// The first parameter should be GemName_GemIdLower
// The second should be the fully qualified name of the class above
AZ_DECLARE_MODULE_CLASS(Gem_HttpRequestor, HttpRequestor::HttpRequestorModule)
@@ -0,0 +1,126 @@
/*
* 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 "HttpRequestor_precompiled.h"
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include "HttpRequestorSystemComponent.h"
namespace HttpRequestor
{
void HttpRequestorSystemComponent::AddRequest(const AZStd::string& URI, Aws::Http::HttpMethod method, const Callback& callback)
{
if(m_httpManager != nullptr)
{
m_httpManager->AddRequest( Parameters(URI, method, callback) );
}
}
void HttpRequestorSystemComponent::AddRequestWithHeaders(const AZStd::string& URI, Aws::Http::HttpMethod method, const Headers & headers, const Callback& callback)
{
if (m_httpManager != nullptr)
{
m_httpManager->AddRequest(Parameters(URI, method, headers, callback));
}
}
void HttpRequestorSystemComponent::AddRequestWithHeadersAndBody(const AZStd::string& URI, Aws::Http::HttpMethod method, const Headers & headers, const AZStd::string& body, const Callback& callback)
{
if (m_httpManager != nullptr)
{
m_httpManager->AddRequest(Parameters(URI, method, headers, body, callback));
}
}
void HttpRequestorSystemComponent::AddTextRequest(const AZStd::string& URI, Aws::Http::HttpMethod method, const TextCallback& callback)
{
if (m_httpManager != nullptr)
{
m_httpManager->AddTextRequest( TextParameters(URI, method, callback));
}
}
void HttpRequestorSystemComponent::AddTextRequestWithHeaders(const AZStd::string& URI, Aws::Http::HttpMethod method, const Headers & headers, const TextCallback& callback)
{
if (m_httpManager != nullptr)
{
m_httpManager->AddTextRequest(TextParameters(URI, method, headers, callback));
}
}
void HttpRequestorSystemComponent::AddTextRequestWithHeadersAndBody(const AZStd::string& URI, Aws::Http::HttpMethod method, const Headers & headers, const AZStd::string& body, const TextCallback& callback)
{
if (m_httpManager != nullptr)
{
m_httpManager->AddTextRequest(TextParameters(URI, method, headers, body, callback));
}
}
void HttpRequestorSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<HttpRequestorSystemComponent, AZ::Component>()
->Version(1);
;
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<HttpRequestorSystemComponent>("HttpRequestor", "Will make HTTP Rest calls")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
// ->Attribute(AZ::Edit::Attributes::Category, "") Set a category
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System"))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
;
}
}
}
void HttpRequestorSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("HttpRequestorService"));
}
void HttpRequestorSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("HttpRequestorService"));
}
void HttpRequestorSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
(void)required;
}
void HttpRequestorSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
(void)dependent;
}
void HttpRequestorSystemComponent::Init()
{
}
void HttpRequestorSystemComponent::Activate()
{
m_httpManager = AZStd::make_shared<Manager>();
HttpRequestorRequestBus::Handler::BusConnect();
}
void HttpRequestorSystemComponent::Deactivate()
{
HttpRequestorRequestBus::Handler::BusDisconnect();
m_httpManager = nullptr;
}
}
@@ -0,0 +1,58 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <HttpRequestor/HttpRequestorBus.h>
#include "HttpRequestManager.h"
namespace HttpRequestor
{
class HttpRequestorSystemComponent
: public AZ::Component
, protected HttpRequestorRequestBus::Handler
{
public:
AZ_COMPONENT(HttpRequestorSystemComponent, "{CF29468F-1F67-497F-B4FF-C0F123584864}");
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
protected:
////////////////////////////////////////////////////////////////////////
// HttpRequestorRequestBus interface implementation
////////////////////////////////////////////////////////////////////////
void AddRequest(const AZStd::string& URI, Aws::Http::HttpMethod method, const Callback& callback) override;
void AddRequestWithHeaders(const AZStd::string& URI, Aws::Http::HttpMethod method, const Headers & headers, const Callback& callback) override;
void AddRequestWithHeadersAndBody(const AZStd::string& URI, Aws::Http::HttpMethod method, const Headers & headers, const AZStd::string& body, const Callback& callback) override;
void AddTextRequest(const AZStd::string& URI, Aws::Http::HttpMethod method, const TextCallback& callback) override;
void AddTextRequestWithHeaders(const AZStd::string& URI, Aws::Http::HttpMethod method, const Headers & headers, const TextCallback& callback) override;
void AddTextRequestWithHeadersAndBody(const AZStd::string& URI, Aws::Http::HttpMethod method, const Headers & headers, const AZStd::string& body, const TextCallback& callback) override;
////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
void Init() override;
void Activate() override;
void Deactivate() override;
////////////////////////////////////////////////////////////////////////
private:
ManagerPtr m_httpManager;
};
}
@@ -0,0 +1,13 @@
/*
* 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 "HttpRequestor_precompiled.h"
@@ -0,0 +1,15 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/PlatformDef.h>
@@ -0,0 +1,11 @@
#
# 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.
#
@@ -0,0 +1,11 @@
#
# 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.
#
@@ -0,0 +1,10 @@
#
# 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.
#
@@ -0,0 +1,10 @@
#
# 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.
#
@@ -0,0 +1,10 @@
#
# 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.
#