vNext ConfigurationModel null reference-ing when picking up a config.json? - asp.net-core

using Microsoft.Framework.ConfigurationModel;
---
public Startup(IHostingEnvironment env)
{
var config = new Configuration();
config.AddEnvironmentVariables();
config.AddJsonFile("config.json");
}
Using the above, with the config.json placed in the root directory under the project name, I get a null reference exception?
This is practically a brand new/empty solution, I've never had this issue before.
I've tried empty files, no file, the default generated contents, different file extension, all give the same error, leading me to think that it is looking outside what should be the root dir.
However, it also does the same when supplied with a direct filepath...
It also doesn't fail when adding env variables on the line above, so it's not likely to be an issue with the Configuration object itself.
Same behaviour across both dnx core/coreclr and full.

Turns out Microsoft.Framework.ConfigurationModel from beta4 was renamed to Microsoft.Framework.Configuration in beta 5/6
with the = new Configuration method being replaced with having to use a ConfigurationBuilder, specifying the app path with appEnv.ApplicationBasePath in it's constructor.
= new ConfigurationBuilder(appEnv.ApplicationBasePath)
See: https://github.com/aspnet/Announcements/issues/25

Related

Spring Cloud Server serving multiple property files for the same application

Lets say I have applicationA that has 3 property files:
-> applicationA
- datasource.properties
- security.properties
- jms.properties
How do I move all properties to a spring cloud config server and keep them separate?
As of today I have configured the config server that will only read ONE property file as this seems to be the standard way. This file the config server picks up seems to be resolved by using the spring.application.name. In my case it will only read ONE file with this name:
-> applicationA.properties
How can I add the other files to be resolved by the config server?
Not possible in the way how you requested. Spring Cloud Config Server uses NativeEnvironmentRepository which is:
Simple implementation of {#link EnvironmentRepository} that uses a SpringApplication and configuration files located through the normal protocols. The resulting Environment is composed of property sources located using the application name as the config file stem (spring.config.name) and the environment name as a Spring profile.
See: https://github.com/spring-cloud/spring-cloud-config/blob/master/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepository.java
So basically every time when client request properties from Config Server it creates ConfigurableApplicationContext using SpringApplicationBuilder. And it is launched with next configuration property:
String config = application;
if (!config.startsWith("application")) {
config = "application," + config;
}
list.add("--spring.config.name=" + config);
So possible names for property files will be only application.properties(or .yml) and config client application name that is requesting configuration - in your case applicationA.properties.
But you can "cheat".
In config server configuration you can add such property
spring:
cloud:
config:
server:
git:
search-paths: '{application}, {application}/your-subdirectory'
In this case Config Server will search for same property file names but in few directories and you can use subdirectories to keep your properties separate.
So with configuration above you will be able to load configuration from:
applicationA/application.properies
applicationA/your-subdirectory/application.properies
This can be done.
You need to create your own EnvironmentRepository, which loads your property files.
org.springframework.cloud.config.server.support.AbstractScmAccessor#getSearchLocations
searches for the property files to load :
for (String prof : profiles) {
for (String app : apps) {
String value = location;
if (app != null) {
value = value.replace("{application}", app);
}
if (prof != null) {
value = value.replace("{profile}", prof);
}
if (label != null) {
value = value.replace("{label}", label);
}
if (!value.endsWith("/")) {
value = value + "/";
}
output.addAll(matchingDirectories(dir, value));
}
}
There you could add custom code, that reads the required property files.
The above code matches exactly the behaviour described in the spring docs.
The NativeEnvironmentRepository does NOT access GIT/SCM in any way, so you should use
JGitEnvironmentRepository as base for your own implementation.
As #nmyk pointed out, NativeEnvironmentRepository boots a mini app in order to collect the properties by providing it with - sort of speak - "hardcoded" {appname}.* and application.* supported property file names. (#Stefan Isele - prefabware.com JGitEnvironmentRepository ends up using NativeEnvironmentRepository as well, for that matter).
I have issued a pull request for spring-cloud-config-server 1.4.x, that supports defining additional file names, through a spring.cloud.config.server.searchNames environment property, in the same sense one can do for a single springboot app, as defined in the Externalized Configuration.Application Property Files section of the documentation, using the spring.config.name enviroment property. I hope they review it soon, since it seems many have asked about this feature in stack overflow, and surely many many more search for it and read the currently advised solutions.
It worths mentioning that many ppl advise "abusing" the profile feature to achieve this, which is a bad practice, in my humble opinion, as I describe in this answer

Serve up file from outside wwwroot

I am migrating an ASP.NET4.5 website to ASP.NET 5. One function we had returned images off the hard disk from an absolute location. The files arent stored within the web directory. Previously this worked fine, with the following code:
public ActionResult GetVideoImage(string serialNumber, int videoEntryId)
{
try
{
var serial = Device.FriendlySerialNumberToNumericalSerialNumber(serialNumber);
var entry = this.service.GetVideoEntry(serial, videoEntryId);
if (entry != null && System.IO.File.Exists(entry.FirstVideoFrameLocation.LocalPath))
{
return this.File(entry.FirstVideoFrameLocation.LocalPath, "image/jpeg"); // adjust content type appropriately
}
}
return this.Redirect("/content/noimage.png");
}
Unfortunately this doesnt work anymore and throws an exception. From what I can tell its because this.File now takes a virtualPath rather than an absolute one so balks at the idea of serving a file from outside of its web directory.
How can I get around this?
Also is ActionResult still the best
return type for this?
I found the answer on a MS thread here that links to a ASP github commit.
Long story short there are new classes available in the Microsoft.AspNet.Mvc namespace that allow the thing I'm looking for. I specifically chose PhysicalFileResult which works as expected

Hadoop DistributedCache caching files without absolute path?

I am in the process of migrating to YARN and it seems the behavior of the DistributedCache changed.
Previously, I would add some files to the cache as follows:
for (String file : args) {
Path path = new Path(cache_root, file);
URI uri = new URI(path.toUri().toString());
DistributedCache.addCacheFile(uri, conf);
}
The path would typically look like
/some/path/to/my/file.txt
Which pre-exists on HDFS and would essentially end up in the DistributedCache as
/$DISTRO_CACHE/some/path/to/my/file.txt
I could symlink to it in my current working directory and use with DistributedCache.getLocalCacheFiles()
With YARN, it seems this file instead ends up in the cache as:
/$DISTRO_CACHE/file.txt
ie, the 'path' part of the file URI got dropped and only the filename remains.
How does with work with different absolute paths ending up with the same filename? Consider the following case:
DistributedCache.addCacheFile("some/path/to/file.txt", conf);
DistributedCache.addCacheFile("some/other/path/to/file.txt", conf);
Arguably someone could use fragments:
DistributedCache.addCacheFile("some/path/to/file.txt#file1", conf);
DistributedCache.addCacheFile("some/other/path/to/file.txt#file2", conf);
But this seems unnecessarily harder to manage. Imagine the scenario where those are command-line arguments, you somehow need to manage that those 2 filenames, although different absolute paths would definitely clash in the DistributedCache and therefore need to re-map these filenames to fragments and propagate as such to the rest of the program?
Is there an easier way to manage this?
Try to add files into Job
It's most likely how you're actually configuring the job and then accessing them in the Mapper.
When you're setting up the job you're going to do something like
job.addCacheFile(new Path("cache/file1.txt").toUri());
job.addCacheFile(new Path("cache/file2.txt").toUri());
Then in your mapper code the urls are going to be stored in an array which can be accessed like so.
URI file1Uri = context.getCacheFiles()[0];
URI file2Uri = context.getCacheFiles()[1];
Hope this could help you.

Unable to bundle file in the format 'jquery.plugin.{version}.min.js'

I am using the code below to try and bundle a pre-minified version of the jQuery simpleModal plugin in an ASP.NET MVC4 project:
public static void RegisterBundles(BundleCollection bundles)
{
AddDefaultIgnorePatterns(bundles.IgnoreList);
bundles.Add(new ScriptBundle("~/ModalBundle").Include("~/Scripts/jquery.simplemodal.{version}.min.js"));
}
where AddDefaultIgnorePatterns() is defined as per ASP.NET MVC 4 ScriptBundle returns empty:
public static void AddDefaultIgnorePatterns(IgnoreList ignoreList)
{
if (ignoreList == null)
throw new ArgumentNullException("ignoreList");
ignoreList.Clear();
ignoreList.Ignore("*.intellisense.js");
ignoreList.Ignore("*-vsdoc.js");
ignoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled);
//ignoreList.Ignore("*.min.js", OptimizationMode.WhenDisabled);
ignoreList.Ignore("*.min.css", OptimizationMode.WhenDisabled);
}
Unfortunately, the requested resource is never included when rendered using #Scripts.Render() after being registered in Application_Start().
The following combinations do seem to work, but where possible I did not want to have to change the file name across a large number of projects:
jquery.simplemodal.1.2.3.min.js (exact version match)
jquery.simplemodal.{version}.js (removal of '.min', with corresponding file rename)
The following do not work:
jquery.simplemodal-{version}.min.js (hyphen before version, with corresponding file rename)
jquery.simplemodal* (loose wildcard, which is very suspicious)
I have verified that the file definitely exists in the expected location, but must be missing something else fundamental. None of my other script or style bundles suffer from this problem. Any ideas?
If you want to use the bundle system you must not use minified files.
When you are un debug mode, your system will load normal files.
When you are in release mode, your system will mingnify it automatically.
you can look a working configuration here :
https://myprettycms.codeplex.com/SourceControl/latest#MyPrettyCMSCommunityManager/Portals/MVC4Portal/App_Start/BundleConfig.cs

NHibernate HybridSessionBuilder, how to switch hibernate cfg based upon url values

I am using the HybridSessionBuilder supplied by Palermo and his team .. link ..
We have our staging environments set up so that the url will be one of the following based on the environment
web-test.company.com
web-cert.company.com
web.company.com
what we normally do is take a look at the url and if it has "-test" we use the test configurations and so on (connection strings, etc).
This is the first project that uses nhibernate in this type of environment. What would be a good way to tell the Session Builder to use the correct hibernate cfg (I will build 1 for each environment).
The HybridSessionBuilder lives in an infrastructure layer and is injected into repositories via StructureMap.
Here's how I select a single configuration file using the HybridSessionBuilder:
public Configuration GetConfiguration()
{
var configuration = new Configuration();
string cfgFile = Path.GetDirectoryName(Assembly.GetAssembly(this.GetType()).CodeBase) +
"\\com.Data.nHibernate.cfg.xml";
configuration.Configure(cfgFile);
configuration.AddAssembly("com.Data");
return configuration;
}
If you want to select configuration files based on the URL I would just identify the call stack that leads to this function and pass in either an enum value or the config file's name directly.