Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
gingters committed May 8, 2020
2 parents df26d0b + 4144cf5 commit f9618ed
Show file tree
Hide file tree
Showing 44 changed files with 514 additions and 478 deletions.
29 changes: 20 additions & 9 deletions Documentation/de/relayserver.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

# Release Notes

## Version 2.3.0-rc3
## Version 2.3.0-rc4

* RabbitMq Verbesserungen
* RabbitMQ Verbesserungen

* Beendete Verbindungen werden nun explizit auch auf dem Rabbit-Client beendet.
* Die Funktion, verlorene Verbindungen zum RabbitMq Server von dessen Client automatisch wiederherstellen zu lassen, wird nun standardmäßig aktiviert.
* Die Funktion, verlorene Verbindungen zum RabbitMQ Server von dessen Client automatisch wiederherstellen zu lassen, wird nun standardmäßig aktiviert.
* Wenn eine Verbindung geschlossen wird, wird sichergestellt dass alle Nachrichten die noch nicht acknowledged wurden, wieder zugestellt werden.
* Um den Durchsatz zu erhöhen werden nun separate Channels (via RoutingKeys) für Requests, Responses und Acknowledgements verwendet.

Expand All @@ -34,12 +34,23 @@
* Es stehen nun alle benötigen Informationen für manuelles Acknowlegment einfacher zur Verfügung.
* Das Request-logging führt nun auch die RequestId mit.
* Registrierungen der On-Premise Connector-Typen für Autofac ist nun möglich.
* Der On-Premise Connector service initialisiert nun die HttpConnection properties.
* Relative Pfade in der Konfiguration werden nun einheitlich relativ zur RelayServer .exe-Datei ausgewertet und nicht mehr zum Ausführungsverzeichnis.
* Es wird jetzt per default JSON statt XML über die eigenen Endpunkte zurück gegeben.
* Eine eigene Implementation (oder von der Standardklasse abgeleiteten) eines IOnPremiseConnectionContext kann in der DI registriert werden.
* Um eine einfachere Migration von geänderten IOnPremiseTargetRequest Implementierungen durchführen zu können, wurde eine Property mit dem Namen "Properties" eingeführt, welche in den Root des JSON serialisiert wird, um im On-Premise Connector in die jeweiligen Properties deserialisiert zu werden.

* Fehlerbehebungen

* Der OnPremiseConnector Demo-Service konnte ein Framwork-Assembly unter bestimmten Voraussetzungen nicht korrekt laden.
* Der OnPremise-Connector wird seinen `HttpClient` mit dem er Antworten an den RelayServer sendet nun erneuern, falls dort Fehler auftreten.
* Der On-Premise Connector Demo-Service konnte ein Framwork-Assembly unter bestimmten Voraussetzungen nicht korrekt laden.
* Der On-Premise Connector wird seinen `HttpClient` mit dem er Antworten an den RelayServer sendet nun erneuern, falls dort Fehler auftreten.
* HttpConfig muss unter bestimmten Umständen explizit initialisiert werden.
* Ein neu erzeugter `HttpClient` erhält nun auch die Authentication-Header seines Vorgängers.
* Auch der Request Interceptor hat nun Zugriff auf den Stream der Daten.
* Der Zugriff auf leere Inhalte in intercepted Requests und Responses wirft nun keine NullReferenceException mehr.
* Das Acknowledgement wurde nicht auf dem korrekten RabbitMQ-Model durchgeführt.
* Eine bereits deaktivierter On-Premise Connector wurde wiederholt deaktiviert.
* Eine Konfigurationsnachricht wurde auch an On-Premise Connectoren geschickt, welche diese gar nicht unterstützt haben.

## Version 2.2.0

Expand All @@ -62,7 +73,7 @@

* Fehlerbehebungen

