Restlet custom configuration properties files - configuration

Frameworks like Spring, Struts facilitates for property file reading. For instance MessageResources in Struts. I want to know whether there are such property files which are in built supported by Restlet framework itself. If there is one, then I will not need to re invent the wheel and be able to use it straight.My application configuration values will be included in that file. I am new to Restlet, I couldn't find any soulution. Any way to do this?

There is no support like this in Restlet. That said you can leverage client protocols to load these properties files from difference locations:
Protocol.FILE - from filesystem directly
Protocol.CLAP - from classpath
Protocol.OBAP - from OSGi bundle
Here is a sample:
ClientResource cr = new ClientResource("clap://someproperties.properties");
Properties props = new Properties();
props.load(cr.get().getStream());
You need to specify this protocol when defining your component:
Component component = new Component();
(...)
component.getServers().add(Protocol.HTTP, 8182);
component.getClients().add(Protocol.CLAP);

Related

Can you preview ASP.NET Core's appsettings.json environment overrides?

In ASP.NET Core, the JsonConfigurationProvider will load configuration from appsettings.json, and then will read in the environment version, appsettings.{Environment}.json, based on what IHostingEnvironment.EnvironmentName is. The environment version can override the values of the base appsettings.json.
Is there any reasonable way to preview what the resulting overridden configuration looks like?
Obviously, you could write unit tests that explicitly test that elements are overridden to your expectations, but that would be a very laborious workaround with upkeep for every time you change a setting. It's not a good solution if you just wanted to validate that you didn't misplace a bracket or misspell an element name.
Back in ASP.NET's web.config transforms, you could simply right-click on a transform in Visual Studio and choose "Preview Transform". There are also many other ways to preview an XSLT transform outside of Visual Studio. Even for web.config parameterization with Parameters.xml, you could at least execute Web Deploy and review the resulting web.config to make sure it came out right.
There does not seem to be any built-in way to preview appsettings.{Environment}.json's effects on the base file in Visual Studio. I haven't been able to find anything outside of VS to help with this either. JSON overriding doesn't appear to be all that commonplace, even though it is now an integral part of ASP.NET Core.
I've figured out you can achieve a preview with Json.NET's Merge function after loading the appsettings files into JObjects.
Here's a simple console app demonstrating this. Provide it the path to where your appsettings files are and it will emit previews of how they'll look in each environment.
static void Main(string[] args)
{
string targetPath = #"C:\path\to\my\app";
// Parse appsettings.json
var baseConfig = ParseAppSettings($#"{targetPath}\appsettings.json");
// Find all appsettings.{env}.json's
var regex = new Regex(#"appsettings\..+\.json");
var environmentConfigs = Directory.GetFiles(targetPath, "*.json")
.Where(path => regex.IsMatch(path));
foreach (var env in environmentConfigs)
{
// Parse appsettings.{env}.json
var transform = ParseAppSettings(env);
// Clone baseConfig since Merge is a void operation
var result = (JObject)baseConfig.DeepClone();
// Merge the two, making sure to overwrite arrays
result.Merge(transform, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Replace
});
// Write the preview to file
string dest = $#"{targetPath}\preview-{Path.GetFileName(env)}";
File.WriteAllText(dest, result.ToString());
}
}
private static JObject ParseAppSettings(string path)
=> JObject.Load(new JsonTextReader(new StreamReader(path)));
While this is no guarantee there won't be some other config source won't override these once deployed, this will at least let you validate that the interactions between these two files will be handled correctly.
There's not really a way to do that, but I think a bit about how this actually works would help you understand why.
With config transforms, there was literal file modification, so it's easy enough to "preview" that, showing the resulting file. The config system in ASP.NET Core is completely different.
It's basically just a dictionary. During startup, each registered configuration provider is run in the order it was registered. The provider reads its configuration source, whether that be a JSON file, system environment variables, command line arguments, etc. and builds key-value pairs, which are then added to the main configuration "dictionary". An "override", such as appsettings.{environment}.json, is really just another JSON provider registered after the appsettings.json provider, which obviously uses a different source (JSON file). Since it's registered after, when an existing key is encountered, its value is overwritten, as is typical for anything being added to a dictionary.
In other words, the "preview" would be completed configuration object (dictionary), which is composed of a number of different sources, not just these JSON files, and things like environment variables or command line arguments will override even the environment-specific JSON (since they're registered after that), so you still wouldn't technically know the the environment-specific JSON applied or not, because the value could be coming from another source that overrode that.
You can use the GetDebugView extension method on the IConfigurationRoot with something like
app.UseEndpoints(endpoints =>
{
if(env.IsDevelopment())
{
endpoints.MapGet("/config", ctx =>
{
var config = (Configuration as IConfigurationRoot).GetDebugView();
return ctx.Response.WriteAsync(config);
});
}
});
However, doing this can impose security risks, as it'll expose all your configuration like connection strings so you should enable this only in development.
You can refer to this article by Andrew Lock to understand how it works: https://andrewlock.net/debugging-configuration-values-in-aspnetcore/

How to use localization in Razor Class Library in Asp.Net Core

I have tried to create the Razor Class Library with Asp.Net Core in following project structure:
I have used in my web application these settings for localization in Startup class:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddViewLocalization(
LanguageViewLocationExpanderFormat.Suffix,
opts => { opts.ResourcesPath = "Resources"; })
.AddDataAnnotationsLocalization();
services.Configure<RequestLocalizationOptions>(
opts =>
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("en")
};
opts.DefaultRequestCulture = new RequestCulture("en");
opts.SupportedCultures = supportedCultures;
opts.SupportedUICultures = supportedCultures;
});
....
var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(options.Value);
In Index.cshtml:
#using Microsoft.AspNetCore.Mvc.Localization
#inject IViewLocalizer Localizer
<h1>#Localizer["Title"]</h1>
Unfortunately, the result is only string "Title". I can't load these resx files from Razor Class Library.
How can I use the localization in Razor Class Library like above?
UPDATE: This is very similiar use case - https://github.com/aspnet/Localization/issues/328 - that provides some example.
I haven't tried the accepted answer and based on the comments, it seems the OP didn't get it to work. I implemented a pattern similar to the View/Page locator pattern that MVC/Razor Pages uses namely, that resources can be provided in a RCL or separate assembly and use ViewLocalizer and it'll just find the matching resource string from the highest precedence resource. You can read my implementation and see if it might work for you.
https://terryaney.wordpress.com/2021/01/04/migrating-to-net-core-overridable-localization-in-razor-class-libraries/
You appear to have forgotten to configure localization correctly using AddLocalization
Using details provided from documentation
Reference Globalization and localization in ASP.NET Core
Configure localization
Localization is configured in the ConfigureServices method:
services.AddLocalization(options => options.ResourcesPath = "Resources"); //<<< This is required
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization Adds the localization services to the services container. The code above also sets the resources path to "Resources".
AddViewLocalization Adds support for localized view files.
AddDataAnnotationsLocalization Adds support for localized DataAnnotations validation messages through IStringLocalizer abstractions.
Localization middleware
The current culture on a request is set in the localization Middleware. The localization middleware is enabled in the Configure method. The localization middleware must be configured before any middleware which might check the request culture (for example, app.UseMvcWithDefaultRoute()).
var supportedCultures = new[] {
new CultureInfo("en-US"),
new CultureInfo("en")
};
app.UseRequestLocalization(new RequestLocalizationOptions{
DefaultRequestCulture = new RequestCulture("en"),
// Formatting numbers, dates, etc.
SupportedCultures = supportedCultures,
// UI strings that we have localized.
SupportedUICultures = supportedCultures;
});
//...other middleware
app.UseMvcWithDefaultRoute();
The path to the resource file shown in the example image follows the path naming convention given that
you are using the ResourcesPath option which was set to "Resources". This should allow the view to find the resource file in the relative path to the "Resources" folder.
An alternative is to not use the ResourcesPath option, and place the .resx file in the same folder as the view, following the naming convention of course.
Base on additional details provided it was indicated that the UI project would be packaged as a nuget package.
Then have the resources files packaged into the nuget package and have them unpacked to the resources folder of the target project when when installed.
The resources need to be in the site root to be available to the view, so you then need to reference all the files in your .nuspec:
<?xml version="1.0"?>
<package>
<metadata>...
</metadata>
<files>
<!-- Add all resource files -->
<file src="Resources\**\*.resx" target="content\Resources" />
</files>
</package>
Reference Creating NuGet packages

