Skip to content
This repository has been archived by the owner on Apr 30, 2019. It is now read-only.

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonCropp committed Jun 25, 2015
1 parent 7fb521d commit 1291ee0
Show file tree
Hide file tree
Showing 15 changed files with 1,431 additions and 1 deletion.
75 changes: 75 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Auto detect text files and perform CRLF normalization
* text=auto eol=crlf

# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

*.exe -text -diff
*.jpg -text -diff
*.png -text -diff
*.gif -text -diff
*.dll -text -diff
*.pdb -text -diff
*.pptx -text -diff
*.xap -text -diff
*.ico -text -diff
*.ttf -text -diff
*.otf -text -diff

*.cs text diff=csharp
*.config text diff=csharp
*.xml text diff=csharp
*.vb text
*.c text
*.cpp text
*.cxx text
*.h text
*.hxx text
*.py text
*.rb text
*.java text
*.html text
*.htm text
*.css text
*.scss text
*.sass text
*.less text
*.js text
*.lisp text
*.clj text
*.sql text
*.php text
*.lua text
*.m text
*.asm text
*.erl text
*.fs text
*.fsx text
*.hs text
*.targets text
*.psm1 text
*.ps1 text
*.md text
*.DotSettings text
*.txt text eol=crlf
*.bat text eol=crlf

