Commit b499b562 authored by Mark van Renswoude's avatar Mark van Renswoude

Renamed Parser/Operations to Reader/Writer

Added usage information when providing invalid arguments
parent bcc3b504
......@@ -2,3 +2,4 @@
/bin/
/packages/
*.suo
*.user
using RabbitMetaQueue.Model;
namespace RabbitMetaQueue.Domain
{
interface ITopologyOperations
{
void ExchangeDeclare(Exchange exchange);
void ExchangeDelete(Exchange exchange);
void QueueDeclare(Queue queue);
void QueueDelete(Queue queue);
void QueueBind(Queue queue, Binding binding);
void QueueUnbind(Queue queue, Binding binding);
}
}
using RabbitMetaQueue.Model;
namespace RabbitMetaQueue.Domain
{
interface ITopologyWriter
{
void CreateExchange(Exchange exchange);
void DeleteExchange(Exchange exchange);
void CreateQueue(Queue queue);
void DeleteQueue(Queue queue);
void CreateBinding(Queue queue, Binding binding);
void DeleteBinding(Queue queue, Binding binding);
}
}
......@@ -8,7 +8,7 @@ namespace RabbitMetaQueue.Domain
public bool AllowRecreate { get; set; }
public bool AllowUnbind { get; set; }
private ITopologyOperations topologyOperations;
private ITopologyWriter topologyWriter;
public TopologyComparator()
......@@ -19,9 +19,9 @@ namespace RabbitMetaQueue.Domain
}
public TopologyComparator(ITopologyOperations topologyOperations)
public TopologyComparator(ITopologyWriter topologyWriter)
{
this.topologyOperations = topologyOperations;
this.topologyWriter = topologyWriter;
}
......
......@@ -5,9 +5,9 @@ using RabbitMetaQueue.Model;
namespace RabbitMetaQueue.Infrastructure
{
// ToDo arguments
class ConsoleTopologyOperations : ITopologyOperations
class ConsoleTopologyWriter : ITopologyWriter
{
public void ExchangeDeclare(Exchange exchange)
public void CreateExchange(Exchange exchange)
{
Console.WriteLine("> Adding exchange: " + exchange.Name);
Console.WriteLine(" Type: " + exchange.ExchangeType);
......@@ -15,26 +15,26 @@ namespace RabbitMetaQueue.Infrastructure
}
public void ExchangeDelete(Exchange exchange)
public void DeleteExchange(Exchange exchange)
{
Console.WriteLine("> Deleting exchange: " + exchange.Name);
}
public void QueueDeclare(Queue queue)
public void CreateQueue(Queue queue)
{
Console.WriteLine("> Adding queue: " + queue.Name);
Console.WriteLine(" Durable: " + queue.Durable);
}
public void QueueDelete(Queue queue)
public void DeleteQueue(Queue queue)
{
Console.WriteLine("> Deleting queue: " + queue.Name);
}
public void QueueBind(Queue queue, Binding binding)
public void CreateBinding(Queue queue, Binding binding)
{
Console.WriteLine("> Binding queue: " + queue.Name);
Console.WriteLine(" Exchange: " + binding.Exchange);
......@@ -42,7 +42,7 @@ namespace RabbitMetaQueue.Infrastructure
}
public void QueueUnbind(Queue queue, Binding binding)
public void DeleteBinding(Queue queue, Binding binding)
{
Console.WriteLine("> Unbinding queue: " + queue.Name);
Console.WriteLine(" Exchange: " + binding.Exchange);
......
using System.Collections.Generic;
using RabbitMetaQueue.Domain;
using RabbitMetaQueue.Model;
namespace RabbitMetaQueue.Infrastructure
{
class MulticastTopologyOperations : ITopologyOperations
{
private readonly List<ITopologyOperations> topologyOperationsList = new List<ITopologyOperations>();
public void Add(ITopologyOperations topologyOperations)
{
topologyOperationsList.Add(topologyOperations);
}
public void ExchangeDeclare(Exchange exchange)
{
topologyOperationsList.ForEach(to => to.ExchangeDeclare(exchange));
}
public void ExchangeDelete(Exchange exchange)
{
topologyOperationsList.ForEach(to => to.ExchangeDelete(exchange));
}
public void QueueDeclare(Queue queue)
{
topologyOperationsList.ForEach(to => to.QueueDeclare(queue));
}
public void QueueDelete(Queue queue)
{
topologyOperationsList.ForEach(to => to.QueueDelete(queue));
}
public void QueueBind(Queue queue, Binding binding)
{
topologyOperationsList.ForEach(to => to.QueueBind(queue, binding));
}
public void QueueUnbind(Queue queue, Binding binding)
{
topologyOperationsList.ForEach(to => to.QueueUnbind(queue, binding));
}
}
}
using System.Collections.Generic;
using RabbitMetaQueue.Domain;
using RabbitMetaQueue.Model;
namespace RabbitMetaQueue.Infrastructure
{
class MulticastTopologyWriter : ITopologyWriter
{
private readonly List<ITopologyWriter> topologyWriters = new List<ITopologyWriter>();
public void Add(ITopologyWriter topologyWriter)
{
topologyWriters.Add(topologyWriter);
}
public void CreateExchange(Exchange exchange)
{
topologyWriters.ForEach(to => to.CreateExchange(exchange));
}
public void DeleteExchange(Exchange exchange)
{
topologyWriters.ForEach(to => to.DeleteExchange(exchange));
}
public void CreateQueue(Queue queue)
{
topologyWriters.ForEach(to => to.CreateQueue(queue));
}
public void DeleteQueue(Queue queue)
{
topologyWriters.ForEach(to => to.DeleteQueue(queue));
}
public void CreateBinding(Queue queue, Binding binding)
{
topologyWriters.ForEach(to => to.CreateBinding(queue, binding));
}
public void DeleteBinding(Queue queue, Binding binding)
{
topologyWriters.ForEach(to => to.DeleteBinding(queue, binding));
}
}
}
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using EasyNetQ.Management.Client;
using EasyNetQ.Management.Client.Model;
......@@ -6,7 +7,7 @@ using RabbitMetaQueue.Model;
namespace RabbitMetaQueue.Infrastructure
{
class RabbitMQTopologyParser
class RabbitMQTopologyReader
{
private static readonly Dictionary<string, Model.ExchangeType> ExchangeTypeMap = new Dictionary<string, Model.ExchangeType>
{
......@@ -23,15 +24,18 @@ namespace RabbitMetaQueue.Infrastructure
foreach (var exchange in client.GetExchanges())
{
var modelExchange = new Model.Exchange
{
Name = exchange.Name,
ExchangeType = ExchangeTypeMap[exchange.Type],
Durable = exchange.Durable,
};
if (!IsSystemExchange(exchange.Name))
{
var modelExchange = new Model.Exchange
{
Name = exchange.Name,
ExchangeType = ExchangeTypeMap[exchange.Type],
Durable = exchange.Durable,
};
MapArguments(exchange.Arguments, modelExchange.Arguments);
topology.Exchanges.Add(modelExchange);
MapArguments(exchange.Arguments, modelExchange.Arguments);
topology.Exchanges.Add(modelExchange);
}
}
foreach (var queue in client.GetQueues())
......@@ -71,5 +75,12 @@ namespace RabbitMetaQueue.Infrastructure
Value = argument.Value
}));
}
private bool IsSystemExchange(string name)
{
return (String.IsNullOrEmpty(name) ||
name.StartsWith("amq.", StringComparison.InvariantCulture));
}
}
}
......@@ -6,7 +6,7 @@ using RabbitMetaQueue.Model;
namespace RabbitMetaQueue.Infrastructure
{
class RabbitMQTopologyOperations : ITopologyOperations
class RabbitMQTopologyWriter : ITopologyWriter
{
private readonly IManagementClient client;
private readonly Vhost virtualHost;
......@@ -20,39 +20,39 @@ namespace RabbitMetaQueue.Infrastructure
};
public RabbitMQTopologyOperations(IManagementClient client, Vhost virtualHost)
public RabbitMQTopologyWriter(IManagementClient client, Vhost virtualHost)
{
this.client = client;
this.virtualHost = virtualHost;
}
public void ExchangeDeclare(Model.Exchange exchange)
public void CreateExchange(Model.Exchange exchange)
{
client.CreateExchange(new ExchangeInfo(exchange.Name, ExchangeTypeMap[exchange.ExchangeType], false, exchange.Durable, false,
MapArguments(exchange.Arguments)), virtualHost);
}
public void ExchangeDelete(Model.Exchange exchange)
public void DeleteExchange(Model.Exchange exchange)
{
client.DeleteExchange(client.GetExchange(exchange.Name, virtualHost));
}
public void QueueDeclare(Model.Queue queue)
public void CreateQueue(Model.Queue queue)
{
client.CreateQueue(new QueueInfo(queue.Name, false, queue.Durable, MapInputArguments(queue.Arguments)), virtualHost);
}
public void QueueDelete(Model.Queue queue)
public void DeleteQueue(Model.Queue queue)
{
client.DeleteQueue(client.GetQueue(queue.Name, virtualHost));
}
public void QueueBind(Model.Queue queue, Model.Binding binding)
public void CreateBinding(Model.Queue queue, Model.Binding binding)
{
client.CreateBinding(client.GetExchange(binding.Exchange, virtualHost),
client.GetQueue(queue.Name, virtualHost),
......@@ -60,7 +60,7 @@ namespace RabbitMetaQueue.Infrastructure
}
public void QueueUnbind(Model.Queue queue, Model.Binding binding)
public void DeleteBinding(Model.Queue queue, Model.Binding binding)
{
foreach (var clientBinding in client.GetBindingsForQueue(client.GetQueue(queue.Name, virtualHost)))
{
......
......@@ -5,7 +5,7 @@ using System.Xml.Serialization;
namespace RabbitMetaQueue.Infrastructure
{
class XmlTopologyParser
class XmlTopologyReader
{
public Model.Topology Parse(string filename)
{
......
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using EasyNetQ.Management.Client;
using EasyNetQ.Management.Client.Model;
......@@ -27,53 +28,64 @@ namespace RabbitMetaQueue
static int Main(string[] args)
{
var options = new Options();
if (!ParseOptions(args, options))
return 1;
try
{
Console.WriteLine("Parsing topology definition");
var definedTopology = new XmlTopologyParser().Parse(options.TopologyFilename);
Console.WriteLine("Connecting to RabbitMQ server [{0}{1}]", options.ConnectionParams.Host, options.ConnectionParams.VirtualHost);
var client = Connect(options.ConnectionParams);
var virtualHost = client.GetVhost(options.ConnectionParams.VirtualHost);
Console.WriteLine("Reading existing topology");
var existingTopology = new RabbitMQTopologyParser().Parse(client, virtualHost);
var operations = new MulticastTopologyOperations();
operations.Add(new ConsoleTopologyOperations());
{
var options = new Options();
if (!ParseOptions(args, options))
return 1;
if (!options.DryRun)
try
{
Console.WriteLine("Changes WILL be applied");
operations.Add(new RabbitMQTopologyOperations(client, virtualHost));
}
else
Console.WriteLine("Dry run - changes will not be applied");
var comparator = new TopologyComparator(operations)
{
AllowDelete = true,
AllowRecreate = true,
AllowUnbind = true
};
Console.WriteLine("Parsing topology definition");
var definedTopology = new XmlTopologyReader().Parse(options.TopologyFilename);
Console.WriteLine("Connecting to RabbitMQ server [{0}{1}]", options.ConnectionParams.Host, options.ConnectionParams.VirtualHost);
var client = Connect(options.ConnectionParams);
var virtualHost = client.GetVhost(options.ConnectionParams.VirtualHost);
Console.WriteLine("Reading existing topology");
var existingTopology = new RabbitMQTopologyReader().Parse(client, virtualHost);
var writer = new MulticastTopologyWriter();
writer.Add(new ConsoleTopologyWriter());
if (!options.DryRun)
{
Console.WriteLine("Changes WILL be applied");
writer.Add(new RabbitMQTopologyWriter(client, virtualHost));
}
else
Console.WriteLine("Dry run - changes will not be applied");
var comparator = new TopologyComparator(writer)
{
AllowDelete = true,
AllowRecreate = true,
AllowUnbind = true
};
Console.WriteLine("Comparing topology");
comparator.Compare(existingTopology, definedTopology);
Console.WriteLine("Comparing topology");
comparator.Compare(existingTopology, definedTopology);
Console.WriteLine("Done!");
return 0;
Console.WriteLine("Done!");
return 0;
}
catch(Exception e)
{
Console.Write("Error: ");
Console.WriteLine(e.Message);
return 1;
}
}
catch(Exception e)
finally
{
Console.Write("Error: ");
Console.WriteLine(e.Message);
return 1;
}
if (Debugger.IsAttached)
{
Console.WriteLine();
Console.WriteLine("Press any Enter key to continue...");
Console.ReadLine();
}
}
}
......@@ -134,6 +146,10 @@ namespace RabbitMetaQueue
{
Console.Write("Invalid arguments: ");
Console.WriteLine(e.Message);
Console.WriteLine("Usage:");
optionSet.WriteOptionDescriptions(Console.Out);
return false;
}
}
......
......@@ -51,13 +51,13 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Infrastructure\ConsoleTopologyOperations.cs" />
<Compile Include="Domain\ITopologyOperations.cs" />
<Compile Include="Infrastructure\MulticastTopologyOperations.cs" />
<Compile Include="Infrastructure\RabbitMQTopologyOperations.cs" />
<Compile Include="Infrastructure\RabbitMQTopologyParser.cs" />
<Compile Include="Infrastructure\ConsoleTopologyWriter.cs" />
<Compile Include="Domain\ITopologyWriter.cs" />
<Compile Include="Infrastructure\MulticastTopologyWriter.cs" />
<Compile Include="Infrastructure\RabbitMQTopologyWriter.cs" />
<Compile Include="Infrastructure\RabbitMQTopologyReader.cs" />
<Compile Include="Domain\TopologyComparator.cs" />
<Compile Include="Infrastructure\XmlTopologyParser.cs" />
<Compile Include="Infrastructure\XmlTopologyReader.cs" />
<Compile Include="Model\Argument.cs" />
<Compile Include="Model\Binding.cs" />
<Compile Include="Model\Exchange.cs" />
......
Disclaimer: this is a list of ideas, not a roadmap.
* Templates in the definition for arguments, for example
a "deadletter" template which can be referenced in each
of the queues.
* Specify prefix to determine scope of the exchanges / queues
Relevant when using the delete options to mirror the definition,
if multiple applications / scopes are on the same server.
Q: Not sure how / if VirtualHosts help in this regard.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment