Nservicebus: File based routing schema improvements

Created on 15 Apr 2016  Â·  32Comments  Â·  Source: Particular/NServiceBus

After reading Scaling out NServiceBus endpoints I was very confused. Machine was not mentioned in the schema on http://docs.particular.net/nservicebus/messaging/file-based-routing#the-file

After a discussion with @timbussmann and @SzymonPobiega it seems that _Machine_ is an extension specific to MSMQ.

Current

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <endpoints>
    <endpoint name="Sales">
      <instance Machine="Sales1"/>
      <instance Machine="Sales2"/>
    </endpoint>
    <endpoint name="Shipping">
      <instance Machine="Shipping"/>
    </endpoint>
  </endpoints>
</root>

Proposal

  • Add schema for MSMQ extension
  • Hosting of schemas at those locations
  • Use of namespaces for intellisense in visual studio
<?xml version="1.0" encoding="utf-8" ?>
<routing xmlns="http://schemas.nservicebus.com/routing"
         xmlns:msmq="http://schemas.nservicebus.com/routing/msmq">
  <endpoints>
    <endpoint name="Sales">
      <instance>
        <msmq:machine host="SalesVM1" />
      </instance>
      <instance>
        <msmq:machine host="SalesVM2" />
      </instance>
    </endpoint>
    <endpoint name="Shipping">
      <instance>
        <msmq:machine host="ShippingVM1" />
      </instance>
    </endpoint>
  </endpoints>
</routing>

References:

All 32 comments

@Particular/transport-maintainers what other transports would need custom extensions like mentioned above? ( schema in sqltransport?)

SQL Server transport might need schema and catalog /cc @tmasternak @weralabaj @mauroservienti

reading the documentation it is not clear to me where the file should be, at all the endpoints? at senders? at recipients?

If I read the following:

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <endpoints>
    <endpoint name="Sales">
      <instance Machine="Sales1"/>
      <instance Machine="Sales2"/>
    </endpoint>
    <endpoint name="Shipping">
      <instance Machine="Shipping"/>
    </endpoint>
  </endpoints>
</root>

and that must be at the sender then it scares me a lot, does it mean that senders must be aware of the topology of the destinations?
If it is only for the client distributor then I still don't like it but I can understand why.

The second sample pointed out by the doco is:

<endpoints>
  <endpoint name="Sales">
    <!-- Scaled-out endpoint -->
    <instance discriminator="1"/>
    <instance discriminator="2"/>
  </endpoint>
  <!-- No need to specify instances for non-scaled-out endpoint (Shipping) -->
</endpoints>

Still if this is at the sender I don't get why the sender needs to be aware of destination instances.

Back to @SzymonPobiega point: yes SQL Transport might need, depending on the configuration, schema and catalog info. They can be specified in the address only right now.

@mauroservienti the first sample you quoted is the MSMQ config file. It must be present at the sender so that the sender knows which machines host the MSMQ instance the receiver uses. It is the necessary evil of MSMQ. Each endpoint can have a copy of the file or it can be shared on a network share, whatever works with the organization/project.

The second example shows the sender-side distribution when a single queue is not enough. Again, the sender needs to know the IDs of receiver instances in order to distribute.

Last but not least, if the system uses SQL Server Transport an example of such config file would be:

<root>
  <endpoints>
    <endpoint name="Sales">
      <instance Schema="sal"/>
    </endpoint>
    <endpoint name="Shipping">
      <instance Schema="shp"/>
    </endpoint>
  </endp

cool, thanks @SzymonPobiega. Much clearer now.

@szymonpobiega while I think the routing doco is good. In light of this conversation do u feel it need any adjustments?

Does it make sense to remove file-based-routing from Core and provide a sample that the users can tweak to whatever level they need?

ping @ramonsmits

Talking to @SzymonPobiega we decided to keep the file for now since its only targeted to MSMQ (yes there is a backdoor so it can be be used for sql) and it will be removed from the core when we pull msmq out in the future.

@mauroservienti There will always need to be a logical to physical translation. In V6 that would be this when having multiple physical destinations.

@andreasohlund @tmasternak We cannot really remove the file based routing as it is documented as being the replacement for MessageEndpointMappings. New V6 users would be advised to use the file based mapping for physical information.

That is my interpretation after reading:

NServiceBus had the concept of an "Owning Endpoint" for any given message type. In Version 6 this has been superseded by the more flexible routing model. The previous configuration in the form of MessageEndpointMappings configuration section is still fully respected by the Version 6 endpoints in order to provide a smoother transition experience.

and

In previous versions NServiceBus used fixed message ownership mappings that allowed only to map the message type (or all types in an assembly or a namespace) to physical addresses (queue names). The flexible routing in Version 6 splits this mapping up into a series of individually configurable steps. NServiceBus 6 still understands the old configuration in form of message-endpoint mappings for backwards compatibility.

@ramonsmits this doco needs to be probably updated. The truth is somewhere in the middle. For all transports other than MSMQ it is enough to specify the logical routing in code via new APIs. No physical mapping needed. For MSMQ it is advised in V6 to use the file-based routing as a complement to the code-based logical routing. I would not recommend using MEMs in the green field V6 endpoint.

@SzymonPobiega I don't agree. I would not even put 'static' routes in code. We always say that where handlers are located is a deployment concern. I would always advise to put routes in config. Just hosting a handler in a different or new endpoint would require a recompile if that route would be put in code.

@ramonsmits we had that discussion initially in the routing TF and we decided that code-based logical routing is the way to go. The logical name of the endpoint that processes the message is the developer's concern, not the infra concern (at least that was the outcome of that discussion).

