ServiceStack Utility to read from Custom Config Sections - servicestack

Is there any ServiceStack utility that can read from custom config sections. ServiceStack has IAppSettings which makes it easy to read from appSettings in a config file. I am wondering if ServiceStack has a similar utility to read from Custom Config Sections.
Thanks
rudrvij

No there isn't, we actively discourage usage of Config Sections which is XML encumbered, in-flexible, non-portable and non-substitutable.
Our preference (when needed) is instead to embed Complex Type configuration in a single AppSetting Text Value which is transparently supported using the human-friendly JSV Format, e.g:
<appSettings>
<add key="RedisConfig"
value="{Host:localhost,Port:6379,Database:1,Timeout:10000}" />
</appSettings>
Which is supported by every App Settings Provider and can be easily serialized into any POCO with:
RedisConfig redisConf = appSettings.Get<RedisConfig>("RedisConf");

Related

How to re-purpose existing instances of Redis and RabbitMQ with ServiceStack

After successfully developing an application with multiple ServiceStack services, we are moving to other testing environments, lots of them due to us running a SAAS model (aka multi-tenant). I'd like to reuse some of the base infrastructure services, primarily Redis and RabbitMQ across a few of these environments.
We're using the IAppSetting interface to pull our configuration from multiple sources into one cohesive settings object at run-time, which is then filtered tier. Since tier drives the configuration per environment it made sense to use Tier to prefix any RabbitMQ messages queues, and prefix any generated cache keys that will be used by Redis, thus providing collision protection per environment.
Below is an example:
RabbitMQ => "Some MQ method here" => "mq:qa1.Outbound.inq"
Redis => "Some Redis method here" => "urn:qa1.somePoco:123"
Here is an example configuration and the various enviroments
<appSettings>
<add key="Tier" value="qa1" />
<!--<add key="Tier" value="dev" />-->
<!--<add key="Tier" value="tst" />-->
<!--<add key="Tier" value="stg" />-->
<!--<add key="Tier" value="prod" />-->
</appSettings>
Thank you,
Stephen
Some examples on how to modify Queue Names are in MqNameTests, e.g:
QueueNames.SetQueuePrefix("site1.");
Will add a prefix on QueueNames, e.g:
site1.mq:TestPrefix.inq
Otherwise you can use QueueNames.ResolveQueueNameFn to have complete control over the MQ name, e.g:
QueueNames.ResolveQueueNameFn = (typeName, suffix) =>
"SITE.{0}{1}".Fmt(typeName, suffix.ToUpper());
QueueNames<TestFilter>.In.Print(); // SITE.TestFilter.INQ
Note the same configuration also needs to applied on the client so the same MQ names gets used.
Configuring ServiceStack with AppSettings
ServiceStack is a code-first framework which means all configuration is done in code, but has a rich and versatile configuration model where you can get the behavior your after by reading App Settings in AppHost.Configure():
QueueNames.SetQueuePrefix(AppSettings.Get("Tier","dev"));
Where if Tier doesn't exist in your Web.config (e.g. in Unit Tests) it will use dev otherwise will use the value in your appSettings:
<appSettings>
<add key="Tier" value="qa1" />
</appSettings>

Configuring a two node hazelcast cluster - avoiding multicast

The context
Two nodes of a Hazelcast cluster, each on a discrete subnet so multicast is not suitable nor working for node location.
I should like to employ the most minimal XML configuration file, say hazelcast.xml, to configure Hazelcast to use TCP/IP to connect the two nodes. Ideally a directory of the IP addresses of the two nodes.
The question
The Hazelcast docs do a good job of showing how this can be achieved programatically, and how hazelcast.jar/hazelcast-default.xml holds the (considerable) default configuration.
What is unclear is: is any XML configuration I supply overlaid upon the settings within hazelcast-default.xml - or simply used in its stead?
I have both my answers, and should like to share them
Just like the programatic API, the XML configuration overlays the defaults found in hazelcast.jar/hazelcast-default.xml, consequently ...
I can establish a very simple two-member cluster with this hazelcast.xml in the classpath
<hazelcast>
<network>
<join>
<multicast enabled="false"></multicast>
<tcp-ip enabled="true">
<member>192.168.100.001</member> <!-- server A -->
<member>192.168.102.200</member> <!-- server B, on separate subnet -->
</tcp-ip>
</join>
</network>
</hazelcast>
I'm not familiar with hazelcast.conf files.
Mostly used is XML or Programmatic api. For good examples see:
https://github.com/hazelcast/hazelcast-code-samples/tree/master/network-configuration
Example of programmatic:
public class Main {
public static void main(String[] args){
Config config = new Config();
config.getNetworkConfig().getJoin().getTcpIpConfig().addMember("localhost").setEnabled(true);
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
HazelcastInstance hz = Hazelcast.newHazelcastInstance(config);
}
}
--
What is unclear is: is any XML configuration I supply overlaid upon the settings within hazelcast-default.xml - or simply used in its stead?
What do you mean? If you use the programmatic API, the rest is not relevant. If you don't provide an explicit Config object while constructing the HazelcastInstance, a defaulting mechanism is used. And eventually it defaults to hazelcast-default.xml.

