NServiceBus with Sql Server Transport Error - sql-server

I have configured NServiceBus to use Sql Server.
Configure.With()
.AutofacBuilder(container)
.UseTransport<SqlServer>("aureus")
.InMemorySubscriptionStorage()
.UnicastBus()
.DisableTimeoutManager()
.CreateBus()
.Start();
When I send a message in the controller.
this._bus.Send(new BillClient { Value = "testing." });
I get the error.
Failed to send message to address: [queue]
Invalid object name 'queue'.
My configuration is as follows:
<UnicastBusConfig>
<MessageEndpointMappings>
<add Assembly="Aureus.Messages" Namespace="Aureus.Messages" Endpoint="queue"/>
</MessageEndpointMappings>
</UnicastBusConfig>
What have I missed? I can't find out if I need to run scripts / or initialise the queues?

Instead of
.Start()
You need
.Start(() => Configure.Instance.ForInstallationOn<Windows>().Install());
To kick off the initialization of the queues.

I'm no expert but I had to use the ConnectionString definition as the argument to .UseTransport() as shown below. In your post it's not clear what "aureus" will mean to NServiceBus software.
.UseTransport<SqlServer>(ConnectionString())
string ConnectionString()
{
return "NServiceBus/Transport\" connectionString=\"Data Source=.\\SQLEXPRESS;Initial Catalog=nservicebus;Integrated Security=True";
}
I was not able to use the ConnectionString name from my config file as an argument either. Here's the section of my config file fyi:
<connectionStrings>
<!-- Message Bus ********************************************** -->
<add name="NServiceBus/Transport" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=nservicebus;Integrated Security=True" />
<!-- Message Bus ********************************************** -->
</connectionStrings>
Also, for Endpoint in my config file, I had to use the namespace of my NServiceBus message handler class. Here's the endpoint section of my config file:
<UnicastBusConfig ForwardReceivedMessagesTo="audit">
<MessageEndpointMappings>
<!--Note - Endpoint must specify the Namespace of the server-->
<add Assembly="My.Messages.Assemblyname" Namespace="My.Messages.AssemblyNamespace" Endpoint="MyMessageHandlerAssy.Namespace" />
</MessageEndpointMappings>
</UnicastBusConfig>
Hope that helps you a bit.

Related

Register an addon in Episerver CMS 12