# Custom for Visual Studio
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
*.sln text eol=crlf merge=union
*.suo -text -diff
*.snk -text -diff
*.cub -text -diff
*.wixlib -text -diff
85 changes: 85 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
nugets
deploy
build32
binaries
*.vshost.*
.nu
_UpgradeReport.*
*.cache
*~
*.swp
results
CommonAssemblyInfo.cs
lib/sqlite/System.Data.SQLite.dll
*.orig
Samples/DataBus/storage
packages
PrecompiledWeb
core-only
Release
Artifacts
LogFiles
csx
*.ncrunchproject
*.ncrunchsolution
_NCrunch_NServiceBus/*
logs
run-git.cmd
src/Chocolatey/Build/*

installer/[F|f]iles
installer/[C|c]ustom[A|a]ctions
installer/ServiceControl-cache

# Created by https://www.gitignore.io

### VisualStudio ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
.vs/

# mac temp file ignore
.DS_Store

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/

# Roslyn cache directories
*.ide/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

#NUNIT
*.VisualState.xml
TestResult.xml

# NCrunch
_NCrunch_*
.*crunch*.local.xml

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

src/scaffolding.config

# Approval tests temp file
*.received.*
10 changes: 10 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
By accessing NServiceBus code here, you are agreeing to the following licensing terms.
If you do not agree to these terms, do not access the NServiceBus code.

Your license to the NServiceBus source and/or binaries is governed by the Reciprocal Public License 1.5 (RPL1.5) license as described here:

http://www.opensource.org/licenses/rpl1.5.txt

If you do not wish to release the source of software you build using NServiceBus, you may use NServiceBus source and/or binaries under the License Agreement described here:

http://particular.net/LicenseAgreement
24 changes: 24 additions & 0 deletions MsmqReturnToSourceQueue.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MsmqReturnToSourceQueue", "MsmqReturnToSourceQueue\MsmqReturnToSourceQueue.csproj", "{0E012C5E-EFB2-435D-8857-3F59F1880775}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0E012C5E-EFB2-435D-8857-3F59F1880775}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E012C5E-EFB2-435D-8857-3F59F1880775}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E012C5E-EFB2-435D-8857-3F59F1880775}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E012C5E-EFB2-435D-8857-3F59F1880775}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.2\lib\NET35;packages\Unity.2.1.505.0\lib\NET35
EndGlobalSection
EndGlobal
570 changes: 570 additions & 0 deletions MsmqReturnToSourceQueue.sln.DotSettings

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions MsmqReturnToSourceQueue/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Reflection;

[assembly: AssemblyTitle("MsmqReturnToSourceQueue")]
[assembly: AssemblyCompany("NServiceBus Ltd.")]
[assembly: AssemblyProduct("MsmqReturnToSourceQueue")]
[assembly: AssemblyCopyright("Copyright NServiceBus. All rights reserved")]
[assembly: AssemblyVersion("6.0.0.0")]
[assembly: AssemblyFileVersion("6.0.0.0")]
152 changes: 152 additions & 0 deletions MsmqReturnToSourceQueue/ErrorManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using System;
using System.Collections.Generic;
using System.Messaging;
using System.Transactions;

class ErrorManager
{
public bool ClusteredQueue { get; set; }

public virtual MsmqAddress InputQueue
{
set
{
var path = MsmqUtilities.GetFullPath(value);
var q = new MessageQueue(path);

if ((!ClusteredQueue) && (!q.Transactional))
{
throw new ArgumentException(string.Format("Queue '{0}' must be transactional.", q.Path));
}

queue = q;

var messageReadPropertyFilter = new MessagePropertyFilter
{
Body = true,
TimeToBeReceived = true,
Recoverable = true,
Id = true,
ResponseQueue = true,
CorrelationId = true,
Extension = true,
AppSpecific = true,
LookupId = true,
};

queue.MessageReadPropertyFilter = messageReadPropertyFilter;
}
}

public void ReturnAll()
{
foreach (var m in queue.GetAllMessages())
{
ReturnMessageToSourceQueue(m.Id);
}
}

/// <summary>
/// May throw a timeout exception if a message with the given id cannot be found.
/// </summary>
public void ReturnMessageToSourceQueue(string messageId)
{
using (var scope = new TransactionScope())
{
try
{
var message = queue.ReceiveById(messageId, TimeoutDuration, MessageQueueTransactionType.Automatic);

var headers = MsmqUtilities.ExtractHeaders(message);
string failedQ;
if (!headers.TryGetValue(Headers.FailedQ, out failedQ))
{
Console.WriteLine("ERROR: Message does not have a header indicating from which queue it came. Cannot be automatically returned to queue.");
return;
}

using (var q = new MessageQueue(MsmqUtilities.GetFullPath(MsmqAddress.Parse(failedQ))))
{
q.Send(message, MessageQueueTransactionType.Automatic);
}

Console.WriteLine("Success.");
scope.Complete();
}
catch (MessageQueueException ex)
{
if (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
{
Console.WriteLine(NoMessageFoundErrorFormat, messageId);

uint messageCount = 0;
foreach (var m in queue.GetAllMessages())
{
messageCount++;
var headers = MsmqUtilities.ExtractHeaders(m);

var originalId = GetOriginalId(headers);

if (string.IsNullOrEmpty(originalId) || messageId != originalId)
{
if (messageCount%ProgressInterval == 0)
{
Console.Write(".");
}
continue;
}

Console.WriteLine();
Console.WriteLine("Found message - going to return to queue.");

using (var tx = new TransactionScope())
{
var failedQueue = headers[Headers.FailedQ];
using (var q = new MessageQueue(MsmqUtilities.GetFullPath(MsmqAddress.Parse(failedQueue))))
{
q.Send(m, MessageQueueTransactionType.Automatic);
}

queue.ReceiveByLookupId(MessageLookupAction.Current, m.LookupId, MessageQueueTransactionType.Automatic);

tx.Complete();
}

Console.WriteLine("Success.");
scope.Complete();

return;
}

Console.WriteLine();
Console.WriteLine(NoMessageFoundInHeadersErrorFormat, messageId);
}
}
}
}

string GetOriginalId(Dictionary<string, string> headers)
{
string originalId;

if (headers.TryGetValue("NServiceBus.OriginalId", out originalId))
{
return originalId;
}
if (headers.TryGetValue(Headers.MessageId, out originalId))
{
return originalId;
}

return null;
}


const string NoMessageFoundErrorFormat = "INFO: No message found with ID '{0}'. Checking headers of all messages.";
const string NoMessageFoundInHeadersErrorFormat = "INFO: No message found with ID '{0}' in any headers.";
const uint ProgressInterval = 100;

TimeSpan TimeoutDuration = TimeSpan.FromSeconds(5);
MessageQueue queue;

}
8 changes: 8 additions & 0 deletions MsmqReturnToSourceQueue/HeaderInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;

[Serializable]
public class HeaderInfo
{
public string Key { get; set; }
public string Value { get; set; }
}
8 changes: 8 additions & 0 deletions MsmqReturnToSourceQueue/Headers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
static class Headers
{
public const string MessageId = "NServiceBus.MessageId";
public const string CorrelationId = "NServiceBus.CorrelationId";
public const string ReplyToAddress = "NServiceBus.ReplyToAddress";
public const string MessageIntent = "NServiceBus.MessageIntent";
public const string FailedQ = "NServiceBus.FailedQ";
}
Loading

0 comments on commit 1291ee0

Please sign in to comment.