Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions HTTP_Adapter/AdapterActions/Pull.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
using BH.oM.Base;
using BH.oM.Data.Requests;
using BH.oM.Adapters.HTTP;
using System;

namespace BH.Adapter.HTTP
{
Expand All @@ -45,39 +46,49 @@ public override IEnumerable<object> Pull(IRequest request,
return Pull(request as dynamic, actionConfig);
}


/***************************************************/
/**** Public Methods ****/
/***************************************************/

public IEnumerable<object> Pull(GetRequest request, ActionConfig actionConfig)
{
string response = Compute.MakeRequest(request);
if (!(actionConfig is HttpPullConfig config))
config = new HttpPullConfig();

if (response == null)
return new List<BHoMObject>();
Uri requestUri = ConstructUri(request.BaseUrl, request.Parameters);

// check if the response is a valid json
if (response.StartsWith("{") || response.StartsWith("["))
return new List<object>() { Engine.Serialiser.Convert.FromJson(response) };
HttpRequestMessage requestMessage = Create.ConstructHttpRequestMessage(HttpMethod.Get, requestUri, request.Headers);

else
return new List<object>() { response };
using (HttpResponseMessage response = m_httpClient.SendAsync(requestMessage).ConfigureAwait(false).GetAwaiter().GetResult())
{
//assert success
if (!response.IsSuccessStatusCode)
{
Engine.Base.Compute.RecordError($"GET request failed with code {response.StatusCode}: {response.ReasonPhrase}");
return new List<object>();
}

if (config.ForceDeserialiseAsBHoM || response.Content.Headers.ContentType.MediaType == "application/bhom")
return Compute.DeserialiseAsBHoMAsync(response).ConfigureAwait(false).GetAwaiter().GetResult();

string responseString = response.Content.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
return new List<object>() { responseString };
}
}

/***************************************************/

public IEnumerable<object> Pull(BatchRequest requests, HTTPConfig config)
public IEnumerable<object> Pull(BatchRequest requests, ActionConfig actionConfig)
{
if (config == null)
if (!(actionConfig is HTTPConfig config))
config = new HTTPConfig();

string[] response = new string[requests.Requests.Count];
List<BHoMObject> result = new List<BHoMObject>();
using (HttpClient client = new HttpClient() { Timeout = config.Timeout })
{
List <GetRequest> getRequests = requests.Requests.OfType<GetRequest>().ToList();
response = Task.WhenAll(getRequests.Select(x => Compute.MakeRequestAsync(x, client))).GetAwaiter().GetResult();
response = Task.WhenAll(getRequests.Select(x => Engine.Adapters.HTTP.Compute.MakeRequestAsync(x, client))).GetAwaiter().GetResult();
client.CancelPendingRequests();
client.Dispose();
}
Expand Down
52 changes: 40 additions & 12 deletions HTTP_Adapter/AdapterActions/Push.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base;
using System.Collections.Generic;
using BH.Engine.Reflection;
using BH.Engine.Serialiser;
using BH.oM.Adapter;
using BH.oM.Adapters.HTTP;
using BH.oM.Base;
using BH.oM.Data.Requests;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace BH.Adapter.HTTP
{
Expand All @@ -33,20 +43,38 @@ public partial class HTTPAdapter
/**** Override Methods ****/
/***************************************************/

public override List<object> Push(IEnumerable<object> objects,
string tag = "",
PushType pushType = PushType.AdapterDefault,
ActionConfig actionConfig = null)
public override List<object> Push(IEnumerable<object> objects, string tag = "", PushType pushType = PushType.AdapterDefault, ActionConfig actionConfig = null)
{
Engine.Base.Compute.RecordError("POST request not implemented.");
return new List<object>();
}
}
}

if (!(actionConfig is HttpPushConfig pushConfig))
{
BH.Engine.Base.Compute.RecordWarning("Provided ActionConfig was not an HttpPushConfig, running with default push config arguments:\nRequestURI=\"\"\nForcePostAsList=false\nDeserialiseAsBHoM=true");
pushConfig = new HttpPushConfig();
}

Uri requestUri = ConstructUri(pushConfig.RequestURL, pushConfig.Parameters);

HttpRequestMessage requestMessage = Create.ConstructHttpRequestMessage(HttpMethod.Post, requestUri, pushConfig.Headers);

if (objects.Count() == 1 & !pushConfig.ForcePostAsList)
Compute.AddBHoMContent(ref requestMessage, objects.Single());
else
Compute.AddBHoMContent(ref requestMessage, objects);

using (HttpResponseMessage response = m_httpClient.SendAsync(requestMessage).ConfigureAwait(false).GetAwaiter().GetResult())
{
//assert success
if (!response.IsSuccessStatusCode)
{
Engine.Base.Compute.RecordError($"POST request failed with code {response.StatusCode}: {response.ReasonPhrase}");
return new List<object>();
}

if (pushConfig.ForceDeserialiseAsBHoM || response.Content.Headers.ContentType.MediaType == "application/bhom")
return Compute.DeserialiseAsBHoMAsync(response).ConfigureAwait(false).GetAwaiter().GetResult();

string responseString = response.Content.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
return new List<object>() { responseString };
}
}
}
}
39 changes: 39 additions & 0 deletions HTTP_Adapter/Compute/AddBHoMContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2026, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;

