OSGi Declarative Services and Config Admin - configuration

I'm writting bundle with declarative services usage. For configuration I'm using properties in DS declaration. Those props can be normally changed by Config Admin, but they are not persisted. After container restart, component has default values.
I'am using Config admin like this:
Configuration c = configurationAdmin.getConfiguration(UserAgent.SERVICE_PID, null);
System.out.println(c.getProperties()); // every time is null!
Dictionary props = new Hashtable();
props.put(UserAgent.PROPERTY_PORT, 5555);
c.update(props);
and in component I have:
// ...
#Modified
public void updated(ComponentContext context) {
config = context.getProperties();
init();
}
#Activate
protected void activate(ComponentContext context) {
config = context.getProperties();
init();
}
//...
I'm using Felix, properties file is stored in cache
service.bundleLocation="file:bundles/cz.b2m.osgi.phonus.core_1.0.0.SNAPSHOT.jar"
service.pid="cz.b2m.osgi.phonus.sip"
port=I"5555"
But after restart isn't loaded. What I'm doing wrong? Thanks for all tips.

Problem was in Pax Runner which every restart (clean) erased the data folder of Config Admin bundle.
To make sure that Pax Runner does not clear the data, you can use the --usePersistedState=true flag.

Related

Overriding application.yml config properties with runtime.groovy properties in Grails 3

I'm having config issues in Grails 3 and want to hook into the config setup process, unless there's a better way
We have a plugin(jasypt) that requires config set in the application.yml or it throws errors(example below). We need to set the config values in runtime.groovy, but they don't override any values set in the yml
application.yml
jasypt:
algorithm: "PBEWITHSHA256AND256BITAES-CBC-BC"
providerName: "BC"
password: "-"
keyObtentionIterations: 10
runtime.groovy
jasypt {
algorithm = ExternalSecureKeyConfig.getInstance().jasypt.algorithm
providerName = ExternalSecureKeyConfig.getInstance().jasypt.providerName
password = ExternalSecureKeyConfig.getInstance().jasypt.password
keyObtentionIterations = ExternalSecureKeyConfig.getInstance().jasypt.keyObtentionIterations
}
Debugging during startup and runtime shows that none of the config gets overridden (password stays "-"). If I move config from the yml to application.groovy the runtime values get applied but I get the following error on startup
org.jasypt.exceptions.EncryptionInitializationException: If "encryptorRegisteredName" is not specified, then "password" (and optionally "algorithm" and "keyObtentionIterations") must be specified
Currently I'm hoping I can manually set the jsypt config values or hook into the groovy config setup to ensure they override the prev set yml values. Having trouble figuring how to do this or if it's possible
jasypt v 2.0.2 with Grails 3.3.10 (hibernate5, gorm 6.1)
Solve
Overriding the application.yml config with values from a custom config file. Still find is strand the runtime.groovy doesn't override yml config values.
class Application extends GrailsAutoConfiguration implements EnvironmentAware {
static void main(String[] args) {
GrailsApp.run(Application, args)
}
#Override
void setEnvironment(Environment environment) {
URL jasyptConfigUrl = getClass().classLoader.getResource('jasypt.groovy')
if (jasyptConfigUrl) {
def jasyptConfig = new ConfigSlurper().parse(jasyptConfigUrl)
environment.propertySources.addFirst(new MapPropertySource('jasypt.groovy', jasyptConfig))
}
}
}

Mapreduce with multiple mappers and reducers