That said, If you feel strongly that that outcome was wrong, please raise a new PlatDev issue and we can discuss it in that issue. I also think that a zoom call might be a good option. If we arrive at a different conclusion now this might be a show stopper for V6.

It seems there isn't yet a consensus between the original task force and @ramonsmits who raised this issue. I'm removing the Consider for flag. Like @SzymonPobiega said if the original task force should reconsider the initial decisions please organize a meeting with the orignal task force members and update the issue description according or raise new issues.

@danielmarbach this issue in following scope:

  • Add schema for MSMQ extension
  • Hosting of schemas at those locations
  • Use of namespaces for intellisense in visual studio

has been included in the https://github.com/Particular/PlatformDevelopment/issues/814 (make routing RC-ready) issue. I don't think the discussion about weather logical routing should be in code or config affects these action items so we are not changing the scope of 814. The discussion should happen outside of scope of 814. Should we decide that logical routing should be always in config 814 is going to be cancelled and replaced by a totally new issue.

@danielmarbach I've created a doco issue for updating the doco about message mapping and routing. That discussion from @tmasternak @andreasohlund @SzymonPobiega and me is off-topic.

Are we really adding a xml schema to config files ?
So in this issue we are proposing to host this schemas in our servers, and keep those schemas up to date every time we change them, this means we need to version them.
Are we really sure we want to do this, I see this as a major burden on releases, as well, I can nearly guarantee that we will forget to update these schemas.

Remember we have never had schemas before, and users are not doing too bad.

Finally, the way I see it, is that the main consumer of these config files are OPS/DEVOPS, and they won't be using an IDE to update these files, these are files that majority of time will change based on the deployed environment.

I really fail to see the benefit here, on the other hand I see plenty of drawbacks.

@johnsimons What is the alternative that you suggest?

We don't have to host the schema, it can also just be part of the package and yes, schemas should be versioned.

By the way, a lot of ops moved on. They also use editors like Atom or alternatives to modify files. You can always modify such files with notepad if you really need to.

We have not decided anything. This is my proposal.

After a discussion with @timbussmann and @SzymonPobiega it seems that Machine is an extension specific to MSMQ.

It is _very_ unclear what the schema is and that is why I think we should have it and primary want to make the configuration more explicit in what the intent is of the attributes and elements.

What is the alternative that you suggest?

None

So in this issue we are proposing to host this schemas in our servers, and keep those schemas up to date every time we change them

The schema was already there, but it was hardcoded in code and therefore invisible and not properly versioned.

Remember we have never had schemas before, and users are not doing too bad.

Did we verify this, or is this an assumption? When I first started development with NServiceBus, this was one of my main concerns; understanding config. I meet quite a few developers who have a hard time understanding v5 configuration.

Although I'm not too sure on the benefits and whether or not it'd be complex to have schemas, I think it'd be lovely if we had them. Especially with the routing changes in v6. I've always longed for them in the past, before my time at Particular. I don't think versioning them is that hard, and we could probably also do some sort of check during build, just like we currently do with API changes and obsoletes and what not. I don't think that being afraid they won't get properly updated is a reason not to do it.

Having schema in an xml file in VS does not make the intellisense just work, the schema actually needs to be configured in VS, so this would require some kind of installation.

BTW, this has been previously discussed see #935

yeah i once went to the effort of getting a schema working in VS. never bothered again

I decided to test the behavior of VS 2015 in how it handles XML schemas, and it seems like it's actually pretty simple to get working.

If the xsd file is added directly to the project (for example via a nuget package) then as soon as you add the matching namespace to your XML element via the xmlns attribute, then the schema file will be used to provide validation.

On the other hand, if we don't want to include it in the nuget package (and force the xsd file to be included in the project) then you can add the xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attibute to your element and then use the xsi:schemaLocation to point the file to a location (local file system, online) where the schema file is, and once again you get validation.

So, we could add those instructions to the docs, or include some sort of stub XML file with the appropriate stuff already set up.

Don't shoot me yet... a sample that has it all set up?

Don't shoot me yet... a sample that has it all set up?

Yeah, an actual doco sample might be an even better idea, since then they could actually download a working file and not need to just copy and paste from the website.

what about showing the schema on the docs page as here: http://docs.particular.net/nservicebus/messaging/file-based-routing#the-file (and one for MSMQ on the MSMQ specific config page) and embedding it in the dll. So we can verify the schema when loading the config and if users really want to use verify themselves they can take these schemas and host them wherever they want (we should have a sample for that scenario I guess)?

my assumption is that 90% of users don't bother validating a schema manually if they don't have to process it. So you should definitely be able to write the config file without including the schemas.

Did we arrive to a conclusion here?

@SzymonPobiega no

open questions are still:

  • should we provide a schema at all. If yes, how?
  • should we validate the received config against that schema?

:-1: for schema validation. _Be conservative in what you do, be liberal in what you accept from others_. I think selecting the nodes via LinqToXml can do the job quite nicely

My initial idea is to use the schema more as a documentation thing, taking advantage of the fact that XML documents can be described unambiguously via XSD. I still believe there is value in such usage of schema.

after discussing this with the @Particular/nservicebus-maintainers we think this issue has been discussed during the routing changes and no further changes need to be made.

The current behavior is:

  • The instance mapping file is only usable with MSMQ
  • We do an internal schema validation, but the schema is very lax due to it's initial design

In case anybody thinks we should change the schema validation part it would make more sense to raise a new issue.

Was this page helpful?
0 / 5 - 0 ratings