namespace BH.Adapter.HTTP
{
public static partial class Compute
{
public static void AddBHoMContent(ref HttpRequestMessage message, object value)
{
string json = BH.Engine.Serialiser.Convert.ToJson(value);
StringContent content = new StringContent(json, Encoding.UTF8, "application/bhom");
message.Content = content;
}
}
}
45 changes: 45 additions & 0 deletions HTTP_Adapter/Compute/DeserialiseAsBHoMAsync.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2026, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace BH.Adapter.HTTP
{
public static partial class Compute
{
public static async Task<List<object>> DeserialiseAsBHoMAsync(HttpResponseMessage response)
{
string jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
object obj = BH.Engine.Serialiser.Convert.FromJson(jsonResponse);

if (obj is IEnumerable<object> objects1)
return objects1.ToList();

return new List<object> { obj };
}
}
}
43 changes: 43 additions & 0 deletions HTTP_Adapter/Create/HttpRequestMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2026, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;

namespace BH.Adapter.HTTP
{
public static partial class Create
{
public static HttpRequestMessage ConstructHttpRequestMessage(HttpMethod method, Uri uri, Dictionary<string, object> headers = null)
{
var message = new HttpRequestMessage(method, uri);

if (headers != null)
foreach (var kvp in headers)
message.Headers.Add(kvp.Key, kvp.Value.ToString());

return message;
}
}
}
47 changes: 47 additions & 0 deletions HTTP_Adapter/HttpAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
*/

using BH.oM.Adapters.HTTP;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;

