This commit is contained in:
xinchen 2015-03-06 23:05:10 -08:00
Родитель 297f87ef04
Коммит ed63e4a632
93 изменённых файлов: 8340 добавлений и 8330 удалений

10
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Denote all files that are truly binary and should not be modified.
*.exe binary
*.dll binary
*.pdb binary
*.ico binary
*.png binary
*.jpg binary

Просмотреть файл

@ -1,28 +1,28 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Navigation;
using Device.Controller.Resources;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Navigation;
using Device.Controller.Resources;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
namespace Device.Controller
{
public partial class App : Application

Просмотреть файл

@ -13,9 +13,9 @@
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using Device.Controller.Resources;
// ------------------------------------------------------------------------------------
using Device.Controller.Resources;
namespace Device.Controller
{
/// <summary>

Просмотреть файл

@ -17,20 +17,20 @@
using Amqp;
using Amqp.Framing;
using Microsoft.Phone.Controls;
using System.Windows.Threading;
using System.Windows.Threading;
namespace Device.Controller
{
/// <summary>
/// The controller runs on Windows Phone 8. The app name is iHome.
/// Ensure the broker is running and change the IP address below.
/// If using "amqps", ensure the broker certificate can be validated
/// on the Phone (e.g. self-generated certificate needs to be imported
/// to the phone).
/// The app works with the test broker. Start it as follows:
/// TestAmqpBroker.exe amqp://localhost:5672 /creds:guest:guest
/// Add "/trace:frame" to output frames for debugging if requried.
/// An "X" displayed in the middle indicates a connection failure.
/// <summary>
/// The controller runs on Windows Phone 8. The app name is iHome.
/// Ensure the broker is running and change the IP address below.
/// If using "amqps", ensure the broker certificate can be validated
/// on the Phone (e.g. self-generated certificate needs to be imported
/// to the phone).
/// The app works with the test broker. Start it as follows:
/// TestAmqpBroker.exe amqp://localhost:5672 /creds:guest:guest
/// Add "/trace:frame" to output frames for debugging if requried.
/// An "X" displayed in the middle indicates a connection failure.
/// </summary>
public partial class MainPage : PhoneApplicationPage
{
@ -39,15 +39,15 @@ namespace Device.Controller
// Constructor
public MainPage()
{
InitializeComponent();
try
{
this.controller = new Controller(this);
}
catch
{
this.btnData.Content = "X";
this.controller = null;
InitializeComponent();
try
{
this.controller = new Controller(this);
}
catch
{
this.btnData.Content = "X";
this.controller = null;
}
}
@ -61,7 +61,7 @@ namespace Device.Controller
public Controller(MainPage parent)
{
this.parent = parent;
this.parent = parent;
Address address = new Address("amqp://guest:guest@10.1.10.76:5672");
this.connection = new Connection(address);
this.session = new Session(connection);
@ -86,18 +86,18 @@ namespace Device.Controller
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (this.controller != null)
{
this.controller.Control(38);
{
if (this.controller != null)
{
this.controller.Control(38);
}
}
private void Button_Click_1(object sender, System.Windows.RoutedEventArgs e)
{
if (this.controller != null)
{
this.controller.Control(40);
{
if (this.controller != null)
{
this.controller.Control(40);
}
}
}

Просмотреть файл

@ -21,11 +21,11 @@ using System.Resources;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
// associated with an assembly.
[assembly: AssemblyTitle("Device.Controller")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Device.Controller")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]

Просмотреть файл

@ -1,108 +1,108 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.0
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Device.Controller.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class AppResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal AppResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Device.Controller.Resources.AppResources", typeof(AppResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to add.
/// </summary>
public static string AppBarButtonText {
get {
return ResourceManager.GetString("AppBarButtonText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Menu Item.
/// </summary>
public static string AppBarMenuItemText {
get {
return ResourceManager.GetString("AppBarMenuItemText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to MY APPLICATION.
/// </summary>
public static string ApplicationTitle {
get {
return ResourceManager.GetString("ApplicationTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to LeftToRight.
/// </summary>
public static string ResourceFlowDirection {
get {
return ResourceManager.GetString("ResourceFlowDirection", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to en-US.
/// </summary>
public static string ResourceLanguage {
get {
return ResourceManager.GetString("ResourceLanguage", resourceCulture);
}
}
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.0
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Device.Controller.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class AppResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal AppResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Device.Controller.Resources.AppResources", typeof(AppResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to add.
/// </summary>
public static string AppBarButtonText {
get {
return ResourceManager.GetString("AppBarButtonText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Menu Item.
/// </summary>
public static string AppBarMenuItemText {
get {
return ResourceManager.GetString("AppBarMenuItemText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to MY APPLICATION.
/// </summary>
public static string ApplicationTitle {
get {
return ResourceManager.GetString("ApplicationTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to LeftToRight.
/// </summary>
public static string ResourceFlowDirection {
get {
return ResourceManager.GetString("ResourceFlowDirection", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to en-US.
/// </summary>
public static string ResourceLanguage {
get {
return ResourceManager.GetString("ResourceLanguage", resourceCulture);
}
}
}
}

Просмотреть файл

@ -18,8 +18,8 @@ using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation;
namespace Device.Thermometer
{
/// <summary>

Просмотреть файл

@ -1,40 +1,40 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Threading;
using Amqp;
using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using AmqpTrace = Amqp.Trace;
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Threading;
using Amqp;
using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using AmqpTrace = Amqp.Trace;
namespace Device.Thermometer
{
/// The thermomeer runs on NETMF. It displays a number for the current
/// temprature. Click up and down buttons to increase/decrease the number.
/// Ensure the broker is running and change the host name below.
/// If using "amqps", ensure SSL is working on the device.
/// The app works with the test broker. Start it as follows:
/// TestAmqpBroker.exe amqp://localhost:5672 /creds:guest:guest
/// Add "/trace:frame" to output frames for debugging if requried.
{
/// The thermomeer runs on NETMF. It displays a number for the current
/// temprature. Click up and down buttons to increase/decrease the number.
/// Ensure the broker is running and change the host name below.
/// If using "amqps", ensure SSL is working on the device.
/// The app works with the test broker. Start it as follows:
/// TestAmqpBroker.exe amqp://localhost:5672 /creds:guest:guest
/// Add "/trace:frame" to output frames for debugging if requried.
public class Program : Application
{
{
string address = "amqp://guest:guest@localhost:5672";
Text text;
int temperature;
@ -57,33 +57,33 @@ namespace Device.Thermometer
}
private void Listen()
{
// real applicaiton needs to implement error handling and recovery
Connection connection = new Connection(new Address(this.address));
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "send-link", "data");
ReceiverLink receiver = new ReceiverLink(session, "receive-link", "control");
receiver.Start(100, this.OnMessage);
{
// real applicaiton needs to implement error handling and recovery
Connection connection = new Connection(new Address(this.address));
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "send-link", "data");
ReceiverLink receiver = new ReceiverLink(session, "receive-link", "control");
receiver.Start(100, this.OnMessage);
while (true)
{
this.changed.WaitOne();
Message message = new Message();
message.ApplicationProperties = new Amqp.Framing.ApplicationProperties();
message.ApplicationProperties["temperature"] = this.temperature;
sender.Send(message, null, null);
AmqpTrace.WriteLine(TraceLevel.Information, "sent data to monitor");
{
this.changed.WaitOne();
Message message = new Message();
message.ApplicationProperties = new Amqp.Framing.ApplicationProperties();
message.ApplicationProperties["temperature"] = this.temperature;
sender.Send(message, null, null);
AmqpTrace.WriteLine(TraceLevel.Information, "sent data to monitor");
}
}
private void OnMessage(ReceiverLink receiver, Message message)
{
AmqpTrace.WriteLine(TraceLevel.Information, "received command from controller");
int button = (int)message.ApplicationProperties["button"];
this.OnAction(button);
}
}
private void OnMessage(ReceiverLink receiver, Message message)
{
AmqpTrace.WriteLine(TraceLevel.Information, "received command from controller");
int button = (int)message.ApplicationProperties["button"];
this.OnAction(button);
}
private void OnAction(int button)
{
WriteTrace("receive action: {0}", button);
@ -120,8 +120,8 @@ namespace Device.Thermometer
// size of the display.
Window window = new Window();
window.Height = SystemMetrics.ScreenHeight;
window.Width = SystemMetrics.ScreenWidth;
window.Width = SystemMetrics.ScreenWidth;
// Create a single text control.
Text text = new Text();
text.TextContent = this.temperature.ToString();

Просмотреть файл

@ -1,47 +1,47 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.0
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Device.Thermometer
{
internal partial class Resources
{
private static System.Resources.ResourceManager manager;
internal static System.Resources.ResourceManager ResourceManager
{
get
{
if ((Resources.manager == null))
{
Resources.manager = new System.Resources.ResourceManager("Device.Thermometer.Resources", typeof(Resources).Assembly);
}
return Resources.manager;
}
}
internal static Microsoft.SPOT.Font GetFont(Resources.FontResources id)
{
return ((Microsoft.SPOT.Font)(Microsoft.SPOT.ResourceUtility.GetObject(ResourceManager, id)));
}
internal static string GetString(Resources.StringResources id)
{
return ((string)(Microsoft.SPOT.ResourceUtility.GetObject(ResourceManager, id)));
}
[System.SerializableAttribute()]
internal enum StringResources : short
{
String1 = 1228,
}
[System.SerializableAttribute()]
internal enum FontResources : short
{
small = 13070,
}
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.0
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Device.Thermometer
{
internal partial class Resources
{
private static System.Resources.ResourceManager manager;
internal static System.Resources.ResourceManager ResourceManager
{
get
{
if ((Resources.manager == null))
{
Resources.manager = new System.Resources.ResourceManager("Device.Thermometer.Resources", typeof(Resources).Assembly);
}
return Resources.manager;
}
}
internal static Microsoft.SPOT.Font GetFont(Resources.FontResources id)
{
return ((Microsoft.SPOT.Font)(Microsoft.SPOT.ResourceUtility.GetObject(ResourceManager, id)));
}
internal static string GetString(Resources.StringResources id)
{
return ((string)(Microsoft.SPOT.ResourceUtility.GetObject(ResourceManager, id)));
}
[System.SerializableAttribute()]
internal enum StringResources : short
{
String1 = 1228,
}
[System.SerializableAttribute()]
internal enum FontResources : short
{
small = 13070,
}
}
}

Просмотреть файл

@ -1,134 +1,134 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Threading;
using Amqp;
using Amqp.Framing;
using Amqp.Types;
namespace Examples.Interop
{
class Client
{
//
// Return message as string.
//
static String GetContent(Message msg)
{
object body = msg.Body;
return body == null ? null : body.ToString();
}
//
// Sample invocation: Interop.Client amqp://guest:guest@localhost:5672 [loopcount]
//
static int Main(string[] args)
{
String url = "amqp://guest:guest@localhost:5672";
String requestQueueName = "service_queue";
int loopcount = 1;
if (args.Length > 0)
url = args[0];
if (args.Length > 1)
loopcount = Convert.ToInt32(args[1]);
Connection.DisableServerCertValidation = true;
// uncomment the following to write frame traces
//Trace.TraceLevel = TraceLevel.Frame;
//Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
Connection connection = null;
try
{
Address address = new Address(url);
connection = new Connection(address);
Session session = new Session(connection);
// Sender attaches to fixed request queue name
SenderLink sender = new SenderLink(session, "Interop.Client-sender", requestQueueName);
// Receiver attaches to dynamic address.
// Discover its name when it attaches.
String replyTo = "";
ManualResetEvent receiverAttached = new ManualResetEvent(false);
OnAttached onReceiverAttached = (l, a) =>
{
replyTo = ((Source)a.Source).Address;
receiverAttached.Set();
};
// Create receiver and wait for it to attach.
ReceiverLink receiver = new ReceiverLink(
session, "Interop.Client-receiver", new Source() { Dynamic = true }, onReceiverAttached);
if (receiverAttached.WaitOne(10000))
{
// Receiver is attached.
// Send a series of requests, gather and print responses.
String[] requests = new String[] {
"Twas brillig, and the slithy toves",
"Did gire and gymble in the wabe.",
"All mimsy were the borogoves,",
"And the mome raths outgrabe."
};
for (int j = 0; j < loopcount; j++)
{
Console.WriteLine("Pass {0}", j);
for (int i = 0; i < requests.Length; i++)
{
Message request = new Message(requests[i]);
request.Properties = new Properties() { MessageId = "request" + i, ReplyTo = replyTo };
sender.Send(request);
Message response = receiver.Receive(10000);
if (null != response)
{
receiver.Accept(response);
Console.WriteLine("Processed request: {0} -> {1}",
GetContent(request), GetContent(response));
}
else
{
Console.WriteLine("Receiver timeout receiving response {0}", i);
break;
}
}
}
}
else
{
Console.WriteLine("Receiver attach timeout");
}
receiver.Close();
sender.Close();
session.Close();
connection.Close();
return 0;
}
catch (Exception e)
{
Console.WriteLine("Exception {0}.", e);
if (null != connection)
{
connection.Close();
}
}
return 1;
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Threading;
using Amqp;
using Amqp.Framing;
using Amqp.Types;
namespace Examples.Interop
{
class Client
{
//
// Return message as string.
//
static String GetContent(Message msg)
{
object body = msg.Body;
return body == null ? null : body.ToString();
}
//
// Sample invocation: Interop.Client amqp://guest:guest@localhost:5672 [loopcount]
//
static int Main(string[] args)
{
String url = "amqp://guest:guest@localhost:5672";
String requestQueueName = "service_queue";
int loopcount = 1;
if (args.Length > 0)
url = args[0];
if (args.Length > 1)
loopcount = Convert.ToInt32(args[1]);
Connection.DisableServerCertValidation = true;
// uncomment the following to write frame traces
//Trace.TraceLevel = TraceLevel.Frame;
//Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
Connection connection = null;
try
{
Address address = new Address(url);
connection = new Connection(address);
Session session = new Session(connection);
// Sender attaches to fixed request queue name
SenderLink sender = new SenderLink(session, "Interop.Client-sender", requestQueueName);
// Receiver attaches to dynamic address.
// Discover its name when it attaches.
String replyTo = "";
ManualResetEvent receiverAttached = new ManualResetEvent(false);
OnAttached onReceiverAttached = (l, a) =>
{
replyTo = ((Source)a.Source).Address;
receiverAttached.Set();
};
// Create receiver and wait for it to attach.
ReceiverLink receiver = new ReceiverLink(
session, "Interop.Client-receiver", new Source() { Dynamic = true }, onReceiverAttached);
if (receiverAttached.WaitOne(10000))
{
// Receiver is attached.
// Send a series of requests, gather and print responses.
String[] requests = new String[] {
"Twas brillig, and the slithy toves",
"Did gire and gymble in the wabe.",
"All mimsy were the borogoves,",
"And the mome raths outgrabe."
};
for (int j = 0; j < loopcount; j++)
{
Console.WriteLine("Pass {0}", j);
for (int i = 0; i < requests.Length; i++)
{
Message request = new Message(requests[i]);
request.Properties = new Properties() { MessageId = "request" + i, ReplyTo = replyTo };
sender.Send(request);
Message response = receiver.Receive(10000);
if (null != response)
{
receiver.Accept(response);
Console.WriteLine("Processed request: {0} -> {1}",
GetContent(request), GetContent(response));
}
else
{
Console.WriteLine("Receiver timeout receiving response {0}", i);
break;
}
}
}
}
else
{
Console.WriteLine("Receiver attach timeout");
}
receiver.Close();
sender.Close();
session.Close();
connection.Close();
return 0;
}
catch (Exception e)
{
Console.WriteLine("Exception {0}.", e);
if (null != connection)
{
connection.Close();
}
}
return 1;
}
}
}

Просмотреть файл

@ -1,20 +1,20 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

Просмотреть файл

@ -1,19 +1,19 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Examples.Interop
{

Просмотреть файл

@ -1,84 +1,84 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Amqp;
using Amqp.Framing;
using Amqp.Types;
namespace Examples.Interop {
class Drain {
//
// Sample invocation: Interop.Drain.exe --broker localhost:5672 --timeout 30 --address my-queue
//
static int Main(string[] args) {
const int ERROR_SUCCESS = 0;
const int ERROR_NO_MESSAGE = 1;
const int ERROR_OTHER = 2;
int exitCode = ERROR_SUCCESS;
Connection connection = null;
try
{
Options options = new Options(args);
Address address = new Address(options.Url);
connection = new Connection(address);
Session session = new Session(connection);
ReceiverLink receiver = new ReceiverLink(session, "receiver-drain", options.Address);
int timeout = int.MaxValue;
if (!options.Forever)
timeout = 1000 * options.Timeout;
Message message = new Message();
int nReceived = 0;
receiver.SetCredit(options.InitialCredit);
while ((message = receiver.Receive(null, timeout)) != null)
{
nReceived++;
if (!options.Quiet)
{
Console.WriteLine("Message(Properties={0}, ApplicationProperties={1}, Body={2}",
message.Properties, message.ApplicationProperties, message.Body);
}
receiver.Accept(message);
if (options.Count > 0 && nReceived == options.Count)
{
break;
}
}
if (message == null)
{
exitCode = ERROR_NO_MESSAGE;
}
receiver.Close();
session.Close();
connection.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception {0}.", e);
if (null != connection)
connection.Close();
exitCode = ERROR_OTHER;
}
return exitCode;
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Amqp;
using Amqp.Framing;
using Amqp.Types;
namespace Examples.Interop {
class Drain {
//
// Sample invocation: Interop.Drain.exe --broker localhost:5672 --timeout 30 --address my-queue
//
static int Main(string[] args) {
const int ERROR_SUCCESS = 0;
const int ERROR_NO_MESSAGE = 1;
const int ERROR_OTHER = 2;
int exitCode = ERROR_SUCCESS;
Connection connection = null;
try
{
Options options = new Options(args);
Address address = new Address(options.Url);
connection = new Connection(address);
Session session = new Session(connection);
ReceiverLink receiver = new ReceiverLink(session, "receiver-drain", options.Address);
int timeout = int.MaxValue;
if (!options.Forever)
timeout = 1000 * options.Timeout;
Message message = new Message();
int nReceived = 0;
receiver.SetCredit(options.InitialCredit);
while ((message = receiver.Receive(null, timeout)) != null)
{
nReceived++;
if (!options.Quiet)
{
Console.WriteLine("Message(Properties={0}, ApplicationProperties={1}, Body={2}",
message.Properties, message.ApplicationProperties, message.Body);
}
receiver.Accept(message);
if (options.Count > 0 && nReceived == options.Count)
{
break;
}
}
if (message == null)
{
exitCode = ERROR_NO_MESSAGE;
}
receiver.Close();
session.Close();
connection.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception {0}.", e);
if (null != connection)
connection.Close();
exitCode = ERROR_OTHER;
}
return exitCode;
}
}
}

Просмотреть файл

@ -1,19 +1,19 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

Просмотреть файл

@ -1,112 +1,112 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Amqp;
using Amqp.Framing;
using Amqp.Types;
namespace Interop.Server
{
class Server
{
//
// Return message as string.
//
static String GetContent(Message msg)
{
object body = msg.Body;
return body == null ? null : body.ToString();
}
//
// Sample invocation: Interop.Server amqp://guest:guest@localhost:5672
//
static int Main(string[] args)
{
String url = "amqp://guest:guest@127.0.0.1:5672";
String requestQueueName = "service_queue";
if (args.Length > 0)
url = args[0];
Connection.DisableServerCertValidation = true;
// uncomment the following to write frame traces
//Trace.TraceLevel = TraceLevel.Frame;
//Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
Connection connection = null;
try
{
Address address = new Address(url);
connection = new Connection(address);
Session session = new Session(connection);
// Create server receiver link
// When messages arrive, reply to them
ReceiverLink receiver = new ReceiverLink(session, "Interop.Server-receiver", requestQueueName);
int linkId = 0;
while (true)
{
Message request = receiver.Receive();
if (null != request)
{
receiver.Accept(request);
String replyTo = request.Properties.ReplyTo;
SenderLink sender = new SenderLink(session, "Interop.Server-sender-" + (++linkId).ToString(), replyTo);
Message response = new Message(GetContent(request).ToUpper());
response.Properties = new Properties() { CorrelationId = request.Properties.MessageId };
try
{
sender.Send(response, 10000);
}
catch (Exception exception)
{
Console.WriteLine("Error waiting for response to be sent: {0} exception {1}",
GetContent(response), exception.Message);
break;
}
sender.Close();
Console.WriteLine("Processed request: {0} -> {1}",
GetContent(request), GetContent(response));
}
else
{
// timed out waiting for request. This is normal.
Console.WriteLine("Timeout waiting for request. Keep waiting...");
}
}
}
catch (Exception e)
{
Console.WriteLine("Exception {0}.", e);
if (null != connection)
{
connection.Close();
}
}
return 1;
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Amqp;
using Amqp.Framing;
using Amqp.Types;
namespace Interop.Server
{
class Server
{
//
// Return message as string.
//
static String GetContent(Message msg)
{
object body = msg.Body;
return body == null ? null : body.ToString();
}
//
// Sample invocation: Interop.Server amqp://guest:guest@localhost:5672
//
static int Main(string[] args)
{
String url = "amqp://guest:guest@127.0.0.1:5672";
String requestQueueName = "service_queue";
if (args.Length > 0)
url = args[0];
Connection.DisableServerCertValidation = true;
// uncomment the following to write frame traces
//Trace.TraceLevel = TraceLevel.Frame;
//Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
Connection connection = null;
try
{
Address address = new Address(url);
connection = new Connection(address);
Session session = new Session(connection);
// Create server receiver link
// When messages arrive, reply to them
ReceiverLink receiver = new ReceiverLink(session, "Interop.Server-receiver", requestQueueName);
int linkId = 0;
while (true)
{
Message request = receiver.Receive();
if (null != request)
{
receiver.Accept(request);
String replyTo = request.Properties.ReplyTo;
SenderLink sender = new SenderLink(session, "Interop.Server-sender-" + (++linkId).ToString(), replyTo);
Message response = new Message(GetContent(request).ToUpper());
response.Properties = new Properties() { CorrelationId = request.Properties.MessageId };
try
{
sender.Send(response, 10000);
}
catch (Exception exception)
{
Console.WriteLine("Error waiting for response to be sent: {0} exception {1}",
GetContent(response), exception.Message);
break;
}
sender.Close();
Console.WriteLine("Processed request: {0} -> {1}",
GetContent(request), GetContent(response));
}
else
{
// timed out waiting for request. This is normal.
Console.WriteLine("Timeout waiting for request. Keep waiting...");
}
}
}
catch (Exception e)
{
Console.WriteLine("Exception {0}.", e);
if (null != connection)
{
connection.Close();
}
}
return 1;
}
}
}

Просмотреть файл

@ -1,20 +1,20 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

Просмотреть файл

@ -1,20 +1,20 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Examples.Interop
{
using System;

Просмотреть файл

@ -1,19 +1,19 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System;
using System.Collections;

Просмотреть файл

@ -1,19 +1,19 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

Просмотреть файл

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

Просмотреть файл

@ -1,97 +1,97 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace PeerToPeer.Client
{
using System;
using Amqp;
using Amqp.Framing;
class Program
{
static void Main(string[] args)
{
string address = "amqp://guest:guest@127.0.0.1:5672";
if (args.Length > 0)
{
address = args[0];
}
// uncomment the following to write frame traces
//Trace.TraceLevel = TraceLevel.Frame;
//Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
Console.WriteLine("Running message client...");
RunMessageClient(address);
Console.WriteLine("Running request client...");
RunRequestClient(address);
}
static void RunMessageClient(string address)
{
const int nMsgs = 10;
Connection connection = new Connection(new Address(address));
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "message-client", "message_processor");
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message("hello");
message.Properties = new Properties() { MessageId = "msg" + i };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
sender.Send(message);
Console.WriteLine("Sent message {0} body {1}", message.Properties, message.Body);
}
sender.Close();
session.Close();
connection.Close();
}
static void RunRequestClient(string address)
{
Connection connection = new Connection(new Address(address));
Session session = new Session(connection);
string replyTo = "client-reply-to";
Attach recvAttach = new Attach()
{
Source = new Source() { Address = "request_processor" },
Target = new Target() { Address = replyTo }
};
ReceiverLink receiver = new ReceiverLink(session, "request-client-receiver", recvAttach, null);
SenderLink sender = new SenderLink(session, "request-client-sender", "request_processor");
Message request = new Message("hello");
request.Properties = new Properties() { MessageId = "request1", ReplyTo = replyTo };
sender.Send(request, null, null);
Console.WriteLine("Sent request {0} body {1}", request.Properties, request.Body);
Message response = receiver.Receive();
Console.WriteLine("Received response: {0} body {1}", response.Properties, response.Body);
receiver.Accept(response);
receiver.Close();
sender.Close();
session.Close();
connection.Close();
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace PeerToPeer.Client
{
using System;
using Amqp;
using Amqp.Framing;
class Program
{
static void Main(string[] args)
{
string address = "amqp://guest:guest@127.0.0.1:5672";
if (args.Length > 0)
{
address = args[0];
}
// uncomment the following to write frame traces
//Trace.TraceLevel = TraceLevel.Frame;
//Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
Console.WriteLine("Running message client...");
RunMessageClient(address);
Console.WriteLine("Running request client...");
RunRequestClient(address);
}
static void RunMessageClient(string address)
{
const int nMsgs = 10;
Connection connection = new Connection(new Address(address));
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "message-client", "message_processor");
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message("hello");
message.Properties = new Properties() { MessageId = "msg" + i };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
sender.Send(message);
Console.WriteLine("Sent message {0} body {1}", message.Properties, message.Body);
}
sender.Close();
session.Close();
connection.Close();
}
static void RunRequestClient(string address)
{
Connection connection = new Connection(new Address(address));
Session session = new Session(connection);
string replyTo = "client-reply-to";
Attach recvAttach = new Attach()
{
Source = new Source() { Address = "request_processor" },
Target = new Target() { Address = replyTo }
};
ReceiverLink receiver = new ReceiverLink(session, "request-client-receiver", recvAttach, null);
SenderLink sender = new SenderLink(session, "request-client-sender", "request_processor");
Message request = new Message("hello");
request.Properties = new Properties() { MessageId = "request1", ReplyTo = replyTo };
sender.Send(request, null, null);
Console.WriteLine("Sent request {0} body {1}", request.Properties, request.Body);
Message response = receiver.Receive();
Console.WriteLine("Received response: {0} body {1}", response.Properties, response.Body);
receiver.Accept(response);
receiver.Close();
sender.Close();
session.Close();
connection.Close();
}
}
}

Просмотреть файл

@ -1,36 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("PeerToPeer.Client")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PeerToPeer.Client")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3f7eff2d-c9f0-4131-a5f2-09167b969c02")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("PeerToPeer.Client")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PeerToPeer.Client")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3f7eff2d-c9f0-4131-a5f2-09167b969c02")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

Просмотреть файл

@ -1,91 +1,91 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace PeerToPeer.Server
{
using System;
using Amqp;
using Amqp.Listener;
class Program
{
static void Main(string[] args)
{
string address = "amqp://guest:guest@127.0.0.1:5672";
if (args.Length > 0)
{
address = args[0];
}
// uncomment the following to write frame traces
//Trace.TraceLevel = TraceLevel.Frame;
//Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
Uri addressUri = new Uri(address);
ContainerHost host = new ContainerHost(new Uri[] { addressUri }, null, addressUri.UserInfo);
host.Open();
Console.WriteLine("Container host is listening on {0}:{1}", addressUri.Host, addressUri.Port);
string messageProcessor = "message_processor";
host.RegisterMessageProcessor(messageProcessor, new MessageProcessor());
Console.WriteLine("Message processor is registered on {0}", messageProcessor);
string requestProcessor = "request_processor";
host.RegisterRequestProcessor(requestProcessor, new RequestProcessor());
Console.WriteLine("Request processor is registered on {0}", requestProcessor);
Console.WriteLine("Press enter key to exist...");
Console.ReadLine();
host.Close();
}
static void PrintMessage(Message message)
{
if (message.Header != null) Console.WriteLine(message.Header.ToString());
if (message.DeliveryAnnotations != null) Console.WriteLine(message.DeliveryAnnotations.ToString());
if (message.MessageAnnotations != null) Console.WriteLine(message.MessageAnnotations.ToString());
if (message.Properties != null) Console.WriteLine(message.Properties.ToString());
if (message.ApplicationProperties != null) Console.WriteLine(message.ApplicationProperties.ToString());
if (message.BodySection != null) Console.WriteLine("body:{0}", message.Body.ToString());
if (message.Footer != null) Console.WriteLine(message.Footer.ToString());
}
class MessageProcessor : IMessageProcessor
{
void IMessageProcessor.Process(MessageContext messageContext)
{
Console.WriteLine("Received a message.");
PrintMessage(messageContext.Message);
messageContext.Complete();
}
}
class RequestProcessor : IRequestProcessor
{
void IRequestProcessor.Process(RequestContext requestContext)
{
Console.WriteLine("Received a request.");
PrintMessage(requestContext.Message);
Message response = new Message("welcome");
requestContext.Complete(response);
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace PeerToPeer.Server
{
using System;
using Amqp;
using Amqp.Listener;
class Program
{
static void Main(string[] args)
{
string address = "amqp://guest:guest@127.0.0.1:5672";
if (args.Length > 0)
{
address = args[0];
}
// uncomment the following to write frame traces
//Trace.TraceLevel = TraceLevel.Frame;
//Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
Uri addressUri = new Uri(address);
ContainerHost host = new ContainerHost(new Uri[] { addressUri }, null, addressUri.UserInfo);
host.Open();
Console.WriteLine("Container host is listening on {0}:{1}", addressUri.Host, addressUri.Port);
string messageProcessor = "message_processor";
host.RegisterMessageProcessor(messageProcessor, new MessageProcessor());
Console.WriteLine("Message processor is registered on {0}", messageProcessor);
string requestProcessor = "request_processor";
host.RegisterRequestProcessor(requestProcessor, new RequestProcessor());
Console.WriteLine("Request processor is registered on {0}", requestProcessor);
Console.WriteLine("Press enter key to exist...");
Console.ReadLine();
host.Close();
}
static void PrintMessage(Message message)
{
if (message.Header != null) Console.WriteLine(message.Header.ToString());
if (message.DeliveryAnnotations != null) Console.WriteLine(message.DeliveryAnnotations.ToString());
if (message.MessageAnnotations != null) Console.WriteLine(message.MessageAnnotations.ToString());
if (message.Properties != null) Console.WriteLine(message.Properties.ToString());
if (message.ApplicationProperties != null) Console.WriteLine(message.ApplicationProperties.ToString());
if (message.BodySection != null) Console.WriteLine("body:{0}", message.Body.ToString());
if (message.Footer != null) Console.WriteLine(message.Footer.ToString());
}
class MessageProcessor : IMessageProcessor
{
void IMessageProcessor.Process(MessageContext messageContext)
{
Console.WriteLine("Received a message.");
PrintMessage(messageContext.Message);
messageContext.Complete();
}
}
class RequestProcessor : IRequestProcessor
{
void IRequestProcessor.Process(RequestContext requestContext)
{
Console.WriteLine("Received a request.");
PrintMessage(requestContext.Message);
Message response = new Message("welcome");
requestContext.Complete(response);
}
}
}
}

Просмотреть файл

@ -1,53 +1,53 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("PeerToPeer.Server")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PeerToPeer.Server")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6f6acc29-cc77-42cd-8ed4-c3407b36f323")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("PeerToPeer.Server")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PeerToPeer.Server")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6f6acc29-cc77-42cd-8ed4-c3407b36f323")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

Просмотреть файл

@ -1,155 +1,155 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace ServiceBus.Cbs
{
using System;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Amqp;
using Amqp.Framing;
using Amqp.Sasl;
class Program
{
// update the following with valid Service Bus namespace and SAS key info
const string sbNamespace = "contoso.servicebus.windows.net";
const string keyName = "key1";
const string keyValue = "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=";
const string entity = "q1";
static void Main(string[] args)
{
Trace.TraceLevel = TraceLevel.Information;
Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
try
{
RunSampleAsync().Wait();
}
catch (Exception e)
{
Trace.WriteLine(TraceLevel.Error, e.ToString());
}
}
static async Task RunSampleAsync()
{
ConnectionFactory factory = new ConnectionFactory();
factory.SASL.Profile = SaslProfile.External;
Trace.WriteLine(TraceLevel.Information, "Establishing a connection...");
Address address = new Address(sbNamespace, 5671, null, null, "/", "amqps");
var connection = await factory.CreateAsync(address);
// before any operation can be performed, a token must be put to the $cbs node
Trace.WriteLine(TraceLevel.Information, "Putting a token to the $cbs node...");
await PutTokenAsync(connection);
Trace.WriteLine(TraceLevel.Information, "Sending a message...");
var session = new Session(connection);
var sender = new SenderLink(session, "ServiceBus.Cbs:sender-link", entity);
await sender.SendAsync(new Message("test"));
await sender.CloseAsync();
Trace.WriteLine(TraceLevel.Information, "Receiving the message back...");
var receiver = new ReceiverLink(session, "ServiceBus.Cbs:receiver-link", entity);
var message = await receiver.ReceiveAsync();
receiver.Accept(message);
await receiver.CloseAsync();
Trace.WriteLine(TraceLevel.Information, "Closing the connection...");
await session.CloseAsync();
await connection.CloseAsync();
}
static async Task PutTokenAsync(Connection connection)
{
var session = new Session(connection);
string cbsClientAddress = "cbs-client-reply-to";
var cbsSender = new SenderLink(session, "cbs-sender", "$cbs");
var receiverAttach = new Attach()
{
Source = new Source() { Address = "$cbs" },
Target = new Target() { Address = cbsClientAddress }
};
var cbsReceiver = new ReceiverLink(session, "cbs-receiver", receiverAttach, null);
var sasToken = GetSASToken(keyName, keyValue, string.Format("http://{0}/{1}", sbNamespace, entity), TimeSpan.FromMinutes(20));
Trace.WriteLine(TraceLevel.Information, " sas token: {0}", sasToken);
// construct the put-token message
var request = new Message(sasToken);
request.Properties = new Properties();
request.Properties.MessageId = "1";
request.Properties.ReplyTo = cbsClientAddress;
request.ApplicationProperties = new ApplicationProperties();
request.ApplicationProperties["operation"] = "put-token";
request.ApplicationProperties["type"] = "servicebus.windows.net:sastoken";
request.ApplicationProperties["name"] = string.Format("amqp://{0}/{1}", sbNamespace, entity);
await cbsSender.SendAsync(request);
Trace.WriteLine(TraceLevel.Information, " request: {0}", request.Properties);
Trace.WriteLine(TraceLevel.Information, " request: {0}", request.ApplicationProperties);
// receive the response
var response = await cbsReceiver.ReceiveAsync();
if (response == null || response.Properties == null || response.ApplicationProperties == null)
{
throw new Exception("invalid response received");
}
// validate message properties and status code.
Trace.WriteLine(TraceLevel.Information, " response: {0}", response.Properties);
Trace.WriteLine(TraceLevel.Information, " response: {0}", response.ApplicationProperties);
int statusCode = (int)response.ApplicationProperties["status-code"];
if (statusCode != (int)HttpStatusCode.Accepted && statusCode != (int)HttpStatusCode.OK)
{
throw new Exception("put-token message was not accepted. Error code: " + statusCode);
}
// the sender/receiver may be kept open for refreshing tokens
await cbsSender.CloseAsync();
await cbsReceiver.CloseAsync();
await session.CloseAsync();
}
static string GetSASToken(string keyName, string keyValue, string requestUri, TimeSpan ttl)
{
// http://msdn.microsoft.com/en-us/library/azure/dn170477.aspx
// the canonical Uri scheme is http because the token is not amqp specific
// signature is computed from joined encoded request Uri string and expiry string
string expiry = ((long)((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)) + ttl).TotalSeconds).ToString();
string encodedUri = HttpUtility.UrlEncode(requestUri);
string sig;
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(keyValue)))
{
sig = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(encodedUri + "\n" + expiry)));
}
return string.Format(
"SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}",
HttpUtility.UrlEncode(sig),
HttpUtility.UrlEncode(expiry),
HttpUtility.UrlEncode(keyName),
encodedUri);
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace ServiceBus.Cbs
{
using System;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Amqp;
using Amqp.Framing;
using Amqp.Sasl;
class Program
{
// update the following with valid Service Bus namespace and SAS key info
const string sbNamespace = "contoso.servicebus.windows.net";
const string keyName = "key1";
const string keyValue = "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=";
const string entity = "q1";
static void Main(string[] args)
{
Trace.TraceLevel = TraceLevel.Information;
Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
try
{
RunSampleAsync().Wait();
}
catch (Exception e)
{
Trace.WriteLine(TraceLevel.Error, e.ToString());
}
}
static async Task RunSampleAsync()
{
ConnectionFactory factory = new ConnectionFactory();
factory.SASL.Profile = SaslProfile.External;
Trace.WriteLine(TraceLevel.Information, "Establishing a connection...");
Address address = new Address(sbNamespace, 5671, null, null, "/", "amqps");
var connection = await factory.CreateAsync(address);
// before any operation can be performed, a token must be put to the $cbs node
Trace.WriteLine(TraceLevel.Information, "Putting a token to the $cbs node...");
await PutTokenAsync(connection);
Trace.WriteLine(TraceLevel.Information, "Sending a message...");
var session = new Session(connection);
var sender = new SenderLink(session, "ServiceBus.Cbs:sender-link", entity);
await sender.SendAsync(new Message("test"));
await sender.CloseAsync();
Trace.WriteLine(TraceLevel.Information, "Receiving the message back...");
var receiver = new ReceiverLink(session, "ServiceBus.Cbs:receiver-link", entity);
var message = await receiver.ReceiveAsync();
receiver.Accept(message);
await receiver.CloseAsync();
Trace.WriteLine(TraceLevel.Information, "Closing the connection...");
await session.CloseAsync();
await connection.CloseAsync();
}
static async Task PutTokenAsync(Connection connection)
{
var session = new Session(connection);
string cbsClientAddress = "cbs-client-reply-to";
var cbsSender = new SenderLink(session, "cbs-sender", "$cbs");
var receiverAttach = new Attach()
{
Source = new Source() { Address = "$cbs" },
Target = new Target() { Address = cbsClientAddress }
};
var cbsReceiver = new ReceiverLink(session, "cbs-receiver", receiverAttach, null);
var sasToken = GetSASToken(keyName, keyValue, string.Format("http://{0}/{1}", sbNamespace, entity), TimeSpan.FromMinutes(20));
Trace.WriteLine(TraceLevel.Information, " sas token: {0}", sasToken);
// construct the put-token message
var request = new Message(sasToken);
request.Properties = new Properties();
request.Properties.MessageId = "1";
request.Properties.ReplyTo = cbsClientAddress;
request.ApplicationProperties = new ApplicationProperties();
request.ApplicationProperties["operation"] = "put-token";
request.ApplicationProperties["type"] = "servicebus.windows.net:sastoken";
request.ApplicationProperties["name"] = string.Format("amqp://{0}/{1}", sbNamespace, entity);
await cbsSender.SendAsync(request);
Trace.WriteLine(TraceLevel.Information, " request: {0}", request.Properties);
Trace.WriteLine(TraceLevel.Information, " request: {0}", request.ApplicationProperties);
// receive the response
var response = await cbsReceiver.ReceiveAsync();
if (response == null || response.Properties == null || response.ApplicationProperties == null)
{
throw new Exception("invalid response received");
}
// validate message properties and status code.
Trace.WriteLine(TraceLevel.Information, " response: {0}", response.Properties);
Trace.WriteLine(TraceLevel.Information, " response: {0}", response.ApplicationProperties);
int statusCode = (int)response.ApplicationProperties["status-code"];
if (statusCode != (int)HttpStatusCode.Accepted && statusCode != (int)HttpStatusCode.OK)
{
throw new Exception("put-token message was not accepted. Error code: " + statusCode);
}
// the sender/receiver may be kept open for refreshing tokens
await cbsSender.CloseAsync();
await cbsReceiver.CloseAsync();
await session.CloseAsync();
}
static string GetSASToken(string keyName, string keyValue, string requestUri, TimeSpan ttl)
{
// http://msdn.microsoft.com/en-us/library/azure/dn170477.aspx
// the canonical Uri scheme is http because the token is not amqp specific
// signature is computed from joined encoded request Uri string and expiry string
string expiry = ((long)((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)) + ttl).TotalSeconds).ToString();
string encodedUri = HttpUtility.UrlEncode(requestUri);
string sig;
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(keyValue)))
{
sig = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(encodedUri + "\n" + expiry)));
}
return string.Format(
"SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}",
HttpUtility.UrlEncode(sig),
HttpUtility.UrlEncode(expiry),
HttpUtility.UrlEncode(keyName),
encodedUri);
}
}
}

Просмотреть файл

@ -1,53 +1,53 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ServiceBus.Cbs")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ServiceBus.Cbs")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("33911019-52fc-47ca-b8e0-2d34c1ac2c84")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ServiceBus.Cbs")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ServiceBus.Cbs")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("33911019-52fc-47ca-b8e0-2d34c1ac2c84")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

660
amqp.sln
Просмотреть файл

@ -1,330 +1,330 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetMF42", "src\Amqp.NetMF42.csproj", "{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.WP", "src\Amqp.WP.csproj", "{CD477EDC-5779-44CD-ABE9-330F1C6531D9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.NetMF42", "test\Test.Amqp.NetMF\Test.Amqp.NetMF42.csproj", "{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Store", "src\Amqp.Store.csproj", "{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.Net", "test\Test.Amqp.Net\Test.Amqp.Net.csproj", "{06CAA70A-20A7-4334-AF03-D6228039C178}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{679989B2-8717-4ECC-9CAD-B104CFA91C38}"
ProjectSection(SolutionItems) = preProject
Amqp.Net.nuspec = Amqp.Net.nuspec
build.cmd = build.cmd
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Net", "src\Amqp.Net.csproj", "{92153715-1D99-43B1-B291-470CF91A156D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetCF39", "src\Amqp.NetCF39.csproj", "{994D25B3-A2C4-4A27-A0E8-3203E954BF58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.NetCF39", "test\Test.Amqp.NetCF39\Test.Amqp.NetCF39.csproj", "{187E608C-FBF4-4517-B61F-A85AFF5BCA75}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetMF43", "src\Amqp.NetMF43.csproj", "{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.NetMF43", "test\Test.Amqp.NetMF\Test.Amqp.NetMF43.csproj", "{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{8F701234-EC60-485C-BCDB-8EE233246832}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Drain", "Examples\Interop\Interop.Drain\Interop.Drain.csproj", "{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Spout", "Examples\Interop\Interop.Spout\Interop.Spout.csproj", "{68470436-2F0D-4A76-B1E6-9C8517844C3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAmqpBroker", "test\TestAmqpBroker\TestAmqpBroker.csproj", "{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Server", "Examples\Interop\Interop.Server\Interop.Server.csproj", "{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Client", "Examples\Interop\Interop.Client\Interop.Client.csproj", "{C272B10E-36BE-4F36-A128-331F715514E6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ServiceBus", "ServiceBus", "{4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBus.Cbs", "Examples\ServiceBus\ServiceBus.Cbs\ServiceBus.Cbs.csproj", "{4681C268-36DB-4838-BD21-9EC9A8363269}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PeerToPeer", "PeerToPeer", "{7FF80B2D-4158-41D3-BC87-60C018028F53}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.Server", "Examples\PeerToPeer\PeerToPeer.Server\PeerToPeer.Server.csproj", "{24C152B0-3813-43C6-82DD-8BB601642F6C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.Client", "Examples\PeerToPeer\PeerToPeer.Client\PeerToPeer.Client.csproj", "{8FC90E46-024B-4089-9590-A7E8C2B092BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Net35", "src\Amqp.Net35.csproj", "{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Device", "Device", "{BF554E12-7096-465F-B1D0-9ACFF00877F2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Device.Thermometer", "Examples\Device\Device.Thermometer\Device.Thermometer.csproj", "{43570F0D-DE6C-423E-A275-AC619A813B79}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Device.Controller", "Examples\Device\Device.Controller\Device.Controller.csproj", "{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|x64.ActiveCfg = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|x86.ActiveCfg = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|Any CPU.Build.0 = Release|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|ARM.ActiveCfg = Release|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|x64.ActiveCfg = Release|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|x86.ActiveCfg = Release|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|ARM.ActiveCfg = Debug|ARM
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|ARM.Build.0 = Debug|ARM
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|x64.ActiveCfg = Debug|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|x86.ActiveCfg = Debug|x86
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|x86.Build.0 = Debug|x86
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|Any CPU.Build.0 = Release|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|ARM.ActiveCfg = Release|ARM
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|ARM.Build.0 = Release|ARM
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|x64.ActiveCfg = Release|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|x86.ActiveCfg = Release|x86
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|x86.Build.0 = Release|x86
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|x64.ActiveCfg = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|x86.ActiveCfg = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|Any CPU.Build.0 = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|Any CPU.Deploy.0 = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|ARM.ActiveCfg = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|x64.ActiveCfg = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|x86.ActiveCfg = Release|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|ARM.ActiveCfg = Debug|ARM
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|ARM.Build.0 = Debug|ARM
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|x64.ActiveCfg = Debug|x64
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|x64.Build.0 = Debug|x64
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|x86.ActiveCfg = Debug|x86
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|x86.Build.0 = Debug|x86
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|Any CPU.Build.0 = Release|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|ARM.ActiveCfg = Release|ARM
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|ARM.Build.0 = Release|ARM
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|x64.ActiveCfg = Release|x64
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|x64.Build.0 = Release|x64
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|x86.ActiveCfg = Release|x86
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|x86.Build.0 = Release|x86
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|Any CPU.Build.0 = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|ARM.ActiveCfg = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|x64.ActiveCfg = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|x86.ActiveCfg = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|Any CPU.ActiveCfg = Release|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|Any CPU.Build.0 = Release|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|ARM.ActiveCfg = Release|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|x64.ActiveCfg = Release|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|x86.ActiveCfg = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|x64.ActiveCfg = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|x86.ActiveCfg = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|Any CPU.Build.0 = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|ARM.ActiveCfg = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|x64.ActiveCfg = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|x86.ActiveCfg = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|ARM.ActiveCfg = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|x64.ActiveCfg = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|x86.ActiveCfg = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|Any CPU.Build.0 = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|ARM.ActiveCfg = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|x64.ActiveCfg = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|x86.ActiveCfg = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|ARM.ActiveCfg = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|x64.ActiveCfg = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|x86.ActiveCfg = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|Any CPU.Build.0 = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|Any CPU.Deploy.0 = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|ARM.ActiveCfg = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|x64.ActiveCfg = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|x86.ActiveCfg = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|x64.ActiveCfg = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|x86.ActiveCfg = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|Any CPU.Build.0 = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|ARM.ActiveCfg = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|x64.ActiveCfg = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|x86.ActiveCfg = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x64.ActiveCfg = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x86.ActiveCfg = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.Build.0 = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.Deploy.0 = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|ARM.ActiveCfg = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x64.ActiveCfg = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x86.ActiveCfg = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|x64.ActiveCfg = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|Any CPU.Build.0 = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|ARM.ActiveCfg = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|x64.ActiveCfg = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|x86.ActiveCfg = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|x64.ActiveCfg = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|x86.ActiveCfg = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|Any CPU.Build.0 = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|ARM.ActiveCfg = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|x64.ActiveCfg = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|x86.ActiveCfg = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|x64.ActiveCfg = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|x86.ActiveCfg = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|Any CPU.Build.0 = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|ARM.ActiveCfg = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|x64.ActiveCfg = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|x86.ActiveCfg = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|ARM.ActiveCfg = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|x64.ActiveCfg = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|x86.ActiveCfg = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|Any CPU.Build.0 = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|ARM.ActiveCfg = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|x64.ActiveCfg = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|x86.ActiveCfg = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|x64.ActiveCfg = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|x86.ActiveCfg = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|Any CPU.Build.0 = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|ARM.ActiveCfg = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|x64.ActiveCfg = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|x86.ActiveCfg = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|x64.ActiveCfg = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|x86.ActiveCfg = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|Any CPU.Build.0 = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|ARM.ActiveCfg = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|x64.ActiveCfg = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|x86.ActiveCfg = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|ARM.ActiveCfg = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|x64.ActiveCfg = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|x86.ActiveCfg = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|Any CPU.Build.0 = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|ARM.ActiveCfg = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|x64.ActiveCfg = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|x86.ActiveCfg = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|x64.ActiveCfg = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|x86.ActiveCfg = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|Any CPU.Build.0 = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|ARM.ActiveCfg = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|x64.ActiveCfg = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|x86.ActiveCfg = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|x64.ActiveCfg = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|x86.ActiveCfg = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|Any CPU.Build.0 = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|ARM.ActiveCfg = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|x64.ActiveCfg = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|x86.ActiveCfg = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|ARM.ActiveCfg = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|x64.ActiveCfg = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|x86.ActiveCfg = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.Build.0 = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.Deploy.0 = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|ARM.ActiveCfg = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|x64.ActiveCfg = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|x86.ActiveCfg = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|ARM.ActiveCfg = Debug|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|ARM.Build.0 = Debug|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|ARM.Deploy.0 = Debug|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|x64.ActiveCfg = Debug|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|x86.ActiveCfg = Debug|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|x86.Build.0 = Debug|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|x86.Deploy.0 = Debug|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|Any CPU.Build.0 = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|Any CPU.Deploy.0 = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|ARM.ActiveCfg = Release|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|ARM.Build.0 = Release|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|ARM.Deploy.0 = Release|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|x64.ActiveCfg = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|x86.ActiveCfg = Release|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|x86.Build.0 = Release|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05} = {8F701234-EC60-485C-BCDB-8EE233246832}
{4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56} = {8F701234-EC60-485C-BCDB-8EE233246832}
{7FF80B2D-4158-41D3-BC87-60C018028F53} = {8F701234-EC60-485C-BCDB-8EE233246832}
{BF554E12-7096-465F-B1D0-9ACFF00877F2} = {8F701234-EC60-485C-BCDB-8EE233246832}
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
{68470436-2F0D-4A76-B1E6-9C8517844C3E} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
{C272B10E-36BE-4F36-A128-331F715514E6} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
{4681C268-36DB-4838-BD21-9EC9A8363269} = {4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}
{24C152B0-3813-43C6-82DD-8BB601642F6C} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
{8FC90E46-024B-4089-9590-A7E8C2B092BE} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
{43570F0D-DE6C-423E-A275-AC619A813B79} = {BF554E12-7096-465F-B1D0-9ACFF00877F2}
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7} = {BF554E12-7096-465F-B1D0-9ACFF00877F2}
EndGlobalSection
EndGlobal
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetMF42", "src\Amqp.NetMF42.csproj", "{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.WP", "src\Amqp.WP.csproj", "{CD477EDC-5779-44CD-ABE9-330F1C6531D9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.NetMF42", "test\Test.Amqp.NetMF\Test.Amqp.NetMF42.csproj", "{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Store", "src\Amqp.Store.csproj", "{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.Net", "test\Test.Amqp.Net\Test.Amqp.Net.csproj", "{06CAA70A-20A7-4334-AF03-D6228039C178}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{679989B2-8717-4ECC-9CAD-B104CFA91C38}"
ProjectSection(SolutionItems) = preProject
Amqp.Net.nuspec = Amqp.Net.nuspec
build.cmd = build.cmd
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Net", "src\Amqp.Net.csproj", "{92153715-1D99-43B1-B291-470CF91A156D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetCF39", "src\Amqp.NetCF39.csproj", "{994D25B3-A2C4-4A27-A0E8-3203E954BF58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.NetCF39", "test\Test.Amqp.NetCF39\Test.Amqp.NetCF39.csproj", "{187E608C-FBF4-4517-B61F-A85AFF5BCA75}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetMF43", "src\Amqp.NetMF43.csproj", "{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.NetMF43", "test\Test.Amqp.NetMF\Test.Amqp.NetMF43.csproj", "{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{8F701234-EC60-485C-BCDB-8EE233246832}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Drain", "Examples\Interop\Interop.Drain\Interop.Drain.csproj", "{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Spout", "Examples\Interop\Interop.Spout\Interop.Spout.csproj", "{68470436-2F0D-4A76-B1E6-9C8517844C3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAmqpBroker", "test\TestAmqpBroker\TestAmqpBroker.csproj", "{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Server", "Examples\Interop\Interop.Server\Interop.Server.csproj", "{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Client", "Examples\Interop\Interop.Client\Interop.Client.csproj", "{C272B10E-36BE-4F36-A128-331F715514E6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ServiceBus", "ServiceBus", "{4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBus.Cbs", "Examples\ServiceBus\ServiceBus.Cbs\ServiceBus.Cbs.csproj", "{4681C268-36DB-4838-BD21-9EC9A8363269}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PeerToPeer", "PeerToPeer", "{7FF80B2D-4158-41D3-BC87-60C018028F53}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.Server", "Examples\PeerToPeer\PeerToPeer.Server\PeerToPeer.Server.csproj", "{24C152B0-3813-43C6-82DD-8BB601642F6C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.Client", "Examples\PeerToPeer\PeerToPeer.Client\PeerToPeer.Client.csproj", "{8FC90E46-024B-4089-9590-A7E8C2B092BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Net35", "src\Amqp.Net35.csproj", "{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Device", "Device", "{BF554E12-7096-465F-B1D0-9ACFF00877F2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Device.Thermometer", "Examples\Device\Device.Thermometer\Device.Thermometer.csproj", "{43570F0D-DE6C-423E-A275-AC619A813B79}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Device.Controller", "Examples\Device\Device.Controller\Device.Controller.csproj", "{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|x64.ActiveCfg = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|x86.ActiveCfg = Debug|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|Any CPU.Build.0 = Release|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|ARM.ActiveCfg = Release|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|x64.ActiveCfg = Release|Any CPU
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|x86.ActiveCfg = Release|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|ARM.ActiveCfg = Debug|ARM
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|ARM.Build.0 = Debug|ARM
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|x64.ActiveCfg = Debug|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|x86.ActiveCfg = Debug|x86
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Debug|x86.Build.0 = Debug|x86
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|Any CPU.Build.0 = Release|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|ARM.ActiveCfg = Release|ARM
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|ARM.Build.0 = Release|ARM
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|x64.ActiveCfg = Release|Any CPU
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|x86.ActiveCfg = Release|x86
{CD477EDC-5779-44CD-ABE9-330F1C6531D9}.Release|x86.Build.0 = Release|x86
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|x64.ActiveCfg = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Debug|x86.ActiveCfg = Debug|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|Any CPU.Build.0 = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|Any CPU.Deploy.0 = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|ARM.ActiveCfg = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|x64.ActiveCfg = Release|Any CPU
{E0B13B0F-C739-4788-BC47-A6BEAF6FB5A6}.Release|x86.ActiveCfg = Release|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|ARM.ActiveCfg = Debug|ARM
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|ARM.Build.0 = Debug|ARM
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|x64.ActiveCfg = Debug|x64
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|x64.Build.0 = Debug|x64
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|x86.ActiveCfg = Debug|x86
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Debug|x86.Build.0 = Debug|x86
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|Any CPU.Build.0 = Release|Any CPU
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|ARM.ActiveCfg = Release|ARM
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|ARM.Build.0 = Release|ARM
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|x64.ActiveCfg = Release|x64
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|x64.Build.0 = Release|x64
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|x86.ActiveCfg = Release|x86
{647AAC43-DC4A-47F0-8C07-E0DA2C312B30}.Release|x86.Build.0 = Release|x86
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|Any CPU.Build.0 = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|ARM.ActiveCfg = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|x64.ActiveCfg = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|x86.ActiveCfg = Debug|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|Any CPU.ActiveCfg = Release|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|Any CPU.Build.0 = Release|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|ARM.ActiveCfg = Release|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|x64.ActiveCfg = Release|Any CPU
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|x86.ActiveCfg = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|x64.ActiveCfg = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|x86.ActiveCfg = Debug|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|Any CPU.Build.0 = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|ARM.ActiveCfg = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|x64.ActiveCfg = Release|Any CPU
{92153715-1D99-43B1-B291-470CF91A156D}.Release|x86.ActiveCfg = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|ARM.ActiveCfg = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|x64.ActiveCfg = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Debug|x86.ActiveCfg = Debug|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|Any CPU.Build.0 = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|ARM.ActiveCfg = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|x64.ActiveCfg = Release|Any CPU
{994D25B3-A2C4-4A27-A0E8-3203E954BF58}.Release|x86.ActiveCfg = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|ARM.ActiveCfg = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|x64.ActiveCfg = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Debug|x86.ActiveCfg = Debug|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|Any CPU.Build.0 = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|Any CPU.Deploy.0 = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|ARM.ActiveCfg = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|x64.ActiveCfg = Release|Any CPU
{187E608C-FBF4-4517-B61F-A85AFF5BCA75}.Release|x86.ActiveCfg = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|x64.ActiveCfg = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|x86.ActiveCfg = Debug|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|Any CPU.Build.0 = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|ARM.ActiveCfg = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|x64.ActiveCfg = Release|Any CPU
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|x86.ActiveCfg = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x64.ActiveCfg = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x86.ActiveCfg = Debug|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.Build.0 = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.Deploy.0 = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|ARM.ActiveCfg = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x64.ActiveCfg = Release|Any CPU
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x86.ActiveCfg = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|x64.ActiveCfg = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|Any CPU.Build.0 = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|ARM.ActiveCfg = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|x64.ActiveCfg = Release|Any CPU
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|x86.ActiveCfg = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|x64.ActiveCfg = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|x86.ActiveCfg = Debug|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|Any CPU.Build.0 = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|ARM.ActiveCfg = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|x64.ActiveCfg = Release|Any CPU
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|x86.ActiveCfg = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|x64.ActiveCfg = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|x86.ActiveCfg = Debug|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|Any CPU.Build.0 = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|ARM.ActiveCfg = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|x64.ActiveCfg = Release|Any CPU
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|x86.ActiveCfg = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|ARM.ActiveCfg = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|x64.ActiveCfg = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|x86.ActiveCfg = Debug|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|Any CPU.Build.0 = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|ARM.ActiveCfg = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|x64.ActiveCfg = Release|Any CPU
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|x86.ActiveCfg = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|x64.ActiveCfg = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|x86.ActiveCfg = Debug|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|Any CPU.Build.0 = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|ARM.ActiveCfg = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|x64.ActiveCfg = Release|Any CPU
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|x86.ActiveCfg = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|x64.ActiveCfg = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|x86.ActiveCfg = Debug|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|Any CPU.Build.0 = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|ARM.ActiveCfg = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|x64.ActiveCfg = Release|Any CPU
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|x86.ActiveCfg = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|ARM.ActiveCfg = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|x64.ActiveCfg = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|x86.ActiveCfg = Debug|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|Any CPU.Build.0 = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|ARM.ActiveCfg = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|x64.ActiveCfg = Release|Any CPU
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|x86.ActiveCfg = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|x64.ActiveCfg = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|x86.ActiveCfg = Debug|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|Any CPU.Build.0 = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|ARM.ActiveCfg = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|x64.ActiveCfg = Release|Any CPU
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|x86.ActiveCfg = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|x64.ActiveCfg = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|x86.ActiveCfg = Debug|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|Any CPU.Build.0 = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|ARM.ActiveCfg = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|x64.ActiveCfg = Release|Any CPU
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|x86.ActiveCfg = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|ARM.ActiveCfg = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|x64.ActiveCfg = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|x86.ActiveCfg = Debug|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.Build.0 = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.Deploy.0 = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|ARM.ActiveCfg = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|x64.ActiveCfg = Release|Any CPU
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|x86.ActiveCfg = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|ARM.ActiveCfg = Debug|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|ARM.Build.0 = Debug|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|ARM.Deploy.0 = Debug|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|x64.ActiveCfg = Debug|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|x86.ActiveCfg = Debug|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|x86.Build.0 = Debug|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Debug|x86.Deploy.0 = Debug|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|Any CPU.Build.0 = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|Any CPU.Deploy.0 = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|ARM.ActiveCfg = Release|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|ARM.Build.0 = Release|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|ARM.Deploy.0 = Release|ARM
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|x64.ActiveCfg = Release|Any CPU
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|x86.ActiveCfg = Release|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|x86.Build.0 = Release|x86
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05} = {8F701234-EC60-485C-BCDB-8EE233246832}
{4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56} = {8F701234-EC60-485C-BCDB-8EE233246832}
{7FF80B2D-4158-41D3-BC87-60C018028F53} = {8F701234-EC60-485C-BCDB-8EE233246832}
{BF554E12-7096-465F-B1D0-9ACFF00877F2} = {8F701234-EC60-485C-BCDB-8EE233246832}
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
{68470436-2F0D-4A76-B1E6-9C8517844C3E} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
{C272B10E-36BE-4F36-A128-331F715514E6} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
{4681C268-36DB-4838-BD21-9EC9A8363269} = {4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}
{24C152B0-3813-43C6-82DD-8BB601642F6C} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
{8FC90E46-024B-4089-9590-A7E8C2B092BE} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
{43570F0D-DE6C-423E-A275-AC619A813B79} = {BF554E12-7096-465F-B1D0-9ACFF00877F2}
{23F5A590-C6D6-4FF7-A787-5AEE6A9522A7} = {BF554E12-7096-465F-B1D0-9ACFF00877F2}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -1,251 +1,251 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using Amqp.Types;
public sealed class Address
{
internal const string Amqp = "AMQP";
internal const string Amqps = "AMQPS";
const int AmqpPort = 5672;
const int AmqpsPort = 5671;
public Address(string address)
{
this.Port = -1;
this.Parse(address);
this.SetDefault();
}
public Address(string host, int port, string user = null, string password = null, string path = "/", string scheme = Amqps)
{
this.Host = host;
this.Port = port;
this.Path = path;
this.Scheme = scheme;
this.User = user;
this.Password = password;
this.SetDefault();
}
public string Scheme
{
get;
private set;
}
public bool UseSsl
{
get;
private set;
}
public string Host
{
get;
private set;
}
public int Port
{
get;
private set;
}
public string User
{
get;
private set;
}
public string Password
{
get;
private set;
}
public string Path
{
get;
private set;
}
enum ParseState
{
Scheme,
Slash1,
Slash2,
User,
Password,
Host,
Port,
Path
}
void Parse(string address)
{
// amqp[s]://user:password@a.contoso.com:port/foo/bar
ParseState state = ParseState.Scheme;
int startIndex = 0;
for (int i = 0; i < address.Length; ++i)
{
switch (address[i])
{
case ':':
if (state == ParseState.Scheme)
{
this.Scheme = address.Substring(startIndex, i - startIndex);
state = ParseState.Slash1;
}
else if (state == ParseState.User)
{
this.User = address.Substring(startIndex, i - startIndex);
state = ParseState.Password;
startIndex = i + 1;
}
else if (state == ParseState.Host)
{
this.Host = address.Substring(startIndex, i - startIndex);
state = ParseState.Port;
startIndex = i + 1;
}
else
{
throw new AmqpException(ErrorCode.InvalidField,
Fx.Format(SRAmqp.InvalidAddressFormat));
}
break;
case '/':
if (state == ParseState.Slash1)
{
state = ParseState.Slash2;
}
else if (state == ParseState.Slash2)
{
state = ParseState.User;
startIndex = i + 1;
}
else if (state == ParseState.User || state == ParseState.Host)
{
this.Host = address.Substring(startIndex, i - startIndex);
state = ParseState.Path;
startIndex = i;
}
else if (state == ParseState.Port)
{
this.Port = int.Parse(address.Substring(startIndex, i - startIndex));
state = ParseState.Path;
startIndex = i;
}
else if (state == ParseState.Password)
{
this.Host = this.User;
this.User = null;
this.Port = int.Parse(address.Substring(startIndex, i - startIndex));
state = ParseState.Path;
startIndex = i;
}
break;
case '@':
if (state == ParseState.Password)
{
this.Password = address.Substring(startIndex, i - startIndex);
state = ParseState.Host;
startIndex = i + 1;
}
else
{
throw new AmqpException(ErrorCode.InvalidField,
Fx.Format(SRAmqp.InvalidAddressFormat));
}
break;
default:
break;
}
if (state == ParseState.Path)
{
this.Path = address.Substring(startIndex);
break;
}
}
// check state in case of no trailing slash
if (state == ParseState.User || state == ParseState.Host)
{
this.Host = address.Substring(startIndex);
}
else if (state == ParseState.Password)
{
this.Host = this.User;
this.User = null;
if (startIndex < address.Length - 1)
{
this.Port = int.Parse(address.Substring(startIndex));
}
}
else if (state == ParseState.Port)
{
this.Port = int.Parse(address.Substring(startIndex));
}
if (this.Password != null && this.Password.Length > 0)
{
this.Password = Uri.UnescapeDataString(this.Password);
}
if (this.User != null && this.User.Length > 0)
{
this.User = Uri.UnescapeDataString(this.User);
}
if (this.Host != null)
{
this.Host = Uri.UnescapeDataString(this.Host);
}
}
void SetDefault()
{
string schemeUpper = this.Scheme.ToUpper();
if (schemeUpper == Amqps)
{
this.UseSsl = true;
}
if (this.Port == -1)
{
if (this.UseSsl)
{
this.Port = AmqpsPort;
}
else if (schemeUpper == Amqp)
{
this.Port = AmqpPort;
}
}
if (this.Path == null)
{
this.Path = "/";
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using Amqp.Types;
public sealed class Address
{
internal const string Amqp = "AMQP";
internal const string Amqps = "AMQPS";
const int AmqpPort = 5672;
const int AmqpsPort = 5671;
public Address(string address)
{
this.Port = -1;
this.Parse(address);
this.SetDefault();
}
public Address(string host, int port, string user = null, string password = null, string path = "/", string scheme = Amqps)
{
this.Host = host;
this.Port = port;
this.Path = path;
this.Scheme = scheme;
this.User = user;
this.Password = password;
this.SetDefault();
}
public string Scheme
{
get;
private set;
}
public bool UseSsl
{
get;
private set;
}
public string Host
{
get;
private set;
}
public int Port
{
get;
private set;
}
public string User
{
get;
private set;
}
public string Password
{
get;
private set;
}
public string Path
{
get;
private set;
}
enum ParseState
{
Scheme,
Slash1,
Slash2,
User,
Password,
Host,
Port,
Path
}
void Parse(string address)
{
// amqp[s]://user:password@a.contoso.com:port/foo/bar
ParseState state = ParseState.Scheme;
int startIndex = 0;
for (int i = 0; i < address.Length; ++i)
{
switch (address[i])
{
case ':':
if (state == ParseState.Scheme)
{
this.Scheme = address.Substring(startIndex, i - startIndex);
state = ParseState.Slash1;
}
else if (state == ParseState.User)
{
this.User = address.Substring(startIndex, i - startIndex);
state = ParseState.Password;
startIndex = i + 1;
}
else if (state == ParseState.Host)
{
this.Host = address.Substring(startIndex, i - startIndex);
state = ParseState.Port;
startIndex = i + 1;
}
else
{
throw new AmqpException(ErrorCode.InvalidField,
Fx.Format(SRAmqp.InvalidAddressFormat));
}
break;
case '/':
if (state == ParseState.Slash1)
{
state = ParseState.Slash2;
}
else if (state == ParseState.Slash2)
{
state = ParseState.User;
startIndex = i + 1;
}
else if (state == ParseState.User || state == ParseState.Host)
{
this.Host = address.Substring(startIndex, i - startIndex);
state = ParseState.Path;
startIndex = i;
}
else if (state == ParseState.Port)
{
this.Port = int.Parse(address.Substring(startIndex, i - startIndex));
state = ParseState.Path;
startIndex = i;
}
else if (state == ParseState.Password)
{
this.Host = this.User;
this.User = null;
this.Port = int.Parse(address.Substring(startIndex, i - startIndex));
state = ParseState.Path;
startIndex = i;
}
break;
case '@':
if (state == ParseState.Password)
{
this.Password = address.Substring(startIndex, i - startIndex);
state = ParseState.Host;
startIndex = i + 1;
}
else
{
throw new AmqpException(ErrorCode.InvalidField,
Fx.Format(SRAmqp.InvalidAddressFormat));
}
break;
default:
break;
}
if (state == ParseState.Path)
{
this.Path = address.Substring(startIndex);
break;
}
}
// check state in case of no trailing slash
if (state == ParseState.User || state == ParseState.Host)
{
this.Host = address.Substring(startIndex);
}
else if (state == ParseState.Password)
{
this.Host = this.User;
this.User = null;
if (startIndex < address.Length - 1)
{
this.Port = int.Parse(address.Substring(startIndex));
}
}
else if (state == ParseState.Port)
{
this.Port = int.Parse(address.Substring(startIndex));
}
if (this.Password != null && this.Password.Length > 0)
{
this.Password = Uri.UnescapeDataString(this.Password);
}
if (this.User != null && this.User.Length > 0)
{
this.User = Uri.UnescapeDataString(this.User);
}
if (this.Host != null)
{
this.Host = Uri.UnescapeDataString(this.Host);
}
}
void SetDefault()
{
string schemeUpper = this.Scheme.ToUpper();
if (schemeUpper == Amqps)
{
this.UseSsl = true;
}
if (this.Port == -1)
{
if (this.UseSsl)
{
this.Port = AmqpsPort;
}
else if (schemeUpper == Amqp)
{
this.Port = AmqpPort;
}
}
if (this.Path == null)
{
this.Path = "/";
}
}
}
}

Просмотреть файл

@ -1,42 +1,42 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using Amqp.Framing;
public sealed class AmqpException : Exception
{
public AmqpException(Error error)
: base(error.Description ?? error.Condition)
{
this.Error = error;
}
public AmqpException(string condition, string description)
: this(new Error() { Condition = condition, Description = description })
{
}
public Error Error
{
get;
private set;
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using Amqp.Framing;
public sealed class AmqpException : Exception
{
public AmqpException(Error error)
: base(error.Description ?? error.Condition)
{
this.Error = error;
}
public AmqpException(string condition, string description)
: this(new Error() { Condition = condition, Description = description })
{
}
public Error Error
{
get;
private set;
}
}
}

Просмотреть файл

@ -31,8 +31,8 @@ namespace Amqp
{
get;
set;
}
}
protected void NotifyClosed(Error error)
{
ManualResetEvent temp = this.endEvent;
@ -49,20 +49,20 @@ namespace Amqp
}
public void Close(int waitUntilEnded = DefaultCloseTimeout, Error error = null)
{
// initialize event first to avoid the race with NotifyClosed
this.endEvent = new ManualResetEvent(false);
if (!this.OnClose(error))
{
if (waitUntilEnded > 0)
{
this.endEvent.WaitOne(waitUntilEnded, false);
}
}
else
{
this.endEvent.Set();
this.NotifyClosed(null);
{
// initialize event first to avoid the race with NotifyClosed
this.endEvent = new ManualResetEvent(false);
if (!this.OnClose(error))
{
if (waitUntilEnded > 0)
{
this.endEvent.WaitOne(waitUntilEnded, false);
}
}
else
{
this.endEvent.Set();
this.NotifyClosed(null);
}
}

Просмотреть файл

@ -41,7 +41,7 @@ namespace Amqp
int end;
bool autoGrow;
public ByteBuffer(byte[] buffer, int offset, int count, int capacity)
public ByteBuffer(byte[] buffer, int offset, int count, int capacity)
: this(buffer, offset, count, capacity, false)
{
}
@ -49,14 +49,14 @@ namespace Amqp
public ByteBuffer(int size, bool autoGrow)
: this(new byte[size], 0, 0, size, autoGrow)
{
}
}
ByteBuffer(byte[] buffer, int offset, int count, int capacity, bool autoGrow)
{
this.buffer = buffer;
this.start = offset;
this.read = offset;
this.write = offset + count;
this.write = offset + count;
this.end = offset + capacity;
this.autoGrow = autoGrow;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -24,12 +24,12 @@ namespace Amqp.Framing
public ApplicationProperties()
: base(Codec.ApplicationProperties, typeof(string))
{
}
#if TRACE
public override string ToString()
{
return "app-properties:" + base.ToString();
}
#if TRACE
public override string ToString()
{
return "app-properties:" + base.ToString();
}
#endif
}

Просмотреть файл

@ -24,13 +24,13 @@ namespace Amqp.Framing
public DeliveryAnnotations()
: base(Codec.DeliveryAnnotations, typeof(Symbol))
{
}
#if TRACE
public override string ToString()
{
return "delivery-annotations:" + base.ToString();
}
#endif
}
#if TRACE
public override string ToString()
{
return "delivery-annotations:" + base.ToString();
}
#endif
}
}

Просмотреть файл

@ -1,57 +1,57 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Framing
{
using Amqp.Types;
public sealed class Error : DescribedList
{
public Error()
: base(Codec.Error, 3)
{
}
public Symbol Condition
{
get { return (Symbol)this.Fields[0]; }
set { this.Fields[0] = value; }
}
public string Description
{
get { return (string)this.Fields[1]; }
set { this.Fields[1] = value; }
}
public Fields Info
{
get { return Amqp.Types.Fields.From(this.Fields, 2); }
set { this.Fields[2] = value; }
}
#if TRACE
public override string ToString()
{
return this.GetDebugString(
"error",
new object[] { "condition", "description", "fields" },
this.Fields);
}
#endif
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Framing
{
using Amqp.Types;
public sealed class Error : DescribedList
{
public Error()
: base(Codec.Error, 3)
{
}
public Symbol Condition
{
get { return (Symbol)this.Fields[0]; }
set { this.Fields[0] = value; }
}
public string Description
{
get { return (string)this.Fields[1]; }
set { this.Fields[1] = value; }
}
public Fields Info
{
get { return Amqp.Types.Fields.From(this.Fields, 2); }
set { this.Fields[2] = value; }
}
#if TRACE
public override string ToString()
{
return this.GetDebugString(
"error",
new object[] { "condition", "description", "fields" },
this.Fields);
}
#endif
}
}

Просмотреть файл

@ -92,7 +92,7 @@ namespace Amqp.Framing
}
public Fields Properties
{
{
get { return Amqp.Types.Fields.From(this.Fields, 10); }
set { this.Fields[10] = value; }
}

Просмотреть файл

@ -25,13 +25,13 @@ namespace Amqp.Framing
public Footer()
: base(Codec.Footer, typeof(Symbol))
{
}
#if TRACE
public override string ToString()
{
return "footer:" + base.ToString();
}
#endif
}
#if TRACE
public override string ToString()
{
return "footer:" + base.ToString();
}
#endif
}
}

Просмотреть файл

@ -1,100 +1,100 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Framing
{
using System;
using Amqp.Types;
enum FrameType : byte
{
Amqp = 0,
Sasl = 1
}
static class Frame
{
const byte DOF = 2;
const int cmdBufferSize = 128;
public static ByteBuffer Encode(FrameType type, ushort channel, DescribedList command)
{
ByteBuffer buffer = new ByteBuffer(cmdBufferSize, true);
EncodeFrame(buffer, type, channel, command);
AmqpBitConverter.WriteInt(buffer.Buffer, 0, buffer.Length);
return buffer;
}
public static ByteBuffer Encode(FrameType type, ushort channel, Transfer transfer,
ByteBuffer payload, int maxFrameSize, out int payloadSize)
{
int bufferSize = cmdBufferSize + payload.Length;
if (bufferSize > maxFrameSize)
{
bufferSize = maxFrameSize;
}
bool more = false; // estimate it first
if (payload.Length > bufferSize - 32)
{
transfer.More = more = true;
}
ByteBuffer buffer = new ByteBuffer(bufferSize, false);
EncodeFrame(buffer, type, channel, transfer);
if (more && payload.Length <= buffer.Size)
{
// guessed it wrong. correct it
transfer.More = false;
buffer.Reset();
EncodeFrame(buffer, type, channel, transfer);
}
payloadSize = Math.Min(payload.Length, buffer.Size);
AmqpBitConverter.WriteBytes(buffer, payload.Buffer, payload.Offset, payloadSize);
payload.Complete(payloadSize);
AmqpBitConverter.WriteInt(buffer.Buffer, 0, buffer.Length);
return buffer;
}
public static void GetFrame(ByteBuffer buffer, out ushort channel, out DescribedList command)
{
AmqpBitConverter.ReadUInt(buffer);
AmqpBitConverter.ReadUByte(buffer);
AmqpBitConverter.ReadUByte(buffer);
channel = AmqpBitConverter.ReadUShort(buffer);
if (buffer.Length > 0)
{
command = (DescribedList)Codec.Decode(buffer);
}
else
{
command = null;
}
}
static void EncodeFrame(ByteBuffer buffer, FrameType type, ushort channel, DescribedList command)
{
AmqpBitConverter.WriteUInt(buffer, 0u);
AmqpBitConverter.WriteUByte(buffer, DOF);
AmqpBitConverter.WriteUByte(buffer, (byte)type);
AmqpBitConverter.WriteUShort(buffer, channel);
Codec.Encode(command, buffer);
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Framing
{
using System;
using Amqp.Types;
enum FrameType : byte
{
Amqp = 0,
Sasl = 1
}
static class Frame
{
const byte DOF = 2;
const int cmdBufferSize = 128;
public static ByteBuffer Encode(FrameType type, ushort channel, DescribedList command)
{
ByteBuffer buffer = new ByteBuffer(cmdBufferSize, true);
EncodeFrame(buffer, type, channel, command);
AmqpBitConverter.WriteInt(buffer.Buffer, 0, buffer.Length);
return buffer;
}
public static ByteBuffer Encode(FrameType type, ushort channel, Transfer transfer,
ByteBuffer payload, int maxFrameSize, out int payloadSize)
{
int bufferSize = cmdBufferSize + payload.Length;
if (bufferSize > maxFrameSize)
{
bufferSize = maxFrameSize;
}
bool more = false; // estimate it first
if (payload.Length > bufferSize - 32)
{
transfer.More = more = true;
}
ByteBuffer buffer = new ByteBuffer(bufferSize, false);
EncodeFrame(buffer, type, channel, transfer);
if (more && payload.Length <= buffer.Size)
{
// guessed it wrong. correct it
transfer.More = false;
buffer.Reset();
EncodeFrame(buffer, type, channel, transfer);
}
payloadSize = Math.Min(payload.Length, buffer.Size);
AmqpBitConverter.WriteBytes(buffer, payload.Buffer, payload.Offset, payloadSize);
payload.Complete(payloadSize);
AmqpBitConverter.WriteInt(buffer.Buffer, 0, buffer.Length);
return buffer;
}
public static void GetFrame(ByteBuffer buffer, out ushort channel, out DescribedList command)
{
AmqpBitConverter.ReadUInt(buffer);
AmqpBitConverter.ReadUByte(buffer);
AmqpBitConverter.ReadUByte(buffer);
channel = AmqpBitConverter.ReadUShort(buffer);
if (buffer.Length > 0)
{
command = (DescribedList)Codec.Decode(buffer);
}
else
{
command = null;
}
}
static void EncodeFrame(ByteBuffer buffer, FrameType type, ushort channel, DescribedList command)
{
AmqpBitConverter.WriteUInt(buffer, 0u);
AmqpBitConverter.WriteUByte(buffer, DOF);
AmqpBitConverter.WriteUByte(buffer, (byte)type);
AmqpBitConverter.WriteUShort(buffer, channel);
Codec.Encode(command, buffer);
}
}
}

Просмотреть файл

@ -24,13 +24,13 @@ namespace Amqp.Framing
public MessageAnnotations()
: base(Codec.MessageAnnotations, typeof(Symbol))
{
}
#if TRACE
public override string ToString()
{
return "msg-annotations:" + base.ToString();
}
#endif
}
#if TRACE
public override string ToString()
{
return "msg-annotations:" + base.ToString();
}
#endif
}
}

Просмотреть файл

@ -16,36 +16,36 @@
// ------------------------------------------------------------------------------------
namespace Amqp.Framing
{
{
using Amqp.Types;
struct ProtocolHeader
{
{
public byte Id;
public byte Major;
public byte Minor;
public byte Revision;
public static ProtocolHeader Create(byte[] buffer, int offset)
{
if (buffer[offset + 0] != (byte)'A' ||
buffer[offset + 1] != (byte)'M' ||
buffer[offset + 2] != (byte)'Q' ||
buffer[offset + 3] != (byte)'P')
{
throw new AmqpException(ErrorCode.InvalidField, "ProtocolName");
}
return new ProtocolHeader()
{
Id = buffer[offset + 4],
Major = buffer[offset + 5],
Minor = buffer[offset + 6],
Revision = buffer[offset + 7]
};
public byte Revision;
public static ProtocolHeader Create(byte[] buffer, int offset)
{
if (buffer[offset + 0] != (byte)'A' ||
buffer[offset + 1] != (byte)'M' ||
buffer[offset + 2] != (byte)'Q' ||
buffer[offset + 3] != (byte)'P')
{
throw new AmqpException(ErrorCode.InvalidField, "ProtocolName");
}
return new ProtocolHeader()
{
Id = buffer[offset + 4],
Major = buffer[offset + 5],
Minor = buffer[offset + 6],
Revision = buffer[offset + 7]
};
}
#if TRACE

Просмотреть файл

@ -30,7 +30,7 @@ namespace Amqp.Framing
throw new ObjectDisposedException(transport.GetType().Name);
}
return ProtocolHeader.Create(smallBuffer, 0);
return ProtocolHeader.Create(smallBuffer, 0);
}
public static ByteBuffer ReadFrameBuffer(ITransport transport, byte[] sizeBuffer, uint maxFrameSize)

Просмотреть файл

@ -1,32 +1,32 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
public interface ITransport
{
// if transport supports async write, it should perform async write with queued buffers
void Send(ByteBuffer buffer);
// this is called from the pump thread, so blocking is fine
int Receive(byte[] buffer, int offset, int count);
void Close();
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
public interface ITransport
{
// if transport supports async write, it should perform async write with queued buffers
void Send(ByteBuffer buffer);
// this is called from the pump thread, so blocking is fine
int Receive(byte[] buffer, int offset, int count);
void Close();
}
}

Просмотреть файл

@ -1,217 +1,217 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Threading;
using Amqp.Framing;
using Amqp.Types;
public delegate void OnAttached(Link link, Attach attach);
public abstract class Link : AmqpObject
{
enum State
{
Start,
AttachSent,
AttachReceived,
Attached,
DetachPipe,
DetachSent,
DetachReceived,
End
}
readonly Session session;
readonly string name;
readonly uint handle;
readonly OnAttached onAttached;
State state;
protected Link(Session session, string name, OnAttached onAttached)
{
this.session = session;
this.name = name;
this.onAttached = onAttached;
this.handle = session.AddLink(this);
this.state = State.Start;
}
public string Name
{
get { return this.name; }
}
public uint Handle
{
get { return this.handle; }
}
internal Session Session
{
get { return this.session; }
}
protected object ThisLock
{
get { return this; }
}
protected bool IsDetaching
{
get { return this.state >= State.DetachPipe; }
}
internal void Abort(Error error)
{
this.OnAbort(error);
if (this.state != State.End)
{
this.state = State.End;
this.NotifyClosed(error);
}
}
internal virtual void OnAttach(uint remoteHandle, Attach attach)
{
lock (this.ThisLock)
{
if (this.state == State.AttachSent)
{
this.state = State.Attached;
}
else if (this.state == State.DetachPipe)
{
this.state = State.DetachSent;
}
else
{
throw new AmqpException(ErrorCode.IllegalState,
Fx.Format(SRAmqp.AmqpIllegalOperationState, "OnAttach", this.state));
}
}
if (this.onAttached != null && attach.Target != null && attach.Source != null)
{
this.onAttached(this, attach);
}
}
internal bool OnDetach(Detach detach)
{
lock (this.ThisLock)
{
if (this.state == State.DetachSent)
{
this.state = State.End;
}
else if (this.state == State.Attached)
{
this.SendDetach(null);
this.state = State.End;
}
else
{
throw new AmqpException(ErrorCode.IllegalState,
Fx.Format(SRAmqp.AmqpIllegalOperationState, "OnDetach", this.state));
}
this.OnClose(detach.Error);
this.NotifyClosed(detach.Error);
return true;
}
}
internal abstract void OnFlow(Flow flow);
internal abstract void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer);
internal abstract void OnDeliveryStateChanged(Delivery delivery);
protected abstract void OnAbort(Error error);
protected override bool OnClose(Error error)
{
lock (this.ThisLock)
{
if (this.state == State.End)
{
return true;
}
else if (this.state == State.AttachSent)
{
this.state = State.DetachPipe;
}
else if (this.state == State.Attached)
{
this.state = State.DetachSent;
}
else if (this.state == State.DetachReceived)
{
this.state = State.End;
}
else
{
throw new AmqpException(ErrorCode.IllegalState,
Fx.Format(SRAmqp.AmqpIllegalOperationState, "Close", this.state));
}
this.SendDetach(error);
return this.state == State.End;
}
}
protected void SendFlow(uint deliveryCount, uint credit)
{
Flow flow = new Flow() { Handle = this.handle, DeliveryCount = deliveryCount, LinkCredit = credit };
this.session.SendFlow(flow);
}
protected void SendAttach(bool role, uint initialDeliveryCount, Attach attach)
{
Fx.Assert(this.state == State.Start, "state must be Start");
this.state = State.AttachSent;
attach.LinkName = this.name;
attach.Handle = this.handle;
attach.Role = role;
if (!role)
{
attach.InitialDeliveryCount = initialDeliveryCount;
}
this.session.SendCommand(attach);
}
protected void ThrowIfDetaching(string operation)
{
if (this.IsDetaching)
{
throw new AmqpException(ErrorCode.IllegalState,
Fx.Format(SRAmqp.AmqpIllegalOperationState, operation, this.state));
}
}
void SendDetach(Error error)
{
Detach detach = new Detach() { Handle = this.handle, Error = error, Closed = true };
this.session.SendCommand(detach);
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Threading;
using Amqp.Framing;
using Amqp.Types;
public delegate void OnAttached(Link link, Attach attach);
public abstract class Link : AmqpObject
{
enum State
{
Start,
AttachSent,
AttachReceived,
Attached,
DetachPipe,
DetachSent,
DetachReceived,
End
}
readonly Session session;
readonly string name;
readonly uint handle;
readonly OnAttached onAttached;
State state;
protected Link(Session session, string name, OnAttached onAttached)
{
this.session = session;
this.name = name;
this.onAttached = onAttached;
this.handle = session.AddLink(this);
this.state = State.Start;
}
public string Name
{
get { return this.name; }
}
public uint Handle
{
get { return this.handle; }
}
internal Session Session
{
get { return this.session; }
}
protected object ThisLock
{
get { return this; }
}
protected bool IsDetaching
{
get { return this.state >= State.DetachPipe; }
}
internal void Abort(Error error)
{
this.OnAbort(error);
if (this.state != State.End)
{
this.state = State.End;
this.NotifyClosed(error);
}
}
internal virtual void OnAttach(uint remoteHandle, Attach attach)
{
lock (this.ThisLock)
{
if (this.state == State.AttachSent)
{
this.state = State.Attached;
}
else if (this.state == State.DetachPipe)
{
this.state = State.DetachSent;
}
else
{
throw new AmqpException(ErrorCode.IllegalState,
Fx.Format(SRAmqp.AmqpIllegalOperationState, "OnAttach", this.state));
}
}
if (this.onAttached != null && attach.Target != null && attach.Source != null)
{
this.onAttached(this, attach);
}
}
internal bool OnDetach(Detach detach)
{
lock (this.ThisLock)
{
if (this.state == State.DetachSent)
{
this.state = State.End;
}
else if (this.state == State.Attached)
{
this.SendDetach(null);
this.state = State.End;
}
else
{
throw new AmqpException(ErrorCode.IllegalState,
Fx.Format(SRAmqp.AmqpIllegalOperationState, "OnDetach", this.state));
}
this.OnClose(detach.Error);
this.NotifyClosed(detach.Error);
return true;
}
}
internal abstract void OnFlow(Flow flow);
internal abstract void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer);
internal abstract void OnDeliveryStateChanged(Delivery delivery);
protected abstract void OnAbort(Error error);
protected override bool OnClose(Error error)
{
lock (this.ThisLock)
{
if (this.state == State.End)
{
return true;
}
else if (this.state == State.AttachSent)
{
this.state = State.DetachPipe;
}
else if (this.state == State.Attached)
{
this.state = State.DetachSent;
}
else if (this.state == State.DetachReceived)
{
this.state = State.End;
}
else
{
throw new AmqpException(ErrorCode.IllegalState,
Fx.Format(SRAmqp.AmqpIllegalOperationState, "Close", this.state));
}
this.SendDetach(error);
return this.state == State.End;
}
}
protected void SendFlow(uint deliveryCount, uint credit)
{
Flow flow = new Flow() { Handle = this.handle, DeliveryCount = deliveryCount, LinkCredit = credit };
this.session.SendFlow(flow);
}
protected void SendAttach(bool role, uint initialDeliveryCount, Attach attach)
{
Fx.Assert(this.state == State.Start, "state must be Start");
this.state = State.AttachSent;
attach.LinkName = this.name;
attach.Handle = this.handle;
attach.Role = role;
if (!role)
{
attach.InitialDeliveryCount = initialDeliveryCount;
}
this.session.SendCommand(attach);
}
protected void ThrowIfDetaching(string operation)
{
if (this.IsDetaching)
{
throw new AmqpException(ErrorCode.IllegalState,
Fx.Format(SRAmqp.AmqpIllegalOperationState, operation, this.state));
}
}
void SendDetach(Error error)
{
Detach detach = new Detach() { Handle = this.handle, Error = error, Closed = true };
this.session.SendCommand(detach);
}
}
}

Просмотреть файл

@ -1,345 +1,345 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using Amqp.Framing;
using Amqp.Types;
public class ContainerHost : IContainer
{
readonly X509Certificate2 certificate;
readonly ConnectionListener[] listeners;
readonly Dictionary<string, MessageProcessor> messageProcessors;
readonly Dictionary<string, RequestProcessor> requestProcessors;
public ContainerHost(Uri addressUri)
: this(new Uri[] { addressUri }, null, null)
{
}
public ContainerHost(IList<Uri> addressUriList, X509Certificate2 certificate, string userInfo)
{
this.certificate = certificate;
this.messageProcessors = new Dictionary<string, MessageProcessor>(StringComparer.OrdinalIgnoreCase);
this.requestProcessors = new Dictionary<string, RequestProcessor>(StringComparer.OrdinalIgnoreCase);
this.listeners = new ConnectionListener[addressUriList.Count];
for (int i = 0; i < addressUriList.Count; i++)
{
this.listeners[i] = new ConnectionListener(addressUriList[i], userInfo, this);
}
}
public void Open()
{
foreach (var listener in this.listeners)
{
listener.Open();
}
}
public void Close()
{
foreach (var listener in this.listeners)
{
try
{
listener.Close();
}
catch (Exception exception)
{
Trace.WriteLine(TraceLevel.Error, exception.ToString());
}
}
}
public void RegisterMessageProcessor(string address, IMessageProcessor messageProcessor)
{
AddProcessor(this.messageProcessors, address, new MessageProcessor(messageProcessor));
}
public void RegisterRequestProcessor(string address, IRequestProcessor requestProcessor)
{
AddProcessor(this.requestProcessors, address, new RequestProcessor(requestProcessor));
}
public void UnregisterMessageProcessor(string address)
{
RemoveProcessor(this.messageProcessors, address);
}
public void UnregisterRequestProcessor(string address)
{
RemoveProcessor(this.requestProcessors, address);
}
static void AddProcessor<T>(Dictionary<string, T> processors, string address, T processor)
{
lock (processors)
{
if (processors.ContainsKey(address))
{
throw new AmqpException(ErrorCode.NotAllowed, typeof(T).Name + " already registered");
}
processors[address] = processor;
}
}
static void RemoveProcessor<T>(Dictionary<string, T> processors, string address)
{
lock (processors)
{
T processor;
if (processors.TryGetValue(address, out processor))
{
processors.Remove(address);
if (processor is IDisposable)
{
((IDisposable)processor).Dispose();
}
}
}
}
static bool TryGetProcessor<T>(Dictionary<string, T> processors, string address, out T processor)
{
lock (processors)
{
return processors.TryGetValue(address, out processor);
}
}
X509Certificate2 IContainer.ServiceCertificate
{
get { return this.certificate; }
}
Message IContainer.CreateMessage(ByteBuffer buffer)
{
return Message.Decode(buffer);
}
Link IContainer.CreateLink(ListenerConnection connection, ListenerSession session, Attach attach)
{
return new ListenerLink(session, attach);
}
bool IContainer.AttachLink(ListenerConnection connection, ListenerSession session, Link link, Attach attach)
{
string address = attach.Role ? ((Source)attach.Source).Address : ((Target)attach.Target).Address;
var listenerLink = (ListenerLink)link;
MessageProcessor messageProcessor;
if (TryGetProcessor(this.messageProcessors, address, out messageProcessor))
{
messageProcessor.AddLink(listenerLink, address);
return true;
}
RequestProcessor requestProcessor;
if (TryGetProcessor(this.requestProcessors, address, out requestProcessor))
{
requestProcessor.AddLink(listenerLink, address, attach);
return true;
}
throw new AmqpException(ErrorCode.NotFound, "No processor was found at " + address);
}
class MessageProcessor : IDisposable
{
static readonly Action<ListenerLink, Message, DeliveryState, object> dispatchMessage = DispatchMessage;
readonly IMessageProcessor processor;
readonly List<ListenerLink> links;
public MessageProcessor(IMessageProcessor processor)
{
this.processor = processor;
this.links = new List<ListenerLink>();
}
public void AddLink(ListenerLink link, string address)
{
if (!link.Role)
{
throw new AmqpException(ErrorCode.NotAllowed, "Only sender link can be attached at " + address);
}
link.InitializeReceiver(300, dispatchMessage, this);
link.Closed += OnLinkClosed;
lock (this.links)
{
this.links.Add(link);
}
}
static void DispatchMessage(ListenerLink link, Message message, DeliveryState deliveryState, object state)
{
MessageContext context = new MessageContext(link, message);
((MessageProcessor)state).processor.Process(context);
}
static void OnLinkClosed(AmqpObject sender, Error error)
{
ListenerLink link = (ListenerLink)sender;
var thisPtr = (MessageProcessor)link.State;
lock (thisPtr.links)
{
thisPtr.links.Remove(link);
}
}
void IDisposable.Dispose()
{
lock (this.links)
{
for (int i = 0; i < this.links.Count; i++)
{
this.links[i].Close(0, new Error() { Condition = ErrorCode.DetachForced, Description = "Processor was unregistered." });
}
this.links.Clear();
}
}
}
class RequestProcessor : IDisposable
{
static readonly Action<ListenerLink, Message, DeliveryState, object> dispatchRequest = DispatchRequest;
readonly IRequestProcessor processor;
readonly List<ListenerLink> requestLinks;
readonly Dictionary<string, ListenerLink> responseLinks;
public RequestProcessor(IRequestProcessor processor)
{
this.processor = processor;
this.requestLinks = new List<ListenerLink>();
this.responseLinks = new Dictionary<string, ListenerLink>(StringComparer.OrdinalIgnoreCase);
}
public IRequestProcessor Processor
{
get { return this.processor; }
}
public IList<ListenerLink> Links
{
get { return this.requestLinks; }
}
public void AddLink(ListenerLink link, string address, Attach attach)
{
if (!link.Role)
{
string replyTo = ((Target)attach.Target).Address;
AddProcessor(this.responseLinks, replyTo, link);
link.SettleOnSend = true;
link.InitializeSender((c, s) => { }, null, Tuple.Create(this, replyTo));
link.Closed += OnLinkClosed;
}
else
{
link.InitializeReceiver(300, dispatchRequest, this);
link.Closed += OnLinkClosed;
lock (this.requestLinks)
{
this.requestLinks.Add(link);
}
}
}
static void OnLinkClosed(AmqpObject sender, Error error)
{
ListenerLink link = (ListenerLink)sender;
if (!link.Role)
{
var tuple = (Tuple<RequestProcessor, string>)link.State;
RemoveProcessor(tuple.Item1.responseLinks, tuple.Item2);
}
else
{
var thisPtr = (RequestProcessor)link.State;
lock (thisPtr.requestLinks)
{
thisPtr.requestLinks.Remove(link);
}
}
}
static void DispatchRequest(ListenerLink link, Message message, DeliveryState deliveryState, object state)
{
RequestProcessor thisPtr = (RequestProcessor)state;
ListenerLink responseLink = null;
if (message.Properties != null || message.Properties.ReplyTo != null)
{
thisPtr.responseLinks.TryGetValue(message.Properties.ReplyTo, out responseLink);
}
Outcome outcome;
if (responseLink == null)
{
outcome = new Rejected()
{
Error = new Error()
{
Condition = ErrorCode.NotFound,
Description = "Not response link was found. Ensure the link is attached or reply-to is set on the request."
}
};
}
else
{
outcome = new Accepted();
}
link.DisposeMessage(message, outcome, true);
RequestContext context = new RequestContext(link, responseLink, message);
thisPtr.processor.Process(context);
}
void IDisposable.Dispose()
{
Error error = new Error() { Condition = ErrorCode.DetachForced, Description = "Processor was unregistered." };
lock (this.requestLinks)
{
for (int i = 0; i < this.requestLinks.Count; i++)
{
this.requestLinks[i].Close(0, error);
}
this.requestLinks.Clear();
}
lock (this.responseLinks)
{
foreach (var link in this.responseLinks.Values)
{
link.Close(0, error);
}
this.responseLinks.Clear();
}
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using Amqp.Framing;
using Amqp.Types;
public class ContainerHost : IContainer
{
readonly X509Certificate2 certificate;
readonly ConnectionListener[] listeners;
readonly Dictionary<string, MessageProcessor> messageProcessors;
readonly Dictionary<string, RequestProcessor> requestProcessors;
public ContainerHost(Uri addressUri)
: this(new Uri[] { addressUri }, null, null)
{
}
public ContainerHost(IList<Uri> addressUriList, X509Certificate2 certificate, string userInfo)
{
this.certificate = certificate;
this.messageProcessors = new Dictionary<string, MessageProcessor>(StringComparer.OrdinalIgnoreCase);
this.requestProcessors = new Dictionary<string, RequestProcessor>(StringComparer.OrdinalIgnoreCase);
this.listeners = new ConnectionListener[addressUriList.Count];
for (int i = 0; i < addressUriList.Count; i++)
{
this.listeners[i] = new ConnectionListener(addressUriList[i], userInfo, this);
}
}
public void Open()
{
foreach (var listener in this.listeners)
{
listener.Open();
}
}
public void Close()
{
foreach (var listener in this.listeners)
{
try
{
listener.Close();
}
catch (Exception exception)
{
Trace.WriteLine(TraceLevel.Error, exception.ToString());
}
}
}
public void RegisterMessageProcessor(string address, IMessageProcessor messageProcessor)
{
AddProcessor(this.messageProcessors, address, new MessageProcessor(messageProcessor));
}
public void RegisterRequestProcessor(string address, IRequestProcessor requestProcessor)
{
AddProcessor(this.requestProcessors, address, new RequestProcessor(requestProcessor));
}
public void UnregisterMessageProcessor(string address)
{
RemoveProcessor(this.messageProcessors, address);
}
public void UnregisterRequestProcessor(string address)
{
RemoveProcessor(this.requestProcessors, address);
}
static void AddProcessor<T>(Dictionary<string, T> processors, string address, T processor)
{
lock (processors)
{
if (processors.ContainsKey(address))
{
throw new AmqpException(ErrorCode.NotAllowed, typeof(T).Name + " already registered");
}
processors[address] = processor;
}
}
static void RemoveProcessor<T>(Dictionary<string, T> processors, string address)
{
lock (processors)
{
T processor;
if (processors.TryGetValue(address, out processor))
{
processors.Remove(address);
if (processor is IDisposable)
{
((IDisposable)processor).Dispose();
}
}
}
}
static bool TryGetProcessor<T>(Dictionary<string, T> processors, string address, out T processor)
{
lock (processors)
{
return processors.TryGetValue(address, out processor);
}
}
X509Certificate2 IContainer.ServiceCertificate
{
get { return this.certificate; }
}
Message IContainer.CreateMessage(ByteBuffer buffer)
{
return Message.Decode(buffer);
}
Link IContainer.CreateLink(ListenerConnection connection, ListenerSession session, Attach attach)
{
return new ListenerLink(session, attach);
}
bool IContainer.AttachLink(ListenerConnection connection, ListenerSession session, Link link, Attach attach)
{
string address = attach.Role ? ((Source)attach.Source).Address : ((Target)attach.Target).Address;
var listenerLink = (ListenerLink)link;
MessageProcessor messageProcessor;
if (TryGetProcessor(this.messageProcessors, address, out messageProcessor))
{
messageProcessor.AddLink(listenerLink, address);
return true;
}
RequestProcessor requestProcessor;
if (TryGetProcessor(this.requestProcessors, address, out requestProcessor))
{
requestProcessor.AddLink(listenerLink, address, attach);
return true;
}
throw new AmqpException(ErrorCode.NotFound, "No processor was found at " + address);
}
class MessageProcessor : IDisposable
{
static readonly Action<ListenerLink, Message, DeliveryState, object> dispatchMessage = DispatchMessage;
readonly IMessageProcessor processor;
readonly List<ListenerLink> links;
public MessageProcessor(IMessageProcessor processor)
{
this.processor = processor;
this.links = new List<ListenerLink>();
}
public void AddLink(ListenerLink link, string address)
{
if (!link.Role)
{
throw new AmqpException(ErrorCode.NotAllowed, "Only sender link can be attached at " + address);
}
link.InitializeReceiver(300, dispatchMessage, this);
link.Closed += OnLinkClosed;
lock (this.links)
{
this.links.Add(link);
}
}
static void DispatchMessage(ListenerLink link, Message message, DeliveryState deliveryState, object state)
{
MessageContext context = new MessageContext(link, message);
((MessageProcessor)state).processor.Process(context);
}
static void OnLinkClosed(AmqpObject sender, Error error)
{
ListenerLink link = (ListenerLink)sender;
var thisPtr = (MessageProcessor)link.State;
lock (thisPtr.links)
{
thisPtr.links.Remove(link);
}
}
void IDisposable.Dispose()
{
lock (this.links)
{
for (int i = 0; i < this.links.Count; i++)
{
this.links[i].Close(0, new Error() { Condition = ErrorCode.DetachForced, Description = "Processor was unregistered." });
}
this.links.Clear();
}
}
}
class RequestProcessor : IDisposable
{
static readonly Action<ListenerLink, Message, DeliveryState, object> dispatchRequest = DispatchRequest;
readonly IRequestProcessor processor;
readonly List<ListenerLink> requestLinks;
readonly Dictionary<string, ListenerLink> responseLinks;
public RequestProcessor(IRequestProcessor processor)
{
this.processor = processor;
this.requestLinks = new List<ListenerLink>();
this.responseLinks = new Dictionary<string, ListenerLink>(StringComparer.OrdinalIgnoreCase);
}
public IRequestProcessor Processor
{
get { return this.processor; }
}
public IList<ListenerLink> Links
{
get { return this.requestLinks; }
}
public void AddLink(ListenerLink link, string address, Attach attach)
{
if (!link.Role)
{
string replyTo = ((Target)attach.Target).Address;
AddProcessor(this.responseLinks, replyTo, link);
link.SettleOnSend = true;
link.InitializeSender((c, s) => { }, null, Tuple.Create(this, replyTo));
link.Closed += OnLinkClosed;
}
else
{
link.InitializeReceiver(300, dispatchRequest, this);
link.Closed += OnLinkClosed;
lock (this.requestLinks)
{
this.requestLinks.Add(link);
}
}
}
static void OnLinkClosed(AmqpObject sender, Error error)
{
ListenerLink link = (ListenerLink)sender;
if (!link.Role)
{
var tuple = (Tuple<RequestProcessor, string>)link.State;
RemoveProcessor(tuple.Item1.responseLinks, tuple.Item2);
}
else
{
var thisPtr = (RequestProcessor)link.State;
lock (thisPtr.requestLinks)
{
thisPtr.requestLinks.Remove(link);
}
}
}
static void DispatchRequest(ListenerLink link, Message message, DeliveryState deliveryState, object state)
{
RequestProcessor thisPtr = (RequestProcessor)state;
ListenerLink responseLink = null;
if (message.Properties != null || message.Properties.ReplyTo != null)
{
thisPtr.responseLinks.TryGetValue(message.Properties.ReplyTo, out responseLink);
}
Outcome outcome;
if (responseLink == null)
{
outcome = new Rejected()
{
Error = new Error()
{
Condition = ErrorCode.NotFound,
Description = "Not response link was found. Ensure the link is attached or reply-to is set on the request."
}
};
}
else
{
outcome = new Accepted();
}
link.DisposeMessage(message, outcome, true);
RequestContext context = new RequestContext(link, responseLink, message);
thisPtr.processor.Process(context);
}
void IDisposable.Dispose()
{
Error error = new Error() { Condition = ErrorCode.DetachForced, Description = "Processor was unregistered." };
lock (this.requestLinks)
{
for (int i = 0; i < this.requestLinks.Count; i++)
{
this.requestLinks[i].Close(0, error);
}
this.requestLinks.Clear();
}
lock (this.responseLinks)
{
foreach (var link in this.responseLinks.Values)
{
link.Close(0, error);
}
this.responseLinks.Clear();
}
}
}
}
}

Просмотреть файл

@ -1,99 +1,99 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using Amqp.Framing;
public interface IMessageProcessor
{
void Process(MessageContext messageContext);
}
public interface IRequestProcessor
{
void Process(RequestContext requestContext);
}
public abstract class Context
{
protected static Accepted Accepted = new Accepted();
protected Context(ListenerLink link, Message message)
{
this.Link = link;
this.Message = message;
}
public ListenerLink Link
{
get;
private set;
}
public Message Message
{
get;
private set;
}
protected void Dispose(DeliveryState deliveryState)
{
this.Link.DisposeMessage(this.Message, deliveryState, true);
}
}
public class MessageContext : Context
{
internal MessageContext(ListenerLink link, Message message)
: base(link, message)
{
}
public void Complete()
{
this.Dispose(Context.Accepted);
}
public void Complete(Error error)
{
this.Dispose(new Rejected() { Error = error });
}
}
public class RequestContext : Context
{
readonly ListenerLink responseLink;
internal RequestContext(ListenerLink requestLink, ListenerLink responseLink, Message request)
: base(requestLink, request)
{
this.responseLink = responseLink;
}
public void Complete(Message response)
{
if (response.Properties == null)
{
response.Properties = new Properties();
}
response.Properties.CorrelationId = this.Message.Properties.MessageId;
this.responseLink.SendMessage(response, response.Encode());
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using Amqp.Framing;
public interface IMessageProcessor
{
void Process(MessageContext messageContext);
}
public interface IRequestProcessor
{
void Process(RequestContext requestContext);
}
public abstract class Context
{
protected static Accepted Accepted = new Accepted();
protected Context(ListenerLink link, Message message)
{
this.Link = link;
this.Message = message;
}
public ListenerLink Link
{
get;
private set;
}
public Message Message
{
get;
private set;
}
protected void Dispose(DeliveryState deliveryState)
{
this.Link.DisposeMessage(this.Message, deliveryState, true);
}
}
public class MessageContext : Context
{
internal MessageContext(ListenerLink link, Message message)
: base(link, message)
{
}
public void Complete()
{
this.Dispose(Context.Accepted);
}
public void Complete(Error error)
{
this.Dispose(new Rejected() { Error = error });
}
}
public class RequestContext : Context
{
readonly ListenerLink responseLink;
internal RequestContext(ListenerLink requestLink, ListenerLink responseLink, Message request)
: base(requestLink, request)
{
this.responseLink = responseLink;
}
public void Complete(Message response)
{
if (response.Properties == null)
{
response.Properties = new Properties();
}
response.Properties.CorrelationId = this.Message.Properties.MessageId;
this.responseLink.SendMessage(response, response.Encode());
}
}
}

Просмотреть файл

@ -1,33 +1,33 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System.Security.Cryptography.X509Certificates;
using Amqp.Framing;
public interface IContainer
{
X509Certificate2 ServiceCertificate { get; }
Message CreateMessage(ByteBuffer buffer);
Link CreateLink(ListenerConnection connection, ListenerSession session, Attach attach);
bool AttachLink(ListenerConnection connection, ListenerSession session, Link link, Attach attach);
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System.Security.Cryptography.X509Certificates;
using Amqp.Framing;
public interface IContainer
{
X509Certificate2 ServiceCertificate { get; }
Message CreateMessage(ByteBuffer buffer);
Link CreateLink(ListenerConnection connection, ListenerSession session, Attach attach);
bool AttachLink(ListenerConnection connection, ListenerSession session, Link link, Attach attach);
}
}

Просмотреть файл

@ -1,49 +1,49 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System.Threading;
using Amqp.Framing;
public class ListenerConnection : Connection
{
readonly ConnectionListener listener;
internal ListenerConnection(ConnectionListener listener, Address address, IAsyncTransport transport)
: base(listener, address, transport, null, null)
{
this.listener = listener;
}
internal ConnectionListener Listener
{
get { return this.listener; }
}
internal override void OnBegin(ushort remoteChannel, Begin begin)
{
// this sends a begin to the remote peer
begin.RemoteChannel = remoteChannel;
var session = new ListenerSession(this, begin);
// this updates the local session state
begin.RemoteChannel = session.Channel;
base.OnBegin(remoteChannel, begin);
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System.Threading;
using Amqp.Framing;
public class ListenerConnection : Connection
{
readonly ConnectionListener listener;
internal ListenerConnection(ConnectionListener listener, Address address, IAsyncTransport transport)
: base(listener, address, transport, null, null)
{
this.listener = listener;
}
internal ConnectionListener Listener
{
get { return this.listener; }
}
internal override void OnBegin(ushort remoteChannel, Begin begin)
{
// this sends a begin to the remote peer
begin.RemoteChannel = remoteChannel;
var session = new ListenerSession(this, begin);
// this updates the local session state
begin.RemoteChannel = session.Channel;
base.OnBegin(remoteChannel, begin);
}
}
}

Просмотреть файл

@ -1,225 +1,225 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System;
using Amqp.Framing;
using Amqp.Types;
public class ListenerLink : Link
{
bool role;
uint credit;
object state;
// send
Action<int, object> onCredit;
Action<Message, DeliveryState, bool, object> onDispose;
// receive
SequenceNumber deliveryCount;
int delivered;
Delivery deliveryCurrent;
Action<ListenerLink, Message, DeliveryState, object> onMessage;
public ListenerLink(ListenerSession session, Attach attach)
: base(session, attach.LinkName, null)
{
this.role = !attach.Role;
this.SettleOnSend = attach.SndSettleMode == SenderSettleMode.Settled;
}
public bool Role
{
get { return this.role; }
}
public bool SettleOnSend
{
get; internal set;
}
public object State
{
get { return this.state; }
}
public void InitializeReceiver(uint credit, Action<ListenerLink, Message, DeliveryState, object> onMessage, object state)
{
this.credit = credit;
this.onMessage = onMessage;
this.state = state;
}
public void InitializeSender(Action<int, object> onCredit, Action<Message, DeliveryState, bool, object> onDispose, object state)
{
this.onCredit = onCredit;
this.onDispose = onDispose;
this.state = state;
}
public void SendMessage(Message message, ByteBuffer buffer)
{
Delivery delivery = new Delivery()
{
Handle = this.Handle,
Message = message,
Buffer = buffer,
Link = this,
Settled = this.SettleOnSend
};
this.Session.SendDelivery(delivery);
this.deliveryCount++;
}
public void DisposeMessage(Message message, DeliveryState deliveryState, bool settled)
{
Delivery delivery = message.Delivery;
if (delivery == null || delivery.Settled)
{
return;
}
this.Session.DisposeDelivery(this.role, delivery, deliveryState, settled);
}
public void CompleteAttach(Attach attach, Error error)
{
if (error != null)
{
this.SendAttach(!attach.Role, attach.InitialDeliveryCount, new Attach() { Target = null, Source = null });
}
else
{
this.SendAttach(!attach.Role, attach.InitialDeliveryCount, new Attach() { Target = attach.Target, Source = attach.Source });
}
base.OnAttach(attach.Handle, attach);
if (error != null)
{
this.Close(0, error);
}
else
{
if (this.credit > 0)
{
this.SendFlow(this.deliveryCount, credit);
}
}
}
internal override void OnAttach(uint remoteHandle, Attach attach)
{
var container = ((ListenerConnection)this.Session.Connection).Listener.Container;
Error error = null;
try
{
bool done = container.AttachLink((ListenerConnection)this.Session.Connection, (ListenerSession)this.Session, this, attach);
if (!done)
{
return;
}
}
catch (AmqpException amqpException)
{
error = amqpException.Error;
}
catch (Exception exception)
{
error = new Error() { Condition = ErrorCode.InternalError, Description = exception.Message };
}
this.CompleteAttach(attach, error);
}
internal override void OnFlow(Flow flow)
{
if (this.onCredit != null)
{
var theirLimit = (SequenceNumber)(flow.DeliveryCount + flow.LinkCredit);
var myLimit = (SequenceNumber)((uint)this.deliveryCount + this.credit);
int delta = theirLimit - myLimit;
if (delta > 0)
{
this.onCredit(delta, this.state);
}
}
}
internal override void OnDeliveryStateChanged(Delivery delivery)
{
if (this.onDispose != null)
{
this.onDispose(delivery.Message, delivery.State, delivery.Settled, this.state);
}
}
internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
{
if (delivery != null)
{
this.deliveryCount++;
if (!transfer.More)
{
// single transfer message - the most common case
delivery.Buffer = buffer;
this.DeliverMessage(delivery);
}
else
{
delivery.Buffer = new ByteBuffer(buffer.Length * 2, true);
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
this.deliveryCurrent = delivery;
}
}
else
{
delivery = this.deliveryCurrent;
if (!transfer.More)
{
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
this.deliveryCurrent = null;
this.DeliverMessage(delivery);
}
else
{
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
}
}
}
protected override void OnAbort(Error error)
{
}
void DeliverMessage(Delivery delivery)
{
var container = ((ListenerConnection)this.Session.Connection).Listener.Container;
delivery.Message = container.CreateMessage(delivery.Buffer);
this.onMessage(this, delivery.Message, delivery.State, this.state);
if (this.delivered++ >= this.credit / 2)
{
this.SendFlow(this.deliveryCount, this.credit);
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System;
using Amqp.Framing;
using Amqp.Types;
public class ListenerLink : Link
{
bool role;
uint credit;
object state;
// send
Action<int, object> onCredit;
Action<Message, DeliveryState, bool, object> onDispose;
// receive
SequenceNumber deliveryCount;
int delivered;
Delivery deliveryCurrent;
Action<ListenerLink, Message, DeliveryState, object> onMessage;
public ListenerLink(ListenerSession session, Attach attach)
: base(session, attach.LinkName, null)
{
this.role = !attach.Role;
this.SettleOnSend = attach.SndSettleMode == SenderSettleMode.Settled;
}
public bool Role
{
get { return this.role; }
}
public bool SettleOnSend
{
get; internal set;
}
public object State
{
get { return this.state; }
}
public void InitializeReceiver(uint credit, Action<ListenerLink, Message, DeliveryState, object> onMessage, object state)
{
this.credit = credit;
this.onMessage = onMessage;
this.state = state;
}
public void InitializeSender(Action<int, object> onCredit, Action<Message, DeliveryState, bool, object> onDispose, object state)
{
this.onCredit = onCredit;
this.onDispose = onDispose;
this.state = state;
}
public void SendMessage(Message message, ByteBuffer buffer)
{
Delivery delivery = new Delivery()
{
Handle = this.Handle,
Message = message,
Buffer = buffer,
Link = this,
Settled = this.SettleOnSend
};
this.Session.SendDelivery(delivery);
this.deliveryCount++;
}
public void DisposeMessage(Message message, DeliveryState deliveryState, bool settled)
{
Delivery delivery = message.Delivery;
if (delivery == null || delivery.Settled)
{
return;
}
this.Session.DisposeDelivery(this.role, delivery, deliveryState, settled);
}
public void CompleteAttach(Attach attach, Error error)
{
if (error != null)
{
this.SendAttach(!attach.Role, attach.InitialDeliveryCount, new Attach() { Target = null, Source = null });
}
else
{
this.SendAttach(!attach.Role, attach.InitialDeliveryCount, new Attach() { Target = attach.Target, Source = attach.Source });
}
base.OnAttach(attach.Handle, attach);
if (error != null)
{
this.Close(0, error);
}
else
{
if (this.credit > 0)
{
this.SendFlow(this.deliveryCount, credit);
}
}
}
internal override void OnAttach(uint remoteHandle, Attach attach)
{
var container = ((ListenerConnection)this.Session.Connection).Listener.Container;
Error error = null;
try
{
bool done = container.AttachLink((ListenerConnection)this.Session.Connection, (ListenerSession)this.Session, this, attach);
if (!done)
{
return;
}
}
catch (AmqpException amqpException)
{
error = amqpException.Error;
}
catch (Exception exception)
{
error = new Error() { Condition = ErrorCode.InternalError, Description = exception.Message };
}
this.CompleteAttach(attach, error);
}
internal override void OnFlow(Flow flow)
{
if (this.onCredit != null)
{
var theirLimit = (SequenceNumber)(flow.DeliveryCount + flow.LinkCredit);
var myLimit = (SequenceNumber)((uint)this.deliveryCount + this.credit);
int delta = theirLimit - myLimit;
if (delta > 0)
{
this.onCredit(delta, this.state);
}
}
}
internal override void OnDeliveryStateChanged(Delivery delivery)
{
if (this.onDispose != null)
{
this.onDispose(delivery.Message, delivery.State, delivery.Settled, this.state);
}
}
internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
{
if (delivery != null)
{
this.deliveryCount++;
if (!transfer.More)
{
// single transfer message - the most common case
delivery.Buffer = buffer;
this.DeliverMessage(delivery);
}
else
{
delivery.Buffer = new ByteBuffer(buffer.Length * 2, true);
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
this.deliveryCurrent = delivery;
}
}
else
{
delivery = this.deliveryCurrent;
if (!transfer.More)
{
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
this.deliveryCurrent = null;
this.DeliverMessage(delivery);
}
else
{
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
}
}
}
protected override void OnAbort(Error error)
{
}
void DeliverMessage(Delivery delivery)
{
var container = ((ListenerConnection)this.Session.Connection).Listener.Container;
delivery.Message = container.CreateMessage(delivery.Buffer);
this.onMessage(this, delivery.Message, delivery.State, this.state);
if (this.delivered++ >= this.credit / 2)
{
this.SendFlow(this.deliveryCount, this.credit);
}
}
}
}

Просмотреть файл

@ -1,38 +1,38 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System;
using Amqp.Framing;
using Amqp.Types;
public class ListenerSession : Session
{
internal ListenerSession(ListenerConnection connection, Begin begin)
: base(connection, begin)
{
}
internal override void OnAttach(Attach attach)
{
var connection = (ListenerConnection)this.Connection;
Link link = connection.Listener.Container.CreateLink(connection, this, attach);
base.OnAttach(attach);
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Listener
{
using System;
using Amqp.Framing;
using Amqp.Types;
public class ListenerSession : Session
{
internal ListenerSession(ListenerConnection connection, Begin begin)
: base(connection, begin)
{
}
internal override void OnAttach(Attach attach)
{
var connection = (ListenerConnection)this.Connection;
Link link = connection.Listener.Container.CreateLink(connection, this, attach);
base.OnAttach(attach);
}
}
}

Просмотреть файл

@ -1,99 +1,99 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
using Amqp.Framing;
using Amqp.Types;
class AsyncPump
{
readonly IAsyncTransport transport;
public AsyncPump(IAsyncTransport transport)
{
this.transport = transport;
}
public void Start(Connection connection)
{
Task task = this.StartAsync(connection);
}
public async Task PumpAsync(Func<ProtocolHeader, bool> onHeader, Func<ByteBuffer, bool> onBuffer)
{
byte[] header = new byte[FixedWidth.ULong];
if (onHeader != null)
{
// header
await this.ReceiveBufferAsync(header, 0, FixedWidth.ULong);
if (!onHeader(ProtocolHeader.Create(header, 0)))
{
return;
}
}
// frames
while (true)
{
await this.ReceiveBufferAsync(header, 0, FixedWidth.UInt);
int frameSize = AmqpBitConverter.ReadInt(header, 0);
byte[] buffer = new byte[frameSize];
Buffer.BlockCopy(header, 0, buffer, 0, FixedWidth.UInt);
await this.ReceiveBufferAsync(buffer, FixedWidth.UInt, frameSize - FixedWidth.UInt);
if (!onBuffer(new ByteBuffer(buffer, 0, frameSize, frameSize)))
{
break;
}
}
}
async Task StartAsync(Connection connection)
{
try
{
await this.PumpAsync(connection.OnHeader, connection.OnFrame);
}
catch (Exception exception)
{
connection.OnIoException(exception);
}
}
async Task ReceiveBufferAsync(byte[] buffer, int offset, int count)
{
while (count > 0)
{
int received = await this.transport.ReceiveAsync(buffer, offset, count);
if (received == 0)
{
throw new SocketException((int)SocketError.ConnectionReset);
}
offset += received;
count -= received;
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
using Amqp.Framing;
using Amqp.Types;
class AsyncPump
{
readonly IAsyncTransport transport;
public AsyncPump(IAsyncTransport transport)
{
this.transport = transport;
}
public void Start(Connection connection)
{
Task task = this.StartAsync(connection);
}
public async Task PumpAsync(Func<ProtocolHeader, bool> onHeader, Func<ByteBuffer, bool> onBuffer)
{
byte[] header = new byte[FixedWidth.ULong];
if (onHeader != null)
{
// header
await this.ReceiveBufferAsync(header, 0, FixedWidth.ULong);
if (!onHeader(ProtocolHeader.Create(header, 0)))
{
return;
}
}
// frames
while (true)
{
await this.ReceiveBufferAsync(header, 0, FixedWidth.UInt);
int frameSize = AmqpBitConverter.ReadInt(header, 0);
byte[] buffer = new byte[frameSize];
Buffer.BlockCopy(header, 0, buffer, 0, FixedWidth.UInt);
await this.ReceiveBufferAsync(buffer, FixedWidth.UInt, frameSize - FixedWidth.UInt);
if (!onBuffer(new ByteBuffer(buffer, 0, frameSize, frameSize)))
{
break;
}
}
}
async Task StartAsync(Connection connection)
{
try
{
await this.PumpAsync(connection.OnHeader, connection.OnFrame);
}
catch (Exception exception)
{
connection.OnIoException(exception);
}
}
async Task ReceiveBufferAsync(byte[] buffer, int offset, int count)
{
while (count > 0)
{
int received = await this.transport.ReceiveAsync(buffer, offset, count);
if (received == 0)
{
throw new SocketException((int)SocketError.ConnectionReset);
}
offset += received;
count -= received;
}
}
}
}

Просмотреть файл

@ -1,251 +1,251 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Diagnostics;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Amqp.Framing;
using Amqp.Sasl;
public class ConnectionFactory
{
internal TcpSettings tcpSettings;
internal SslSettings sslSettings;
internal SaslSettings saslSettings;
internal AmqpSettings amqpSettings;
public ConnectionFactory()
{
this.amqpSettings = new AmqpSettings()
{
MaxFrameSize = (int)Connection.DefaultMaxFrameSize,
ContainerId = Process.GetCurrentProcess().ProcessName,
IdleTimeout = int.MaxValue,
MaxSessionsPerConnection = 8
};
}
public TcpSettings TCP
{
get
{
return this.tcpSettings ?? (this.tcpSettings = new TcpSettings());
}
}
public SslSettings SSL
{
get
{
return this.sslSettings ?? (this.sslSettings = new SslSettings());
}
}
public SaslSettings SASL
{
get
{
return this.saslSettings ?? (this.saslSettings = new SaslSettings());
}
}
public AmqpSettings AMQP
{
get { return this.amqpSettings; }
}
public Task<Connection> CreateAsync(Address address)
{
return this.CreateAsync(address, null, null);
}
public Task<Connection> CreateAsync(Address address, OnOpened onOpened)
{
return this.CreateAsync(address, null, onOpened);
}
public async Task<Connection> CreateAsync(Address address, Open open, OnOpened onOpened)
{
IAsyncTransport transport;
if (WebSocketTransport.MatchScheme(address.Scheme))
{
WebSocketTransport wsTransport = new WebSocketTransport();
await wsTransport.ConnectAsync(address);
transport = wsTransport;
}
else
{
TcpTransport tcpTransport = new TcpTransport();
await tcpTransport.ConnectAsync(address, this);
transport = tcpTransport;
}
if (address.User != null)
{
SaslPlainProfile profile = new SaslPlainProfile(address.User, address.Password);
transport = await profile.OpenAsync(address.Host, transport);
}
else if (this.saslSettings != null && this.saslSettings.Profile != null)
{
transport = await this.saslSettings.Profile.OpenAsync(address.Host, transport);
}
AsyncPump pump = new AsyncPump(transport);
Connection connection = new Connection(this, address, transport, open, onOpened);
pump.Start(connection);
return connection;
}
public class TcpSettings
{
const int DefaultBufferSize = 8192;
bool? noDelay;
int? receiveBufferSize;
int? receiveTimeout;
int? sendBufferSize;
int? sendTimeout;
public LingerOption LingerOption
{
get;
set;
}
public bool NoDelay
{
get { return this.noDelay ?? false; }
set { this.noDelay = value; }
}
public int ReceiveBufferSize
{
get { return this.receiveBufferSize ?? DefaultBufferSize; }
set { this.receiveBufferSize = value; }
}
public int ReceiveTimeout
{
get { return this.receiveTimeout ?? 0; }
set { this.receiveTimeout = value; }
}
public int SendBufferSize
{
get { return this.sendBufferSize ?? DefaultBufferSize; }
set { this.sendBufferSize = value; }
}
public int SendTimeout
{
get { return this.sendTimeout ?? 0; }
set { this.sendTimeout = value; }
}
internal void Configure(Socket socket)
{
if (this.noDelay != null) socket.NoDelay = this.noDelay.Value;
if (this.receiveBufferSize != null) socket.ReceiveBufferSize = this.receiveBufferSize.Value;
if (this.receiveTimeout != null) socket.ReceiveTimeout = this.receiveTimeout.Value;
if (this.sendBufferSize != null) socket.SendBufferSize = this.sendBufferSize.Value;
if (this.sendTimeout != null) socket.SendTimeout = this.sendTimeout.Value;
if (this.LingerOption != null) socket.LingerState = this.LingerOption;
}
}
public class SslSettings
{
public SslSettings()
{
this.Protocols = SslProtocols.Default;
this.ClientCertificates = new X509CertificateCollection();
}
public X509CertificateCollection ClientCertificates
{
get;
set;
}
public SslProtocols Protocols
{
get;
set;
}
public bool CheckCertificateRevocation
{
get;
set;
}
public RemoteCertificateValidationCallback RemoteCertificateValidationCallback
{
get;
set;
}
}
public class SaslSettings
{
public SaslProfile Profile
{
get;
set;
}
}
public class AmqpSettings
{
public int MaxFrameSize
{
get;
set;
}
public string ContainerId
{
get;
set;
}
public string HostName
{
get;
set;
}
public ushort MaxSessionsPerConnection
{
get;
set;
}
public int IdleTimeout
{
get;
set;
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Diagnostics;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Amqp.Framing;
using Amqp.Sasl;
public class ConnectionFactory
{
internal TcpSettings tcpSettings;
internal SslSettings sslSettings;
internal SaslSettings saslSettings;
internal AmqpSettings amqpSettings;
public ConnectionFactory()
{
this.amqpSettings = new AmqpSettings()
{
MaxFrameSize = (int)Connection.DefaultMaxFrameSize,
ContainerId = Process.GetCurrentProcess().ProcessName,
IdleTimeout = int.MaxValue,
MaxSessionsPerConnection = 8
};
}
public TcpSettings TCP
{
get
{
return this.tcpSettings ?? (this.tcpSettings = new TcpSettings());
}
}
public SslSettings SSL
{
get
{
return this.sslSettings ?? (this.sslSettings = new SslSettings());
}
}
public SaslSettings SASL
{
get
{
return this.saslSettings ?? (this.saslSettings = new SaslSettings());
}
}
public AmqpSettings AMQP
{
get { return this.amqpSettings; }
}
public Task<Connection> CreateAsync(Address address)
{
return this.CreateAsync(address, null, null);
}
public Task<Connection> CreateAsync(Address address, OnOpened onOpened)
{
return this.CreateAsync(address, null, onOpened);
}
public async Task<Connection> CreateAsync(Address address, Open open, OnOpened onOpened)
{
IAsyncTransport transport;
if (WebSocketTransport.MatchScheme(address.Scheme))
{
WebSocketTransport wsTransport = new WebSocketTransport();
await wsTransport.ConnectAsync(address);
transport = wsTransport;
}
else
{
TcpTransport tcpTransport = new TcpTransport();
await tcpTransport.ConnectAsync(address, this);
transport = tcpTransport;
}
if (address.User != null)
{
SaslPlainProfile profile = new SaslPlainProfile(address.User, address.Password);
transport = await profile.OpenAsync(address.Host, transport);
}
else if (this.saslSettings != null && this.saslSettings.Profile != null)
{
transport = await this.saslSettings.Profile.OpenAsync(address.Host, transport);
}
AsyncPump pump = new AsyncPump(transport);
Connection connection = new Connection(this, address, transport, open, onOpened);
pump.Start(connection);
return connection;
}
public class TcpSettings
{
const int DefaultBufferSize = 8192;
bool? noDelay;
int? receiveBufferSize;
int? receiveTimeout;
int? sendBufferSize;
int? sendTimeout;
public LingerOption LingerOption
{
get;
set;
}
public bool NoDelay
{
get { return this.noDelay ?? false; }
set { this.noDelay = value; }
}
public int ReceiveBufferSize
{
get { return this.receiveBufferSize ?? DefaultBufferSize; }
set { this.receiveBufferSize = value; }
}
public int ReceiveTimeout
{
get { return this.receiveTimeout ?? 0; }
set { this.receiveTimeout = value; }
}
public int SendBufferSize
{
get { return this.sendBufferSize ?? DefaultBufferSize; }
set { this.sendBufferSize = value; }
}
public int SendTimeout
{
get { return this.sendTimeout ?? 0; }
set { this.sendTimeout = value; }
}
internal void Configure(Socket socket)
{
if (this.noDelay != null) socket.NoDelay = this.noDelay.Value;
if (this.receiveBufferSize != null) socket.ReceiveBufferSize = this.receiveBufferSize.Value;
if (this.receiveTimeout != null) socket.ReceiveTimeout = this.receiveTimeout.Value;
if (this.sendBufferSize != null) socket.SendBufferSize = this.sendBufferSize.Value;
if (this.sendTimeout != null) socket.SendTimeout = this.sendTimeout.Value;
if (this.LingerOption != null) socket.LingerState = this.LingerOption;
}
}
public class SslSettings
{
public SslSettings()
{
this.Protocols = SslProtocols.Default;
this.ClientCertificates = new X509CertificateCollection();
}
public X509CertificateCollection ClientCertificates
{
get;
set;
}
public SslProtocols Protocols
{
get;
set;
}
public bool CheckCertificateRevocation
{
get;
set;
}
public RemoteCertificateValidationCallback RemoteCertificateValidationCallback
{
get;
set;
}
}
public class SaslSettings
{
public SaslProfile Profile
{
get;
set;
}
}
public class AmqpSettings
{
public int MaxFrameSize
{
get;
set;
}
public string ContainerId
{
get;
set;
}
public string HostName
{
get;
set;
}
public ushort MaxSessionsPerConnection
{
get;
set;
}
public int IdleTimeout
{
get;
set;
}
}
}
}

Просмотреть файл

@ -1,33 +1,33 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public interface IAsyncTransport : ITransport
{
void SetConnection(Connection connection);
// true: pending, false: completed
bool SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize);
Task<int> ReceiveAsync(byte[] buffer, int offset, int count);
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public interface IAsyncTransport : ITransport
{
void SetConnection(Connection connection);
// true: pending, false: completed
bool SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize);
Task<int> ReceiveAsync(byte[] buffer, int offset, int count);
}
}

Просмотреть файл

@ -1,143 +1,143 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Threading.Tasks;
using Amqp.Framing;
using Amqp.Sasl;
using Amqp.Transactions;
using Amqp.Types;
public static class TaskExtensions
{
public static T GetBody<T>(this Message message)
{
if (message.BodySection != null &&
message.BodySection.Descriptor.Code == Codec.AmqpValue.Code)
{
return ((AmqpValue)message.BodySection).GetValue<T>();
}
return (T)message.Body;
}
public static Task CloseAsync(this AmqpObject amqpObject, int timeout = 60000)
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
try
{
amqpObject.Closed += (o, e) =>
{
if (e != null)
{
tcs.SetException(new AmqpException(e));
}
else
{
tcs.SetResult(null);
}
};
amqpObject.Close(0);
}
catch (Exception exception)
{
tcs.SetException(exception);
}
return tcs.Task;
}
public static async Task SendAsync(this SenderLink sender, Message message)
{
var txnState = await ResourceManager.GetTransactionalStateAsync(sender);
await sender.SendAsync(message, txnState);
}
public static Task<Message> ReceiveAsync(this ReceiverLink receiver, int timeout = 60000)
{
TaskCompletionSource<Message> tcs = new TaskCompletionSource<Message>();
try
{
var message = receiver.Receive(
(l, m) => tcs.SetResult(m),
timeout);
if (message != null)
{
tcs.SetResult(message);
}
}
catch (Exception exception)
{
tcs.SetException(exception);
}
return tcs.Task;
}
internal static async Task<IAsyncTransport> OpenAsync(this SaslProfile saslProfile, string hostname, IAsyncTransport transport)
{
ProtocolHeader header = saslProfile.Start(hostname, transport);
AsyncPump pump = new AsyncPump(transport);
await pump.PumpAsync(
h => { saslProfile.OnHeader(header, h); return true; },
b => { SaslCode code; return saslProfile.OnFrame(transport, b, out code); });
return (IAsyncTransport)saslProfile.UpgradeTransportInternal(transport);
}
static Task SendAsync(this SenderLink sender, Message message, DeliveryState deliveryState)
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
try
{
sender.Send(
message,
deliveryState,
false,
(m, o, s) =>
{
var t = (TaskCompletionSource<object>)s;
if (o.Descriptor.Code == Codec.Accepted.Code)
{
t.SetResult(null);
}
else if (o.Descriptor.Code == Codec.Rejected.Code)
{
t.SetException(new AmqpException(((Rejected)o).Error));
}
else
{
t.SetException(new AmqpException(ErrorCode.InternalError, o.Descriptor.Name));
}
},
tcs);
}
catch (Exception exception)
{
tcs.SetException(exception);
}
return tcs.Task;
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Threading.Tasks;
using Amqp.Framing;
using Amqp.Sasl;
using Amqp.Transactions;
using Amqp.Types;
public static class TaskExtensions
{
public static T GetBody<T>(this Message message)
{
if (message.BodySection != null &&
message.BodySection.Descriptor.Code == Codec.AmqpValue.Code)
{
return ((AmqpValue)message.BodySection).GetValue<T>();
}
return (T)message.Body;
}
public static Task CloseAsync(this AmqpObject amqpObject, int timeout = 60000)
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
try
{
amqpObject.Closed += (o, e) =>
{
if (e != null)
{
tcs.SetException(new AmqpException(e));
}
else
{
tcs.SetResult(null);
}
};
amqpObject.Close(0);
}
catch (Exception exception)
{
tcs.SetException(exception);
}
return tcs.Task;
}
public static async Task SendAsync(this SenderLink sender, Message message)
{
var txnState = await ResourceManager.GetTransactionalStateAsync(sender);
await sender.SendAsync(message, txnState);
}
public static Task<Message> ReceiveAsync(this ReceiverLink receiver, int timeout = 60000)
{
TaskCompletionSource<Message> tcs = new TaskCompletionSource<Message>();
try
{
var message = receiver.Receive(
(l, m) => tcs.SetResult(m),
timeout);
if (message != null)
{
tcs.SetResult(message);
}
}
catch (Exception exception)
{
tcs.SetException(exception);
}
return tcs.Task;
}
internal static async Task<IAsyncTransport> OpenAsync(this SaslProfile saslProfile, string hostname, IAsyncTransport transport)
{
ProtocolHeader header = saslProfile.Start(hostname, transport);
AsyncPump pump = new AsyncPump(transport);
await pump.PumpAsync(
h => { saslProfile.OnHeader(header, h); return true; },
b => { SaslCode code; return saslProfile.OnFrame(transport, b, out code); });
return (IAsyncTransport)saslProfile.UpgradeTransportInternal(transport);
}
static Task SendAsync(this SenderLink sender, Message message, DeliveryState deliveryState)
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
try
{
sender.Send(
message,
deliveryState,
false,
(m, o, s) =>
{
var t = (TaskCompletionSource<object>)s;
if (o.Descriptor.Code == Codec.Accepted.Code)
{
t.SetResult(null);
}
else if (o.Descriptor.Code == Codec.Rejected.Code)
{
t.SetException(new AmqpException(((Rejected)o).Error));
}
else
{
t.SetException(new AmqpException(ErrorCode.InternalError, o.Descriptor.Name));
}
},
tcs);
}
catch (Exception exception)
{
tcs.SetException(exception);
}
return tcs.Task;
}
}
}

Просмотреть файл

@ -1,381 +1,381 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading.Tasks;
sealed class TcpTransport : IAsyncTransport
{
static readonly RemoteCertificateValidationCallback noneCertValidator = (a, b, c, d) => true;
Connection connection;
Writer writer;
IAsyncTransport socketTransport;
public TcpTransport()
{
}
// called by listener
public TcpTransport(Socket socket)
{
this.socketTransport = new TcpSocket(this, socket);
this.writer = new Writer(this, this.socketTransport);
}
// called by listener
public TcpTransport(SslStream sslStream)
{
this.socketTransport = new SslSocket(this, sslStream);
this.writer = new Writer(this, this.socketTransport);
}
public void Connect(Connection connection, Address address, bool noVerification)
{
this.ConnectAsync(address, new ConnectionFactory()).Wait();
}
public async Task ConnectAsync(Address address, ConnectionFactory factory)
{
Socket socket;
IPAddress[] ipAddresses;
IPAddress ipAddress;
if (IPAddress.TryParse(address.Host, out ipAddress))
{
socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
ipAddresses = new IPAddress[] { ipAddress };
}
else
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ipAddresses = Dns.GetHostEntry(address.Host).AddressList;
}
if (factory.tcpSettings != null)
{
factory.tcpSettings.Configure(socket);
}
await Task.Factory.FromAsync(
(c, s) => ((Socket)s).BeginConnect(ipAddresses, address.Port, c, s),
(r) => ((Socket)r.AsyncState).EndConnect(r),
socket);
IAsyncTransport transport;
if (address.UseSsl)
{
SslStream sslStream;
var ssl = factory.sslSettings;
if (ssl == null)
{
sslStream = new SslStream(new NetworkStream(socket));
await sslStream.AuthenticateAsClientAsync(address.Host);
}
else
{
sslStream = new SslStream(new NetworkStream(socket), false, ssl.RemoteCertificateValidationCallback);
await sslStream.AuthenticateAsClientAsync(address.Host, ssl.ClientCertificates,
ssl.Protocols, ssl.CheckCertificateRevocation);
}
transport = new SslSocket(this, sslStream);
}
else
{
transport = new TcpSocket(this, socket);
}
this.socketTransport = transport;
this.writer = new Writer(this, this.socketTransport);
}
void IAsyncTransport.SetConnection(Connection connection)
{
this.connection = connection;
}
Task<int> IAsyncTransport.ReceiveAsync(byte[] buffer, int offset, int count)
{
return this.socketTransport.ReceiveAsync(buffer, offset, count);
}
bool IAsyncTransport.SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize)
{
throw new InvalidOperationException();
}
void ITransport.Close()
{
this.socketTransport.Close();
}
void ITransport.Send(ByteBuffer buffer)
{
this.writer.Write(buffer);
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
return this.socketTransport.Receive(buffer, offset, count);
}
class TcpSocket : IAsyncTransport
{
readonly static EventHandler<SocketAsyncEventArgs> onWriteComplete = OnWriteComplete;
readonly TcpTransport transport;
readonly Socket socket;
readonly SocketAsyncEventArgs args;
public TcpSocket(TcpTransport transport, Socket socket)
{
this.transport = transport;
this.socket = socket;
this.args = new SocketAsyncEventArgs();
this.args.Completed += onWriteComplete;
this.args.UserToken = this;
}
static void OnWriteComplete(object sender, SocketAsyncEventArgs eventArgs)
{
var thisPtr = (TcpSocket)eventArgs.UserToken;
if (eventArgs.SocketError != SocketError.Success)
{
thisPtr.transport.connection.OnIoException(new SocketException((int)eventArgs.SocketError));
}
else
{
thisPtr.transport.writer.ContinueWrite();
}
}
void IAsyncTransport.SetConnection(Connection connection)
{
throw new NotImplementedException();
}
bool IAsyncTransport.SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize)
{
if (buffer != null)
{
this.args.BufferList = null;
this.args.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Length);
}
else
{
this.args.SetBuffer(null, 0, 0);
this.args.BufferList = bufferList;
}
return this.socket.SendAsync(this.args);
}
Task<int> IAsyncTransport.ReceiveAsync(byte[] buffer, int offset, int count)
{
return Task.Factory.FromAsync(
(c, s) => ((TcpSocket)s).socket.BeginReceive(buffer, offset, count, SocketFlags.None, c, s),
(r) => ((TcpSocket)r.AsyncState).socket.EndReceive(r),
this);
}
void ITransport.Send(ByteBuffer buffer)
{
throw new InvalidOperationException();
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
return this.socket.Receive(buffer, offset, count, SocketFlags.None);
}
void ITransport.Close()
{
this.socket.Close();
this.args.Dispose();
}
}
class SslSocket : IAsyncTransport
{
readonly TcpTransport transport;
readonly SslStream sslStream;
public SslSocket(TcpTransport transport, SslStream sslStream)
{
this.transport = transport;
this.sslStream = sslStream;
}
void IAsyncTransport.SetConnection(Connection connection)
{
throw new NotImplementedException();
}
bool IAsyncTransport.SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize)
{
ArraySegment<byte> writeBuffer;
if (buffer != null)
{
writeBuffer = new ArraySegment<byte>(buffer.Buffer, buffer.Offset, buffer.Length);
}
else
{
byte[] temp = new byte[listSize];
int offset = 0;
for (int i = 0; i < bufferList.Count; i++)
{
ArraySegment<byte> segment = bufferList[i];
Buffer.BlockCopy(segment.Array, segment.Offset, temp, offset, segment.Count);
offset += segment.Count;
}
writeBuffer = new ArraySegment<byte>(temp, 0, listSize);
}
Task task = this.sslStream.WriteAsync(writeBuffer.Array, writeBuffer.Offset, writeBuffer.Count);
bool pending = !task.IsCompleted;
if (pending)
{
task.ContinueWith(
(t, s) =>
{
var thisPtr = (SslSocket)s;
if (t.IsFaulted)
{
thisPtr.transport.connection.OnIoException(t.Exception.InnerException);
}
else
{
thisPtr.transport.writer.ContinueWrite();
}
},
this);
}
return pending;
}
Task<int> IAsyncTransport.ReceiveAsync(byte[] buffer, int offset, int count)
{
return this.sslStream.ReadAsync(buffer, offset, count);
}
void ITransport.Send(ByteBuffer buffer)
{
throw new InvalidOperationException();
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
return this.sslStream.Read(buffer, offset, count);
}
void ITransport.Close()
{
this.sslStream.Close();
}
}
sealed class Writer
{
readonly TcpTransport owner;
readonly IAsyncTransport transport;
Queue<ByteBuffer> bufferQueue;
bool writing;
public Writer(TcpTransport owner, IAsyncTransport transport)
{
this.owner = owner;
this.transport = transport;
this.bufferQueue = new Queue<ByteBuffer>();
}
public void Write(ByteBuffer buffer)
{
lock (this.bufferQueue)
{
if (this.writing)
{
this.bufferQueue.Enqueue(buffer);
return;
}
this.writing = true;
}
if (!this.transport.SendAsync(buffer, null, 0))
{
this.ContinueWrite();
}
}
public void ContinueWrite()
{
ByteBuffer buffer = null;
IList<ArraySegment<byte>> buffers = null;
int listSize = 0;
do
{
lock (this.bufferQueue)
{
int queueDepth = this.bufferQueue.Count;
if (queueDepth == 0)
{
this.writing = false;
return;
}
else if (queueDepth == 1)
{
buffer = this.bufferQueue.Dequeue();
buffers = null;
}
else
{
buffer = null;
listSize = 0;
buffers = new ArraySegment<byte>[queueDepth];
for (int i = 0; i < queueDepth; i++)
{
ByteBuffer item = this.bufferQueue.Dequeue();
buffers[i] = new ArraySegment<byte>(item.Buffer, item.Offset, item.Length);
listSize += item.Length;
}
}
}
try
{
if (this.transport.SendAsync(buffer, buffers, listSize))
{
break;
}
}
catch (Exception exception)
{
this.owner.connection.OnIoException(exception);
break;
}
}
while (true);
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading.Tasks;
sealed class TcpTransport : IAsyncTransport
{
static readonly RemoteCertificateValidationCallback noneCertValidator = (a, b, c, d) => true;
Connection connection;
Writer writer;
IAsyncTransport socketTransport;
public TcpTransport()
{
}
// called by listener
public TcpTransport(Socket socket)
{
this.socketTransport = new TcpSocket(this, socket);
this.writer = new Writer(this, this.socketTransport);
}
// called by listener
public TcpTransport(SslStream sslStream)
{
this.socketTransport = new SslSocket(this, sslStream);
this.writer = new Writer(this, this.socketTransport);
}
public void Connect(Connection connection, Address address, bool noVerification)
{
this.ConnectAsync(address, new ConnectionFactory()).Wait();
}
public async Task ConnectAsync(Address address, ConnectionFactory factory)
{
Socket socket;
IPAddress[] ipAddresses;
IPAddress ipAddress;
if (IPAddress.TryParse(address.Host, out ipAddress))
{
socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
ipAddresses = new IPAddress[] { ipAddress };
}
else
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ipAddresses = Dns.GetHostEntry(address.Host).AddressList;
}
if (factory.tcpSettings != null)
{
factory.tcpSettings.Configure(socket);
}
await Task.Factory.FromAsync(
(c, s) => ((Socket)s).BeginConnect(ipAddresses, address.Port, c, s),
(r) => ((Socket)r.AsyncState).EndConnect(r),
socket);
IAsyncTransport transport;
if (address.UseSsl)
{
SslStream sslStream;
var ssl = factory.sslSettings;
if (ssl == null)
{
sslStream = new SslStream(new NetworkStream(socket));
await sslStream.AuthenticateAsClientAsync(address.Host);
}
else
{
sslStream = new SslStream(new NetworkStream(socket), false, ssl.RemoteCertificateValidationCallback);
await sslStream.AuthenticateAsClientAsync(address.Host, ssl.ClientCertificates,
ssl.Protocols, ssl.CheckCertificateRevocation);
}
transport = new SslSocket(this, sslStream);
}
else
{
transport = new TcpSocket(this, socket);
}
this.socketTransport = transport;
this.writer = new Writer(this, this.socketTransport);
}
void IAsyncTransport.SetConnection(Connection connection)
{
this.connection = connection;
}
Task<int> IAsyncTransport.ReceiveAsync(byte[] buffer, int offset, int count)
{
return this.socketTransport.ReceiveAsync(buffer, offset, count);
}
bool IAsyncTransport.SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize)
{
throw new InvalidOperationException();
}
void ITransport.Close()
{
this.socketTransport.Close();
}
void ITransport.Send(ByteBuffer buffer)
{
this.writer.Write(buffer);
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
return this.socketTransport.Receive(buffer, offset, count);
}
class TcpSocket : IAsyncTransport
{
readonly static EventHandler<SocketAsyncEventArgs> onWriteComplete = OnWriteComplete;
readonly TcpTransport transport;
readonly Socket socket;
readonly SocketAsyncEventArgs args;
public TcpSocket(TcpTransport transport, Socket socket)
{
this.transport = transport;
this.socket = socket;
this.args = new SocketAsyncEventArgs();
this.args.Completed += onWriteComplete;
this.args.UserToken = this;
}
static void OnWriteComplete(object sender, SocketAsyncEventArgs eventArgs)
{
var thisPtr = (TcpSocket)eventArgs.UserToken;
if (eventArgs.SocketError != SocketError.Success)
{
thisPtr.transport.connection.OnIoException(new SocketException((int)eventArgs.SocketError));
}
else
{
thisPtr.transport.writer.ContinueWrite();
}
}
void IAsyncTransport.SetConnection(Connection connection)
{
throw new NotImplementedException();
}
bool IAsyncTransport.SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize)
{
if (buffer != null)
{
this.args.BufferList = null;
this.args.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Length);
}
else
{
this.args.SetBuffer(null, 0, 0);
this.args.BufferList = bufferList;
}
return this.socket.SendAsync(this.args);
}
Task<int> IAsyncTransport.ReceiveAsync(byte[] buffer, int offset, int count)
{
return Task.Factory.FromAsync(
(c, s) => ((TcpSocket)s).socket.BeginReceive(buffer, offset, count, SocketFlags.None, c, s),
(r) => ((TcpSocket)r.AsyncState).socket.EndReceive(r),
this);
}
void ITransport.Send(ByteBuffer buffer)
{
throw new InvalidOperationException();
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
return this.socket.Receive(buffer, offset, count, SocketFlags.None);
}
void ITransport.Close()
{
this.socket.Close();
this.args.Dispose();
}
}
class SslSocket : IAsyncTransport
{
readonly TcpTransport transport;
readonly SslStream sslStream;
public SslSocket(TcpTransport transport, SslStream sslStream)
{
this.transport = transport;
this.sslStream = sslStream;
}
void IAsyncTransport.SetConnection(Connection connection)
{
throw new NotImplementedException();
}
bool IAsyncTransport.SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize)
{
ArraySegment<byte> writeBuffer;
if (buffer != null)
{
writeBuffer = new ArraySegment<byte>(buffer.Buffer, buffer.Offset, buffer.Length);
}
else
{
byte[] temp = new byte[listSize];
int offset = 0;
for (int i = 0; i < bufferList.Count; i++)
{
ArraySegment<byte> segment = bufferList[i];
Buffer.BlockCopy(segment.Array, segment.Offset, temp, offset, segment.Count);
offset += segment.Count;
}
writeBuffer = new ArraySegment<byte>(temp, 0, listSize);
}
Task task = this.sslStream.WriteAsync(writeBuffer.Array, writeBuffer.Offset, writeBuffer.Count);
bool pending = !task.IsCompleted;
if (pending)
{
task.ContinueWith(
(t, s) =>
{
var thisPtr = (SslSocket)s;
if (t.IsFaulted)
{
thisPtr.transport.connection.OnIoException(t.Exception.InnerException);
}
else
{
thisPtr.transport.writer.ContinueWrite();
}
},
this);
}
return pending;
}
Task<int> IAsyncTransport.ReceiveAsync(byte[] buffer, int offset, int count)
{
return this.sslStream.ReadAsync(buffer, offset, count);
}
void ITransport.Send(ByteBuffer buffer)
{
throw new InvalidOperationException();
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
return this.sslStream.Read(buffer, offset, count);
}
void ITransport.Close()
{
this.sslStream.Close();
}
}
sealed class Writer
{
readonly TcpTransport owner;
readonly IAsyncTransport transport;
Queue<ByteBuffer> bufferQueue;
bool writing;
public Writer(TcpTransport owner, IAsyncTransport transport)
{
this.owner = owner;
this.transport = transport;
this.bufferQueue = new Queue<ByteBuffer>();
}
public void Write(ByteBuffer buffer)
{
lock (this.bufferQueue)
{
if (this.writing)
{
this.bufferQueue.Enqueue(buffer);
return;
}
this.writing = true;
}
if (!this.transport.SendAsync(buffer, null, 0))
{
this.ContinueWrite();
}
}
public void ContinueWrite()
{
ByteBuffer buffer = null;
IList<ArraySegment<byte>> buffers = null;
int listSize = 0;
do
{
lock (this.bufferQueue)
{
int queueDepth = this.bufferQueue.Count;
if (queueDepth == 0)
{
this.writing = false;
return;
}
else if (queueDepth == 1)
{
buffer = this.bufferQueue.Dequeue();
buffers = null;
}
else
{
buffer = null;
listSize = 0;
buffers = new ArraySegment<byte>[queueDepth];
for (int i = 0; i < queueDepth; i++)
{
ByteBuffer item = this.bufferQueue.Dequeue();
buffers[i] = new ArraySegment<byte>(item.Buffer, item.Offset, item.Length);
listSize += item.Length;
}
}
}
try
{
if (this.transport.SendAsync(buffer, buffers, listSize))
{
break;
}
}
catch (Exception exception)
{
this.owner.connection.OnIoException(exception);
break;
}
}
while (true);
}
}
}
}

Просмотреть файл

@ -1,184 +1,184 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
sealed class WebSocketTransport : IAsyncTransport
{
public const string WebSocketSubProtocol = "AMQPWSB10";
public const string WebSockets = "WS";
public const string SecureWebSockets = "WSS";
const int WebSocketsPort = 80;
const int SecureWebSocketsPort = 443;
WebSocket webSocket;
Queue<ByteBuffer> bufferQueue;
bool writing;
Connection connection;
public WebSocketTransport()
{
this.bufferQueue = new Queue<ByteBuffer>();
}
public WebSocketTransport(WebSocket webSocket)
: this()
{
this.webSocket = webSocket;
}
public static bool MatchScheme(string scheme)
{
return string.Equals(scheme, WebSockets, StringComparison.OrdinalIgnoreCase) ||
string.Equals(scheme, SecureWebSockets, StringComparison.OrdinalIgnoreCase);
}
public async Task ConnectAsync(Address address)
{
Uri uri = new UriBuilder()
{
Scheme = address.Scheme,
Port = GetDefaultPort(address.Scheme, address.Port),
Host = address.Host,
Path = address.Path
}.Uri;
ClientWebSocket cws = new ClientWebSocket();
cws.Options.AddSubProtocol(WebSocketSubProtocol);
await cws.ConnectAsync(uri, CancellationToken.None);
if (cws.SubProtocol != WebSocketSubProtocol)
{
cws.Abort();
throw new NotSupportedException(
string.Format(
CultureInfo.InvariantCulture,
"WebSocket SubProtocol used by the host is not the same that was requested: {0}",
cws.SubProtocol ?? "<null>"));
}
this.webSocket = cws;
}
void IAsyncTransport.SetConnection(Connection connection)
{
this.connection = connection;
}
async Task<int> IAsyncTransport.ReceiveAsync(byte[] buffer, int offset, int count)
{
if (this.webSocket.State != WebSocketState.Open)
{
return 0;
}
var result = await this.webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close)
{
return 0;
}
return result.Count;
}
bool IAsyncTransport.SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize)
{
throw new InvalidOperationException();
}
void ITransport.Close()
{
this.webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "close", CancellationToken.None).Wait();
}
void ITransport.Send(ByteBuffer buffer)
{
lock (this.bufferQueue)
{
if (this.writing)
{
this.bufferQueue.Enqueue(buffer);
return;
}
this.writing = true;
}
Task task = this.WriteAsync(buffer);
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
throw new InvalidOperationException();
}
static int GetDefaultPort(string scheme, int port)
{
if (port < 0)
{
string temp = scheme.ToUpperInvariant();
if (temp == WebSockets)
{
port = WebSocketsPort;
}
else if (temp == SecureWebSockets)
{
port = SecureWebSocketsPort;
}
}
return port;
}
async Task WriteAsync(ByteBuffer buffer)
{
do
{
try
{
await this.webSocket.SendAsync(new ArraySegment<byte>(buffer.Buffer, buffer.Offset, buffer.Length),
WebSocketMessageType.Binary, true, CancellationToken.None);
}
catch (Exception exception)
{
this.connection.OnIoException(exception);
break;
}
lock (this.bufferQueue)
{
if (this.bufferQueue.Count > 0)
{
buffer = this.bufferQueue.Dequeue();
}
else
{
this.writing = false;
buffer = null;
}
}
}
while (buffer != null);
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
sealed class WebSocketTransport : IAsyncTransport
{
public const string WebSocketSubProtocol = "AMQPWSB10";
public const string WebSockets = "WS";
public const string SecureWebSockets = "WSS";
const int WebSocketsPort = 80;
const int SecureWebSocketsPort = 443;
WebSocket webSocket;
Queue<ByteBuffer> bufferQueue;
bool writing;
Connection connection;
public WebSocketTransport()
{
this.bufferQueue = new Queue<ByteBuffer>();
}
public WebSocketTransport(WebSocket webSocket)
: this()
{
this.webSocket = webSocket;
}
public static bool MatchScheme(string scheme)
{
return string.Equals(scheme, WebSockets, StringComparison.OrdinalIgnoreCase) ||
string.Equals(scheme, SecureWebSockets, StringComparison.OrdinalIgnoreCase);
}
public async Task ConnectAsync(Address address)
{
Uri uri = new UriBuilder()
{
Scheme = address.Scheme,
Port = GetDefaultPort(address.Scheme, address.Port),
Host = address.Host,
Path = address.Path
}.Uri;
ClientWebSocket cws = new ClientWebSocket();
cws.Options.AddSubProtocol(WebSocketSubProtocol);
await cws.ConnectAsync(uri, CancellationToken.None);
if (cws.SubProtocol != WebSocketSubProtocol)
{
cws.Abort();
throw new NotSupportedException(
string.Format(
CultureInfo.InvariantCulture,
"WebSocket SubProtocol used by the host is not the same that was requested: {0}",
cws.SubProtocol ?? "<null>"));
}
this.webSocket = cws;
}
void IAsyncTransport.SetConnection(Connection connection)
{
this.connection = connection;
}
async Task<int> IAsyncTransport.ReceiveAsync(byte[] buffer, int offset, int count)
{
if (this.webSocket.State != WebSocketState.Open)
{
return 0;
}
var result = await this.webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close)
{
return 0;
}
return result.Count;
}
bool IAsyncTransport.SendAsync(ByteBuffer buffer, IList<ArraySegment<byte>> bufferList, int listSize)
{
throw new InvalidOperationException();
}
void ITransport.Close()
{
this.webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "close", CancellationToken.None).Wait();
}
void ITransport.Send(ByteBuffer buffer)
{
lock (this.bufferQueue)
{
if (this.writing)
{
this.bufferQueue.Enqueue(buffer);
return;
}
this.writing = true;
}
Task task = this.WriteAsync(buffer);
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
throw new InvalidOperationException();
}
static int GetDefaultPort(string scheme, int port)
{
if (port < 0)
{
string temp = scheme.ToUpperInvariant();
if (temp == WebSockets)
{
port = WebSocketsPort;
}
else if (temp == SecureWebSockets)
{
port = SecureWebSocketsPort;
}
}
return port;
}
async Task WriteAsync(ByteBuffer buffer)
{
do
{
try
{
await this.webSocket.SendAsync(new ArraySegment<byte>(buffer.Buffer, buffer.Offset, buffer.Length),
WebSocketMessageType.Binary, true, CancellationToken.None);
}
catch (Exception exception)
{
this.connection.OnIoException(exception);
break;
}
lock (this.bufferQueue)
{
if (this.bufferQueue.Count > 0)
{
buffer = this.bufferQueue.Dequeue();
}
else
{
this.writing = false;
buffer = null;
}
}
}
while (buffer != null);
}
}
}

Просмотреть файл

@ -1,145 +1,145 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
sealed class TcpTransport : ITransport
{
static RemoteCertificateValidationCallback NoVerifyCallback = (a, b, c, d) => true;
ITransport socketTransport;
public void Connect(Connection connection, Address address, bool noVerification)
{
var ipHostEntry = Dns.GetHostEntry(address.Host);
Exception exception = null;
TcpSocket socket = null;
foreach (var ipAddress in ipHostEntry.AddressList)
{
if (ipAddress == null)
{
continue;
}
try
{
socket = new TcpSocket();
socket.Connect(new IPEndPoint(ipAddress, address.Port));
exception = null;
break;
}
catch (SocketException socketException)
{
if (socket != null)
{
socket.Close();
socket = null;
}
exception = socketException;
}
}
if (exception != null)
{
throw exception;
}
if (address.UseSsl)
{
SslSocket sslSocket = new SslSocket(socket, noVerification);
sslSocket.AuthenticateAsClient(address.Host);
this.socketTransport = sslSocket;
}
else
{
this.socketTransport = socket;
}
}
public void Close()
{
this.socketTransport.Close();
}
public void Send(ByteBuffer buffer)
{
this.socketTransport.Send(buffer);
}
public int Receive(byte[] buffer, int offset, int count)
{
return this.socketTransport.Receive(buffer, offset, count);
}
class TcpSocket : Socket, ITransport
{
public TcpSocket()
: base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
}
void ITransport.Send(ByteBuffer buffer)
{
base.Send(buffer.Buffer, buffer.Offset, buffer.Length, SocketFlags.None);
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
return base.Receive(buffer, offset, count, SocketFlags.None);
}
void ITransport.Close()
{
base.Close();
}
}
class SslSocket : SslStream, ITransport
{
Socket socket;
public SslSocket(Socket socket, bool noVerification)
: base(new NetworkStream(socket), false, noVerification ? NoVerifyCallback : null)
{
this.socket = socket;
}
void ITransport.Send(ByteBuffer buffer)
{
base.Write(buffer.Buffer, buffer.Offset, buffer.Length);
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
//if (this.socket.Available <= 0) System.Threading.Thread.Sleep(20);
//Trace.WriteLine(TraceLevel.Information, "Data Available: {0}", this.DataAvailable);
return base.Read(buffer, offset, count);
}
void ITransport.Close()
{
base.Close();
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using System;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
sealed class TcpTransport : ITransport
{
static RemoteCertificateValidationCallback NoVerifyCallback = (a, b, c, d) => true;
ITransport socketTransport;
public void Connect(Connection connection, Address address, bool noVerification)
{
var ipHostEntry = Dns.GetHostEntry(address.Host);
Exception exception = null;
TcpSocket socket = null;
foreach (var ipAddress in ipHostEntry.AddressList)
{
if (ipAddress == null)
{
continue;
}
try
{
socket = new TcpSocket();
socket.Connect(new IPEndPoint(ipAddress, address.Port));
exception = null;
break;
}
catch (SocketException socketException)
{
if (socket != null)
{
socket.Close();
socket = null;
}
exception = socketException;
}
}
if (exception != null)
{
throw exception;
}
if (address.UseSsl)
{
SslSocket sslSocket = new SslSocket(socket, noVerification);
sslSocket.AuthenticateAsClient(address.Host);
this.socketTransport = sslSocket;
}
else
{
this.socketTransport = socket;
}
}
public void Close()
{
this.socketTransport.Close();
}
public void Send(ByteBuffer buffer)
{
this.socketTransport.Send(buffer);
}
public int Receive(byte[] buffer, int offset, int count)
{
return this.socketTransport.Receive(buffer, offset, count);
}
class TcpSocket : Socket, ITransport
{
public TcpSocket()
: base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
}
void ITransport.Send(ByteBuffer buffer)
{
base.Send(buffer.Buffer, buffer.Offset, buffer.Length, SocketFlags.None);
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
return base.Receive(buffer, offset, count, SocketFlags.None);
}
void ITransport.Close()
{
base.Close();
}
}
class SslSocket : SslStream, ITransport
{
Socket socket;
public SslSocket(Socket socket, bool noVerification)
: base(new NetworkStream(socket), false, noVerification ? NoVerifyCallback : null)
{
this.socket = socket;
}
void ITransport.Send(ByteBuffer buffer)
{
base.Write(buffer.Buffer, buffer.Offset, buffer.Length);
}
int ITransport.Receive(byte[] buffer, int offset, int count)
{
//if (this.socket.Available <= 0) System.Threading.Thread.Sleep(20);
//Trace.WriteLine(TraceLevel.Information, "Data Available: {0}", this.DataAvailable);
return base.Read(buffer, offset, count);
}
void ITransport.Close()
{
base.Close();
}
}
}
}

Просмотреть файл

@ -24,9 +24,9 @@ namespace Amqp
sealed class TcpTransport : ITransport
{
ITransport socketTransport;
public void Connect(Connection connection, Address address, bool noVerification)
ITransport socketTransport;
public void Connect(Connection connection, Address address, bool noVerification)
{
var ipHostEntry = Dns.GetHostEntry(address.Host);
Exception exception = null;

Просмотреть файл

@ -24,9 +24,9 @@ namespace Amqp
sealed class TcpTransport : ITransport
{
ITransport socketTransport;
public void Connect(Connection connection, Address address, bool noVerification)
ITransport socketTransport;
public void Connect(Connection connection, Address address, bool noVerification)
{
var ipHostEntry = Dns.GetHostEntry(address.Host);
Exception exception = null;

Просмотреть файл

@ -1,441 +1,441 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using Amqp.Framing;
using Amqp.Types;
using System.Threading;
public delegate void MessageCallback(ReceiverLink receiver, Message message);
public class ReceiverLink : Link
{
#if DOTNET
const int DefaultCredit = 200;
#else
const int DefaultCredit = 20;
#endif
// flow control
SequenceNumber deliveryCount;
int totalCredit;
int credit;
int restored;
// received messages queue
LinkedList receivedMessages;
Delivery deliveryCurrent;
// pending receivers
LinkedList waiterList;
MessageCallback onMessage;
public ReceiverLink(Session session, string name, string adderss)
: this(session, name, new Source() { Address = adderss }, null)
{
}
public ReceiverLink(Session session, string name, Source source, OnAttached onAttached)
: this(session, name, new Attach() { Source = source, Target = new Target() }, onAttached)
{
}
public ReceiverLink(Session session, string name, Attach attach, OnAttached onAttached)
: base(session, name, onAttached)
{
this.totalCredit = -1;
this.receivedMessages = new LinkedList();
this.waiterList = new LinkedList();
this.SendAttach(true, 0, attach);
}
public void Start(int credit, MessageCallback onMessage = null)
{
this.onMessage = onMessage;
this.SetCredit(credit, true);
}
public void SetCredit(int credit, bool autoRestore = true)
{
uint dc;
lock (this.ThisLock)
{
if (this.IsDetaching)
{
return;
}
this.totalCredit = autoRestore ? credit : 0;
this.credit = credit;
this.restored = 0;
dc = this.deliveryCount;
}
this.SendFlow(dc, (uint)credit);
}
public Message Receive(int timeout = 60000)
{
return this.ReceiveInternal(null, timeout);
}
#if DOTNET
public Message Receive(MessageCallback callback, int timeout = 60000)
{
return this.ReceiveInternal(callback, timeout);
}
internal void SetInitialDeliveryCount(uint deliveryCount)
{
this.deliveryCount = deliveryCount;
}
#endif
public void Accept(Message message)
{
this.ThrowIfDetaching("Accept");
this.DisposeMessage(message, new Accepted());
}
public void Release(Message message)
{
this.ThrowIfDetaching("Release");
this.DisposeMessage(message, new Released());
}
public void Reject(Message message, Error error = null)
{
this.ThrowIfDetaching("Reject");
this.DisposeMessage(message, new Rejected() { Error = error });
}
internal override void OnFlow(Flow flow)
{
}
internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
{
if (!transfer.More)
{
Waiter waiter;
MessageCallback callback;
lock (this.ThisLock)
{
if (delivery == null)
{
// multi-transfer delivery
delivery = this.deliveryCurrent;
this.deliveryCurrent = null;
Fx.Assert(delivery != null, "Must have a delivery in the queue");
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
delivery.Message = Message.Decode(delivery.Buffer);
delivery.Buffer = null;
}
else
{
// single tranfer delivery
this.OnDelivery(transfer.DeliveryId);
delivery.Message = Message.Decode(buffer);
}
callback = this.onMessage;
waiter = (Waiter)this.waiterList.First;
if (waiter != null)
{
this.waiterList.Remove(waiter);
}
if (waiter == null && callback == null)
{
this.receivedMessages.Add(new MessageNode() { Message = delivery.Message });
return;
}
}
while (waiter != null)
{
if (waiter.Signal(delivery.Message))
{
this.OnDeliverMessage();
return;
}
lock (this.ThisLock)
{
waiter = (Waiter)this.waiterList.First;
if (waiter != null)
{
this.waiterList.Remove(waiter);
}
else if (callback == null)
{
this.receivedMessages.Add(new MessageNode() { Message = delivery.Message });
return;
}
}
}
Fx.Assert(waiter == null, "waiter must be null now");
Fx.Assert(callback != null, "callback must not be null now");
callback(this, delivery.Message);
this.OnDeliverMessage();
}
else
{
lock (this.ThisLock)
{
if (delivery == null)
{
delivery = this.deliveryCurrent;
Fx.Assert(delivery != null, "Must have a current delivery");
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
}
else
{
this.OnDelivery(transfer.DeliveryId);
delivery.Buffer = new ByteBuffer(buffer.Length * 2, true);
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
this.deliveryCurrent = delivery;
}
}
}
}
internal override void OnAttach(uint remoteHandle, Attach attach)
{
base.OnAttach(remoteHandle, attach);
this.deliveryCount = attach.InitialDeliveryCount;
}
internal override void OnDeliveryStateChanged(Delivery delivery)
{
}
protected override bool OnClose(Error error)
{
this.OnAbort(error);
return base.OnClose(error);
}
protected override void OnAbort(Error error)
{
Waiter waiter;
lock (this.ThisLock)
{
waiter = (Waiter)this.waiterList.Clear();
}
while (waiter != null)
{
waiter.Signal(null);
waiter = (Waiter)waiter.Next;
}
}
void OnDeliverMessage()
{
if (this.totalCredit > 0 &&
Interlocked.Increment(ref this.restored) >= (this.totalCredit / 2))
{
this.SetCredit(this.totalCredit, true);
}
}
Message ReceiveInternal(MessageCallback callback, int timeout = 60000)
{
this.ThrowIfDetaching("Receive");
if (this.totalCredit < 0)
{
this.SetCredit(DefaultCredit, true);
}
Waiter waiter = null;
lock (this.ThisLock)
{
MessageNode first = (MessageNode)this.receivedMessages.First;
if (first != null)
{
this.receivedMessages.Remove(first);
this.OnDeliverMessage();
return first.Message;
}
if (timeout == 0)
{
return null;
}
#if DOTNET
waiter = callback == null ? (Waiter)new SyncWaiter() : new AsyncWaiter(this, callback);
#else
waiter = new SyncWaiter();
#endif
this.waiterList.Add(waiter);
}
return waiter.Wait(timeout);
}
void DisposeMessage(Message message, Outcome outcome)
{
Delivery delivery = message.Delivery;
if (delivery == null || delivery.Settled)
{
return;
}
DeliveryState state = outcome;
bool settled = true;
#if DOTNET
var txnState = Amqp.Transactions.ResourceManager.GetTransactionalStateAsync(this).Result;
if (txnState != null)
{
txnState.Outcome = outcome;
state = txnState;
settled = false;
}
#endif
this.Session.DisposeDelivery(true, delivery, state, settled);
}
void OnDelivery(SequenceNumber deliveryId)
{
// called with lock held
if (this.credit <= 0)
{
throw new AmqpException(ErrorCode.TransferLimitExceeded,
Fx.Format(SRAmqp.DeliveryLimitExceeded, deliveryId));
}
this.deliveryCount++;
this.credit--;
}
sealed class MessageNode : INode
{
public Message Message { get; set; }
public INode Previous { get; set; }
public INode Next { get; set; }
}
abstract class Waiter : INode
{
public INode Previous { get; set; }
public INode Next { get; set; }
public abstract Message Wait(int timeout);
public abstract bool Signal(Message message);
}
sealed class SyncWaiter : Waiter
{
readonly ManualResetEvent signal;
Message message;
bool expired;
public SyncWaiter()
{
this.signal = new ManualResetEvent(false);
}
public override Message Wait(int timeout)
{
this.signal.WaitOne(timeout, false);
lock (this)
{
this.expired = this.message == null;
return this.message;
}
}
public override bool Signal(Message message)
{
bool signaled = false;
lock (this)
{
if (!this.expired)
{
this.message = message;
signaled = true;
}
}
this.signal.Set();
return signaled;
}
}
#if DOTNET
sealed class AsyncWaiter : Waiter
{
readonly static TimerCallback onTimer = OnTimer;
readonly ReceiverLink link;
readonly MessageCallback callback;
Timer timer;
int state; // 0: created, 1: waiting, 2: signaled
public AsyncWaiter(ReceiverLink link, MessageCallback callback)
{
this.link = link;
this.callback = callback;
}
public override Message Wait(int timeout)
{
this.timer = new Timer(onTimer, this, timeout, -1);
if (Interlocked.CompareExchange(ref this.state, 1, 0) != 0)
{
// already signaled
this.timer.Dispose();
}
return null;
}
public override bool Signal(Message message)
{
int old = Interlocked.Exchange(ref this.state, 2);
if (old != 2)
{
if (old == 1)
{
this.timer.Dispose();
}
this.callback(this.link, message);
return true;
}
else
{
return false;
}
}
static void OnTimer(object state)
{
var thisPtr = (AsyncWaiter)state;
thisPtr.Signal(null);
}
}
#endif
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp
{
using Amqp.Framing;
using Amqp.Types;
using System.Threading;
public delegate void MessageCallback(ReceiverLink receiver, Message message);
public class ReceiverLink : Link
{
#if DOTNET
const int DefaultCredit = 200;
#else
const int DefaultCredit = 20;
#endif
// flow control
SequenceNumber deliveryCount;
int totalCredit;
int credit;
int restored;
// received messages queue
LinkedList receivedMessages;
Delivery deliveryCurrent;
// pending receivers
LinkedList waiterList;
MessageCallback onMessage;
public ReceiverLink(Session session, string name, string adderss)
: this(session, name, new Source() { Address = adderss }, null)
{
}
public ReceiverLink(Session session, string name, Source source, OnAttached onAttached)
: this(session, name, new Attach() { Source = source, Target = new Target() }, onAttached)
{
}
public ReceiverLink(Session session, string name, Attach attach, OnAttached onAttached)
: base(session, name, onAttached)
{
this.totalCredit = -1;
this.receivedMessages = new LinkedList();
this.waiterList = new LinkedList();
this.SendAttach(true, 0, attach);
}
public void Start(int credit, MessageCallback onMessage = null)
{
this.onMessage = onMessage;
this.SetCredit(credit, true);
}
public void SetCredit(int credit, bool autoRestore = true)
{
uint dc;
lock (this.ThisLock)
{
if (this.IsDetaching)
{
return;
}
this.totalCredit = autoRestore ? credit : 0;
this.credit = credit;
this.restored = 0;
dc = this.deliveryCount;
}
this.SendFlow(dc, (uint)credit);
}
public Message Receive(int timeout = 60000)
{
return this.ReceiveInternal(null, timeout);
}
#if DOTNET
public Message Receive(MessageCallback callback, int timeout = 60000)
{
return this.ReceiveInternal(callback, timeout);
}
internal void SetInitialDeliveryCount(uint deliveryCount)
{
this.deliveryCount = deliveryCount;
}
#endif
public void Accept(Message message)
{
this.ThrowIfDetaching("Accept");
this.DisposeMessage(message, new Accepted());
}
public void Release(Message message)
{
this.ThrowIfDetaching("Release");
this.DisposeMessage(message, new Released());
}
public void Reject(Message message, Error error = null)
{
this.ThrowIfDetaching("Reject");
this.DisposeMessage(message, new Rejected() { Error = error });
}
internal override void OnFlow(Flow flow)
{
}
internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer)
{
if (!transfer.More)
{
Waiter waiter;
MessageCallback callback;
lock (this.ThisLock)
{
if (delivery == null)
{
// multi-transfer delivery
delivery = this.deliveryCurrent;
this.deliveryCurrent = null;
Fx.Assert(delivery != null, "Must have a delivery in the queue");
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
delivery.Message = Message.Decode(delivery.Buffer);
delivery.Buffer = null;
}
else
{
// single tranfer delivery
this.OnDelivery(transfer.DeliveryId);
delivery.Message = Message.Decode(buffer);
}
callback = this.onMessage;
waiter = (Waiter)this.waiterList.First;
if (waiter != null)
{
this.waiterList.Remove(waiter);
}
if (waiter == null && callback == null)
{
this.receivedMessages.Add(new MessageNode() { Message = delivery.Message });
return;
}
}
while (waiter != null)
{
if (waiter.Signal(delivery.Message))
{
this.OnDeliverMessage();
return;
}
lock (this.ThisLock)
{
waiter = (Waiter)this.waiterList.First;
if (waiter != null)
{
this.waiterList.Remove(waiter);
}
else if (callback == null)
{
this.receivedMessages.Add(new MessageNode() { Message = delivery.Message });
return;
}
}
}
Fx.Assert(waiter == null, "waiter must be null now");
Fx.Assert(callback != null, "callback must not be null now");
callback(this, delivery.Message);
this.OnDeliverMessage();
}
else
{
lock (this.ThisLock)
{
if (delivery == null)
{
delivery = this.deliveryCurrent;
Fx.Assert(delivery != null, "Must have a current delivery");
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
}
else
{
this.OnDelivery(transfer.DeliveryId);
delivery.Buffer = new ByteBuffer(buffer.Length * 2, true);
AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length);
this.deliveryCurrent = delivery;
}
}
}
}
internal override void OnAttach(uint remoteHandle, Attach attach)
{
base.OnAttach(remoteHandle, attach);
this.deliveryCount = attach.InitialDeliveryCount;
}
internal override void OnDeliveryStateChanged(Delivery delivery)
{
}
protected override bool OnClose(Error error)
{
this.OnAbort(error);
return base.OnClose(error);
}
protected override void OnAbort(Error error)
{
Waiter waiter;
lock (this.ThisLock)
{
waiter = (Waiter)this.waiterList.Clear();
}
while (waiter != null)
{
waiter.Signal(null);
waiter = (Waiter)waiter.Next;
}
}
void OnDeliverMessage()
{
if (this.totalCredit > 0 &&
Interlocked.Increment(ref this.restored) >= (this.totalCredit / 2))
{
this.SetCredit(this.totalCredit, true);
}
}
Message ReceiveInternal(MessageCallback callback, int timeout = 60000)
{
this.ThrowIfDetaching("Receive");
if (this.totalCredit < 0)
{
this.SetCredit(DefaultCredit, true);
}
Waiter waiter = null;
lock (this.ThisLock)
{
MessageNode first = (MessageNode)this.receivedMessages.First;
if (first != null)
{
this.receivedMessages.Remove(first);
this.OnDeliverMessage();
return first.Message;
}
if (timeout == 0)
{
return null;
}
#if DOTNET
waiter = callback == null ? (Waiter)new SyncWaiter() : new AsyncWaiter(this, callback);
#else
waiter = new SyncWaiter();
#endif
this.waiterList.Add(waiter);
}
return waiter.Wait(timeout);
}
void DisposeMessage(Message message, Outcome outcome)
{
Delivery delivery = message.Delivery;
if (delivery == null || delivery.Settled)
{
return;
}
DeliveryState state = outcome;
bool settled = true;
#if DOTNET
var txnState = Amqp.Transactions.ResourceManager.GetTransactionalStateAsync(this).Result;
if (txnState != null)
{
txnState.Outcome = outcome;
state = txnState;
settled = false;
}
#endif
this.Session.DisposeDelivery(true, delivery, state, settled);
}
void OnDelivery(SequenceNumber deliveryId)
{
// called with lock held
if (this.credit <= 0)
{
throw new AmqpException(ErrorCode.TransferLimitExceeded,
Fx.Format(SRAmqp.DeliveryLimitExceeded, deliveryId));
}
this.deliveryCount++;
this.credit--;
}
sealed class MessageNode : INode
{
public Message Message { get; set; }
public INode Previous { get; set; }
public INode Next { get; set; }
}
abstract class Waiter : INode
{
public INode Previous { get; set; }
public INode Next { get; set; }
public abstract Message Wait(int timeout);
public abstract bool Signal(Message message);
}
sealed class SyncWaiter : Waiter
{
readonly ManualResetEvent signal;
Message message;
bool expired;
public SyncWaiter()
{
this.signal = new ManualResetEvent(false);
}
public override Message Wait(int timeout)
{
this.signal.WaitOne(timeout, false);
lock (this)
{
this.expired = this.message == null;
return this.message;
}
}
public override bool Signal(Message message)
{
bool signaled = false;
lock (this)
{
if (!this.expired)
{
this.message = message;
signaled = true;
}
}
this.signal.Set();
return signaled;
}
}
#if DOTNET
sealed class AsyncWaiter : Waiter
{
readonly static TimerCallback onTimer = OnTimer;
readonly ReceiverLink link;
readonly MessageCallback callback;
Timer timer;
int state; // 0: created, 1: waiting, 2: signaled
public AsyncWaiter(ReceiverLink link, MessageCallback callback)
{
this.link = link;
this.callback = callback;
}
public override Message Wait(int timeout)
{
this.timer = new Timer(onTimer, this, timeout, -1);
if (Interlocked.CompareExchange(ref this.state, 1, 0) != 0)
{
// already signaled
this.timer.Dispose();
}
return null;
}
public override bool Signal(Message message)
{
int old = Interlocked.Exchange(ref this.state, 2);
if (old != 2)
{
if (old == 1)
{
this.timer.Dispose();
}
this.callback(this.link, message);
return true;
}
else
{
return false;
}
}
static void OnTimer(object state)
{
var thisPtr = (AsyncWaiter)state;
thisPtr.Signal(null);
}
}
#endif
}
}

Просмотреть файл

@ -1,43 +1,43 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
using Amqp.Types;
sealed class SaslExternalProfile : SaslProfile
{
public SaslExternalProfile()
{
}
protected override ITransport UpgradeTransport(ITransport transport)
{
return transport;
}
protected override DescribedList GetStartCommand(string hostname)
{
return new SaslInit() { Mechanism = "EXTERNAL" };
}
protected override DescribedList OnCommand(DescribedList command)
{
return null;
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
using Amqp.Types;
sealed class SaslExternalProfile : SaslProfile
{
public SaslExternalProfile()
{
}
protected override ITransport UpgradeTransport(ITransport transport)
{
return transport;
}
protected override DescribedList GetStartCommand(string hostname)
{
return new SaslInit() { Mechanism = "EXTERNAL" };
}
protected override DescribedList OnCommand(DescribedList command)
{
return null;
}
}
}

Просмотреть файл

@ -1,26 +1,26 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
abstract class SaslMechanism
{
public abstract string Name { get; }
public abstract SaslProfile CreateProfile();
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
abstract class SaslMechanism
{
public abstract string Name { get; }
public abstract SaslProfile CreateProfile();
}
}

Просмотреть файл

@ -1,96 +1,96 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
using System;
using System.Text;
using Amqp.Framing;
using Amqp.Types;
class SaslPlainMechanism : SaslMechanism
{
readonly string user;
readonly string password;
public SaslPlainMechanism(string user, string password)
{
this.user = user;
this.password = password;
}
public override string Name
{
get { return "PLAIN"; }
}
public override SaslProfile CreateProfile()
{
return new SaslPlainProfile(this);
}
class SaslPlainProfile : SaslProfile
{
readonly SaslPlainMechanism mechanism;
public SaslPlainProfile(SaslPlainMechanism mechanism)
{
this.mechanism = mechanism;
}
protected override ITransport UpgradeTransport(ITransport transport)
{
return transport;
}
protected override DescribedList GetStartCommand(string hostname)
{
throw new NotImplementedException();
}
protected override DescribedList OnCommand(DescribedList command)
{
if (command.Descriptor.Code == Codec.SaslInit.Code)
{
SaslInit init = (SaslInit)command;
SaslCode code = this.ValidateCredentials(init);
return new SaslOutcome() { Code = code };
}
throw new AmqpException(ErrorCode.NotAllowed, command.ToString());
}
SaslCode ValidateCredentials(SaslInit init)
{
byte[] response = init.InitialResponse;
if (response.Length > 0)
{
string message = Encoding.UTF8.GetString(response, 0, response.Length);
string[] items = message.Split('\0');
if (items.Length == 3 &&
string.Equals(this.mechanism.user, items[1], StringComparison.OrdinalIgnoreCase) &&
string.Equals(this.mechanism.password, items[2], StringComparison.Ordinal))
{
return SaslCode.Ok;
}
}
return SaslCode.Auth;
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
using System;
using System.Text;
using Amqp.Framing;
using Amqp.Types;
class SaslPlainMechanism : SaslMechanism
{
readonly string user;
readonly string password;
public SaslPlainMechanism(string user, string password)
{
this.user = user;
this.password = password;
}
public override string Name
{
get { return "PLAIN"; }
}
public override SaslProfile CreateProfile()
{
return new SaslPlainProfile(this);
}
class SaslPlainProfile : SaslProfile
{
readonly SaslPlainMechanism mechanism;
public SaslPlainProfile(SaslPlainMechanism mechanism)
{
this.mechanism = mechanism;
}
protected override ITransport UpgradeTransport(ITransport transport)
{
return transport;
}
protected override DescribedList GetStartCommand(string hostname)
{
throw new NotImplementedException();
}
protected override DescribedList OnCommand(DescribedList command)
{
if (command.Descriptor.Code == Codec.SaslInit.Code)
{
SaslInit init = (SaslInit)command;
SaslCode code = this.ValidateCredentials(init);
return new SaslOutcome() { Code = code };
}
throw new AmqpException(ErrorCode.NotAllowed, command.ToString());
}
SaslCode ValidateCredentials(SaslInit init)
{
byte[] response = init.InitialResponse;
if (response.Length > 0)
{
string message = Encoding.UTF8.GetString(response, 0, response.Length);
string[] items = message.Split('\0');
if (items.Length == 3 &&
string.Equals(this.mechanism.user, items[1], StringComparison.OrdinalIgnoreCase) &&
string.Equals(this.mechanism.password, items[2], StringComparison.Ordinal))
{
return SaslCode.Ok;
}
}
return SaslCode.Auth;
}
}
}
}

Просмотреть файл

@ -1,63 +1,63 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
using System;
using System.Text;
using Amqp.Types;
sealed class SaslPlainProfile : SaslProfile
{
readonly string user;
readonly string password;
public SaslPlainProfile(string user, string password)
{
this.user = user;
this.password = password;
}
protected override ITransport UpgradeTransport(ITransport transport)
{
return transport;
}
protected override DescribedList GetStartCommand(string hostname)
{
byte[] b1 = Encoding.UTF8.GetBytes(this.user);
byte[] b2 = Encoding.UTF8.GetBytes(this.password);
byte[] message = new byte[2 + b1.Length + b2.Length];
Array.Copy(b1, 0, message, 1, b1.Length);
Array.Copy(b2, 0, message, b1.Length + 2, b2.Length);
SaslInit init = new SaslInit()
{
Mechanism = "PLAIN",
InitialResponse = message,
HostName = hostname
};
return init;
}
protected override DescribedList OnCommand(DescribedList command)
{
return null;
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
using System;
using System.Text;
using Amqp.Types;
sealed class SaslPlainProfile : SaslProfile
{
readonly string user;
readonly string password;
public SaslPlainProfile(string user, string password)
{
this.user = user;
this.password = password;
}
protected override ITransport UpgradeTransport(ITransport transport)
{
return transport;
}
protected override DescribedList GetStartCommand(string hostname)
{
byte[] b1 = Encoding.UTF8.GetBytes(this.user);
byte[] b2 = Encoding.UTF8.GetBytes(this.password);
byte[] message = new byte[2 + b1.Length + b2.Length];
Array.Copy(b1, 0, message, 1, b1.Length);
Array.Copy(b2, 0, message, b1.Length + 2, b2.Length);
SaslInit init = new SaslInit()
{
Mechanism = "PLAIN",
InitialResponse = message,
HostName = hostname
};
return init;
}
protected override DescribedList OnCommand(DescribedList command)
{
return null;
}
}
}

Просмотреть файл

@ -1,145 +1,145 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
using System;
using Amqp.Framing;
using Amqp.Types;
public abstract class SaslProfile
{
public static SaslProfile External
{
get { return new SaslExternalProfile(); }
}
internal ITransport Open(string hostname, ITransport transport)
{
ProtocolHeader myHeader = this.Start(hostname, transport);
ProtocolHeader theirHeader = Reader.ReadHeader(transport);
Trace.WriteLine(TraceLevel.Frame, "RECV AMQP {0}", theirHeader);
this.OnHeader(myHeader, theirHeader);
SaslCode code = SaslCode.SysTemp;
while (true)
{
ByteBuffer buffer = Reader.ReadFrameBuffer(transport, new byte[4], uint.MaxValue);
if (buffer == null)
{
throw new ObjectDisposedException(transport.GetType().Name);
}
if (!this.OnFrame(transport, buffer, out code))
{
break;
}
}
if (code != SaslCode.Ok)
{
throw new AmqpException(ErrorCode.UnauthorizedAccess,
Fx.Format(SRAmqp.SaslNegoFailed, code));
}
return this.UpgradeTransport(transport);
}
internal ProtocolHeader Start(string hostname, ITransport transport)
{
ProtocolHeader myHeader = new ProtocolHeader() { Id = 3, Major = 1, Minor = 0, Revision = 0 };
ByteBuffer headerBuffer = new ByteBuffer(
new byte[] { (byte)'A', (byte)'M', (byte)'Q', (byte)'P', myHeader.Id, myHeader.Major, myHeader.Minor, myHeader.Revision },
0,
8,
8);
transport.Send(headerBuffer);
Trace.WriteLine(TraceLevel.Frame, "SEND AMQP {0}", myHeader);
DescribedList command = this.GetStartCommand(hostname);
if (command != null)
{
this.SendCommand(transport, command);
}
return myHeader;
}
internal void OnHeader(ProtocolHeader myHeader, ProtocolHeader theirHeader)
{
if (theirHeader.Id != myHeader.Id || theirHeader.Major != myHeader.Major ||
theirHeader.Minor != myHeader.Minor || theirHeader.Revision != myHeader.Revision)
{
throw new AmqpException(ErrorCode.NotImplemented, theirHeader.ToString());
}
}
internal bool OnFrame(ITransport transport, ByteBuffer buffer, out SaslCode code)
{
ushort channel;
DescribedList command;
Frame.GetFrame(buffer, out channel, out command);
Trace.WriteLine(TraceLevel.Frame, "RECV {0}", command);
bool shouldContinue = true;
if (command.Descriptor.Code == Codec.SaslOutcome.Code)
{
code = ((SaslOutcome)command).Code;
shouldContinue = false;
}
else
{
code = SaslCode.Ok;
DescribedList response = this.OnCommand(command);
if (response != null)
{
this.SendCommand(transport, response);
shouldContinue = response.Descriptor.Code != Codec.SaslOutcome.Code;
}
}
return shouldContinue;
}
internal DescribedList OnCommandInternal(DescribedList command)
{
return this.OnCommand(command);
}
internal ITransport UpgradeTransportInternal(ITransport transport)
{
return this.UpgradeTransport(transport);
}
// if a profile handles signing and/or encryption, it should create
// a new transport
protected abstract ITransport UpgradeTransport(ITransport transport);
protected abstract DescribedList GetStartCommand(string hostname);
protected abstract DescribedList OnCommand(DescribedList command);
void SendCommand(ITransport transport, DescribedList command)
{
ByteBuffer buffer = Frame.Encode(FrameType.Sasl, 0, command);
transport.Send(buffer);
Trace.WriteLine(TraceLevel.Frame, "SEND {0}", command);
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Sasl
{
using System;
using Amqp.Framing;
using Amqp.Types;
public abstract class SaslProfile
{
public static SaslProfile External
{
get { return new SaslExternalProfile(); }
}
internal ITransport Open(string hostname, ITransport transport)
{
ProtocolHeader myHeader = this.Start(hostname, transport);
ProtocolHeader theirHeader = Reader.ReadHeader(transport);
Trace.WriteLine(TraceLevel.Frame, "RECV AMQP {0}", theirHeader);
this.OnHeader(myHeader, theirHeader);
SaslCode code = SaslCode.SysTemp;
while (true)
{
ByteBuffer buffer = Reader.ReadFrameBuffer(transport, new byte[4], uint.MaxValue);
if (buffer == null)
{
throw new ObjectDisposedException(transport.GetType().Name);
}
if (!this.OnFrame(transport, buffer, out code))
{
break;
}
}
if (code != SaslCode.Ok)
{
throw new AmqpException(ErrorCode.UnauthorizedAccess,
Fx.Format(SRAmqp.SaslNegoFailed, code));
}
return this.UpgradeTransport(transport);
}
internal ProtocolHeader Start(string hostname, ITransport transport)
{
ProtocolHeader myHeader = new ProtocolHeader() { Id = 3, Major = 1, Minor = 0, Revision = 0 };
ByteBuffer headerBuffer = new ByteBuffer(
new byte[] { (byte)'A', (byte)'M', (byte)'Q', (byte)'P', myHeader.Id, myHeader.Major, myHeader.Minor, myHeader.Revision },
0,
8,
8);
transport.Send(headerBuffer);
Trace.WriteLine(TraceLevel.Frame, "SEND AMQP {0}", myHeader);
DescribedList command = this.GetStartCommand(hostname);
if (command != null)
{
this.SendCommand(transport, command);
}
return myHeader;
}
internal void OnHeader(ProtocolHeader myHeader, ProtocolHeader theirHeader)
{
if (theirHeader.Id != myHeader.Id || theirHeader.Major != myHeader.Major ||
theirHeader.Minor != myHeader.Minor || theirHeader.Revision != myHeader.Revision)
{
throw new AmqpException(ErrorCode.NotImplemented, theirHeader.ToString());
}
}
internal bool OnFrame(ITransport transport, ByteBuffer buffer, out SaslCode code)
{
ushort channel;
DescribedList command;
Frame.GetFrame(buffer, out channel, out command);
Trace.WriteLine(TraceLevel.Frame, "RECV {0}", command);
bool shouldContinue = true;
if (command.Descriptor.Code == Codec.SaslOutcome.Code)
{
code = ((SaslOutcome)command).Code;
shouldContinue = false;
}
else
{
code = SaslCode.Ok;
DescribedList response = this.OnCommand(command);
if (response != null)
{
this.SendCommand(transport, response);
shouldContinue = response.Descriptor.Code != Codec.SaslOutcome.Code;
}
}
return shouldContinue;
}
internal DescribedList OnCommandInternal(DescribedList command)
{
return this.OnCommand(command);
}
internal ITransport UpgradeTransportInternal(ITransport transport)
{
return this.UpgradeTransport(transport);
}
// if a profile handles signing and/or encryption, it should create
// a new transport
protected abstract ITransport UpgradeTransport(ITransport transport);
protected abstract DescribedList GetStartCommand(string hostname);
protected abstract DescribedList OnCommand(DescribedList command);
void SendCommand(ITransport transport, DescribedList command)
{
ByteBuffer buffer = Frame.Encode(FrameType.Sasl, 0, command);
transport.Send(buffer);
Trace.WriteLine(TraceLevel.Frame, "SEND {0}", command);
}
}
}

Просмотреть файл

@ -1,55 +1,55 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,
AllowMultiple = false, Inherited = true)]
public sealed class AmqpContractAttribute : Attribute
{
public AmqpContractAttribute()
{
this.Encoding = EncodingType.List;
this.Code = -1;
}
public string Name
{
get;
set;
}
public long Code
{
get;
set;
}
public EncodingType Encoding
{
get;
set;
}
internal ulong? InternalCode
{
get { return this.Code >= 0 ? (ulong?)this.Code : null; }
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,
AllowMultiple = false, Inherited = true)]
public sealed class AmqpContractAttribute : Attribute
{
public AmqpContractAttribute()
{
this.Encoding = EncodingType.List;
this.Code = -1;
}
public string Name
{
get;
set;
}
public long Code
{
get;
set;
}
public EncodingType Encoding
{
get;
set;
}
internal ulong? InternalCode
{
get { return this.Code >= 0 ? (ulong?)this.Code : null; }
}
}
}

Просмотреть файл

@ -1,46 +1,46 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field,
AllowMultiple = false, Inherited = true)]
public sealed class AmqpMemberAttribute : Attribute
{
int? order;
public string Name
{
get;
set;
}
public int Order
{
get { return this.order.HasValue ? this.order.Value : 0; }
set { this.order = value; }
}
internal int? InternalOrder
{
get { return this.order; }
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field,
AllowMultiple = false, Inherited = true)]
public sealed class AmqpMemberAttribute : Attribute
{
int? order;
public string Name
{
get;
set;
}
public int Order
{
get { return this.order.HasValue ? this.order.Value : 0; }
set { this.order = value; }
}
internal int? InternalOrder
{
get { return this.order; }
}
}
}

Просмотреть файл

@ -1,38 +1,38 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,
Inherited = true, AllowMultiple = true)]
public sealed class AmqpProvidesAttribute : Attribute
{
readonly Type type;
public AmqpProvidesAttribute(Type type)
{
this.type = type;
}
public Type Type
{
get { return this.type; }
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,
Inherited = true, AllowMultiple = true)]
public sealed class AmqpProvidesAttribute : Attribute
{
readonly Type type;
public AmqpProvidesAttribute(Type type)
{
this.type = type;
}
public Type Type
{
get { return this.type; }
}
}
}

Просмотреть файл

@ -1,25 +1,25 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
public enum EncodingType
{
List,
Map
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
public enum EncodingType
{
List,
Map
}
}

Просмотреть файл

@ -1,31 +1,31 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
public interface IAmqpSerializable
{
int EncodeSize
{
get;
}
void Encode(ByteBuffer buffer);
void Decode(ByteBuffer buffer);
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
public interface IAmqpSerializable
{
int EncodeSize
{
get;
}
void Encode(ByteBuffer buffer);
void Decode(ByteBuffer buffer);
}
}

Просмотреть файл

@ -1,187 +1,187 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Serialization;
abstract class MemberAccessor
{
readonly Type type;
Func<object, object> getter;
Action<object, object> setter;
protected MemberAccessor(Type type)
{
this.type = type;
}
public Type Type
{
get { return this.type; }
}
public static MemberAccessor Create(MemberInfo memberInfo, bool requiresSetter)
{
if (memberInfo.MemberType == MemberTypes.Field)
{
return new FieldMemberAccessor((FieldInfo)memberInfo);
}
else if (memberInfo.MemberType == MemberTypes.Property)
{
return new PropertyMemberAccessor((PropertyInfo)memberInfo, requiresSetter);
}
throw new NotSupportedException(memberInfo.MemberType.ToString());
}
public object Get(object container)
{
return this.getter(container);
}
public void Set(object container, object value)
{
this.setter(container, value);
}
static void EmitTypeConversion(ILGenerator generator, Type castType, bool isContainer)
{
if (castType == typeof(object))
{
}
else if (castType.IsValueType)
{
generator.Emit(isContainer ? OpCodes.Unbox : OpCodes.Unbox_Any, castType);
}
else
{
generator.Emit(OpCodes.Castclass, castType);
}
}
static void EmitCall(ILGenerator generator, MethodInfo method)
{
OpCode opcode = (method.IsStatic || method.DeclaringType.IsValueType) ? OpCodes.Call : OpCodes.Callvirt;
generator.EmitCall(opcode, method, null);
}
static string GetAccessorName(bool isGetter, string name)
{
return (isGetter ? "get_" : "set_") + name;
}
sealed class FieldMemberAccessor : MemberAccessor
{
public FieldMemberAccessor(FieldInfo fieldInfo)
: base(fieldInfo.FieldType)
{
this.InitializeGetter(fieldInfo);
this.InitializeSetter(fieldInfo);
}
void InitializeGetter(FieldInfo fieldInfo)
{
DynamicMethod method = new DynamicMethod(GetAccessorName(true, fieldInfo.Name), typeof(object), new[] { typeof(object) }, true);
ILGenerator generator = method.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
EmitTypeConversion(generator, fieldInfo.DeclaringType, true);
generator.Emit(OpCodes.Ldfld, fieldInfo);
if (fieldInfo.FieldType.IsValueType)
{
generator.Emit(OpCodes.Box, fieldInfo.FieldType);
}
generator.Emit(OpCodes.Ret);
this.getter = (Func<object, object>)method.CreateDelegate(typeof(Func<object, object>));
}
void InitializeSetter(FieldInfo fieldInfo)
{
DynamicMethod method = new DynamicMethod(GetAccessorName(false, fieldInfo.Name), typeof(void), new[] { typeof(object), typeof(object) }, true);
ILGenerator generator = method.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
EmitTypeConversion(generator, fieldInfo.DeclaringType, true);
generator.Emit(OpCodes.Ldarg_1);
EmitTypeConversion(generator, fieldInfo.FieldType, false);
generator.Emit(OpCodes.Stfld, fieldInfo);
generator.Emit(OpCodes.Ret);
this.setter = (Action<object, object>)method.CreateDelegate(typeof(Action<object, object>));
}
}
sealed class PropertyMemberAccessor : MemberAccessor
{
public PropertyMemberAccessor(PropertyInfo propertyInfo, bool requiresSetter)
: base(propertyInfo.PropertyType)
{
this.InitializeGetter(propertyInfo);
this.InitializeSetter(propertyInfo, requiresSetter);
}
void InitializeGetter(PropertyInfo propertyInfo)
{
DynamicMethod method = new DynamicMethod(GetAccessorName(true, propertyInfo.Name), typeof(object), new[] { typeof(object) }, true);
ILGenerator generator = method.GetILGenerator();
generator.DeclareLocal(typeof(object));
generator.Emit(OpCodes.Ldarg_0);
EmitTypeConversion(generator, propertyInfo.DeclaringType, true);
EmitCall(generator, propertyInfo.GetGetMethod(true));
if (propertyInfo.PropertyType.IsValueType)
{
generator.Emit(OpCodes.Box, propertyInfo.PropertyType);
}
generator.Emit(OpCodes.Ret);
this.getter = (Func<object, object>)method.CreateDelegate(typeof(Func<object, object>));
}
void InitializeSetter(PropertyInfo propertyInfo, bool requiresSetter)
{
MethodInfo setMethod = propertyInfo.GetSetMethod(true);
if (setMethod == null)
{
if (requiresSetter)
{
throw new SerializationException("Property annotated with AmqpMemberAttribute must have a setter.");
}
else
{
return;
}
}
DynamicMethod method = new DynamicMethod(GetAccessorName(false, propertyInfo.Name), typeof(void), new[] { typeof(object), typeof(object) }, true);
ILGenerator generator = method.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
EmitTypeConversion(generator, propertyInfo.DeclaringType, true);
generator.Emit(OpCodes.Ldarg_1);
EmitTypeConversion(generator, propertyInfo.PropertyType, false);
EmitCall(generator, setMethod);
generator.Emit(OpCodes.Ret);
this.setter = (Action<object, object>)method.CreateDelegate(typeof(Action<object, object>));
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Serialization;
abstract class MemberAccessor
{
readonly Type type;
Func<object, object> getter;
Action<object, object> setter;
protected MemberAccessor(Type type)
{
this.type = type;
}
public Type Type
{
get { return this.type; }
}
public static MemberAccessor Create(MemberInfo memberInfo, bool requiresSetter)
{
if (memberInfo.MemberType == MemberTypes.Field)
{
return new FieldMemberAccessor((FieldInfo)memberInfo);
}
else if (memberInfo.MemberType == MemberTypes.Property)
{
return new PropertyMemberAccessor((PropertyInfo)memberInfo, requiresSetter);
}
throw new NotSupportedException(memberInfo.MemberType.ToString());
}
public object Get(object container)
{
return this.getter(container);
}
public void Set(object container, object value)
{
this.setter(container, value);
}
static void EmitTypeConversion(ILGenerator generator, Type castType, bool isContainer)
{
if (castType == typeof(object))
{
}
else if (castType.IsValueType)
{
generator.Emit(isContainer ? OpCodes.Unbox : OpCodes.Unbox_Any, castType);
}
else
{
generator.Emit(OpCodes.Castclass, castType);
}
}
static void EmitCall(ILGenerator generator, MethodInfo method)
{
OpCode opcode = (method.IsStatic || method.DeclaringType.IsValueType) ? OpCodes.Call : OpCodes.Callvirt;
generator.EmitCall(opcode, method, null);
}
static string GetAccessorName(bool isGetter, string name)
{
return (isGetter ? "get_" : "set_") + name;
}
sealed class FieldMemberAccessor : MemberAccessor
{
public FieldMemberAccessor(FieldInfo fieldInfo)
: base(fieldInfo.FieldType)
{
this.InitializeGetter(fieldInfo);
this.InitializeSetter(fieldInfo);
}
void InitializeGetter(FieldInfo fieldInfo)
{
DynamicMethod method = new DynamicMethod(GetAccessorName(true, fieldInfo.Name), typeof(object), new[] { typeof(object) }, true);
ILGenerator generator = method.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
EmitTypeConversion(generator, fieldInfo.DeclaringType, true);
generator.Emit(OpCodes.Ldfld, fieldInfo);
if (fieldInfo.FieldType.IsValueType)
{
generator.Emit(OpCodes.Box, fieldInfo.FieldType);
}
generator.Emit(OpCodes.Ret);
this.getter = (Func<object, object>)method.CreateDelegate(typeof(Func<object, object>));
}
void InitializeSetter(FieldInfo fieldInfo)
{
DynamicMethod method = new DynamicMethod(GetAccessorName(false, fieldInfo.Name), typeof(void), new[] { typeof(object), typeof(object) }, true);
ILGenerator generator = method.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
EmitTypeConversion(generator, fieldInfo.DeclaringType, true);
generator.Emit(OpCodes.Ldarg_1);
EmitTypeConversion(generator, fieldInfo.FieldType, false);
generator.Emit(OpCodes.Stfld, fieldInfo);
generator.Emit(OpCodes.Ret);
this.setter = (Action<object, object>)method.CreateDelegate(typeof(Action<object, object>));
}
}
sealed class PropertyMemberAccessor : MemberAccessor
{
public PropertyMemberAccessor(PropertyInfo propertyInfo, bool requiresSetter)
: base(propertyInfo.PropertyType)
{
this.InitializeGetter(propertyInfo);
this.InitializeSetter(propertyInfo, requiresSetter);
}
void InitializeGetter(PropertyInfo propertyInfo)
{
DynamicMethod method = new DynamicMethod(GetAccessorName(true, propertyInfo.Name), typeof(object), new[] { typeof(object) }, true);
ILGenerator generator = method.GetILGenerator();
generator.DeclareLocal(typeof(object));
generator.Emit(OpCodes.Ldarg_0);
EmitTypeConversion(generator, propertyInfo.DeclaringType, true);
EmitCall(generator, propertyInfo.GetGetMethod(true));
if (propertyInfo.PropertyType.IsValueType)
{
generator.Emit(OpCodes.Box, propertyInfo.PropertyType);
}
generator.Emit(OpCodes.Ret);
this.getter = (Func<object, object>)method.CreateDelegate(typeof(Func<object, object>));
}
void InitializeSetter(PropertyInfo propertyInfo, bool requiresSetter)
{
MethodInfo setMethod = propertyInfo.GetSetMethod(true);
if (setMethod == null)
{
if (requiresSetter)
{
throw new SerializationException("Property annotated with AmqpMemberAttribute must have a setter.");
}
else
{
return;
}
}
DynamicMethod method = new DynamicMethod(GetAccessorName(false, propertyInfo.Name), typeof(void), new[] { typeof(object), typeof(object) }, true);
ILGenerator generator = method.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
EmitTypeConversion(generator, propertyInfo.DeclaringType, true);
generator.Emit(OpCodes.Ldarg_1);
EmitTypeConversion(generator, propertyInfo.PropertyType, false);
EmitCall(generator, setMethod);
generator.Emit(OpCodes.Ret);
this.setter = (Action<object, object>)method.CreateDelegate(typeof(Action<object, object>));
}
}
}
}

Просмотреть файл

@ -1,167 +1,167 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
using System.Reflection;
using System.Reflection.Emit;
abstract class MethodAccessor
{
delegate object MethodDelegate(object container, object[] parameters);
static readonly Type[] delegateParamsType = { typeof(object), typeof(object[]) };
bool isStatic;
MethodDelegate methodDelegate;
public static MethodAccessor Create(MethodInfo methodInfo)
{
return new TypeMethodAccessor(methodInfo);
}
public static MethodAccessor Create(ConstructorInfo constructorInfo)
{
return new ConstructorAccessor(constructorInfo);
}
public object Invoke(object[] parameters)
{
if (!this.isStatic)
{
throw new InvalidOperationException("Instance required to call an instance method.");
}
return this.Invoke(null, parameters);
}
public object Invoke(object container, object[] parameters)
{
if (this.isStatic && container != null)
{
throw new InvalidOperationException("Static method must be called with null instance.");
}
return this.methodDelegate(container, parameters);
}
Type[] GetParametersType(ParameterInfo[] paramsInfo)
{
Type[] paramsType = new Type[paramsInfo.Length];
for (int i = 0; i < paramsInfo.Length; i++)
{
paramsType[i] = paramsInfo[i].ParameterType.IsByRef ? paramsInfo[i].ParameterType.GetElementType() : paramsInfo[i].ParameterType;
}
return paramsType;
}
void LoadArguments(ILGenerator generator, Type[] paramsType)
{
for (int i = 0; i < paramsType.Length; i++)
{
generator.Emit(OpCodes.Ldarg_1);
switch (i)
{
case 0: generator.Emit(OpCodes.Ldc_I4_0); break;
case 1: generator.Emit(OpCodes.Ldc_I4_1); break;
case 2: generator.Emit(OpCodes.Ldc_I4_2); break;
case 3: generator.Emit(OpCodes.Ldc_I4_3); break;
case 4: generator.Emit(OpCodes.Ldc_I4_4); break;
case 5: generator.Emit(OpCodes.Ldc_I4_5); break;
case 6: generator.Emit(OpCodes.Ldc_I4_6); break;
case 7: generator.Emit(OpCodes.Ldc_I4_7); break;
case 8: generator.Emit(OpCodes.Ldc_I4_8); break;
default: generator.Emit(OpCodes.Ldc_I4, i); break;
}
generator.Emit(OpCodes.Ldelem_Ref);
if (paramsType[i].IsValueType)
{
generator.Emit(OpCodes.Unbox_Any, paramsType[i]);
}
else if (paramsType[i] != typeof(object))
{
generator.Emit(OpCodes.Castclass, paramsType[i]);
}
}
}
sealed class ConstructorAccessor : MethodAccessor
{
public ConstructorAccessor(ConstructorInfo constructorInfo)
{
this.isStatic = true;
DynamicMethod method = new DynamicMethod("ctor_" + constructorInfo.DeclaringType.Name, typeof(object), delegateParamsType, true);
Type[] paramsType = this.GetParametersType(constructorInfo.GetParameters());
ILGenerator generator = method.GetILGenerator();
this.LoadArguments(generator, paramsType);
generator.Emit(OpCodes.Newobj, constructorInfo);
if (constructorInfo.DeclaringType.IsValueType)
{
generator.Emit(OpCodes.Box, constructorInfo.DeclaringType);
}
generator.Emit(OpCodes.Ret);
this.methodDelegate = (MethodDelegate)method.CreateDelegate(typeof(MethodDelegate));
}
}
sealed class TypeMethodAccessor : MethodAccessor
{
public TypeMethodAccessor(MethodInfo methodInfo)
{
Type[] paramsType = this.GetParametersType(methodInfo.GetParameters());
DynamicMethod method = new DynamicMethod("method_" + methodInfo.Name, typeof(object), delegateParamsType, true);
ILGenerator generator = method.GetILGenerator();
if (!this.isStatic)
{
generator.Emit(OpCodes.Ldarg_0);
if (methodInfo.DeclaringType.IsValueType)
{
generator.Emit(OpCodes.Unbox_Any, methodInfo.DeclaringType);
}
else
{
generator.Emit(OpCodes.Castclass, methodInfo.DeclaringType);
}
}
this.LoadArguments(generator, paramsType);
if (methodInfo.IsFinal)
{
generator.Emit(OpCodes.Call, methodInfo);
}
else
{
generator.Emit(OpCodes.Callvirt, methodInfo);
}
if (methodInfo.ReturnType == typeof(void))
{
generator.Emit(OpCodes.Ldnull);
}
else if (methodInfo.ReturnType.IsValueType)
{
generator.Emit(OpCodes.Box, methodInfo.ReturnType);
}
generator.Emit(OpCodes.Ret);
this.methodDelegate = (MethodDelegate)method.CreateDelegate(typeof(MethodDelegate));
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
using System;
using System.Reflection;
using System.Reflection.Emit;
abstract class MethodAccessor
{
delegate object MethodDelegate(object container, object[] parameters);
static readonly Type[] delegateParamsType = { typeof(object), typeof(object[]) };
bool isStatic;
MethodDelegate methodDelegate;
public static MethodAccessor Create(MethodInfo methodInfo)
{
return new TypeMethodAccessor(methodInfo);
}
public static MethodAccessor Create(ConstructorInfo constructorInfo)
{
return new ConstructorAccessor(constructorInfo);
}
public object Invoke(object[] parameters)
{
if (!this.isStatic)
{
throw new InvalidOperationException("Instance required to call an instance method.");
}
return this.Invoke(null, parameters);
}
public object Invoke(object container, object[] parameters)
{
if (this.isStatic && container != null)
{
throw new InvalidOperationException("Static method must be called with null instance.");
}
return this.methodDelegate(container, parameters);
}
Type[] GetParametersType(ParameterInfo[] paramsInfo)
{
Type[] paramsType = new Type[paramsInfo.Length];
for (int i = 0; i < paramsInfo.Length; i++)
{
paramsType[i] = paramsInfo[i].ParameterType.IsByRef ? paramsInfo[i].ParameterType.GetElementType() : paramsInfo[i].ParameterType;
}
return paramsType;
}
void LoadArguments(ILGenerator generator, Type[] paramsType)
{
for (int i = 0; i < paramsType.Length; i++)
{
generator.Emit(OpCodes.Ldarg_1);
switch (i)
{
case 0: generator.Emit(OpCodes.Ldc_I4_0); break;
case 1: generator.Emit(OpCodes.Ldc_I4_1); break;
case 2: generator.Emit(OpCodes.Ldc_I4_2); break;
case 3: generator.Emit(OpCodes.Ldc_I4_3); break;
case 4: generator.Emit(OpCodes.Ldc_I4_4); break;
case 5: generator.Emit(OpCodes.Ldc_I4_5); break;
case 6: generator.Emit(OpCodes.Ldc_I4_6); break;
case 7: generator.Emit(OpCodes.Ldc_I4_7); break;
case 8: generator.Emit(OpCodes.Ldc_I4_8); break;
default: generator.Emit(OpCodes.Ldc_I4, i); break;
}
generator.Emit(OpCodes.Ldelem_Ref);
if (paramsType[i].IsValueType)
{
generator.Emit(OpCodes.Unbox_Any, paramsType[i]);
}
else if (paramsType[i] != typeof(object))
{
generator.Emit(OpCodes.Castclass, paramsType[i]);
}
}
}
sealed class ConstructorAccessor : MethodAccessor
{
public ConstructorAccessor(ConstructorInfo constructorInfo)
{
this.isStatic = true;
DynamicMethod method = new DynamicMethod("ctor_" + constructorInfo.DeclaringType.Name, typeof(object), delegateParamsType, true);
Type[] paramsType = this.GetParametersType(constructorInfo.GetParameters());
ILGenerator generator = method.GetILGenerator();
this.LoadArguments(generator, paramsType);
generator.Emit(OpCodes.Newobj, constructorInfo);
if (constructorInfo.DeclaringType.IsValueType)
{
generator.Emit(OpCodes.Box, constructorInfo.DeclaringType);
}
generator.Emit(OpCodes.Ret);
this.methodDelegate = (MethodDelegate)method.CreateDelegate(typeof(MethodDelegate));
}
}
sealed class TypeMethodAccessor : MethodAccessor
{
public TypeMethodAccessor(MethodInfo methodInfo)
{
Type[] paramsType = this.GetParametersType(methodInfo.GetParameters());
DynamicMethod method = new DynamicMethod("method_" + methodInfo.Name, typeof(object), delegateParamsType, true);
ILGenerator generator = method.GetILGenerator();
if (!this.isStatic)
{
generator.Emit(OpCodes.Ldarg_0);
if (methodInfo.DeclaringType.IsValueType)
{
generator.Emit(OpCodes.Unbox_Any, methodInfo.DeclaringType);
}
else
{
generator.Emit(OpCodes.Castclass, methodInfo.DeclaringType);
}
}
this.LoadArguments(generator, paramsType);
if (methodInfo.IsFinal)
{
generator.Emit(OpCodes.Call, methodInfo);
}
else
{
generator.Emit(OpCodes.Callvirt, methodInfo);
}
if (methodInfo.ReturnType == typeof(void))
{
generator.Emit(OpCodes.Ldnull);
}
else if (methodInfo.ReturnType.IsValueType)
{
generator.Emit(OpCodes.Box, methodInfo.ReturnType);
}
generator.Emit(OpCodes.Ret);
this.methodDelegate = (MethodDelegate)method.CreateDelegate(typeof(MethodDelegate));
}
}
}
}

Просмотреть файл

@ -1,46 +1,46 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
sealed class SerialiableMember
{
public string Name
{
get;
set;
}
public int Order
{
get;
set;
}
public MemberAccessor Accessor
{
get;
set;
}
public SerializableType Type
{
get;
set;
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Serialization
{
sealed class SerialiableMember
{
public string Name
{
get;
set;
}
public int Order
{
get;
set;
}
public MemberAccessor Accessor
{
get;
set;
}
public SerializableType Type
{
get;
set;
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,70 +1,70 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Transactions
{
using System;
using System.Threading.Tasks;
using Amqp;
using Amqp.Framing;
sealed class Controller : SenderLink
{
public Controller(Session session)
: base(session, GetName(), new Attach() { Target = new Coordinator(), Source = new Source() }, null)
{
}
public Task<byte[]> DeclareAsync()
{
Message message = new Message(new Declare());
TaskCompletionSource<byte[]> tcs = new TaskCompletionSource<byte[]>();
this.Send(message, null, false, OnOutcome, tcs);
return tcs.Task;
}
public Task DischargeAsync(byte[] txnId, bool fail)
{
Message message = new Message(new Discharge() { TxnId = txnId, Fail = fail });
TaskCompletionSource<byte[]> tcs = new TaskCompletionSource<byte[]>();
this.Send(message, null, false, OnOutcome, tcs);
return tcs.Task;
}
static string GetName()
{
return "controller-link-" + Guid.NewGuid().ToString("N").Substring(0, 5);
}
static void OnOutcome(Message message, Outcome outcome, object state)
{
var tcs = (TaskCompletionSource<byte[]>)state;
if (outcome.Descriptor.Code == Codec.Declared.Code)
{
tcs.SetResult(((Declared)outcome).TxnId);
}
else if (outcome.Descriptor.Code == Codec.Rejected.Code)
{
tcs.SetException(new AmqpException(((Rejected)outcome).Error));
}
else
{
tcs.SetCanceled();
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Transactions
{
using System;
using System.Threading.Tasks;
using Amqp;
using Amqp.Framing;
sealed class Controller : SenderLink
{
public Controller(Session session)
: base(session, GetName(), new Attach() { Target = new Coordinator(), Source = new Source() }, null)
{
}
public Task<byte[]> DeclareAsync()
{
Message message = new Message(new Declare());
TaskCompletionSource<byte[]> tcs = new TaskCompletionSource<byte[]>();
this.Send(message, null, false, OnOutcome, tcs);
return tcs.Task;
}
public Task DischargeAsync(byte[] txnId, bool fail)
{
Message message = new Message(new Discharge() { TxnId = txnId, Fail = fail });
TaskCompletionSource<byte[]> tcs = new TaskCompletionSource<byte[]>();
this.Send(message, null, false, OnOutcome, tcs);
return tcs.Task;
}
static string GetName()
{
return "controller-link-" + Guid.NewGuid().ToString("N").Substring(0, 5);
}
static void OnOutcome(Message message, Outcome outcome, object state)
{
var tcs = (TaskCompletionSource<byte[]>)state;
if (outcome.Descriptor.Code == Codec.Declared.Code)
{
tcs.SetResult(((Declared)outcome).TxnId);
}
else if (outcome.Descriptor.Code == Codec.Rejected.Code)
{
tcs.SetException(new AmqpException(((Rejected)outcome).Error));
}
else
{
tcs.SetCanceled();
}
}
}
}

Просмотреть файл

@ -1,213 +1,213 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Transactions
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Transactions;
using Amqp;
using Amqp.Framing;
sealed class ResourceManager
{
static readonly ResourceManager instance = new ResourceManager();
readonly Dictionary<Connection, Controller> controllers;
readonly Dictionary<string, Enlistment> enlistments;
ResourceManager()
{
this.controllers = new Dictionary<Connection, Controller>();
this.enlistments = new Dictionary<string, Enlistment>(StringComparer.OrdinalIgnoreCase);
}
object SyncRoot { get { return this.enlistments; } }
public static async Task<TransactionalState> GetTransactionalStateAsync(Link link)
{
Transaction txn = Transaction.Current;
if (txn != null)
{
byte[] txnId = await instance.EnlistAsync(link, txn);
return new TransactionalState() { TxnId = txnId };
}
return null;
}
async Task<byte[]> EnlistAsync(Link link, Transaction txn)
{
string id = txn.TransactionInformation.LocalIdentifier;
Enlistment enlistment;
lock (this.SyncRoot)
{
if (!this.enlistments.TryGetValue(id, out enlistment))
{
enlistment = new Enlistment(this, txn);
this.enlistments.Add(id, enlistment);
txn.TransactionCompleted += this.OnTransactionCompleted;
if (!txn.EnlistPromotableSinglePhase(enlistment))
{
this.enlistments.Remove(id);
txn.TransactionCompleted -= this.OnTransactionCompleted;
throw new InvalidOperationException("DTC not supported");
}
}
}
return await enlistment.EnlistAsync(link);
}
void OnTransactionCompleted(object sender, TransactionEventArgs e)
{
lock (this.SyncRoot)
{
this.enlistments.Remove(e.Transaction.TransactionInformation.LocalIdentifier);
}
}
Controller GetOrCreateController(Link link)
{
Controller controller;
lock (this.SyncRoot)
{
if (!this.controllers.TryGetValue(link.Session.Connection, out controller))
{
Session session = new Session(link.Session.Connection);
controller = new Controller(session);
controller.Closed += this.OnControllerClosed;
this.controllers.Add(link.Session.Connection, controller);
}
}
return controller;
}
void OnControllerClosed(AmqpObject obj, Error error)
{
var controller = (Controller)obj;
bool removed;
lock (this.SyncRoot)
{
removed = this.controllers.Remove(controller.Session.Connection);
}
if (removed)
{
controller.Session.Close(0);
}
}
class Enlistment : IPromotableSinglePhaseNotification
{
static readonly TimeSpan rollbackTimeout = TimeSpan.FromMinutes(1);
readonly ResourceManager owner;
readonly Transaction transaction;
readonly string transactionId;
readonly object syncRoot;
Controller controller;
Task<byte[]> declareTask;
byte[] txnid;
public Enlistment(ResourceManager owner, Transaction transaction)
{
this.owner = owner;
this.transaction = transaction;
this.transactionId = this.transaction.TransactionInformation.LocalIdentifier;
this.syncRoot = new object();
}
public async Task<byte[]> EnlistAsync(Link link)
{
if (this.txnid != null)
{
return this.txnid;
}
lock (this.syncRoot)
{
if (this.declareTask == null)
{
this.controller = this.owner.GetOrCreateController(link);
this.declareTask = this.controller.DeclareAsync();
}
}
return this.txnid = await this.declareTask;
}
void IPromotableSinglePhaseNotification.Initialize()
{
}
void IPromotableSinglePhaseNotification.Rollback(SinglePhaseEnlistment singlePhaseEnlistment)
{
lock (this.syncRoot)
{
if (this.txnid != null)
{
this.controller.DischargeAsync(this.txnid, true).ContinueWith(
(t, o) =>
{
var spe = (SinglePhaseEnlistment)o;
if (t.IsFaulted)
{
spe.Aborted(t.Exception.InnerException);
}
else
{
spe.Done();
}
},
singlePhaseEnlistment);
}
}
}
void IPromotableSinglePhaseNotification.SinglePhaseCommit(SinglePhaseEnlistment singlePhaseEnlistment)
{
lock (this.syncRoot)
{
if (this.txnid != null)
{
this.controller.DischargeAsync(this.txnid, false).ContinueWith(
(t, o) =>
{
var spe = (SinglePhaseEnlistment)o;
if (t.IsFaulted)
{
spe.Aborted(t.Exception.InnerException);
}
else
{
spe.Done();
}
},
singlePhaseEnlistment);
}
}
}
byte[] ITransactionPromoter.Promote()
{
throw new TransactionPromotionException("DTC not supported");
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Transactions
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Transactions;
using Amqp;
using Amqp.Framing;
sealed class ResourceManager
{
static readonly ResourceManager instance = new ResourceManager();
readonly Dictionary<Connection, Controller> controllers;
readonly Dictionary<string, Enlistment> enlistments;
ResourceManager()
{
this.controllers = new Dictionary<Connection, Controller>();
this.enlistments = new Dictionary<string, Enlistment>(StringComparer.OrdinalIgnoreCase);
}
object SyncRoot { get { return this.enlistments; } }
public static async Task<TransactionalState> GetTransactionalStateAsync(Link link)
{
Transaction txn = Transaction.Current;
if (txn != null)
{
byte[] txnId = await instance.EnlistAsync(link, txn);
return new TransactionalState() { TxnId = txnId };
}
return null;
}
async Task<byte[]> EnlistAsync(Link link, Transaction txn)
{
string id = txn.TransactionInformation.LocalIdentifier;
Enlistment enlistment;
lock (this.SyncRoot)
{
if (!this.enlistments.TryGetValue(id, out enlistment))
{
enlistment = new Enlistment(this, txn);
this.enlistments.Add(id, enlistment);
txn.TransactionCompleted += this.OnTransactionCompleted;
if (!txn.EnlistPromotableSinglePhase(enlistment))
{
this.enlistments.Remove(id);
txn.TransactionCompleted -= this.OnTransactionCompleted;
throw new InvalidOperationException("DTC not supported");
}
}
}
return await enlistment.EnlistAsync(link);
}
void OnTransactionCompleted(object sender, TransactionEventArgs e)
{
lock (this.SyncRoot)
{
this.enlistments.Remove(e.Transaction.TransactionInformation.LocalIdentifier);
}
}
Controller GetOrCreateController(Link link)
{
Controller controller;
lock (this.SyncRoot)
{
if (!this.controllers.TryGetValue(link.Session.Connection, out controller))
{
Session session = new Session(link.Session.Connection);
controller = new Controller(session);
controller.Closed += this.OnControllerClosed;
this.controllers.Add(link.Session.Connection, controller);
}
}
return controller;
}
void OnControllerClosed(AmqpObject obj, Error error)
{
var controller = (Controller)obj;
bool removed;
lock (this.SyncRoot)
{
removed = this.controllers.Remove(controller.Session.Connection);
}
if (removed)
{
controller.Session.Close(0);
}
}
class Enlistment : IPromotableSinglePhaseNotification
{
static readonly TimeSpan rollbackTimeout = TimeSpan.FromMinutes(1);
readonly ResourceManager owner;
readonly Transaction transaction;
readonly string transactionId;
readonly object syncRoot;
Controller controller;
Task<byte[]> declareTask;
byte[] txnid;
public Enlistment(ResourceManager owner, Transaction transaction)
{
this.owner = owner;
this.transaction = transaction;
this.transactionId = this.transaction.TransactionInformation.LocalIdentifier;
this.syncRoot = new object();
}
public async Task<byte[]> EnlistAsync(Link link)
{
if (this.txnid != null)
{
return this.txnid;
}
lock (this.syncRoot)
{
if (this.declareTask == null)
{
this.controller = this.owner.GetOrCreateController(link);
this.declareTask = this.controller.DeclareAsync();
}
}
return this.txnid = await this.declareTask;
}
void IPromotableSinglePhaseNotification.Initialize()
{
}
void IPromotableSinglePhaseNotification.Rollback(SinglePhaseEnlistment singlePhaseEnlistment)
{
lock (this.syncRoot)
{
if (this.txnid != null)
{
this.controller.DischargeAsync(this.txnid, true).ContinueWith(
(t, o) =>
{
var spe = (SinglePhaseEnlistment)o;
if (t.IsFaulted)
{
spe.Aborted(t.Exception.InnerException);
}
else
{
spe.Done();
}
},
singlePhaseEnlistment);
}
}
}
void IPromotableSinglePhaseNotification.SinglePhaseCommit(SinglePhaseEnlistment singlePhaseEnlistment)
{
lock (this.syncRoot)
{
if (this.txnid != null)
{
this.controller.DischargeAsync(this.txnid, false).ContinueWith(
(t, o) =>
{
var spe = (SinglePhaseEnlistment)o;
if (t.IsFaulted)
{
spe.Aborted(t.Exception.InnerException);
}
else
{
spe.Done();
}
},
singlePhaseEnlistment);
}
}
}
byte[] ITransactionPromoter.Promote()
{
throw new TransactionPromotionException("DTC not supported");
}
}
}
}

Просмотреть файл

@ -1,30 +1,30 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Transactions
{
using Amqp.Types;
static class TxnCapabilities
{
public static readonly Symbol LocalTransactions = "amqp:local-transactions";
public static readonly Symbol DistributedTxn = "amqp:distributed-transactions";
public static readonly Symbol PrototableTransactions = "amqp:prototable-transactions";
public static readonly Symbol MultiTxnsPerSsn = "amqp:multi-txns-per-ssn";
public static readonly Symbol MultiSsnsPerTxn = "amqp:multi-ssns-per-txn";
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Transactions
{
using Amqp.Types;
static class TxnCapabilities
{
public static readonly Symbol LocalTransactions = "amqp:local-transactions";
public static readonly Symbol DistributedTxn = "amqp:distributed-transactions";
public static readonly Symbol PrototableTransactions = "amqp:prototable-transactions";
public static readonly Symbol MultiTxnsPerSsn = "amqp:multi-txns-per-ssn";
public static readonly Symbol MultiSsnsPerTxn = "amqp:multi-ssns-per-txn";
}
}

Просмотреть файл

@ -21,24 +21,24 @@ namespace Amqp.Types
{
public void Encode(ByteBuffer buffer)
{
AmqpBitConverter.WriteUByte(buffer, FormatCode.Described);
AmqpBitConverter.WriteUByte(buffer, FormatCode.Described);
this.EncodeDescriptor(buffer);
this.EncodeValue(buffer);
}
public void Decode(ByteBuffer buffer)
{
Encoder.ReadFormatCode(buffer);
this.DecodeDescriptor(buffer);
this.DecodeValue(buffer);
}
internal abstract void EncodeDescriptor(ByteBuffer buffer);
internal abstract void EncodeValue(ByteBuffer buffer);
internal abstract void DecodeDescriptor(ByteBuffer buffer);
}
public void Decode(ByteBuffer buffer)
{
Encoder.ReadFormatCode(buffer);
this.DecodeDescriptor(buffer);
this.DecodeValue(buffer);
}
internal abstract void EncodeDescriptor(ByteBuffer buffer);
internal abstract void EncodeValue(ByteBuffer buffer);
internal abstract void DecodeDescriptor(ByteBuffer buffer);
internal abstract void DecodeValue(ByteBuffer buffer);
}
}

Просмотреть файл

@ -1,70 +1,70 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Types
{
using System;
public class DescribedValue : Described
{
object descriptor;
object value;
public DescribedValue(object descriptor, object value)
{
this.descriptor = descriptor;
this.value = value;
}
public object Descriptor
{
get { return this.descriptor; }
}
public object Value
{
get { return this.value; }
}
internal override void EncodeDescriptor(ByteBuffer buffer)
{
Encoder.WriteObject(buffer, this.descriptor);
}
internal override void EncodeValue(ByteBuffer buffer)
{
Encoder.WriteObject(buffer, this.value);
}
internal override void DecodeDescriptor(ByteBuffer buffer)
{
this.descriptor = Encoder.ReadObject(buffer);
}
internal override void DecodeValue(ByteBuffer buffer)
{
this.value = Encoder.ReadObject(buffer);
}
#if TRACE
public override string ToString()
{
return this.value == null ? "nil" : this.value.ToString();
}
#endif
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Types
{
using System;
public class DescribedValue : Described
{
object descriptor;
object value;
public DescribedValue(object descriptor, object value)
{
this.descriptor = descriptor;
this.value = value;
}
public object Descriptor
{
get { return this.descriptor; }
}
public object Value
{
get { return this.value; }
}
internal override void EncodeDescriptor(ByteBuffer buffer)
{
Encoder.WriteObject(buffer, this.descriptor);
}
internal override void EncodeValue(ByteBuffer buffer)
{
Encoder.WriteObject(buffer, this.value);
}
internal override void DecodeDescriptor(ByteBuffer buffer)
{
this.descriptor = Encoder.ReadObject(buffer);
}
internal override void DecodeValue(ByteBuffer buffer)
{
this.value = Encoder.ReadObject(buffer);
}
#if TRACE
public override string ToString()
{
return this.value == null ? "nil" : this.value.ToString();
}
#endif
}
}

Просмотреть файл

@ -57,7 +57,7 @@ namespace Amqp.Types
public const string TransactionRollback = "amqp:transaction:rollback";
public const string TransactionTimeout = "amqp:transaction:timeout";
// messaging
// messaging
public const string MessageReleased = "amqp:message:released";
}
}

Просмотреть файл

@ -1,55 +1,55 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Types
{
using System;
public class Fields : Map
{
public static Fields From(object[] array, int index)
{
object obj = array[index];
if (obj != null)
{
Fields fields = array[index] as Fields;
if (fields == null)
{
fields = new Fields();
Map map = (Map)obj;
foreach (var key in map.Keys)
{
fields.Add(key, map[key]);
}
array[index] = fields;
}
return fields;
}
else
{
return null;
}
}
protected override void CheckKeyType(Type keyType)
{
Map.ValidateKeyType(typeof(Symbol), keyType);
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Amqp.Types
{
using System;
public class Fields : Map
{
public static Fields From(object[] array, int index)
{
object obj = array[index];
if (obj != null)
{
Fields fields = array[index] as Fields;
if (fields == null)
{
fields = new Fields();
Map map = (Map)obj;
foreach (var key in map.Keys)
{
fields.Add(key, map[key]);
}
array[index] = fields;
}
return fields;
}
else
{
return null;
}
}
protected override void CheckKeyType(Type keyType)
{
Map.ValidateKeyType(typeof(Symbol), keyType);
}
}
}

Просмотреть файл

@ -17,8 +17,8 @@
namespace Amqp.Types
{
using System;
using System;
public partial class Map
{
public new object this[object key]
@ -34,18 +34,18 @@ namespace Amqp.Types
this.CheckKeyType(key.GetType());
base[key] = value;
}
}
internal static void ValidateKeyType(Type expected, Type actual)
{
if (expected != actual)
{
throw new InvalidOperationException(Fx.Format(SRAmqp.InvalidMapKeyType, actual.Name, expected.Name));
}
}
protected virtual void CheckKeyType(Type keyType)
{
internal static void ValidateKeyType(Type expected, Type actual)
{
if (expected != actual)
{
throw new InvalidOperationException(Fx.Format(SRAmqp.InvalidMapKeyType, actual.Name, expected.Name));
}
}
protected virtual void CheckKeyType(Type keyType)
{
}
#if TRACE

Просмотреть файл

@ -19,24 +19,24 @@ namespace Amqp
{
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
sealed class TcpTransport : ITransport
{
readonly Queue<ByteBuffer> writeQueue;
readonly Queue<ByteBuffer> writeQueue;
Connection connection;
StreamSocket socket;
public TcpTransport()
{
this.writeQueue = new Queue<ByteBuffer>();
}
public void Connect(Connection connection, Address address, bool noVerification)
{
}
public void Connect(Connection connection, Address address, bool noVerification)
{
this.connection = connection;
this.socket = new StreamSocket();
this.socket.ConnectAsync(
@ -73,15 +73,15 @@ namespace Amqp
async void SendAsync(ByteBuffer buffer)
{
while (buffer != null)
{
try
{
await this.socket.OutputStream.WriteAsync(buffer.Buffer.AsBuffer(buffer.Offset, buffer.Length));
}
catch (Exception exception)
{
this.connection.OnIoException(exception);
break;
{
try
{
await this.socket.OutputStream.WriteAsync(buffer.Buffer.AsBuffer(buffer.Offset, buffer.Length));
}
catch (Exception exception)
{
this.connection.OnIoException(exception);
break;
}
lock (this.writeQueue)

Просмотреть файл

@ -16,32 +16,32 @@
// ------------------------------------------------------------------------------------
namespace System.Threading
{
{
using global::Windows.System.Threading;
delegate void TimerCallback(object state);
class Timer
{
readonly TimerCallback callback;
readonly object state;
readonly ThreadPoolTimer timer;
public Timer(TimerCallback callback, object state, int dueTime, int period)
{
this.callback = callback;
this.state = state;
this.timer = ThreadPoolTimer.CreatePeriodicTimer(this.OnTimer, TimeSpan.FromMilliseconds(dueTime));
}
public void Dispose()
{
this.timer.Cancel();
}
void OnTimer(ThreadPoolTimer t)
{
this.callback(this.state);
{
readonly TimerCallback callback;
readonly object state;
readonly ThreadPoolTimer timer;
public Timer(TimerCallback callback, object state, int dueTime, int period)
{
this.callback = callback;
this.state = state;
this.timer = ThreadPoolTimer.CreatePeriodicTimer(this.OnTimer, TimeSpan.FromMilliseconds(dueTime));
}
public void Dispose()
{
this.timer.Cancel();
}
void OnTimer(ThreadPoolTimer t)
{
this.callback(this.state);
}
}
}

Просмотреть файл

@ -1,33 +1,33 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using VSAssert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
namespace Test.Amqp
{
static class Assert
{
public static void IsTrue(bool condition, string message = null)
{
VSAssert.IsTrue(condition, message ?? "Condition is not true.");
}
public static void AreEqual(object expected, object actual, string message = null)
{
VSAssert.AreEqual(expected, actual, message ?? "Objects are not equal.");
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using VSAssert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
namespace Test.Amqp
{
static class Assert
{
public static void IsTrue(bool condition, string message = null)
{
VSAssert.IsTrue(condition, message ?? "Condition is not true.");
}
public static void AreEqual(object expected, object actual, string message = null)
{
VSAssert.AreEqual(expected, actual, message ?? "Objects are not equal.");
}
}
}

Просмотреть файл

@ -1,99 +1,99 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Threading;
using Amqp;
using Amqp.Framing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Test.Amqp
{
[TestClass]
public class PerfTests
{
Address address = LinkTests.address;
[ClassInitialize]
public static void Initialize(TestContext context)
{
LinkTests.Initialize(context);
}
int totalCount;
int completedCount;
int initialCount;
int batchCount;
OutcomeCallback onOutcome;
SenderLink sender;
ManualResetEvent done;
[Description("Messages are sent unsettled. Completed count is incremented when the ack is received.")]
//[TestMethod]
public void PerfAtLeastOnceSend()
{
string testName = "PerfAtLeastOnceSend";
Connection connection = new Connection(address);
Session session = new Session(connection);
this.sender = new SenderLink(session, "sender-" + testName, "q1");
this.onOutcome = OnSendComplete;
this.done = new ManualResetEvent(false);
this.totalCount = 1000000;
this.completedCount = 0;
this.initialCount = 300;
this.batchCount = 100;
Trace.TraceLevel = TraceLevel.Information;
var watch = new System.Diagnostics.Stopwatch();
watch.Start();
this.SendMessages(initialCount);
this.done.WaitOne();
watch.Stop();
Trace.WriteLine(TraceLevel.Information, "total: {0}, time: {1}ms", this.totalCount, watch.ElapsedMilliseconds);
connection.Close();
}
void SendMessages(int count)
{
for (int i = 0; i < count; ++i)
{
Message message = new Message("hello");
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = "perf" };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
this.sender.Send(message, onOutcome, this);
}
}
static void OnSendComplete(Message m, Outcome o, object state)
{
PerfTests thisPtr = (PerfTests)state;
int sentCount = Interlocked.Increment(ref thisPtr.completedCount);
if (sentCount >= thisPtr.totalCount)
{
thisPtr.done.Set();
}
else if (sentCount % thisPtr.batchCount == 0)
{
thisPtr.SendMessages(thisPtr.batchCount);
}
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Threading;
using Amqp;
using Amqp.Framing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Test.Amqp
{
[TestClass]
public class PerfTests
{
Address address = LinkTests.address;
[ClassInitialize]
public static void Initialize(TestContext context)
{
LinkTests.Initialize(context);
}
int totalCount;
int completedCount;
int initialCount;
int batchCount;
OutcomeCallback onOutcome;
SenderLink sender;
ManualResetEvent done;
[Description("Messages are sent unsettled. Completed count is incremented when the ack is received.")]
//[TestMethod]
public void PerfAtLeastOnceSend()
{
string testName = "PerfAtLeastOnceSend";
Connection connection = new Connection(address);
Session session = new Session(connection);
this.sender = new SenderLink(session, "sender-" + testName, "q1");
this.onOutcome = OnSendComplete;
this.done = new ManualResetEvent(false);
this.totalCount = 1000000;
this.completedCount = 0;
this.initialCount = 300;
this.batchCount = 100;
Trace.TraceLevel = TraceLevel.Information;
var watch = new System.Diagnostics.Stopwatch();
watch.Start();
this.SendMessages(initialCount);
this.done.WaitOne();
watch.Stop();
Trace.WriteLine(TraceLevel.Information, "total: {0}, time: {1}ms", this.totalCount, watch.ElapsedMilliseconds);
connection.Close();
}
void SendMessages(int count)
{
for (int i = 0; i < count; ++i)
{
Message message = new Message("hello");
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = "perf" };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
this.sender.Send(message, onOutcome, this);
}
}
static void OnSendComplete(Message m, Outcome o, object state)
{
PerfTests thisPtr = (PerfTests)state;
int sentCount = Interlocked.Increment(ref thisPtr.completedCount);
if (sentCount >= thisPtr.totalCount)
{
thisPtr.done.Set();
}
else if (sentCount % thisPtr.batchCount == 0)
{
thisPtr.SendMessages(thisPtr.batchCount);
}
}
}
}

Просмотреть файл

@ -1,178 +1,178 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Test.Amqp
{
using System;
using System.Collections.Generic;
using global::Amqp.Serialization;
using global::Amqp.Types;
using global::Amqp;
[AmqpContract(Name = "person", Code = 0)]
[AmqpProvides(typeof(Student))]
[AmqpProvides(typeof(Teacher))]
class Person
{
public Person(string name)
{
this.Name = name;
}
[AmqpMember(Order = 1)]
public string Name
{
get;
private set;
}
[AmqpMember(Order = 2)]
public int Age
{
get;
set;
}
[AmqpMember(Order = 3)]
public DateTime? DateOfBirth;
public IDictionary<string, object> Properties
{
get
{
if (this.properties == null)
{
this.properties = new Dictionary<string, object>();
}
return this.properties;
}
}
[AmqpMember(Order = 8)]
Dictionary<string, object> properties;
[System.Runtime.Serialization.OnDeserialized]
void OnDesrialized()
{
this.Age = this.Age + 1;
}
}
[AmqpContract(Name = "student", Code = 1)]
class Student : Person
{
Student() : base(null) { }
public Student(string name)
: base(name)
{
}
[AmqpMember(Name = "address", Order = 4)]
public StreetAddress Address;
[AmqpMember(Name = "grades", Order = 10)]
public List<int> Grades { get; set; }
}
[AmqpContract(Name = "teacher", Code = 2)]
class Teacher : Person
{
public Teacher(string name)
: base(name)
{
this.Id = EmployeeId.New();
}
[AmqpMember(Name = "sallary", Order = 4)]
public int Sallary;
[AmqpMember(Order = 10)]
public EmployeeId Id
{
get;
private set;
}
[AmqpMember(Order = 11)]
public Dictionary<int, string> Classes
{
get;
set;
}
[System.Runtime.Serialization.OnDeserialized]
void OnDesrialized()
{
this.Sallary *= 2;
}
}
[AmqpContract(Name = "address", Code = 3)]
class StreetAddress
{
[AmqpMember]
public string FullAddress;
}
class EmployeeId : IAmqpSerializable
{
Guid uuid;
EmployeeId(Guid uuid)
{
this.uuid = uuid;
}
public int EncodeSize
{
get { return 16; }
}
public void Encode(ByteBuffer buffer)
{
byte[] bytes = this.uuid.ToByteArray();
buffer.Validate(true, bytes.Length);
Buffer.BlockCopy(bytes, 0, buffer.Buffer, buffer.WritePos, bytes.Length);
buffer.Append(bytes.Length);
}
public void Decode(ByteBuffer buffer)
{
byte[] bytes = new byte[16];
Buffer.BlockCopy(buffer.Buffer, buffer.Offset, bytes, 0, bytes.Length);
this.uuid = new Guid(bytes);
buffer.Complete(bytes.Length);
}
public static EmployeeId New()
{
return new EmployeeId(Guid.NewGuid());
}
public override bool Equals(object obj)
{
return obj is EmployeeId && ((EmployeeId)obj).uuid == this.uuid;
}
public override int GetHashCode()
{
return this.uuid.GetHashCode();
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace Test.Amqp
{
using System;
using System.Collections.Generic;
using global::Amqp.Serialization;
using global::Amqp.Types;
using global::Amqp;
[AmqpContract(Name = "person", Code = 0)]
[AmqpProvides(typeof(Student))]
[AmqpProvides(typeof(Teacher))]
class Person
{
public Person(string name)
{
this.Name = name;
}
[AmqpMember(Order = 1)]
public string Name
{
get;
private set;
}
[AmqpMember(Order = 2)]
public int Age
{
get;
set;
}
[AmqpMember(Order = 3)]
public DateTime? DateOfBirth;
public IDictionary<string, object> Properties
{
get
{
if (this.properties == null)
{
this.properties = new Dictionary<string, object>();
}
return this.properties;
}
}
[AmqpMember(Order = 8)]
Dictionary<string, object> properties;
[System.Runtime.Serialization.OnDeserialized]
void OnDesrialized()
{
this.Age = this.Age + 1;
}
}
[AmqpContract(Name = "student", Code = 1)]
class Student : Person
{
Student() : base(null) { }
public Student(string name)
: base(name)
{
}
[AmqpMember(Name = "address", Order = 4)]
public StreetAddress Address;
[AmqpMember(Name = "grades", Order = 10)]
public List<int> Grades { get; set; }
}
[AmqpContract(Name = "teacher", Code = 2)]
class Teacher : Person
{
public Teacher(string name)
: base(name)
{
this.Id = EmployeeId.New();
}
[AmqpMember(Name = "sallary", Order = 4)]
public int Sallary;
[AmqpMember(Order = 10)]
public EmployeeId Id
{
get;
private set;
}
[AmqpMember(Order = 11)]
public Dictionary<int, string> Classes
{
get;
set;
}
[System.Runtime.Serialization.OnDeserialized]
void OnDesrialized()
{
this.Sallary *= 2;
}
}
[AmqpContract(Name = "address", Code = 3)]
class StreetAddress
{
[AmqpMember]
public string FullAddress;
}
class EmployeeId : IAmqpSerializable
{
Guid uuid;
EmployeeId(Guid uuid)
{
this.uuid = uuid;
}
public int EncodeSize
{
get { return 16; }
}
public void Encode(ByteBuffer buffer)
{
byte[] bytes = this.uuid.ToByteArray();
buffer.Validate(true, bytes.Length);
Buffer.BlockCopy(bytes, 0, buffer.Buffer, buffer.WritePos, bytes.Length);
buffer.Append(bytes.Length);
}
public void Decode(ByteBuffer buffer)
{
byte[] bytes = new byte[16];
Buffer.BlockCopy(buffer.Buffer, buffer.Offset, bytes, 0, bytes.Length);
this.uuid = new Guid(bytes);
buffer.Complete(bytes.Length);
}
public static EmployeeId New()
{
return new EmployeeId(Guid.NewGuid());
}
public override bool Equals(object obj)
{
return obj is EmployeeId && ((EmployeeId)obj).uuid == this.uuid;
}
public override int GetHashCode()
{
return this.uuid.GetHashCode();
}
}
}

Просмотреть файл

@ -1,244 +1,244 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Threading;
using System.Threading.Tasks;
using Amqp;
using Amqp.Framing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Test.Amqp
{
[TestClass]
public class TaskTests
{
Address address = LinkTests.address;
[ClassInitialize]
public static void Initialize(TestContext context)
{
LinkTests.Initialize(context);
}
[TestMethod]
public async Task BasicSendReceiveAsync()
{
string testName = "BasicSendReceiveAsync";
int nMsgs = 10;
Connection connection = await Connection.Factory.CreateAsync(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message();
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
await sender.SendAsync(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = await receiver.ReceiveAsync();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.ApplicationProperties["sn"]);
receiver.Accept(message);
}
await sender.CloseAsync();
await receiver.CloseAsync();
await session.CloseAsync();
await connection.CloseAsync();
}
[TestMethod]
public async Task CustomMessgeBody()
{
string testName = "CustomMessgeBody";
Connection connection = await Connection.Factory.CreateAsync(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
Student student = new Student("Tom");
student.Age = 16;
student.Address = new StreetAddress() { FullAddress = "100 Main St. Small Town" };
student.DateOfBirth = new System.DateTime(1988, 5, 1, 1, 2, 3, 100, System.DateTimeKind.Utc);
Message message = new Message(student);
message.Properties = new Properties() { MessageId = "student" };
await sender.SendAsync(message);
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
Message message2 = await receiver.ReceiveAsync();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message2.Properties);
receiver.Accept(message);
await sender.CloseAsync();
await receiver.CloseAsync();
await session.CloseAsync();
await connection.CloseAsync();
Student student2 = message2.GetBody<Student>();
Assert.AreEqual(student.Age, student2.Age - 1); // incremented in OnDeserialized
Assert.AreEqual(student.DateOfBirth, student2.DateOfBirth);
Assert.AreEqual(student.Address.FullAddress, student2.Address.FullAddress);
}
[TestMethod]
public async Task LargeMessageSendReceiveAsync()
{
string testName = "LargeMessageSendReceiveAsync";
int nMsgs = 50;
Connection connection = await Connection.Factory.CreateAsync(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
int messageSize = 100 * 1024;
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message(new string('D', messageSize));
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
await sender.SendAsync(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = await receiver.ReceiveAsync();
string value = message.GetBody<string>();
Trace.WriteLine(TraceLevel.Information, "receive: {0} body {1}x{2}",
message.ApplicationProperties["sn"], value[0], value.Length);
receiver.Accept(message);
}
await sender.CloseAsync();
await receiver.CloseAsync();
await session.CloseAsync();
await connection.CloseAsync();
}
[TestMethod]
public async Task LargeMessageOnMessageCallback()
{
string testName = "LargeMessageOnMessageCallback";
int nMsgs = 50;
Connection connection = await Connection.Factory.CreateAsync(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
int messageSize = 100 * 1024;
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message(new string('D', messageSize));
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
sender.Send(message, null, null);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
ManualResetEvent done = new ManualResetEvent(false);
int count = 0;
receiver.Start(30, (link, message) =>
{
string value = message.GetBody<string>();
Trace.WriteLine(TraceLevel.Information, "receive: {0} body {1}x{2}",
message.ApplicationProperties["sn"], value[0], value.Length);
receiver.Accept(message);
if (++count == nMsgs) done.Set();
});
Assert.IsTrue(done.WaitOne(120000));
connection.Close();
}
[TestMethod]
public async Task CustomTransportConfiguration()
{
string testName = "CustomTransportConfiguration";
ConnectionFactory factory = new ConnectionFactory();
factory.TCP.NoDelay = true;
factory.TCP.SendBufferSize = 16 * 1024;
factory.TCP.SendTimeout = 30000;
factory.SSL.RemoteCertificateValidationCallback = (a, b, c, d) => true;
factory.AMQP.MaxFrameSize = 64 * 1024;
factory.AMQP.HostName = "contoso.com";
factory.AMQP.ContainerId = "container:" + testName;
Address sslAddress = new Address("amqps://guest:guest@127.0.0.1:5671");
Connection connection = await factory.CreateAsync(sslAddress);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
Message message = new Message("custom transport config");
message.Properties = new Properties() { MessageId = testName };
await sender.SendAsync(message);
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
Message message2 = await receiver.ReceiveAsync();
Assert.IsTrue(message2 != null, "no message received");
receiver.Accept(message2);
await connection.CloseAsync();
}
[TestMethod]
public async Task WebSocketSendReceiveAsync()
{
string testName = "WebSocketSendReceiveAsync";
// assuming it matches the broker's setup
Address wsAddress = new Address("ws://guest:guest@localhost:80");
int nMsgs = 50;
Connection connection = await Connection.Factory.CreateAsync(wsAddress);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message();
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
await sender.SendAsync(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = await receiver.ReceiveAsync();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.ApplicationProperties["sn"]);
receiver.Accept(message);
}
await sender.CloseAsync();
await receiver.CloseAsync();
await session.CloseAsync();
await connection.CloseAsync();
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Threading;
using System.Threading.Tasks;
using Amqp;
using Amqp.Framing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Test.Amqp
{
[TestClass]
public class TaskTests
{
Address address = LinkTests.address;
[ClassInitialize]
public static void Initialize(TestContext context)
{
LinkTests.Initialize(context);
}
[TestMethod]
public async Task BasicSendReceiveAsync()
{
string testName = "BasicSendReceiveAsync";
int nMsgs = 10;
Connection connection = await Connection.Factory.CreateAsync(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message();
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
await sender.SendAsync(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = await receiver.ReceiveAsync();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.ApplicationProperties["sn"]);
receiver.Accept(message);
}
await sender.CloseAsync();
await receiver.CloseAsync();
await session.CloseAsync();
await connection.CloseAsync();
}
[TestMethod]
public async Task CustomMessgeBody()
{
string testName = "CustomMessgeBody";
Connection connection = await Connection.Factory.CreateAsync(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
Student student = new Student("Tom");
student.Age = 16;
student.Address = new StreetAddress() { FullAddress = "100 Main St. Small Town" };
student.DateOfBirth = new System.DateTime(1988, 5, 1, 1, 2, 3, 100, System.DateTimeKind.Utc);
Message message = new Message(student);
message.Properties = new Properties() { MessageId = "student" };
await sender.SendAsync(message);
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
Message message2 = await receiver.ReceiveAsync();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message2.Properties);
receiver.Accept(message);
await sender.CloseAsync();
await receiver.CloseAsync();
await session.CloseAsync();
await connection.CloseAsync();
Student student2 = message2.GetBody<Student>();
Assert.AreEqual(student.Age, student2.Age - 1); // incremented in OnDeserialized
Assert.AreEqual(student.DateOfBirth, student2.DateOfBirth);
Assert.AreEqual(student.Address.FullAddress, student2.Address.FullAddress);
}
[TestMethod]
public async Task LargeMessageSendReceiveAsync()
{
string testName = "LargeMessageSendReceiveAsync";
int nMsgs = 50;
Connection connection = await Connection.Factory.CreateAsync(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
int messageSize = 100 * 1024;
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message(new string('D', messageSize));
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
await sender.SendAsync(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = await receiver.ReceiveAsync();
string value = message.GetBody<string>();
Trace.WriteLine(TraceLevel.Information, "receive: {0} body {1}x{2}",
message.ApplicationProperties["sn"], value[0], value.Length);
receiver.Accept(message);
}
await sender.CloseAsync();
await receiver.CloseAsync();
await session.CloseAsync();
await connection.CloseAsync();
}
[TestMethod]
public async Task LargeMessageOnMessageCallback()
{
string testName = "LargeMessageOnMessageCallback";
int nMsgs = 50;
Connection connection = await Connection.Factory.CreateAsync(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
int messageSize = 100 * 1024;
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message(new string('D', messageSize));
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
sender.Send(message, null, null);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
ManualResetEvent done = new ManualResetEvent(false);
int count = 0;
receiver.Start(30, (link, message) =>
{
string value = message.GetBody<string>();
Trace.WriteLine(TraceLevel.Information, "receive: {0} body {1}x{2}",
message.ApplicationProperties["sn"], value[0], value.Length);
receiver.Accept(message);
if (++count == nMsgs) done.Set();
});
Assert.IsTrue(done.WaitOne(120000));
connection.Close();
}
[TestMethod]
public async Task CustomTransportConfiguration()
{
string testName = "CustomTransportConfiguration";
ConnectionFactory factory = new ConnectionFactory();
factory.TCP.NoDelay = true;
factory.TCP.SendBufferSize = 16 * 1024;
factory.TCP.SendTimeout = 30000;
factory.SSL.RemoteCertificateValidationCallback = (a, b, c, d) => true;
factory.AMQP.MaxFrameSize = 64 * 1024;
factory.AMQP.HostName = "contoso.com";
factory.AMQP.ContainerId = "container:" + testName;
Address sslAddress = new Address("amqps://guest:guest@127.0.0.1:5671");
Connection connection = await factory.CreateAsync(sslAddress);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
Message message = new Message("custom transport config");
message.Properties = new Properties() { MessageId = testName };
await sender.SendAsync(message);
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
Message message2 = await receiver.ReceiveAsync();
Assert.IsTrue(message2 != null, "no message received");
receiver.Accept(message2);
await connection.CloseAsync();
}
[TestMethod]
public async Task WebSocketSendReceiveAsync()
{
string testName = "WebSocketSendReceiveAsync";
// assuming it matches the broker's setup
Address wsAddress = new Address("ws://guest:guest@localhost:80");
int nMsgs = 50;
Connection connection = await Connection.Factory.CreateAsync(wsAddress);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = new Message();
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
message.ApplicationProperties = new ApplicationProperties();
message.ApplicationProperties["sn"] = i;
await sender.SendAsync(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
for (int i = 0; i < nMsgs; ++i)
{
Message message = await receiver.ReceiveAsync();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.ApplicationProperties["sn"]);
receiver.Accept(message);
}
await sender.CloseAsync();
await receiver.CloseAsync();
await session.CloseAsync();
await connection.CloseAsync();
}
}
}

Просмотреть файл

@ -1,237 +1,237 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Threading;
using System.Threading.Tasks;
using Amqp;
using Amqp.Framing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Transactions;
namespace Test.Amqp
{
[TestClass]
public class TransactionTests
{
Address address = LinkTests.address;
[ClassInitialize]
public static void Initialize(TestContext context)
{
LinkTests.Initialize(context);
}
// if the project is targeted 4.5.1, TransactionScope can be created with
// TransactionScopeAsyncFlowOption.Enabled option, and message can be sent
// using SendAsync method.
[TestMethod]
public void TransactedPosting()
{
string testName = "TransactedPosting";
int nMsgs = 5;
Connection connection = new Connection(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
// commit
using (var ts = new TransactionScope())
{
for (int i = 0; i < nMsgs; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "commit" + i, GroupId = testName };
sender.Send(message);
}
ts.Complete();
}
// rollback
using (var ts = new TransactionScope())
{
for (int i = nMsgs; i < nMsgs * 2; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "rollback" + i, GroupId = testName };
sender.Send(message);
}
}
// commit
using (var ts = new TransactionScope())
{
for (int i = 0; i < nMsgs; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "commit" + i, GroupId = testName };
sender.Send(message);
}
ts.Complete();
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
for (int i = 0; i < nMsgs * 2; i++)
{
Message message = receiver.Receive();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.Properties.MessageId);
receiver.Accept(message);
Assert.IsTrue(message.Properties.MessageId.StartsWith("commit"));
}
connection.Close();
}
[TestMethod]
public void TransactedRetiring()
{
string testName = "TransactedRetiring";
int nMsgs = 10;
Connection connection = new Connection(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
// send one extra for validation
for (int i = 0; i < nMsgs + 1; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
sender.Send(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
Message[] messages = new Message[nMsgs];
for (int i = 0; i < nMsgs; i++)
{
messages[i] = receiver.Receive();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", messages[i].Properties.MessageId);
}
// commit harf
using (var ts = new TransactionScope())
{
for (int i = 0; i < nMsgs / 2; i++)
{
receiver.Accept(messages[i]);
}
ts.Complete();
}
// rollback
using (var ts = new TransactionScope())
{
for (int i = nMsgs / 2; i < nMsgs; i++)
{
receiver.Accept(messages[i]);
}
}
// after rollback, messages should be still acquired
{
Message message = receiver.Receive();
Assert.AreEqual("msg" + nMsgs, message.Properties.MessageId);
receiver.Release(message);
}
// commit
using (var ts = new TransactionScope())
{
for (int i = nMsgs / 2; i < nMsgs; i++)
{
receiver.Accept(messages[i]);
}
ts.Complete();
}
// only the last message is left
{
Message message = receiver.Receive();
Assert.AreEqual("msg" + nMsgs, message.Properties.MessageId);
receiver.Accept(message);
}
// at this point, the queue should have zero messages.
// If there are messages, it is a bug in the broker.
connection.Close();
}
[TestMethod]
public void TransactedRetiringAndPosting()
{
string testName = "TransactedRetiringAndPosting";
int nMsgs = 10;
Connection connection = new Connection(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
for (int i = 0; i < nMsgs; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
sender.Send(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
receiver.SetCredit(2, false);
Message message1 = receiver.Receive();
Message message2 = receiver.Receive();
// ack message1 and send a new message in a txn
using (var ts = new TransactionScope())
{
receiver.Accept(message1);
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "msg" + nMsgs, GroupId = testName };
sender.Send(message);
ts.Complete();
}
// ack message2 and send a new message in a txn but abort the txn
using (var ts = new TransactionScope())
{
receiver.Accept(message2);
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "msg" + (nMsgs + 1), GroupId = testName };
sender.Send(message1);
}
receiver.Release(message2);
// receive all messages. should see the effect of the first txn
receiver.SetCredit(nMsgs, false);
for (int i = 1; i <= nMsgs; i++)
{
Message message = receiver.Receive();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.Properties.MessageId);
receiver.Accept(message);
Assert.AreEqual("msg" + i, message.Properties.MessageId);
}
connection.Close();
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Threading;
using System.Threading.Tasks;
using Amqp;
using Amqp.Framing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Transactions;
namespace Test.Amqp
{
[TestClass]
public class TransactionTests
{
Address address = LinkTests.address;
[ClassInitialize]
public static void Initialize(TestContext context)
{
LinkTests.Initialize(context);
}
// if the project is targeted 4.5.1, TransactionScope can be created with
// TransactionScopeAsyncFlowOption.Enabled option, and message can be sent
// using SendAsync method.
[TestMethod]
public void TransactedPosting()
{
string testName = "TransactedPosting";
int nMsgs = 5;
Connection connection = new Connection(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
// commit
using (var ts = new TransactionScope())
{
for (int i = 0; i < nMsgs; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "commit" + i, GroupId = testName };
sender.Send(message);
}
ts.Complete();
}
// rollback
using (var ts = new TransactionScope())
{
for (int i = nMsgs; i < nMsgs * 2; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "rollback" + i, GroupId = testName };
sender.Send(message);
}
}
// commit
using (var ts = new TransactionScope())
{
for (int i = 0; i < nMsgs; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "commit" + i, GroupId = testName };
sender.Send(message);
}
ts.Complete();
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
for (int i = 0; i < nMsgs * 2; i++)
{
Message message = receiver.Receive();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.Properties.MessageId);
receiver.Accept(message);
Assert.IsTrue(message.Properties.MessageId.StartsWith("commit"));
}
connection.Close();
}
[TestMethod]
public void TransactedRetiring()
{
string testName = "TransactedRetiring";
int nMsgs = 10;
Connection connection = new Connection(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
// send one extra for validation
for (int i = 0; i < nMsgs + 1; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
sender.Send(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
Message[] messages = new Message[nMsgs];
for (int i = 0; i < nMsgs; i++)
{
messages[i] = receiver.Receive();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", messages[i].Properties.MessageId);
}
// commit harf
using (var ts = new TransactionScope())
{
for (int i = 0; i < nMsgs / 2; i++)
{
receiver.Accept(messages[i]);
}
ts.Complete();
}
// rollback
using (var ts = new TransactionScope())
{
for (int i = nMsgs / 2; i < nMsgs; i++)
{
receiver.Accept(messages[i]);
}
}
// after rollback, messages should be still acquired
{
Message message = receiver.Receive();
Assert.AreEqual("msg" + nMsgs, message.Properties.MessageId);
receiver.Release(message);
}
// commit
using (var ts = new TransactionScope())
{
for (int i = nMsgs / 2; i < nMsgs; i++)
{
receiver.Accept(messages[i]);
}
ts.Complete();
}
// only the last message is left
{
Message message = receiver.Receive();
Assert.AreEqual("msg" + nMsgs, message.Properties.MessageId);
receiver.Accept(message);
}
// at this point, the queue should have zero messages.
// If there are messages, it is a bug in the broker.
connection.Close();
}
[TestMethod]
public void TransactedRetiringAndPosting()
{
string testName = "TransactedRetiringAndPosting";
int nMsgs = 10;
Connection connection = new Connection(this.address);
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");
for (int i = 0; i < nMsgs; i++)
{
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "msg" + i, GroupId = testName };
sender.Send(message);
}
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");
receiver.SetCredit(2, false);
Message message1 = receiver.Receive();
Message message2 = receiver.Receive();
// ack message1 and send a new message in a txn
using (var ts = new TransactionScope())
{
receiver.Accept(message1);
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "msg" + nMsgs, GroupId = testName };
sender.Send(message);
ts.Complete();
}
// ack message2 and send a new message in a txn but abort the txn
using (var ts = new TransactionScope())
{
receiver.Accept(message2);
Message message = new Message("test");
message.Properties = new Properties() { MessageId = "msg" + (nMsgs + 1), GroupId = testName };
sender.Send(message1);
}
receiver.Release(message2);
// receive all messages. should see the effect of the first txn
receiver.SetCredit(nMsgs, false);
for (int i = 1; i <= nMsgs; i++)
{
Message message = receiver.Receive();
Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.Properties.MessageId);
receiver.Accept(message);
Assert.AreEqual("msg" + i, message.Properties.MessageId);
}
connection.Close();
}
}
}

Просмотреть файл

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

Просмотреть файл

@ -1,139 +1,139 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace TestAmqpBroker
{
using System;
using System.Linq;
using System.Collections.Generic;
using Amqp;
class Program
{
static void Usage()
{
Console.WriteLine("AmqpTestBroker url [url] [/creds:user:pwd] [/cert:ssl_cert] [/trace:level] [/queues:q1;q2;...]");
Console.WriteLine(" url=amqp|amqps://host[:port] (can be multiple)");
Console.WriteLine(" creds=username:passwrod");
Console.WriteLine(" cert=ssl cert find value (thumbprint or subject)");
Console.WriteLine(" trace=level (info, warn, error, frame)");
Console.WriteLine(" queues: semicolon separated queue names. If not specified, the broker implicitly");
Console.WriteLine(" creates a new node for any address and deletes it when the connection is closed.");
}
static void Main(string[] args)
{
if (args.Length < 1)
{
Usage();
}
else
{
try
{
Run(args);
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
}
}
static void Run(string[] args)
{
List<Uri> endpoints = new List<Uri>();
string creds = null;
string trace = null;
string sslValue = null;
string[] queues = null;
bool parseEndpoint = true;
for (int i = 0; i < args.Length; i++)
{
if (args[i][0] != '/' && parseEndpoint)
{
endpoints.Add(new Uri(args[i]));
}
else
{
parseEndpoint = false;
if (args[i].StartsWith("/creds:", StringComparison.OrdinalIgnoreCase))
{
creds = args[i].Substring(7);
}
else if (args[i].StartsWith("/trace:", StringComparison.OrdinalIgnoreCase))
{
trace = args[i].Substring(7);
}
else if (args[i].StartsWith("/queues:", StringComparison.OrdinalIgnoreCase))
{
queues = args[i].Substring(8).Split(';');
}
else if (args[i].StartsWith("/cert:", StringComparison.OrdinalIgnoreCase))
{
sslValue = args[i].Substring(6);
}
else
{
Console.WriteLine("Unknown argument: {0}", args[i]);
Usage();
return;
}
}
}
if (trace != null)
{
TraceLevel level = 0;
switch (trace)
{
case "info":
level = TraceLevel.Information;
break;
case "warn":
level = TraceLevel.Warning;
break;
case "error":
level = TraceLevel.Error;
break;
case "verbose":
level = TraceLevel.Verbose;
break;
case "frame":
level = TraceLevel.Frame;
break;
default:
Usage();
return;
}
Trace.TraceLevel = level;
Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
}
var broker = new TestAmqpBroker(endpoints, creds, sslValue, queues);
broker.Start();
Console.WriteLine("Broker started. Press the enter key to exit...");
Console.ReadLine();
broker.Stop();
Console.WriteLine("Broker stopped");
}
}
}
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
namespace TestAmqpBroker
{
using System;
using System.Linq;
using System.Collections.Generic;
using Amqp;
class Program
{
static void Usage()
{
Console.WriteLine("AmqpTestBroker url [url] [/creds:user:pwd] [/cert:ssl_cert] [/trace:level] [/queues:q1;q2;...]");
Console.WriteLine(" url=amqp|amqps://host[:port] (can be multiple)");
Console.WriteLine(" creds=username:passwrod");
Console.WriteLine(" cert=ssl cert find value (thumbprint or subject)");
Console.WriteLine(" trace=level (info, warn, error, frame)");
Console.WriteLine(" queues: semicolon separated queue names. If not specified, the broker implicitly");
Console.WriteLine(" creates a new node for any address and deletes it when the connection is closed.");
}
static void Main(string[] args)
{
if (args.Length < 1)
{
Usage();
}
else
{
try
{
Run(args);
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
}
}
static void Run(string[] args)
{
List<Uri> endpoints = new List<Uri>();
string creds = null;
string trace = null;
string sslValue = null;
string[] queues = null;
bool parseEndpoint = true;
for (int i = 0; i < args.Length; i++)
{
if (args[i][0] != '/' && parseEndpoint)
{
endpoints.Add(new Uri(args[i]));
}
else
{
parseEndpoint = false;
if (args[i].StartsWith("/creds:", StringComparison.OrdinalIgnoreCase))
{
creds = args[i].Substring(7);
}
else if (args[i].StartsWith("/trace:", StringComparison.OrdinalIgnoreCase))
{
trace = args[i].Substring(7);
}
else if (args[i].StartsWith("/queues:", StringComparison.OrdinalIgnoreCase))
{
queues = args[i].Substring(8).Split(';');
}
else if (args[i].StartsWith("/cert:", StringComparison.OrdinalIgnoreCase))
{
sslValue = args[i].Substring(6);
}
else
{
Console.WriteLine("Unknown argument: {0}", args[i]);
Usage();
return;
}
}
}
if (trace != null)
{
TraceLevel level = 0;
switch (trace)
{
case "info":
level = TraceLevel.Information;
break;
case "warn":
level = TraceLevel.Warning;
break;
case "error":
level = TraceLevel.Error;
break;
case "verbose":
level = TraceLevel.Verbose;
break;
case "frame":
level = TraceLevel.Frame;
break;
default:
Usage();
return;
}
Trace.TraceLevel = level;
Trace.TraceListener = (f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a));
}
var broker = new TestAmqpBroker(endpoints, creds, sslValue, queues);
broker.Start();
Console.WriteLine("Broker started. Press the enter key to exit...");
Console.ReadLine();
broker.Stop();
Console.WriteLine("Broker stopped");
}
}
}

Просмотреть файл

@ -1,53 +1,53 @@
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TestAmqpBroker")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TestAmqpBroker")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("82f5fead-0cf9-43e1-bb1d-ad79da1b0700")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// ------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------------------
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TestAmqpBroker")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TestAmqpBroker")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("82f5fead-0cf9-43e1-bb1d-ad79da1b0700")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]