Skip to content

Commit

Permalink
#146 - Initial version of ObjectSender.
Browse files Browse the repository at this point in the history
  • Loading branch information
maraf committed Feb 15, 2019
1 parent 0f615e1 commit cd0eb0b
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 5 deletions.
100 changes: 100 additions & 0 deletions src/Neptuo.Net.Http.Routing/ObjectSender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using Neptuo.Formatters.Generics;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Neptuo.Net.Http.Routing
{
public class ObjectSender
{
private readonly HttpClient httpClient;
private readonly IRouteTable routes;

public ObjectSender(HttpClient httpClient, IRouteTable routes)
{
Ensure.NotNull(httpClient, "httpClient");
Ensure.NotNull(routes, "routes");
this.httpClient = httpClient;
this.routes = routes;
}

public async Task<object> SendAsync(object message, CancellationToken cancellationToken)
{
Ensure.NotNull(message, "message");

Type messageType = message.GetType();
if (routes.TryGet(messageType, out RouteDefinition route))
{
HttpRequestMessage httpRequest = await CreateRequestAsync(message, route);
HttpResponseMessage httpResponse = await httpClient.SendAsync(httpRequest, cancellationToken);
httpResponse.EnsureSuccessStatusCode();

if (route.ResponseDeserializer != null)
{
using (Stream httpResponseContent = await httpResponse.Content.ReadAsStreamAsync())
{
var responseDeserializerContext = new DefaultDeserializerContext();
if (await route.ResponseDeserializer.TryDeserializeAsync(httpResponseContent, responseDeserializerContext))
{
return responseDeserializerContext.Output;
}
else
{
// TODO: Throw.
}
}
}
}

// Throw.
throw Ensure.Exception.NotImplemented();
}

private async Task<HttpRequestMessage> CreateRequestAsync(object message, RouteDefinition route)
{
HttpMethod httpMethod = HttpMethod.Post;
string httpUrl = route.Url;

switch (route.Method)
{
case RouteMethod.Post:
httpMethod = HttpMethod.Post;
break;
case RouteMethod.Put:
httpMethod = HttpMethod.Put;
break;
case RouteMethod.Delete:
httpMethod = HttpMethod.Delete;
break;
case RouteMethod.Get:
httpMethod = HttpMethod.Get;
break;
default:
throw Ensure.Exception.NotSupported(route.Method);
}

StringContent httpContent = new StringContent(await route.RequestSerializer.SerializeAsync(message));

HttpRequestMessage httpRequest = new HttpRequestMessage()
{
Content = httpContent,
Method = httpMethod,
RequestUri = new Uri(httpUrl, UriKind.Absolute)
};

httpRequest.Headers.Add("Content-Type", route.ContentType);
httpRequest.Headers.Accept.Clear();
httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(route.ContentType));

// TODO: Additional headers like authentication.

return httpRequest;
}
}
}
2 changes: 1 addition & 1 deletion src/Neptuo.Net.Http.Routing/RelativeRouteTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public bool TryGet(Type inputType, out RouteDefinition route)
if (route.Url.StartsWith("~/"))
{
string relativeUrl = route.Url.Substring(1);
route = new RouteDefinition(baseUrl + relativeUrl, route.Method, route.Serializer, route.ContentType);
route = new RouteDefinition(baseUrl + relativeUrl, route.Method, route.RequestSerializer, route.ContentType);
return true;
}
}
Expand Down
15 changes: 11 additions & 4 deletions src/Neptuo.Net.Http.Routing/RouteDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ public class RouteDefinition
/// <summary>
/// Gets a serializer for the route.
/// </summary>
public ISerializer Serializer { get; }
public ISerializer RequestSerializer { get; }

/// <summary>
/// Gets a deserializer for processing of the response.
/// </summary>
public IDeserializer ResponseDeserializer { get; }

/// <summary>
/// Gets a content type for the route.
Expand All @@ -37,13 +42,15 @@ public class RouteDefinition
/// </summary>
/// <param name="url">A route URL.</param>
/// <param name="method">A HTTP method used for the route.</param>
/// <param name="serializer">A serializer for the route.</param>
/// <param name="requestSerializer">A serializer for the route.</param>
/// <param name="responseDeserializer">A deserializer for processing of the response.</param>
/// <param name="contentType">A content type for the route.</param>
public RouteDefinition(string url, RouteMethod method, ISerializer serializer, string contentType)
public RouteDefinition(string url, RouteMethod method, ISerializer requestSerializer, IDeserializer responseDeserializer, string contentType)
{
Url = url;
Method = method;
Serializer = serializer;
RequestSerializer = requestSerializer;
ResponseDeserializer = responseDeserializer;
ContentType = contentType;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Neptuo.Net.Http.Routing/RouteMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public enum RouteMethod
{
Post,
Put,
Delete,
Get
}
}

0 comments on commit cd0eb0b

Please sign in to comment.