* Der automatische Disconnect stand in individuellen OnPremiseConnector-Implementationen nicht korrekt zur Verfügung.
* Der automatische Disconnect stand in individuellen On-Premise Connector-Implementationen nicht korrekt zur Verfügung.

## Version 2.1.0

Expand All @@ -84,7 +95,7 @@
* Fehlerbehebungen

* Wenn eine weiterzuleitende Anfrage einen Query-Parameter namens 'path' enthielt, führte das zu unerwartetem Verhalten.
* Die konfigurierbare Filterung des Inhaltes von OnPremise-seitigen Fehler-Antworten wurde korrigiert.
* Die konfigurierbare Filterung des Inhaltes von on-premise-seitigen Fehler-Antworten wurde korrigiert.
* Eine genauere Fehlermeldung wird angezeigt wenn die Konfigurationsdatei des RelayServers fehlt.

## Version 2.0.0
Expand All @@ -93,9 +104,9 @@

* Mehrere RelayServer können zur Lastverteilung parallel betrieben werden. Die Server müssen hierzu Zugriff auf einen gemeinsamen Netzwerk-Ordner haben, in dem zu übertragende Daten zwischen den Servern ausgetauscht werden.

* Verbesserte Verbindungsstabilität mit neueren OnPremiseConnectoren
* Verbesserte Verbindungsstabilität mit neueren On-Premise Connectoren

* Der RelayServer wird einen OnPremiseConnector mit Version 2.x oder neuer nun regelmässig mit einem Heartbeat anfragen. Bleibt dieser Heartbeat aus, so wird der OnPremiseConnector versuchen die Verbindung zum RelayServer neu aufzubauen.
* Der RelayServer wird einen On-Premise Connector mit Version 2.x oder neuer nun regelmässig mit einem Heartbeat anfragen. Bleibt dieser Heartbeat aus, so wird der On-Premise Connector versuchen die Verbindung zum RelayServer neu aufzubauen.

* Eigenen Code ausführen

Expand Down
39 changes: 25 additions & 14 deletions Documentation/en/relayserver.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ The goal of this list is to highlight companies who pay back to this open source

# Version history

## Version 2.3.0-rc3
## Version 2.3.0-rc4

* RabbitMq Improvements
* RabbitMQ Improvements

* Closed Rabbit connections will now be automatically unbound at the client.
* The automatic recovery feature of the rabbit client will now be enabled by default.
Expand All @@ -28,7 +28,7 @@ The goal of this list is to highlight companies who pay back to this open source

* On-Premise Interceptors

* It is now possible to add custom code into the On-Premise connector that is able to intercept and modifiy requests and responses.
* It is now possible to add custom code into the On-Premise Connector that is able to intercept and modifiy requests and responses.

* Modify content streams

Expand All @@ -42,13 +42,24 @@ The goal of this list is to highlight companies who pay back to this open source
* Logging of sensitive data is now configurable and enabled by default.
* Now all information required for manual acknowledgment is provided for easier handling.
* Request logging now also tracks the request id.
* It is now possible to register the OnPremise Connector types with Autofac.
* It is now possible to register the On-Premise Connector types with Autofac.
* The On-Premise Connector service now initializes http connection properties.
* Relative paths in configuration are now consistently evaluated against the exe directory of the RelayServer and not against the execution dir anymore.
* The new default for our own responses now is JSON and not XML.
* An own implementation (or inherited from the default one) of an IOnPremiseConnectionContext can be registered in the DI.
* For an easier migration scenario of changed IOnPremiseTargetRequest implementations a property called "Properties" was introduced, which will be serialized onto the root JSON object to be deserialized as properties on the on-premise side.

* Bugfixes

