Wednesday 21 September 2011

Msbuild and VS solution/project "platform" inconsistency

If you want to build a solution using MSBUILD under a specific configuration you have to specify a valid combination of build-configuration and platform.

For example "Debug|Any CPU"

This is fine, unless you are using a composite target that works on both solution and projects; in our case we were using the solution to build some web projects and their dependent projects and then calling a target to build the web project hosts. (An alternative would have been to build from a project list, but it's convenient to utilise a solution where dependants are resolved auto-magically!)

The problem was that introducing "platform" as a parameter worked for the "build solutions" target - we build under the correct configuration, but it broke the "build web-project-package" target.

The reason is an inconsistency between solutions and projects

Solutions platform Any cpu = "Any CPU", but for projects it's "AnyCPU"

See here

As a side note:

If the solution contains an azure web role project and this project has it's own service configuration then the .csfg file is likely to be called "ServiceConfiguration.[my config name].csfg"

If this is the case you need to pass the parameter "TargetProfile=[My config name]" when building the solution, or else remove the azure web role project from the build list, which may not be desirable.

There is some default behaviour with the azure web role project build target, if a valid value for parameter "TargetProfile" is not passed then the default behaviour is to look for "ServiceConfiguration.Cloud.csfg" first, followed by "ServiceConfiguration.csfg" if neither is found there's an error.

Thursday 8 September 2011

Re-connecting service-bus endpoint - Unexpected - the specified address already exists

Consider two"on premise" WCF service endpoints pointing at a azure service-bus namespace to make them "address-able" to trusted callers going via azure.

Note that the URI are almost the same, except MyContractA has an additional qualification
(a)
<endpoint contract="MyContractA"
binding="netTcpRelayBinding"          address="sb://MyNS.servicebus.windows.net/Company/Area/Service"/>

(b)
<endpoint contract="MyContractB"
binding="netTcpRelayBinding"          address="sb://MyNS.servicebus.windows.net/Company/Area"/>


Remember that each on-premise service that should be address-able via service bus need to be started to establish the connection to the sb relay(which if hosting in app fabric can be accomplished via the warm start feature), but after long periods of inactivity, the connection may be dropped and can be restored by issuing an HTTP Get to each (to re-establish the outbound connection to azure).

What we found was that we'd occasionally get this error trying to re-establish a connection (the services are hosted only once, because at the time of writing Azure SB supports only a single connection per endpoint)

The specified address already exists. Address sb://MyNS.servicebus.windows.net/Company/Area/Service/ already in use.

Which didn't make sense at all in this case.

The thought was that the order in which we "connected, or re-connected" the two services was important, if we started the service with the longer address (a) in example above, first, then no error.



Thanks to Paolo for finding us an explanation of this

Extract from that:-

"Suppose we need to expose the url i.e. just http://.servicebus.windows.net/ e.g. to expose client access policy file through services bus. Then once the base url (as mentioned earlier) is registered, for any further url registration like http://.servicebus.windows.net// appfabric will through the below mentioned error message even if the url is tried to register for the first time.
The specified address already exists.Address sb://.servicebus.windows.net// already in use.
So the resolution is, if needed then first register url like http://.servicebus.windows.net// and then only register the url http://.servicebus.windows.net/ for any appfabric service namespace. "