Skip to content

Commit

Permalink
-Added in SSL support for both AMQPS and HTTPS including SslHelper cl…
Browse files Browse the repository at this point in the history
…ass.

-Support for queue subscriptions.
-Added in methods that query RabbitMQ REST API to query exchanges and queues.
-Added more events for both IAmqpBrokerConnection and AmqpClient.
-Filled out AmqpClient implementation more so it has more complete parity with IAmqpBrokerConnection.
-Updated the AmqpDemo scene form design, added exchange dropdowns instead of text fields, and added a message publishing form.
-Various bug fixes and updates.
  • Loading branch information
meverett committed Mar 14, 2017
1 parent a901c05 commit e2fd214
Show file tree
Hide file tree
Showing 24 changed files with 681 additions and 42 deletions.
3 changes: 3 additions & 0 deletions src/CymaticLabs.Unity3D.Amqp.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using System.Linq;
using CymaticLabs.Unity3D.Amqp;

using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace CymaticLabs.Unity3D.Amqp.Cli
{
class Program
Expand Down
2 changes: 2 additions & 0 deletions src/CymaticLabs.Unity3D.Amqp/CymaticLabs.Unity3D.Amqp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@
<Compile Include="AmqpQueueMessageReceivedEventHandler.cs" />
<Compile Include="AmqpExchangeReceivedMessage.cs" />
<Compile Include="AmqpSubscriptionBase.cs" />
<Compile Include="ExceptionEventArgs.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Helpers\AmqpHelper.cs" />
<Compile Include="Helpers\SslHelper.cs" />
<Compile Include="IAmqpReceivedMessage.cs" />
<Compile Include="IAmqpMessageProperties.cs" />
<Compile Include="IAmqpBrokerConnection.cs" />
Expand Down
25 changes: 25 additions & 0 deletions src/CymaticLabs.Unity3D.Amqp/ExceptionEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;

namespace CymaticLabs.Unity3D.Amqp
{
/// <summary>
/// Event agurment for events that relate to an exception.
/// </summary>
public class ExceptionEventArgs : EventArgs
{
/// <summary>
/// Gets the exception that occurred as part of the event.
/// </summary>
public Exception Exception { get; private set; }

/// <summary>
/// Creates a new event argument for the given exception.
/// </summary>
/// <param name="ex">The exception that occurred.</param>
public ExceptionEventArgs(Exception ex)
{
if (ex == null) throw new ArgumentNullException("ex");
this.Exception = ex;
}
}
}
55 changes: 55 additions & 0 deletions src/CymaticLabs.Unity3D.Amqp/Helpers/SslHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace CymaticLabs.Unity3D.Amqp
{
/// <summary>
/// Class used for helping with SSL/TLS.
/// </summary>
public static class SslHelper
{
#region Constructor

static SslHelper()
{
// Setup custom SSL validation to avoid Mono SSL issues (slightly unsecure)
ServicePointManager.ServerCertificateValidationCallback = SslHelper.RemoteCertificateValidationCallback;
}

#endregion Constructor

#region Methods

/// <summary>
/// Custom SSL certificate validation callback.
/// </summary>
public static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool isOk = true;
// If there are errors in the certificate chain, look at each error to determine the cause.
if (sslPolicyErrors != SslPolicyErrors.None)
{
for (int i = 0; i < chain.ChainStatus.Length; i++)
{
if (chain.ChainStatus[i].Status != X509ChainStatusFlags.RevocationStatusUnknown)
{
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
bool chainIsValid = chain.Build(new X509Certificate2(certificate));
if (!chainIsValid)
{
isOk = false;
}
}
}
}
return isOk;
}

#endregion Methods
}
}
5 changes: 5 additions & 0 deletions src/CymaticLabs.Unity3D.Amqp/IAmqpBrokerConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public interface IAmqpBrokerConnection
/// </summary>
event EventHandler Reconnecting;

/// <summary>
/// Occurs when there is a connection error.
/// </summary>
event EventHandler<ExceptionEventArgs> ConnectionError;

/// <summary>
/// Occurs when an exchange has been subscribed to.
/// </summary>
Expand Down
33 changes: 23 additions & 10 deletions src/CymaticLabs.Unity3D.Amqp/RabbitMq/RabbitMqBrokerConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ public bool IsConnected
/// </summary>
public event EventHandler Reconnecting;

/// <summary>
/// Occurs when there is a connection error.
/// </summary>
public event EventHandler<ExceptionEventArgs> ConnectionError;

