Adding custom MSMQ properties - properties

I am designing an application that creates, uses and deletes MSMQ message queues. Each queue has custom properties which I am currently storing in a file.
I find this messy however and the whole system could go down if this file were to dissappear.
Is there a way I can bind custom properties (e.g. a property xml string) to the actual message queues which I am using?
Cheers,
Shane

While I don't know if that is possible you many not want your configuration to go down with the queue either. I would suggest some other kind of external storage mechanism. You could use another queue that holds messages for each queue configuration(just make sure it's a durable one). You could also look into using a database to hold your configuration and make sure that is backed up.

The queues are either defined in Active Directory or as text files (in the system32\msmq\storage\LQS folder), for public and private respectively.
In theory you may be able to add custom properties to the public queue object in AD.
Similarly, you may be able to add text to the private queue text file (although it may get stripped out should the queue properties be changed).

Related

BizTalk - sharing a schema with promoted properties

In our BizTalk application we would like all internal messages to have the same structure, with a Header element with routing and logging information (this header is the same for all messages), all properties of which are promoted, and a Body element which is different for each specific message. When I create a new message based on the above (by setting the schema's DataStructure or BaseType), I would like the promotions to be kept as well.
I tried getting this to work by creating a Header message with the required fields and promotions, and also by creating a "complete" BaseMessage with a Header and Body element (again with all properties in the header promoted), but either way in a schema using this DataStructure the property promotions are not kept (which I guess makes sense; the XPaths indicated in the PropertySchema are different, because the BaseMessage namespace is different from the derived message).
Is there a way to have a shared schema including property promotions? Or can you copy the structure in a derived message, but you always have to redo the promotions?
Thanks for any insights!
We have a similar header structure that is imported and always have to redo the promotions.
My recommendation would be to solve this problem by not doing what you're describing. While it sounds good in theory, you will find eventually that it's over-engineering with little practical benefit.
What will matter is the routing information, meaning, the Properties, not the Header section. So, it's fine to have shared Property Schemas (deployed separately) but don't try to shoehorn the messages into a 'common' wrapper.

Mapping properties from namespace PS_INTERNET_HEADERS to PS_PUBLIC_STRINGS

I have an Outlook COM add-in (C#, Visual Studio 2012) that extends the standard form with additional message properties. The add-in works with Outlook 2010, 2013 and 2016.
The requirements for the add-in dictate that it supports reading and writing a set of properties in namespace PS_INTERNET_HEADERS. I follow the guidelines in http://blogs.technet.com/b/exchange/archive/2009/04/06/3407221.aspx to have such headers on incoming messages promoted to MAPI properties.
But as I understand it, all such headers will become MAPI string properties, right?! But several of these headers actually have more natural types. One the headers is an RFC5322 date-time header and will have a value like 'Wed, 28 Sep 2016 06:27:00 GMT'. Having such a header mapped to a MAPI property of type PT_UNICODE is not optimal as you cannot sort messages based on it, you cannot really use it in searches, etc.
Is there a good solution to this problem?
The only idea I have is to do some kind of mapping from properties in namespace PS_INTERNET_HEADERS to properties in namespace PS_PUBLIC_STRINGS. That would would also have the nice side-effect that properties will be included when printing messages. But if I have to go down that road, I need some kind of hook for doing the mapping. I can of course loop through all messages in a message store, listen for new messages coming in, listen for changed messages, etc - but it does not feel like a good solution. I guess I could also write an Exchange Transport Agent, but I would really like to keep logic on the client side.
Any suggestions?
Edit after Dmitry's comment:
For outgoing messages, I have to use properties in namespace PS_INTERNET_HEADERS since such messages are eventually transported by SMTP (outside Exchange) to other systems. In detail, I have to adhere to https://www.rfc-editor.org/rfc/rfc6477. As a side-effect, Exchange will for incoming messages promote such headers to properties in namespace PS_INTERNET_HEADERS. And that's all working fine.
But even in that case, I would like to follow your suggestion to extract properties explicitly in my code and write some new ones in namespace PS_PUBLIC_STRINGS. The challenge as I see it is which hook to use for running that code. Users should be able to use the mapped properties as columns in views, for sorting, for filtering, for search, inbox rules, etc. I can sweep entire message stores to do that mapping, I can listen for various Outlook object model events, but in the end I have a hard time seeing how I can avoid users to temporarily see messages that my code haven't treated yet.
I have an old add-in written in C++ using Extended MAPI with a similar challenge. On start-up, for each inbox in each IMsgStore it sweeps the entire inbox (potentially a quite expensive operation) and then subscribes to changes using IMAPIFolder::GetContentsTable and then IMAPITable::Advise. But my experience is that I will get table notifications TABLE_ERROR or TABLE_RELOAD now and then and will have to do another sweep. For IMsgStore::Advise I guess similar challenges are present?! In a C# context, I could use the events in Redemption class RDOStore (e.g. OnMessageModified) , but I assume that class uses IMsgStore::Advise?!
No, the property type will never to converted. It always stay as a string. Why not read the internet headers from the PR_TRANSPORT_MESSAGE_HEADERS property (DASL name http://schemas.microsoft.com/mapi/proptag/0x007D001F) and extract the properties explicitly in your code? You will have full control over which properties are extracted and how they are converted.

Self-contained or versionable messages?

I'm having some message design head-aches. I want to start up an NServiceBus saga for a long running process. Part of the data needed to do the initialization is a list of constraints, which are implementations of an abstract base class. As I've understood the design philosophy, messages should ideally be
Self-contained, that is contain all the data needed to process them. Following this, I would pass along all the list of constraints in the message.
Versionable. NServiceBus does this by using an XML serializer which does not pass along type information (see this thread answer by Udi). In my case, that means I cannot on the recieving end pick up the specifics of the constraints.
The serialization problems can be "solved" by using the BinarySerializer, but this does not seem to be a recommended practice since it breaks versioning. The alternative is to send along some identifier so that the constraints can be retrieved from some datastore, but that would remove the "self-containedness".
Is there a third way here, or do I simply have to choose some "least bad" solution?
There is also the option of having these objects injected into your saga via DI.
Just create a boostrapping class that at startup will call:
Configure.Instance.Configurer.ConfigureProperty<yourSaga>(s => s.SomeProperty = value);

Is it possible, in WCF, to add a global message inspector?

There are a bunch of questions regarding global error handlers and such but none of those address what I need.
Is there any way to add a behavior that will attach to every endpoint or service through .config?
*Specifically what I want to do is add a logger that will capture and log every SOAP request/response. But I would prefer that behavior to be automatically added to every service I have instead of having to manually add it to each.
I looked into behavior extensions and thought that would be the solution but no, you have to add the behavior to every service.*
You may be able to use the <commonBehaviors> section of your machine.config file to define a behavior which would be applied to all services in your machine. Notice that updating the machine.config is really like using a bazooka to solve your problem (and in many scenarios the group policy may forbid you from doing that), so it may not work for all scenarios. You'll also need to make sure that the behavior extension is registered (also in machine.config), and that whatever application you're using with WCF has access to the assembly referenced in the extension (possibly via GAC).
Another alternative would be to use a common library for creating the service hosts (either directly for self-hosted services or via a service host factory for webhosted services), and use that library (which would in turn add the inspector).
Its always good to have a message inspector to get rid of this kind of problem. Message Inspector is an implementation of WCF extension which works nicely to track every incoming request(s) and outgoing response(s) for your service, even if its fails in Message Validation it has an option to trap and work accordingly. More precisely the message inspector can configure using configuration files without making changes in your existing service.
More details about your Message inspector and its implementation can be found Here
Hope this helps !!
Happy Coding :)

questions about using MEF in a WCF service

I'm just starting to play with MEF and have a couple questions.
1) I wrote a WCF service that takes in some xml and passes the xml off to a parser. The parsers are composed using MEF. (metadata in the xml lets me determine which parser to use). I can add a new parser, and support new XML, by just dropping the dll in a directory. That part all works. But, WCF services can be instantiated multiple times, I want my parser catalog to be static, that is, if multiple instances of my service are spun up, and they get the same XML, I only need one instance of the parser running, they are written to be thread safe. I can't seem to configure MEF to do this. Anyone know how?
2) I can drop in a new parser into the directory and a catalog refresh will automatically discover it, that works great. But if I try to drop a modified dll into the directory, and that parser has been activated in the service, I get an error saying the file is in use. Is there a way to override this?
1) It sounds like you should make your MEF container and catalogs static so they only get created once. Make sure you specify that the CompositionContainer should be thread safe by using the constructor with the isThreadSafe parameter and setting it to true.
2) You can enable shadow copying which will prevent the file from being locked when the DLL is loaded. However, you can't unload DLLs from an AppDomain in .NET, and furthermore it is not safe to recompose a CompositionContainer that can be used on multiple threads. In other words, using the isThreadSafe parameter only makes the container thread-safe for "reading"/pulling exports from the container, not modifying it via composition/recomposition.
So if you want to add a new parser it's probably best to restart the service.