* Under certain circumstances the on-premise connector demo service wasn't able to load a framework assembly.
* The OnPremise-Connector is now able to recreate the `HttpClient` that is used to send responses to the RelayServer in case there are errors when posting.
* Under certain circumstances the On-Premise Connector demo service wasn't able to load a framework assembly.
* The On-Premise Connector is now able to recreate the `HttpClient` that is used to send responses to the RelayServer in case there are errors when posting.
* HttpConfig needs to be explicitely initialized under certain circumstances.
* A newly created HttpClient now also receives the authentication header values of its predecessor.
* The request interceptor now also has access to the request body.
* Accessing empty bodies on intercepted requests and responses does not throw a NullReferenceException anymore.
* The acknowledgement was not done on the correct RabbitMQ model.
* An already deactivated connection was repeatingly deactivated again.
* The config message was accidentally sent to On-Premise Connectors not supporting it.

## Version 2.2.0

Expand All @@ -71,23 +82,23 @@ The goal of this list is to highlight companies who pay back to this open source

* Bugfixes

* The automatic disconnect feature was not correctly made available for custom implementations of the On-Premise connector service.
* The automatic disconnect feature was not correctly made available for custom implementations of the On-Premise Connector service.

## Version 2.1.0

* Server-side Link configuration

* It is now possible to configure link-specific settings on the RelayServer itself.

* Automatic disconnect of On-Premises connectors
* Automatic disconnect of On-Premises Connectors

* If required, it is possible to have an On-Premises connector auto-disconnect itself after a maximum absolute connection time and/or after a maximum idle time.
* If required, it is possible to have an On-Premises Connector auto-disconnect itself after a maximum absolute connection time and/or after a maximum idle time.

* General improvements

* The On-Premises connectors settings for reconnect timeouts (maximum and minimum) are now configurable, to be able to prevent accidental DDoS detections i.e. when the server restarts and all connectors want to reconnect in the same 30 second window.
* The On-Premises Connectors settings for reconnect timeouts (maximum and minimum) are now configurable, to be able to prevent accidental DDoS detections i.e. when the server restarts and all Connectors want to reconnect in the same 30 second window.
* Interceptors now can read the local uri that the client requested, i.e. to set forwarded headers.
* It is now possible to configure whether the On-Premises connector automatically follows an http redirect response from a On-Premises target, or if the redirect will be relayed too.
* It is now possible to configure whether the On-Premises Connector automatically follows an http redirect response from a On-Premises target, or if the redirect will be relayed too.
* It is now possible to use a custom implementation of an `IPasswordComplexityValidator` by registering that in an Autofac module within a custom code assembly.

* Bugfixes
Expand All @@ -102,9 +113,9 @@ The goal of this list is to highlight companies who pay back to this open source

* It is now possible to operate multiple RelayServers in parallel for better load distribution. All servers need to have access to a shared network folder in order to exchange binary files with request or response payloads.

* Improved connection stability with new On-Premises connectors
* Improved connection stability with new On-Premises Connectors

* The RelayServer is now capable of heart beating On-Premises connectors of version 2.x or newer. A connector that does not receive this heartbeat will automatically try to reconnect to the server.
* The RelayServer is now capable of heart beating On-Premises Connectors of version 2.x or newer. A Connector that does not receive this heartbeat will automatically try to reconnect to the server.

* Implementation of custom code

Expand Down Expand Up @@ -133,7 +144,7 @@ The goal of this list is to highlight companies who pay back to this open source

* Optimizations

* Memory consumption of the RelayServer and On-Premises connectors has been reduced. Additionally we optimized general performance to make the system more efficient.
* Memory consumption of the RelayServer and On-Premises Connectors has been reduced. Additionally we optimized general performance to make the system more efficient.

* Security improvements

Expand Down
2 changes: 1 addition & 1 deletion Shared/AssemblyInfo.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

[assembly: AssemblyVersion("2.3.0.0")]
[assembly: AssemblyFileVersion("2.3.0.0")]
[assembly: AssemblyInformationalVersion("2.3.0.0-rc3")]
[assembly: AssemblyInformationalVersion("2.3.0.0-rc4")]
2 changes: 1 addition & 1 deletion Shared/ProjectProperties.shared.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!-- WARNING: This file is shared between all RelayServer .NET Core library projects -->
<PropertyGroup>
<VersionPrefix>2.3.0</VersionPrefix>
<PackageVersion>2.3.0-rc3</PackageVersion>
<PackageVersion>2.3.0-rc4</PackageVersion>