/// <summary>
/// Occurs when an exchange has been subscribed to.
/// </summary>
Expand Down Expand Up @@ -224,7 +229,7 @@ private void EnsureConnection()
if (State == AmqpConnectionStates.Connected && (Connection == null || !Connection.IsOpen))
{
State = AmqpConnectionStates.Disconnected;
if (Disconnected != null) Disconnected(this, EventArgs.Empty);
Disconnected?.Invoke(this, EventArgs.Empty);
}
}

Expand All @@ -235,6 +240,7 @@ public void Connect()
{
if (IsConnected) return;
State = AmqpConnectionStates.Connecting;

//StreamRuntime.Current.LogInfo("Connecting to {0}...", this);
Console.WriteLine("Connecting to {0}...", this);

Expand Down Expand Up @@ -266,8 +272,12 @@ public void Connect()
// Enable encrypted connection based on port
factory.Ssl.Enabled = AmqpPort == 5671 ? true : false;
factory.Ssl.ServerName = Server; // this is needed so that Mono won't have an exception when it's NULL
// Add in custom SSL certificate validator so we have the ability to enable untrusted SSL certificates and deal with Mono issues
factory.Ssl.CertificateValidationCallback = SslHelper.RemoteCertificateValidationCallback;
// TODO Remove this line and setup proper certification registration policy for tighter security
// TODO Eventually allow requiring server name/cert matching to be configurable, for now disable enforcement
factory.Ssl.AcceptablePolicyErrors = System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch;
// Create the connection for the connection
Expand All @@ -289,7 +299,7 @@ public void Connect()
bc.State = AmqpConnectionStates.Connected;
//StreamRuntime.Current.LogInfo("Connected to {0}", this);
Console.WriteLine("Connected to {0}", this);
if (Connected != null) Connected(this, EventArgs.Empty);
Connected?.Invoke(this, EventArgs.Empty);
}
catch (Exception ex)
{
Expand All @@ -305,7 +315,8 @@ public void Connect()
// Don't attempt to reconnect, we know the credentials are bad
bc.State = AmqpConnectionStates.Disconnected;
if (Disconnected != null) Disconnected(this, EventArgs.Empty);
Disconnected?.Invoke(this, EventArgs.Empty);
ConnectionError?.Invoke(this, new ExceptionEventArgs(ex));
}
else
{
Expand All @@ -315,9 +326,11 @@ public void Connect()
//StreamRuntime.Current.LogError("(retries:{0}) Error connecting to {1} => {2}",
// retryCount, this, ex.Message);
Console.WriteLine("(retries:{0}) Error connecting to {1} => {2}", retryCount, this, ex.Message);
if (Reconnecting != null) Reconnecting(this, EventArgs.Empty);
Reconnecting?.Invoke(this, EventArgs.Empty);
}
ConnectionError?.Invoke(this, new ExceptionEventArgs(ex));
// Sleep a bit before retrying to connect
Thread.Sleep(ReconnectInterval * 1000);
}
Expand All @@ -341,7 +354,7 @@ public void Disconnect()
Connection.Close();
State = AmqpConnectionStates.Disconnected;
Console.WriteLine("Disconnected from {0}", this);
if (Disconnected != null) Disconnected(this, EventArgs.Empty);
Disconnected?.Invoke(this, EventArgs.Empty);
}
}

Expand Down Expand Up @@ -456,7 +469,7 @@ public void Subscribe(AmqpExchangeSubscription subscription)
exchangeSubscriptions.Add(subscription);

// Notify
if (SubscribedToExchange != null) SubscribedToExchange(subscription);
SubscribedToExchange?.Invoke(subscription);
}

/// <summary>
Expand Down Expand Up @@ -488,7 +501,7 @@ public void Unsubscribe(AmqpExchangeSubscription subscription)
exchangeSubscriptions.Remove(subscription);

// Notify
if (UnsubscribedFromExchange != null) UnsubscribedFromExchange(subscription);
UnsubscribedFromExchange?.Invoke(subscription);
}

#endregion Exchange
Expand Down Expand Up @@ -550,7 +563,7 @@ public void Subscribe(AmqpQueueSubscription subscription)
queueSubscriptions.Add(subscription);

// Notify
if (SubscribedToQueue != null) SubscribedToQueue(subscription);
SubscribedToQueue?.Invoke(subscription);
}

/// <summary>
Expand Down Expand Up @@ -581,7 +594,7 @@ public void Unsubscribe(AmqpQueueSubscription subscription)
queueSubscriptions.Remove(subscription);

// Notify
if (UnsubscribedFromQueue != null) UnsubscribedFromQueue(subscription);
UnsubscribedFromQueue?.Invoke(subscription);
}

#endregion Queue
Expand Down
Binary file removed src/CymaticLabs.Unity3D.Amqp/UpgradeLog.htm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Loading

0 comments on commit e2fd214

Please sign in to comment.