Skip to content

Commit

Permalink
feat: support ad-hoc calls
Browse files Browse the repository at this point in the history
  • Loading branch information
nagtilak committed Jan 24, 2023
1 parent 6febe25 commit da5b029
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 8 deletions.
66 changes: 66 additions & 0 deletions MetasysServices.Tests/MetasysClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2357,5 +2357,71 @@ public void TestMiscNullTokenValue()
}

#endregion

#region Ad-Hoc Calls
[Test]
public async Task TestSendAsyncWithAbsoluteUrl()
{
var requestUrl = "https://hostname/api/v5-preview/someController/someAction";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, requestUrl);
await client.SendAsync(httpRequest);

httpTest.ShouldHaveCalled(requestUrl)
.WithVerb(HttpMethod.Get)
.Times(1);
}

[Test]
public async Task TestSendAsyncWithRelativeUrl()
{
var requestUrl = "api/v5-preview/someController/someAction";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, requestUrl);
await client.SendAsync(httpRequest);

httpTest.ShouldHaveCalled($"https://hostname/{requestUrl}")
.WithVerb(HttpMethod.Get)
.Times(1);
}

[Test]
public async Task TestSendAsyncCheckQueryStringAndFragmentsAreUsed()
{
var requestUrl = $"api/v5-preview/someController/someAction?fqr=itemReference#fragment1";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, requestUrl);
await client.SendAsync(httpRequest);

httpTest.ShouldHaveCalled($"https://hostname/{requestUrl}")
.WithVerb(HttpMethod.Get)
.WithQueryParamValue("fqr", "itemReference")
.With(call => call.Request.RequestUri.Fragment.StartsWith("#fragment1"))
.Times(1);
}

[Test]
public async Task TestSendAsyncCheckRequestHeadersAreUsed()
{
var requestUrl = "api/v5-preview/someController/someAction";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, requestUrl);
httpRequest.Headers.Add("Accept", "application/json");
await client.SendAsync(httpRequest);

httpTest.ShouldHaveCalled($"https://hostname/{requestUrl}")
.WithVerb(HttpMethod.Get)
.WithHeader("Accept")
.Times(1);
}

[Test]
public void TestSendAsyncWithInvalidAbsoluteUrlThrowsException()
{
var requestUrl = "https://different-hostname/api/v5-preview/someController/someAction";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, requestUrl);
var e = Assert.Throws<MetasysHttpException>(() =>
client.SendAsync(httpRequest).GetAwaiter().GetResult());

PrintMessage($"TestSendAsyncWithInvalidAbsoluteUrlThrowsException: {e.Message}", true);
}

#endregion
}
}
10 changes: 10 additions & 0 deletions MetasysServices/Interfaces/IMetasysClient.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using JohnsonControls.Metasys.BasicServices;

Expand Down Expand Up @@ -404,5 +406,13 @@ public interface IMetasysClient :IBasicService
/// <inheritdoc cref="IMetasysClient.GetServerTime()"/>
Task<DateTime> GetServerTimeAsync();

/// <summary>
/// Send an HTTP request as an asynchronous operation.
/// </summary>
/// <param name="request">The HTTP request message to send.</param>
/// <param name="completionOption"> When the operation should complete (as soon as a response is available or after reading the whole response content).</param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead, CancellationToken cancellationToken = default);
}
}
40 changes: 40 additions & 0 deletions MetasysServices/MetasysClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
using System.Dynamic;
using System.IdentityModel.Tokens.Jwt;
using System.Timers;
using System.Net.Http.Headers;
using System.Threading;

namespace JohnsonControls.Metasys.BasicServices
{
Expand Down Expand Up @@ -1207,7 +1209,45 @@ private async Task SendCommandRequestAsync(Guid id, string command, IEnumerable<
}
}

#region "ad-hoc calls" // =========================================================================================================
// Support Ad-Hoc calls -----------------------------------------------------------------------------------------------------------
///<inheritdoc/>
public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead, CancellationToken cancellationToken = default)
{
var response = new HttpResponseMessage();
try
{
var flurlRequest = Client.Request();
flurlRequest.Url = GetUrlFromHttpRequest(requestMessage);
flurlRequest.WithHeaders(requestMessage.Headers);

response = await flurlRequest.SendAsync(requestMessage.Method, requestMessage.Content, cancellationToken, completionOption).ConfigureAwait(false);
}
catch (FlurlHttpException e)
{
ThrowHttpException(e);
}
return response;
}