Read custom config setting from config file of application deployed on Azure

I would like to read custom setting which i have done in ServiceConfiguration.cscfg & ServiceDefinition.csdef and want to read that setting by code in C#.
For that i created REST call to get deployment as per mentioned on msdn link
In that xml response configuration is 64 base encoded string, i think my custom setting lies within there (correct me if i am wrong!), if i need application id then i can directly read Private ID from that xml but ho can i rad my custom setting?
<?xml version="1.0" encoding="utf-8"?>
<Deployment xmlns="http://schemas.microsoft.com/windowsazure">
<Name>deployment-name</Name>
.......
.......
<Configuration>base-64-encoded-configuration-file</Configuration>
.......
.......
</Deployment>
Thanks in Advance
As far as I know for now the customized configuration section is not support. But maybe you can serialize your configuration into one CSCFG setting and deserialize it in your code.

How to setup NServiceBus and Log4Net to save to a file (without profiles)

I am running NServiceBus and having this issue. To try and troubleshoot it I would like to make NServiceBus log to a file.
The problem is that I am hosting NServiceBus in IIS, not NServiceBus.Host.exe. Because of that I don't know a way to turn on the the production profile.
Is there a way to tell NServiceBus to log to a file not using profiles? (Or a way to set the profile when not using NServiceBus.Host.exe?)
I had hoped that there is a way change NServiceBus.Configure.With().Log4Net(); to put an Appender in that will log to a file. But I don't see anyway to do that in code (all the examples use xml).
Alternatly if there is a way to change this to log to a file that would be great too:
<configSections>
<section name="Logging" type="NServiceBus.Config.Logging, NServiceBus.Core" />
</configSections>
<Logging Threshold="FINE" />
Does anyone know how to do either of these things?
Implement IWantCustomLogging:
https://github.com/NServiceBus/NServiceBus/blob/master/Samples/GenericHost/LoggingFromAppConfig/EndpointConfig.cs
And specify the RollingFileAppender in code:
Configure.Log4net< RollingFileAppender>(...)

Log4Net and GAC - How to reference Configuration Files?

I am using log4net during my development, as as part of a project constraint, I now need to add it to the Global Assembly Cache.
The logging definitions are in a file Log4Net.xml. That file is referenced in my assemblyinfo as: [assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.xml", Watch = true)]. So long as the xml file was in the same directory as the log4net.dll, everything has been working fine.
However now that I've added log4net to the GAC, it is no longer picking up the xml file.
Does anyone know what I need to change in order to have it pick up the XML file again? Is hardcoding the patch in the assembly reference the only way?
Many thanks
log4net expects the config file to be in the path returned by:
System.AppDomain.CurrentDomain.BaseDirectory
Let your application print this information to some file and then you know where you need to place the config file.
Of course there are other solutions, but then you cannot use the attribute anymore. Calling the ConfigureAndWatch() method directly allows you to figure out yourself where the config file is; you can even decide on a location (does not have to be a hard-coded path).
You might ensure that your log4net.xml file is set to "Copy Always" (Right Click on log4net.xml -> Properties -> Copy to Output Directory = Copy always). To ensure that your config file is being copied, you should check your bin\debug or bin\release directory and verify that the log4net.xml file exists in the same directory that your application executes.
If that doesn't workthen you can try enabling internal debugging in log4net. To enable internal debugging, add the following key to your app.config file. This will send internal log4net debug messages to your Visual Studio Output window (View -> Output).
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
For more information on log4net's internal debugging, you might check Phil Haack's blog post here.
If all else fails, you can turn on internal debugging and explicitly load the configuration by calling log4net's XmlConfigurator.ConfigureAndWatch method.
var fi = new FileInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\log4net.xml");
XmlConfigurator.ConfigureAndWatch(fi);

Resources