Plugin UI are developed in a separate MVC project and CMS 12 is in another projects. Following is a test solution that just to explain the issue we are having.
Solution structure
Please consider followings
The TestAddon project is a Simple MVC project with basic UI. We need to get this UI rendered in a CMS 12 Admin menu. We have created a menu provider as well.
Then build the TestAddon project and copied DLLs to CMS-> bin folder.
Created module/_protected folder and added TestAddon/TestAddon.zip
module.config was created as described in the documentation(https://world.optimizely.com/documentation/developer-guides/CMS/configuration/Configuring-moduleconfig/)
<module productName="TestAddon" loadFromBin="false" tags="EPiServerModulePackage" clientResourceRelativePath="1.0.0">
<assemblies>
<add assembly="TestAddon" />
<add assembly="TestAddon.Views" />
</assemblies>
<route url="{controller}/{action}" >
<defaults>
<!--<add key="moduleArea" value="TestAddon" />-->
<add key="controller" value="CustomAdminPage" />
<add key="action" value="Index" />
</defaults>
</route>
<clientResources>
<!-- <add name="myscript" path="ClientResources/index.js" resourceType="Script" ></add> -->
</clientResources>
<clientModule>
<moduleDependencies>
<add dependency="CMS" />
<add dependency="Shell"/>
<add dependency="EPiServer.Cms.UI.Admin" type="RunAfter"/>
<add dependency="EPiServer.Cms.UI.Settings" type="RunAfter"/>
</moduleDependencies>
<requiredResources>
</requiredResources>
</clientModule>
</module>
Set Auto discovery in startup file
services.Configure<ProtectedModuleOptions>(x => x.AutoDiscovery = EPiServer.Shell.Configuration.AutoDiscoveryLevel.Modules);
When we then start the project it is giving following error
Error Screenshot
Stacktrace
When we removed the auto discovery setting form startup class. It works to build the project
Does anyone have experienced this?
Please point me in a correct direction
You don't need to copy files to your sample project for local testing. You can add a project reference to your add-on project instead, then add this in your sample project's startup so the files are loaded correctly:
var moduleName = typeof(SomeClassInYourAddOn).Assembly.GetName().Name;
services.Configure<CompositeFileProviderOptions>(options =>
{
options.BasePathFileProviders.Add(new MappingPhysicalFileProvider(
$"/EPiServer/{moduleName}",
string.Empty,
Path.GetFullPath($"..\\..\\src\\{moduleName}")));
});
services.Configure<ProtectedModuleOptions>(options =>
{
options.Items.Add(new ModuleDetails { Name = moduleName });
});
Not sure if this is needed, but I don't think protected modules are auto discovered. So if you have a configuration method in your add-on that consumers of your add-on need to call, then you can add this in the method:
var moduleName = typeof(SomeClassInYourAddOn).Assembly.GetName().Name;
services.Configure<ProtectedModuleOptions>(options =>
{
if (!options.Items.Any(i => i.Name.Equals(moduleName, StringComparison.OrdinalIgnoreCase)))
{
options.Items.Add(new ModuleDetails() { Name = moduleName });
}
});
Then your add-on is added even if auto discovery is not enabled.

Spring boot Auto connection to database [duplicate]

I have a nice little Spring Boot JPA web application. It is deployed on Amazon Beanstalk and uses an Amazon RDS for persisting data. It is however not used that often and therefore fails after a while with this kind of exception:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 79,870,633 milliseconds ago.
The last packet sent successfully to the server was 79,870,634 milliseconds ago. is longer than the server configured value of 'wait_timeout'.
You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
I am not sure how to configure this setting and can not find information on it on http://spring.io (a very good site though). What are some ideas or pointers to information?
I assume that boot is configuring the DataSource for you. In this case, and since you are using MySQL, you can add the following to your application.properties up to 1.3
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
As djxak noted in the comment, 1.4+ defines specific namespaces for the four connections pools Spring Boot supports: tomcat, hikari, dbcp, dbcp2 (dbcp is deprecated as of 1.5). You need to check which connection pool you are using and check if that feature is supported. The example above was for tomcat so you'd have to write it as follows in 1.4+:
spring.datasource.tomcat.testOnBorrow=true
spring.datasource.tomcat.validationQuery=SELECT 1
Note that the use of autoReconnect is not recommended:
The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don't handle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead and stale connections properly.
The above suggestions did not work for me.
What really worked was the inclusion of the following lines in the application.properties
spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
spring.datasource.validationQuery = SELECT 1
You can find the explanation out here
Setting spring.datasource.tomcat.testOnBorrow=true in application.properties didn't work.
Programmatically setting like below worked without any issues.
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
#Bean
public DataSource dataSource() {
PoolProperties poolProperties = new PoolProperties();
poolProperties.setUrl(this.properties.getDatabase().getUrl());
poolProperties.setUsername(this.properties.getDatabase().getUsername());
poolProperties.setPassword(this.properties.getDatabase().getPassword());
//here it is
poolProperties.setTestOnBorrow(true);
poolProperties.setValidationQuery("SELECT 1");
return new DataSource(poolProperties);
}
I just moved to Spring Boot 1.4 and found these properties were renamed:
spring.datasource.dbcp.test-while-idle=true
spring.datasource.dbcp.time-between-eviction-runs-millis=3600000
spring.datasource.dbcp.validation-query=SELECT 1
whoami's answer is the correct one. Using the properties as suggested I was unable to get this to work (using Spring Boot 1.5.3.RELEASE)
I'm adding my answer since it's a complete configuration class so it might help someone using Spring Boot:
#Configuration
#Log4j
public class SwatDataBaseConfig {
#Value("${swat.decrypt.location}")
private String fileLocation;
#Value("${swat.datasource.url}")
private String dbURL;
#Value("${swat.datasource.driver-class-name}")
private String driverName;
#Value("${swat.datasource.username}")
private String userName;
#Value("${swat.datasource.password}")
private String hashedPassword;
#Bean
public DataSource primaryDataSource() {
PoolProperties poolProperties = new PoolProperties();
poolProperties.setUrl(dbURL);
poolProperties.setUsername(userName);
poolProperties.setPassword(password);
poolProperties.setDriverClassName(driverName);
poolProperties.setTestOnBorrow(true);
poolProperties.setValidationQuery("SELECT 1");
poolProperties.setValidationInterval(0);
DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource(poolProperties);
return ds;
}
}
I have similar problem. Spring 4 and Tomcat 8. I solve the problem with Spring configuration
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="initialSize" value="10" />
<property name="maxActive" value="25" />
<property name="maxIdle" value="20" />
<property name="minIdle" value="10" />
...
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />
</bean>
I have tested. It works well! This two line does everything in order to reconnect to database:
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />
In case anyone is using custom DataSource
#Bean(name = "managementDataSource")
#ConfigurationProperties(prefix = "management.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
Properties should look like the following. Notice the #ConfigurationProperties with prefix. The prefix is everything before the actual property name
management.datasource.test-on-borrow=true
management.datasource.validation-query=SELECT 1
A reference for Spring Version 1.4.4.RELEASE
As some people already pointed out, spring-boot 1.4+, has specific namespaces for the four connections pools. By default, hikaricp is used in spring-boot 2+. So you will have to specify the SQL here. The default is SELECT 1. Here's what you would need for DB2 for example:
spring.datasource.hikari.connection-test-query=SELECT current date FROM sysibm.sysdummy1
Caveat: If your driver supports JDBC4 we strongly recommend not setting this property. This is for "legacy" drivers that do not support the JDBC4 Connection.isValid() API. This is the query that will be executed just before a connection is given to you from the pool to validate that the connection to the database is still alive. Again, try running the pool without this property, HikariCP will log an error if your driver is not JDBC4 compliant to let you know. Default: none
For those who want to do it from YAML with multiple data sources, there is a great blog post about it: https://springframework.guru/how-to-configure-multiple-data-sources-in-a-spring-boot-application/
It basically says you both need to configure data source properties and datasource like this:
#Bean
#Primary
#ConfigurationProperties("app.datasource.member")
public DataSourceProperties memberDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#Primary
#ConfigurationProperties("app.datasource.member.hikari")
public DataSource memberDataSource() {
return memberDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
Do not forget to remove #Primary from other datasources.

What's the difference between app.config's connection string and c# connection string

Is there any difference between the following two lines of code in c# and app.config file.
C# connectionString declaration.
string conn = "/server = test/ DB = test_dev/ env = dev"
and
app.config declartion
<connectionStrings>
<add name="Test" connectionString="Data Source=.;Initial Catalog=test_dev;" providerName="System.Data.SqlClient" />
</connectionStrings>
How can I declare c# connection string to the format in the app.config file so that I can read from the app.config file.
There's no real difference between hard coding a connection string and pulling one out of the app.config file.
The advantage of using app.config is that you can use that same connection string in multiple places in your application, and then if you need to change it (for testing purposes or anything else really), you only have to change it in one spot that is nicely contained in a configuration file.
As mentioned in the comments, to read a connection string directly from your app.config, you can use this:
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Test"];
although there are many different ways to access the connection string (DataSet, etc.)
To read connectionString values in your C# code, you can access System.Configuration.ConnectionStringSettingsCollection
System.Configuration.ConfigurationManager.ConnectionStrings
will return collection of all connection strings defined in <connectionStrings></connectionStrings> section
You can access connection strings by name using
string conn =
System.Configuration.ConfigurationManager.ConnectionStrings["Test"];

Azure Diagnostics: Access to the path '(GUID)-mswapd-lock' is denied?

Code and configuration:
I've enabled Diagnostics per the official tutorial at https://www.windowsazure.com/en-us/develop/net/common-tasks/diagnostics/. My diagnostic initializer is invoked from Global.asax (no WebRole.cs for this WCF ported to Azure WebRole) and its quite simple like:
public bool Initialize()
{
DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();
config.WindowsEventLog.DataSources.Add("Application!*");
config.WindowsEventLog.ScheduledTransferPeriod = System.TimeSpan.FromMinutes(1.0);
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);
return true;
}
Cloud and Local strings same:
I'm using the SAME cloud based diagnostic connection string for local and cloud configurations.
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="MyApp.API.Azure1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="2" osVersion="*" schemaVersion="2012-05.1.7">
<Role name="MyApp.API">
<Instances count="1" />
<ConfigurationSettings>
...
<Setting name="Microsoft.WindowsAzure.Plugins.Caching.ConfigStoreConnectionString" value="DefaultEndpointsProtocol=https;AccountName=myapi;AccountKey=MyVeryLongStringHereWhichIsActuallyAKeyForAPlaceInTheCloudWhereUnicornsDanceUnderDoubleRainbows" />
</ConfigurationSettings>
<Certificates>
<Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" thumbprint="ThumbPrintStringsAreBiggerThanPinkiePrintString" thumbprintAlgorithm="sha1" />
</Certificates>
</Role>
</ServiceConfiguration>
Error:
When I run the above within Azure Emulator (local compute) I do not get the error (despite the cloud connection string for diagnostics). When I run the webrole on Azure (with same diagnostic sting and of course, code), I get the following error:
[UnauthorizedAccessException: Access to the path '05d5e525-e1bc-4a37-8bfb-010bb2941301-mswapd-lock' is denied.]
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +12895415
System.Threading.MutexTryCodeHelper.MutexTryCode(Object userData) +229
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) +0
System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew, MutexSecurity mutexSecurity) +629
System.Threading.Mutex..ctor(Boolean initiallyOwned, String name, Boolean& createdNew) +18
Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.StartDiagnosticsMonitorProcess(DiagnosticMonitorStartupInfo info) +171
Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.ReconfigureMonitoringProcess(ConfigRequest req) +209
Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.UpdateState(DiagnosticMonitorStartupInfo startupInfo) +207
Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.StartWithExplicitConfiguration(DiagnosticMonitorStartupInfo startupInfo, DiagnosticMonitorConfiguration initialConfiguration) +643
Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.Start(CloudStorageAccount storageAccount, DiagnosticMonitorConfiguration initialConfiguration) +47
Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitor.Start(String diagnosticsStorageAccountConfigurationSettingName, DiagnosticMonitorConfiguration initialConfiguration) +108
myApp.api.Diag.Diagnostics.Initialize() in c:\Work\MyApp.API\source\Diag\Diagnostics.cs:42
Global.Application_Start(Object sender, EventArgs e) in c:\Work\MyApp.API\source\Global.asax.cs:30
Attempts: None worked
Disabled all Azure monitoring and logging (from portal) for this storage account in case Azure's own monitoring/logging mechanisms were locking it down
Replaced UseDevelopmentStorage=true with real cloud connection string for diagnostics even for local configuration (local compute/Azure emulator).
Simplified diagnostic initializer to bare minimum (seen above). However, DiagnosticMonitor.Start(...) always fails.
Created another diagnostic connection string in .cscfg file (with reference in .csdef too) so that if the original Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString is also used by Azure infrastructure, I have another string for it. No help, same error.
I've burnt many hours trying to debug this but I always get this error on Azure.
Question:
Can someone help me get rid of this error? I can try a few ideas you may have. I'm disappointed by the MS tutorial but disappointment doesn't help.
Exactly the same symptoms here (but in an ASP.NET MVC application).
Basically you shouldn't be using the DiagnosticMonitor.Start() any more.
The below worked for me (Azure SDK 1.8, October 2012)
I simplified the init code from this article:
http://convective.wordpress.com/2010/12/01/configuration-changes-to-windows-azure-diagnostics-in-azure-sdk-v1-3/
private void ConfigureDiagnostics()
{
var wadConnectionString ="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
var cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(wadConnectionString));
var roleInstanceDiagnosticManager =
cloudStorageAccount.CreateRoleInstanceDiagnosticManager(
RoleEnvironment.DeploymentId,
RoleEnvironment.CurrentRoleInstance.Role.Name,
RoleEnvironment.CurrentRoleInstance.Id);
var diagnosticMonitorConfiguration = roleInstanceDiagnosticManager.GetCurrentConfiguration();
diagnosticMonitorConfiguration.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);
diagnosticMonitorConfiguration.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);
diagnosticMonitorConfiguration.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
roleInstanceDiagnosticManager.SetCurrentConfiguration(diagnosticMonitorConfiguration);
}
I'm calling it from the Application_Start() in Global.asax.cs and it works fine now. Both locally and in the cloud.
You also need this in your web.config:
<system.diagnostics>
<trace>
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
</listeners>
</trace>
</system.diagnostics>
and this in your ServiceDefinition.csdef 's WebRole section:
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
These are added by the wizard by default, but still worth checking when migrating existing code to Azure.
A note to log4net users:
Specialized appenders are not really necessary, you can use the standard log4net.Appender.TraceAppender which comes with log4net - just configure it in your web.config and init log4net as usual it in your Application_Start() or prior to the 1st use.
Removing from trace listeners element this line fixed the problem for me.
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics" />
Know I'm thinking how to update already existing application configuration and not create one during the application start.