private Url GetUrlFromHttpRequest(HttpRequestMessage requestMessage)
{
var baseUri = new Uri(Client.BaseUrl);
var requestUri = requestMessage.RequestUri.ToString();
if (Uri.IsWellFormedUriString(requestUri, UriKind.Absolute))
{
if (Uri.Compare(baseUri, requestMessage.RequestUri, UriComponents.SchemeAndServer, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) != 0)
{
throw new MetasysHttpException("HTTP request can not be made.", "You are trying to connect to a different host.");
}
return new Url(requestUri);
}
else
{
return new Url($"{baseUri.AbsoluteUri.Replace(baseUri.AbsolutePath, string.Empty)}/{requestUri}");
}
}
#endregion
}

}
Expand Down
49 changes: 49 additions & 0 deletions MetasysServicesExampleApp/FeaturesDemo/AdHocCallsDemo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using JohnsonControls.Metasys.BasicServices;
using System;
using System.Net.Http;

namespace MetasysServicesExampleApp.FeaturesDemo
{
public class AdHocCallsDemo
{
private MetasysClient client;
private LogInitializer log;

public AdHocCallsDemo(MetasysClient client)
{
this.client = client;
log = new LogInitializer(typeof(AdHocCallsDemo));
}

public void Run()
{
try
{
Console.WriteLine("\nEnter the endpoint you want to make the request to (Example: \"https://hostname/api/v5-preview/someController/someAction\"): .");
string endpoint = Console.ReadLine();
Console.WriteLine($"\nMaking the call to {endpoint}...");
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, endpoint);

var response = client.SendAsync(httpRequest).Result;
var statusCode = ((int)response.StatusCode).ToString();
if (statusCode.StartsWith("2") || statusCode.StartsWith("3"))
{
Console.WriteLine($"\n \nStatus - {response.StatusCode}");
Console.WriteLine("\nResponse content - ");
var content = response.Content.ReadAsStringAsync().Result;
Console.WriteLine("\n \n" + content);
}
else
{
Console.WriteLine(string.Format("\n \nRequest failed with - {0}", response.StatusCode));
}
}
catch (Exception exception)
{
log.Logger.Error(string.Format("An error occured while making the request - {0}", exception.Message));
Console.WriteLine("\n \nAn Error occurred. Press Enter to return to Main Menu");
}
Console.ReadLine();
}
}
}
18 changes: 10 additions & 8 deletions MetasysServicesExampleApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static void Main(string[] args)
connectionDetails = Console.ReadLine();
args = connectionDetails.Split(' ');
}
string username=null, password= null, hostname= null, credManTarget=null; string version = null;
string username = null, password = null, hostname = null, credManTarget = null; string version = null;

if (args.Length > 3)
{
Expand All @@ -42,7 +42,7 @@ static void Main(string[] args)

Console.WriteLine("\nLogging in...");
var apiVersion = (ApiVersion)Enum.Parse(typeof(ApiVersion), version);
var client = new MetasysClient(hostname,true,apiVersion,logClientErrors:false); // Disable default logging since it is handled in this app.
var client = new MetasysClient(hostname, true, apiVersion, logClientErrors: false); // Disable default logging since it is handled in this app.
// var client = new MetasysClient(hostname, true); // Ignore Certificate Errors
// var client = new MetasysClient(hostname, false, ApiVersion.v2, culture);

Expand All @@ -65,12 +65,12 @@ static void Main(string[] args)
showMenu = MainMenu(client);
}
}
catch(Exception exception)
catch (Exception exception)
{
log.Logger.Error(string.Format("An error occured while login - {0}", exception.Message));
Console.WriteLine("\n \nAn Error occurred. Press Enter to exit");
Console.ReadLine();
}
}
}

private static bool MainMenu(MetasysClient client)
Expand All @@ -86,16 +86,17 @@ private static bool MainMenu(MetasysClient client)
Console.WriteLine("7) Trends");
Console.WriteLine("8) Audits");
Console.WriteLine("9) JSON Output");
Console.WriteLine("10) Exit");
Console.WriteLine("10) Ad-hoc Calls");
Console.WriteLine("11) Exit");
Console.Write("\r\nSelect an option: ");
var option = "9";// Console.ReadLine();
var option = "10";// Console.ReadLine();
Console.WriteLine();
switch (option)
{
case "1":
case "1":
new GetObjectIdentifierDemo(client).Run();
return true;
case "2":
case "2":
new GeneralDemo(client).Run();
return true;
case "3":
Expand All @@ -120,6 +121,7 @@ private static bool MainMenu(MetasysClient client)
new JsonOutputDemo(client).Run();
return false;
case "10":
new AdHocCallsDemo(client).Run();
return false;
default:
return true;
Expand Down

0 comments on commit da5b029

Please sign in to comment.