<Copyright>Copyright © Thinktecture AG 2015 - 2020. All rights reserved.</Copyright>
<PackageTags>thinktecture;relayserver</PackageTags>
Expand Down
3 changes: 3 additions & 0 deletions Thinktecture.Relay.CustomCodeDemo/CustomCodeModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ protected override void Load(ContainerBuilder builder)
// Example: Override request logger with a custom version
builder.RegisterType<NoopRequestLogger>().AsImplementedInterfaces();

// Example: Override the on-premise connector context with an own implementation
builder.RegisterType<DemoOnPremiseConnectorContext>().AsImplementedInterfaces().InstancePerDependency();

base.Load(builder);
}
}
Expand Down
15 changes: 15 additions & 0 deletions Thinktecture.Relay.CustomCodeDemo/DemoOnPremiseConnectorContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Serilog;
using Thinktecture.Relay.Server.Communication;

namespace Thinktecture.Relay.CustomCodeDemo
{
internal class DemoOnPremiseConnectorContext : OnPremiseConnectionContext
{
public DemoOnPremiseConnectorContext(ILogger logger)
{
logger?.Information("Creating own connector context");
}

public override bool SupportsConfiguration => false;
}
}
23 changes: 21 additions & 2 deletions Thinktecture.Relay.CustomCodeDemo/DemoRequestInterceptor.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Text;
using System.Web.Http.Controllers;
using Serilog;
using Thinktecture.Relay.Server;
using Thinktecture.Relay.Server.Interceptor;
Expand All @@ -17,16 +18,19 @@ namespace Thinktecture.Relay.CustomCodeDemo
public class DemoRequestInterceptor : IOnPremiseRequestInterceptor
{
private readonly ILogger _logger;
private readonly HttpRequestContext _context;

/// <summary>
/// Creates a new instance of the <see cref="DemoRequestInterceptor"/>
/// </summary>
/// <param name="logger">An instance of an <see cref="ILogger"/>, that will be injected by Autofac when this interceptor is created</param>
public DemoRequestInterceptor(ILogger logger)
/// <param name="context">An instance of an <see cref="HttpRequestContext"/> for access to request specifics.</param>
public DemoRequestInterceptor(ILogger logger, HttpRequestContext context)
{
// You can also have the DI inject different custom dependencies, as long as
// they are all registered in your interceptors Autofac module
_logger = logger;
_context = context;
}

/// <summary>
Expand All @@ -38,6 +42,21 @@ public HttpResponseMessage OnRequestReceived(IInterceptedRequest request)
{
_logger?.Debug($"{nameof(DemoRequestInterceptor)}.{nameof(OnRequestReceived)} is called.");

if (_context.IsLocal)
{
_logger?.Debug("This request comes from localhost.");
}

// Example: Move query parameters into own JSON property
if (request.Url.Contains("?"))
{
var parts = request.Url.Split('?');
request.Url = parts[0];
request.Properties = new Dictionary<string, object>() {
{ "Parameter", parts[1] }
};
}

// Example: Modify content
if (request.HttpHeaders.TryGetValue("Content-Type", out var contentType) && contentType == "application/json")
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
<ItemGroup>
<Compile Include="DemoController.cs" />
<Compile Include="CustomCodeModule.cs" />
<Compile Include="DemoOnPremiseConnectorContext.cs" />
<Compile Include="NoopPasswordComplexityValidator.cs" />
<Compile Include="NoopRequestLogger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;

Expand All @@ -16,6 +17,10 @@ public static class HttpClientExtensions
/// <param name="password">The password to set.</param>
public static void SetBasicAuthentication(this HttpClient client, string userName, string password)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (userName == null) throw new ArgumentNullException(nameof(userName));
if (password == null) throw new ArgumentNullException(nameof(password));

client.DefaultRequestHeaders.Authorization = new BasicAuthenticationHeaderValue(userName, password);
}

Expand All @@ -27,16 +32,34 @@ public static void SetBasicAuthentication(this HttpClient client, string userNam
/// <param name="token">The token to set.</param>
public static void SetToken(this HttpClient client, string scheme, string token)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (scheme == null) throw new ArgumentNullException(nameof(scheme));
if (token == null) throw new ArgumentNullException(nameof(token));

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(scheme, token);
}

/// <summary>
/// Gets header value for token authentication.
/// </summary>
/// <param name="client">The <see cref="HttpClient"/> to get the header value from.</param>
public static string GetToken(this HttpClient client)
{
if (client == null) throw new ArgumentNullException(nameof(client));

return client.DefaultRequestHeaders?.Authorization?.Parameter;
}

/// <summary>
/// Sets headers for bearer token authentication.
/// </summary>
/// <param name="client">The <see cref="HttpClient"/> to set the headers on.</param>
/// <param name="token">The token to set as a bearer token.</param>
public static void SetBearerToken(this HttpClient client, string token)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (token == null) throw new ArgumentNullException(nameof(token));

client.SetToken("Bearer", token);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ public RelayServerHttpConnection(ILogger logger, Uri relayServerUri, TimeSpan re
_requestTimeout = requestTimeout;

#if NETSTANDARD2_0
ServicePointManager.FindServicePoint(relayServerUri).ConnectionLeaseTimeout = requestTimeout.Milliseconds;
ServicePointManager.DnsRefreshTimeout = requestTimeout.Milliseconds;
ServicePointManager.FindServicePoint(relayServerUri).ConnectionLeaseTimeout = (int)requestTimeout.TotalMilliseconds;

if (requestTimeout.Milliseconds < ServicePointManager.DnsRefreshTimeout)
{
ServicePointManager.DnsRefreshTimeout = (int)requestTimeout.TotalMilliseconds;
}
#endif

CreateHttpClient();
Expand Down Expand Up @@ -78,9 +82,11 @@ public void SetBearerToken(string accessToken)

private void RecreateHttpClient()
{
var token = _httpClient.GetToken();
var oldClient = _httpClient;

CreateHttpClient();
_httpClient.SetBearerToken(token);

oldClient?.Dispose();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ public async Task StartAsync()
_connector.RegisterOnPremiseTarget(onPremiseTarget.Key, handlerType);
}

var timeout = (int)section.RequestTimeout.TotalMilliseconds;
ServicePointManager.FindServicePoint(new Uri(section.BaseUrl)).ConnectionLeaseTimeout = timeout;
if (timeout < ServicePointManager.DnsRefreshTimeout)
{
ServicePointManager.DnsRefreshTimeout = timeout;
}

await _connector.ConnectAsync().ConfigureAwait(false);
}
catch (Exception ex)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Reactive.Subjects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Thinktecture.Relay.Server.Communication.RabbitMq;
using Thinktecture.Relay.Server.OnPremise;

namespace Thinktecture.Relay.Server.Communication.BackendCommunicationTests
Expand All @@ -15,7 +16,7 @@ public Prepare()

var responseSubject = new Subject<IOnPremiseConnectorResponse>();
MessageDispatcherMock.Setup(d => d.OnResponseReceived()).Returns(responseSubject);
var acknowledgeSubject = new Subject<string>();
var acknowledgeSubject = new Subject<IAcknowledgeRequest>();
MessageDispatcherMock.Setup(d => d.OnAcknowledgeReceived()).Returns(acknowledgeSubject);
}

Expand Down
Loading

0 comments on commit f9618ed

Please sign in to comment.