namespace BH.Adapter.HTTP
{
Expand All @@ -33,20 +36,64 @@

public static string AdapterID = "HTTPAdapter";

public HttpClient HttpClient => m_httpClient; //allows custom requests in code if necessary (e.g. need to POST with some custom non-bhom content)

/***************************************************/
/**** Constructors ****/
/***************************************************/

public HTTPAdapter()

Check warning on line 45 in HTTP_Adapter/HttpAdapter.cs

View workflow job for this annotation

GitHub Actions / ci-documentation-compliance

HTTP_Adapter/HttpAdapter.cs#L45

HTTP_Adapter/HttpAdapter.cs#L45: Adapter constructor must contain a Description attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasDescriptionAttribute Method must contain an Output or MultiOutput attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasOutputAttribute

Check warning on line 45 in HTTP_Adapter/HttpAdapter.cs

View check run for this annotation

BHoMBot-CI / documentation-compliance

HTTP_Adapter/HttpAdapter.cs#L45

Adapter constructor must contain a Description attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasDescriptionAttribute Method must contain an Output or MultiOutput attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasOutputAttribute
{
// Use TLS 1.2 and TLS 1.3 (if available). Deprecated protocols not supported any longer: SSL3, TLS 1.0, TLS 1.1.
// TLS 1.2 is widely supported and secure. TLS 1.3 may not be available in all .NET Framework versions.
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | (SecurityProtocolType)3072; // 3072 = Tls13
m_httpClient = new HttpClient();
}

/***************************************************/
public HTTPAdapter(string baseAddress)

Check warning on line 54 in HTTP_Adapter/HttpAdapter.cs

View workflow job for this annotation

GitHub Actions / ci-documentation-compliance

HTTP_Adapter/HttpAdapter.cs#L54

HTTP_Adapter/HttpAdapter.cs#L54: Adapter constructor must contain a Description attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasDescriptionAttribute Method must contain an Output or MultiOutput attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasOutputAttribute Input parameter requires a matching Input attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/IsInputAttributePresent

Check warning on line 54 in HTTP_Adapter/HttpAdapter.cs

View check run for this annotation

BHoMBot-CI / documentation-compliance

HTTP_Adapter/HttpAdapter.cs#L54

Adapter constructor must contain a Description attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasDescriptionAttribute Method must contain an Output or MultiOutput attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasOutputAttribute Input parameter requires a matching Input attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/IsInputAttributePresent
{
// Use TLS 1.2 and TLS 1.3 (if available). Deprecated protocols not supported any longer: SSL3, TLS 1.0, TLS 1.1.
// TLS 1.2 is widely supported and secure. TLS 1.3 may not be available in all .NET Framework versions.
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | (SecurityProtocolType)3072; // 3072 = Tls13
m_httpClient = new HttpClient() { BaseAddress = new Uri(baseAddress) };
}

/***************************************************/

public HTTPAdapter(HttpClient httpClient)

Check warning on line 64 in HTTP_Adapter/HttpAdapter.cs

View workflow job for this annotation

GitHub Actions / ci-documentation-compliance

HTTP_Adapter/HttpAdapter.cs#L64

HTTP_Adapter/HttpAdapter.cs#L64: Adapter constructor must contain a Description attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasDescriptionAttribute Method must contain an Output or MultiOutput attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasOutputAttribute Input parameter requires a matching Input attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/IsInputAttributePresent

Check warning on line 64 in HTTP_Adapter/HttpAdapter.cs

View check run for this annotation

BHoMBot-CI / documentation-compliance

HTTP_Adapter/HttpAdapter.cs#L64

Adapter constructor must contain a Description attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasDescriptionAttribute Method must contain an Output or MultiOutput attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/HasOutputAttribute Input parameter requires a matching Input attribute - For more information see https://bhom.xyz/documentation/DevOps/Code%20Compliance%20and%20CI/Compliance%20Checks/IsInputAttributePresent
{
// Use TLS 1.2 and TLS 1.3 (if available). Deprecated protocols not supported any longer: SSL3, TLS 1.0, TLS 1.1.
// TLS 1.2 is widely supported and secure. TLS 1.3 may not be available in all .NET Framework versions.
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | (SecurityProtocolType)3072; // 3072 = Tls13
m_httpClient = httpClient;
}

/***************************************************/
/**** Private Methods ****/
/***************************************************/

private Uri ConstructUri(string absoluteOrRelativeUrl, Dictionary<string, object> parameters)
{
Uri baseUri;

if (m_httpClient.BaseAddress != null)
baseUri = new Uri(m_httpClient.BaseAddress, absoluteOrRelativeUrl);
else
baseUri = new Uri(absoluteOrRelativeUrl);

string queryParameters = Engine.Adapters.HTTP.Convert.ToUrlString(parameters);

UriBuilder builder = new UriBuilder(baseUri) { Query = queryParameters };

return builder.Uri;
}

/***************************************************/
/**** Private Fields ****/
/***************************************************/

private readonly HttpClient m_httpClient;
}
}

Expand Down
36 changes: 36 additions & 0 deletions HTTP_oM/HttpPullConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2026, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Adapter;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace BH.oM.Adapters.HTTP
{
public class HttpPullConfig: ActionConfig
{
[Description("If the response from the GET request is expected to be a BHoM object but doesn't have content type of 'application/bhom', this forces the adapter to deserialise the result as BHoM formatted json. Otherwise the adapter returns the response content as a string.")]
public virtual bool ForceDeserialiseAsBHoM { get; set; } = true;
}
}
Loading
Loading