How to configure NearCache with Hazelcast 3.5 without an explicit Client

Based on this question, I'm trying to switch to the version 3.5-EA of Hibernate.
Up to now I had a configuration like this:
CacheConfiguration<K, V> configuration = new CacheConfig<K, V>()
.setNearCacheConfig(new NearCacheConfig().setInMemoryFormat(InMemoryFormat.OBJECT))
.setExpiryPolicyFactory(createExpiryPolicyFactory(expiryDuration));
cache = cacheManager.createCache(cacheName, configuration);
But now the setNearCacheConfig method is gone. There only exists a addNearCacheConfig on the ClientCacheConfig. But I don't have a ClientCacheConfig.
I basically don't know where to put the NearCacheConfig.
the configuration of the nearcache can be done on the client side. http://docs.hazelcast.org/docs/3.5/manual/html-single/hazelcast-documentation.html#hazelcast-java-client
If you do not want to use xml for configuration (http://docs.hazelcast.org/docs/latest/manual/html-single/hazelcast-documentation.html#near-cache) - you could probably do something like this -
Config cfg = new Config();
MapConfig mc = new MapConfig();
mc.setNearCacheConfig(new NearCacheConfig());
cfg.addMapConfig(mc);
HazelcastInstance hi = Hazelcast.newHazelcastInstance(cfg);
As per my opinion, NearCache feature is useful when you are using Client-Server hazelcast api and when youa re trying to access cache externally, but if you are gonna make call within hazelcast cluster internally and do not want to use Hazelcast client api than there no need to use NearCache feature.
Since there will not be any benefit out of it.

Is it possible to reflect changes in portal-ext.properties without restarting whole Liferay portal?

My problem is every time after changing the Liferay portal-properties (and this is frequent especially at beginning of a new portal project) I need to restart the whole portal.
Some properties I can set over hook and these values will be changed after redeployment. Also that must be possible to change most portal properties at run time.
However, do you know some approach to reflect changes in portal-ext.properties without restarting Liferay portal?
As stoldark mentioned, this is not possible in a production environment at all. Since portal.properties's properties are loaded at portal start-up.
But for development you can use a tool like JRebel, some steps to configure it here. The only issue you would get with this tool is that it is paid ;-).
I know it is a very old thread but it may be helpful for someone who is looking for some type of work around
As we know there is no straight forward way for this but I did this by using java reflection and class loader.
Liferay Version : 6.x
//Loading the PropsUtil class by using PortalClassLoader
Class<?> prospsUtilClass = PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.util.PropsUtil");
//getting the reload method of PropsUtil class
Method reloadMethod = prospsUtilClass.getMethod("reload", null);
//Invoking the static reload method
reloadMethod.invoke(null, null);
Reload method (re)loads the portal-ext properties to the portal so we can use new properties without restarting Liferay server.
This has also been asked in Liferay forums:
https://www.liferay.com/community/forums/-/message_boards/message/800954
But I am afraid that most properties are only read once during portal startup.
Usually, the use of a properties file as in this case has this drawback.
There's even an issue open at Liferay about this, but is still unresolved:
http://issues.liferay.com/browse/LEP-5579
If you create a hook to override portal properties, you will be able to change properties with just deploying the hook without restarting the Portal.
Be aware that you cannot modify all properties with a hook. For a list of the ones that you can modify, check out: https://docs.liferay.com/portal/6.2/definitions/.
I've just searched for reloading portal-ext.properties and landed here.
Ok - not a feature in Liferay.
So I'll use an old trick I like:
place custom properties in (liferay-tomcat-home)/conf/filename.properties
reload them whenever you want by
Properties customProperties = new Properties();
customProperties.load(new FileInputStream(new File(System.getProperty("catalina.base"), "conf/filename.properties")));
I must confess I haven't tried this in a Liferay-Portlet-Environment, but this system property ("catalina.base") should be available in this context, at least by using some Liferay-Helper-Class.
Some of the Liferay classes read their properties when initialising static field constants. E.g.:
public static final boolean ENABLED = GetterUtil.getBoolean(
PropsUtil.get(DynamicCSSFilter.class.getName()));
Basically, it is possible to reload the properties (eg via script in control-panel), but all those static constants will remain.

Castle Windsor - Register compoents before my Facilities load. - Delay loading configuration file?

I would like to register some components in my Windsor container before my Facilities load - (so that I can use some the components in the facilities)
I was thinking there should be some way to initialize windsor without a configuration file, register some components, and only then load the configuration? - this would result in that my configured facilities would load only after I registered my components.
For example:
var container = new WindsorContainer();
//Register a custom component, which will be used in some of the facilities
container.Register(Component.For<IMyService>().ImplementedBy<MyService>());
//Now load via the configuration - unfortunately the method "Configure" doesn't exist
container.Configure(new XmlInterpreter(new ConfigResource("castle")));
Appreciate any help on this,
Thanks!
container.Install(Configuration.FromAppConfig());
See the documentation.