I am trying to implement multiple mappers and reducers code. Here is my main method
public static void main(String[] args) {
//create a new configuration
Configuration configuration = new Configuration();
Path out = new Path(args[1]);
try {
//This is the first job to get the number of providers per state
Job numberOfProvidersPerStateJob = Job.getInstance(configuration, "Total number of Providers per state");
//Set the Jar file class, mapper and reducer class
numberOfProvidersPerStateJob.setJarByClass(ProviderCount.class);
numberOfProvidersPerStateJob.setMapperClass(MapForProviderCount.class);
numberOfProvidersPerStateJob.setReducerClass(ReduceForProviderCount.class);
numberOfProvidersPerStateJob.setOutputKeyClass(Text.class);
numberOfProvidersPerStateJob.setOutputValueClass(IntWritable.class);
//Provide the input and output argument this will be needed when running the jar file in hadoop
FileInputFormat.addInputPath(numberOfProvidersPerStateJob, new Path(args[0]));
FileOutputFormat.setOutputPath(numberOfProvidersPerStateJob, new Path(out,"out1"));
if (!numberOfProvidersPerStateJob.waitForCompletion(true)) {
System.exit(1);
}
//Job 2 for getting the state with maximum provider
Job maxJobProviderState = Job.getInstance(configuration, "State With Max Job providers");
//Set the Jar file class, mapper and reducer class
maxJobProviderState.setJarByClass(ProviderCount.class);
maxJobProviderState.setMapperClass(MapForMaxProvider.class);
maxJobProviderState.setReducerClass(ReducerForMaxProvider.class);
maxJobProviderState.setOutputKeyClass(IntWritable.class);
maxJobProviderState.setOutputValueClass(Text.class);
//Provide the input and output argument this will be needed when running the jar file in hadoop
FileInputFormat.addInputPath(maxJobProviderState, new Path(out,"out1"));
FileOutputFormat.setOutputPath(maxJobProviderState, new Path(out,"out2"));
//Exit when results are ready
System.exit(maxJobProviderState.waitForCompletion(true)?0:1);
}
The problem is whenever I am running it. It gives me final output from 2nd mapper class and not the reducer class. It is something like my 2nd reducer class is getting ignored.
You can implement ChainMappers using ( org.apache.hadoop.mapreduce.lib.chain.ChainMapper )and ChainReducers using ( org.apache.hadoop.mapreduce.lib.chain.ChainReducer ) , It will resolve your issue.

When to use JoranConfigurator?

Can someone explain to me when should we use JoranConfigurtor?
I have logback.xml existing in a directory. I wonder what's happening in this piece of code?
Doesn't LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); initializes the context? So what is Joran is doing?
private static void configureLoggerContext(String logbackConfigFileUrl) {
File file = new File(logbackConfigFileUrl);
LoggerListener loggerListener = new LoggerListener();
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.reset();
loggerContext.addListener(loggerListener);
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(loggerContext);
try {
configurator.doConfigure(file);
} catch (JoranException je) {
throw new RuntimeException(je.getMessage());
}
}
Jorana is just a configuration library that Logback relies on.
https://logback.qos.ch/manual/configuration.html#joranDirectly
You use JoranConfigurator to configure your logging when your application needs explicit configuration rather than just using something like web.xml on a servlet environment (which will use the configurator behind the scenes).
For example, if you create a simple desktop application and you would want to config using a local logback.xml file, you would load it using the configurator
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(context);
configurator.doConfigure(new File("path/to/logback.xml"));
The logger context is just the context of Logback which includes the implementation of the logback components, it will allow you to create Loggers for your classes. when .doConfigure is called, the context will be configured according to what's inside the logback.xml.
From the LoggerContext doc:
LoggerContext implements the ILoggerFactory acting as the manufacturing source of Logger instances.

Startup.cs error (ASP.Net Core configuration)

I am trying to set up an ASP.Net Core application to read in configuration settings from a json file. I am using VS2015 and .NetCore 1.0 (with .Net Core Tools preview 2). I am having problems getting a simple piece of boiler plate code to compile.
I am using the following code, which was published at
http://asp.net-hacker.rocks/2016/03/21/configure-aspnetcore.html
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
if (env.IsDevelopment())
{
// This will push telemetry data through Application Insights
// pipeline faster, allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
Configuration = builder.Build();
}
However, the IDE/compiler complains that 'the name "Configuration" does not exist in the current context' (last line of code). The only suggestion from the IDE is to include Microsoft.Extensions.Configuration. However this is a namespace which does not contain an object or property named "Configuration".
In addition 'AddApplicationInsightsSettings' fails with does IConfigurationBuilder not contain a definition for AddApplicationInsightsSettings and no extension method AddApplicationInsightsSettings accepting a first argument of type IConfigurationBuilder could be found
Any suggestions please ?
Thanks
Simply add Configuration property to your Startup class, tutorial has missed this 'step':
public IConfigurationRoot Configuration { get; set; }
ConfigurationBuilder.Build() method just returns instance of IConfigurationRoot, that you should save, if need to get settings further in Startup class (in ConfigureServices method for example).
Regarding second error, looks like you didn't add the Application Insights dependency:
{
"dependencies": {
"Microsoft.ApplicationInsights.AspNetCore": "1.0.0"
}
}

Configuration of asp.net core using settings

I'm evaluating asp.net core and .net core and I'm not yet sure about some things. In the past it was possible to configure many components using the web.config out of the box.
To name some examples:
There was the membership-provider and I could implement many providers but I was able ton configure later which provider should be used. This was dependend of the use-case. Now I should use asp.net identity - but I can only find configurations that are performed in sourcecode.
Same for authentication. I can define "CookieAuthentication" and have to set the name, loginpath or the timeout within sourcecode. In the past I was able to set timeout, etc... via web.config.
Is there any way to configure partially these things out of the box from a config-file? Or is this not supported anymore and I have to implement this configuration on my own? In the past this was a really comfortable way.
In ASP.NET Core, Web.config file is used ONLY for IIS configuration, you cannot use it for application configuration, but there are new, better, more flexible configuration options that you can use.
There are multiple configuration sources that you can use, but in this example I'm using json. These examples are from working code in my SimpleAuth project.
You can configure things in startup from configuration files.
First you add a config file in json format that maps to your class. You can see my example class here, and the json file it maps from here
builder.AddJsonFile("simpleauthsettings.json", optional: true);
Then, in the ConfigureServices method you configure your class to be wired up from the config system as shown
services.Configure<SimpleAuthSettings>(Configuration.GetSection("SimpleAuthSettings"));
Then you add an IOptions accessor of your class to the method signature of the Configure method in the Startup.cs
The Dependency Injection will inject it into that method for you so you can use it there to configure things. Specifically I'm setting the cookie authentication scheme and name from my settings object.
The noteworthy part is that you can add whatever you want to the Configure method signature, and as long as it is something that has been registered in the ConfigureServices method, the DI will be able to inject it for you.
public class Startup
{
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
// this file is the custom configuration file to hydrate my settings from
builder.AddJsonFile("simpleauthsettings.json", optional: true);
....
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
....
services.Configure<SimpleAuthSettings>(Configuration.GetSection("SimpleAuthSettings"));
....
}
// note that the DI can inject whatever you need into this method signature
// I added IOptions<SimpleAuthSettings> authSettingsAccessor to the method signature
// you can add anything you want as long as you register it in ConfigureServices
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory,
IOptions<SimpleAuthSettings> authSettingsAccessor
)
{
...
// Add cookie-based authentication to the request pipeline
SimpleAuthSettings authSettings = authSettingsAccessor.Value;
var ApplicationCookie = new CookieAuthenticationOptions
{
AuthenticationScheme = authSettings.AuthenticationScheme,
CookieName = authSettings.AuthenticationScheme,
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/Login/Index"),
Events = new CookieAuthenticationEvents
{
//OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
}
};
app.UseCookieAuthentication(ApplicationCookie);
// authentication MUST be added before MVC
app.UseMvc();
}
}