Using ASP.NET ActiveDirectoryMembershipProvider with a Forest

I'm trying to setup an ActiveDirectoryMembershipProvider to go against a Forest and I can't seem to get it working. One of our AD Admins suggested I refer to the global catalog but it seems that is not supported. Anyone know if you can and if so how do you configure the AD Membership Provider to go against a Forest?
Here are some of the permutations I've tried and the resultant errors.
<add name="ADConnectionString1"
connectionString="LDAP://domain.org/DC=domain,DC=org:3268" />
"A referral was returned from the
server"
<add name="ADConnectionString2"
connectionString="LDAP://domain.org/DC=domain,DC=org:" />
A null reference exception.
<add name="ADConnectionString3"
connectionString="LDAP://domain.org" />
A null reference exception
<add name="ADConnectionString4"
connectionString="LDAP://domain.org:3268" />
"LDAP connections on the GC port are
not supported against Active
Directory."
<add name="ADConnectionString5"
connectionString="LDAP://domain.org:3268/DC=domain,DC=org:3268" />
"LDAP connections on the GC port are
not supported against Active
Directory."
<add name="ADConnectionString6"
connectionString="LDAP://domain.org:3268/DC=domain,DC=org" />
"LDAP connections on the GC port are
not supported against Active
Directory."
I don't have access to test an ActiveDirectoryMembershipProvider at the moment but global catalog searches are usually performed using the GC:// moniker. E.g.
using (DirectoryEntry searchRoot = new DirectoryEntry("GC://DC=yourdomain,DC=com"))
using (DirectorySearcher ds = new DirectorySearcher(searchRoot))
{
ds.Filter = "(sAMAccountName=userID1)";
ds.SearchScope = SearchScope.Subtree;
using (SearchResultCollection src = ds.FindAll())
{
foreach (SearchResult sr in src)
{
uxFred.Content = sr.Path;
}
}
}
My suggestion when working in ASP.NET is always to get your search filters, etc. working using LDP or just a plain console/winform/wpf app.

Resources