Saturday 19 November 2016

NServiceBus Saga persisted with NHibernate errors with "The following types may not be used as proxies"

If you use an NServiceBus Saga persisted with NHibernate and you use the Saga Data as per the sample code it errors with "The following types may not be used as proxies"

The sample code is:

public class OrderSagaData :
    IContainSagaData
{
    public Guid Id { get; set; }
    public string Originator { get; set; }
    public string OriginalMessageId { get; set; }
    [Unique]
    public string OrderId { get; set; }
}

The solution is to mark all the properties as virtual.

Thursday 17 November 2016

NServiceBus doesn't create TimeoutEntity or Subscription databases, even in Integration mode

Note: this refers to NServiceBus 4.6.5. Other versions may differ.

I had a problem whereby I was running an NServiceBus server on a new machine. It was using the
NHibernate ORM with SQL Server as the persistence store.

However, even with the endpoint running in NServiceBus.Integration mode, I found that the underlying databases were not being created. On starting the endpoint it would throw an ADOException with messages like

"could not execute query\r\n[ SELECT this_.Id as y0_, this_.Time as y1_ FROM TimeoutEntity this_ WHERE this_.Endpoint = @p0 and (this_.Time >= @p1 and this_.Time <= @p2) ORDER BY this_.Time asc ]\r\n  Name:cp0 - Value:SchemaCreator  Name:cp1 - Value:17/11/2006 15:10:37  Name:cp2 - Value:17/11/2016 15:10:37\r\n[SQL: SELECT this_.Id as y0_, this_.Time as y1_ FROM TimeoutEntity this_ WHERE this_.Endpoint = @p0 and (this_.Time >= @p1 and this_.Time <= @p2) ORDER BY this_.Time asc]"

as it was unable to read from the (not yet created) database.

The startup code was below:


        
        private static IBus SetupBus()
        {
            Configure.Serialization.Json();
            return Configure
                    .With(GetAssembliesToScan())
                    .DefaultBuilder()
                    .UseNHibernateSubscriptionPersister()
                    .UseNHibernateTimeoutPersister()
                    .UseNHibernateSagaPersister()
                    .UseNHibernateGatewayPersister()
                    .UseInMemoryGatewayDeduplication()
                    // Hack the unobtrusive conventions to force the console to work.
                    .DefiningEventsAs(t => t.Namespace != null && t.Namespace.StartsWith("Orders.Contracts"))
                    .UnicastBus()

                    // Load handlers to allow subscriptions to be set up.
                    .LoadMessageHandlers()
                    .CreateBus()
                    .Start(() => Configure.Instance.ForInstallationOn().Install());
        }

        private static Assembly[] GetAssembliesToScan()
        {
            return new[]
            {
                typeof(IOrder).Assembly,
                typeof(Program).Assembly
            };
        }

In the end after stepping through lots of NServiceBus and NServiceBus.NHibernate code I found the answer to the problem.
NServiceBus scans assemblies for code implementing the INeedToInstallSomething interface. The NServiceBus.Unicast.Subscriptions.NHibernate.Installer.Installer class implements this interface and it is this which calls the NHibernate SchemaUpdate.Execute() method.

However, despite the application's XML configuration referring to NHibernate and the code above explicitly defining the NHibernate persister, the installation code is not run because the implementing classes have not been scanned.

The solution is to modify the code GetAssembliesToScan method above to include the NServiceBus.NHibernate assembly.


        
        private static Assembly[] GetAssembliesToScan()
        {
            return new[]
            {
                typeof(IOrder).Assembly,
                typeof(Program).Assembly,
                typeof(NServiceBus.Unicast.Subscriptions.NHibernate.Installer.Installer).Assembly
            };
        }

Additionally, if your endpoint works with a Saga you need to scan the assembly that contains the SagaData.

public static IEnumerable AssembliesToScan
        {
            get
            {
                yield return typeof(IOrderCreated).Assembly;
                yield return typeof(OrderSagaData).Assembly;
                yield return typeof(NServiceBus.Unicast.Subscriptions.NHibernate.Installer.Installer).Assembly;
            }
        }

Wednesday 16 November 2016

Samsung Galaxy 5 (SM-900F) doesn't support 4G in the USA

Having paid for a data upgrade for EE in the USA - I discovered the Samsung Galaxy 5 - SM900F, doesn't support the 4G frequencies in the USA.

Friday 4 November 2016

Virgin Media CGNV4 - a security risk?

I've noticed that the Hitron CGNV4 router used by Virgin Media for its high-speed broadband has port 8080 open. So far I've been on the phone to them for 45 minutes and nobody knows what it's for!