When mapping Typesafe configuration to a bean class (ConfigBeanFactory) is there a way to flag mis-spelled attributes? - javabeans

Our application is using a reference.conf to provide defaults for one of our POJO's that carries configuration information.
Say the Pojo is:
class Person {
String first;
String last;
// corresponding setters / getters not shown
}
The reference.conf has the defaults:
Person {
first: "joe"
last: "shmoe"
}
So if your application.conf had:
Person {
first: "mike"
}
Thus when you did this:
public static Person getInstance(Config config) {
return ConfigBeanFactory.create(config.getConfig("Person"), Person.class);
}
You'd get back a Person with first/last == mike/shmoe
Now..say I have some users who are not getting enough sleep, and one of them
misconfigures their application like this (mis-spelling 'first'):
Person {
frist: "mike"
}
The way I'm doing things now the Pojo loaded from this config has default first/last == joe/shmoe.
There is no warning about the mis-spelling ("frist").
I could write code to reflect against my Bean class and see what attributes the user provided which don't
correspond to the available setters, and then raise an error if any 'wrong' attributes are found.
But it seems like someone (maybe even the Typesafe config base library) must already have this feature.
Any pointer to a good existing way to do this very much appreciated.

Related

Google Guice runtime dependency injection

I am looking for a way to dynamically select the correct dependency during runtime using google guice.
My usecase is a kotlin application which can work with either sqlite or h2 databases depending on the configuration file provided.
The file is read when the application is executed and if the database is not found, the correct one is created and migrated into.
My database structure contains the Database (Interface), H2Database: Database, SQLiteDatabase: Database and the module binding class which looks like this:
class DatabaseModule: KotlinModule() {
override fun configure() {
bind<Database>().annotatedWith<configuration.H2>().to<H2Database>()
bind<Database>().annotatedWith<configuration.SQLite>().to<SQLiteDatabase>()
}
}
So far, with SQlite alone, I would simply request the dependency using:
#Inject
#SQLite
private lateinit var database: Database
How would I make this selection during runtime?
Without knowing too much about the specific of your code, I'll offer three general approaches.
(Also, I have never used Kotlin. I hope Java samples are enough for you to figure things out.)
First Approach
It sounds like you need some non-trivial logic to determine which Database implementation is the right one to use. This is a classic case for a ProviderBinding. Instead binding Database to a specific implementation, you bind Database to a class that is responsible providing instances (a Provider). For example, you might have this class:
public class MyDatabaseProvider.class implements Provider<Database> {
#Inject
public MyDatabaseProvider.class(Provider<SQLiteDatabase> sqliteProvider, Provider<H2Database> h2Provider) {
this.sqliteProvider = sqliteProvider;
this.h2Provider = h2Provider;
}
public Database get() {
// Logic to determine database type goes here
if (isUsingSqlite) {
return sqliteProvider.get();
} else if (isUsingH2) {
return h2Provider.get();
} else {
throw new ProvisionException("Could not determine correct database implementation.");
}
}
}
(Side note: This sample code gets you a new instance every time. It is fairly straightforward to make this also return a singleton instance.)
Then, to use it, you have two options. In your module, you would bind Database not to a specific implementation, but to your DatabaseProvider. Like this:
protected void configure() {
bind(Database.class).toProvider(MyDatabaseProvider.class);
}
The advantage of this approach is that you don't need to know the correct database implementation until Guice tries to construct an object that requires Database as one of its constructor args.
Second Approach
You could create a DatabaseRoutingProxy class which implements Database and then delegates to the correct database implementation. (I've used this pattern professionally. I don't think there's an "official" name for this design pattern, but you can find a discussion here.) This approach is based on lazy loading with Provider using the Providers that Guice automatically creates(1) for every bound type.
public class DatabaseRoutingProxy implements Database {
private Provider<SqliteDatabse> sqliteDatabaseProvider;
private Provider<H2Database> h2DatabaseProvider;
#Inject
public DatabaseRoutingProxy(Provider<SqliteDatabse> sqliteDatabaseProvider, Provider<H2Database> h2DatabaseProvider) {
this.sqliteDatabaseProvider = sqliteDatabaseProvider;
this.h2DatabaseProvider = h2DatabaseProvider;
}
// Not an overriden method
private Database getDatabase() {
boolean isSqlite = // ... decision logic, or maintain a decision state somewhere
// If these providers don't return singletons, then you should probably write some code
// to call the provider once and save the result for future use.
if (isSqlite) {
return sqliteDatabaseProvider.get();
} else {
return h2DatabaseProvider.get();
}
}
#Override
public QueryResult queryDatabase(QueryInput queryInput) {
return getDatabase().queryDatabase(queryInput);
}
// Implement rest of methods here, delegating as above
}
And in your Guice module:
protected void configure() {
bind(Database.class).to(DatabaseRoutingProxy.class);
// Bind these just so that Guice knows about them. (This might not actually be necessary.)
bind(SqliteDatabase.class);
bind(H2Database.class);
}
The advantage of this approach is that you don't need to be able to know which database implementation to use until you actually make a database call.
Both of these approaches have been assuming that you cannot instantiate an instance of H2Database or SqliteDatabase unless the backing database file actually exists. If it's possible to instantiate the object without the backing database file, then your code becomes much simpler. (Just have a router/proxy/delegator/whatever that takes the actual Database instances as the constructor args.)
Third Approach
This approach is completely different then the last two. It seems to me like your code is actually dealing with two questions:
Does a database actually exist? (If not, then make one.)
Which database exists? (And get the correct class to interact with it.)
If you can solve question 1 before even creating the guice injector that needs to know the answer to question 2, then you don't need to do anything complicated. You can just have a database module like this:
public class MyDatabaseModule extends AbstractModule {
public enum DatabaseType {
SQLITE,
H2
}
private DatabaseType databaseType;
public MyDatabaseModule(DatabaseType databaseType) {
this.databaseType = databaseType;
}
protected void configure() {
if (SQLITE.equals(databaseType)) {
bind(Database.class).to(SqliteDatabase.class);
} else if (H2.equals(databaseType)) {
bind(Database.class).to(H2Database.class);
}
}
}
Since you've separated out questions 1 & 2, when you create the injector that will use the MyDatabaseModule, you can pass in the appropriate value for the constructor argument.
Notes
The Injector documentation states that there will exist a Provider<T> for every binding T. I have successfully created bindings without creating the corresponding provider, therefore Guice must be automatically creating a Provider for configured bindings. (Edit: I found more documentation that states this more clearly.)

Extend Aurelia Validation Rules on a per class basis

If I have a class
export class Person {
public name: string = "";
public foo: string = "";
}
ValidationRules
.ensure((p :Person) => p.name)
.required()
.withMessage("name is required")
.on(Person);
Is there any way to extend those rules on a per controller basis? For example in my App class I also want to ensure the foo property is set, however adding this as a rule here seems to override the name rule from the above code.
export class App {
public person: Person = new Person();
#observable
public message: string = "";
constructor(public vc: ValidationController, public vld: Validator) {
ValidationRules
.ensure((p: Person) => p.foo).required().withMessage("foo is required").on(this.person);
this.vc.addObject(this.person);
this.vc.validate();
}
}
Yes that's possible, but it requires a slightly different approach.
There are 2 important things to note here:
The fluent api initializer (static method ensure() on ValidationRules) always instantiates a new FluentEnsure object. It doesn't look for existing stuff - not even if you finalize on the same target. To extend a ruleset with more rules, you need to call .ensure() on the existing ruleset.
The finalizer (instance method on() on FluentEnsure) stores the rules in the .prototype.__rules__ (if it's a Function) or .__rules__ property of the target you pass in and will overwrite any existing one.
In other words when you finalize on an instance of Person, you're storing a brand new rules object on person.__rules__ which effectively hides Person.prototype.__rules__.
For the record, the static methods Rules.set(target, rules) and Rules.get(target) are wrappers around the .__rules__ property. You'll definitely want to call those and not try to access the property directly.
Now you might think something like Rules.get(Person).ensure(...).on(person) but that would also modify the original rules on Person.prototype.
So how to work with that?
Enter tags
It can get messy with fetching and combining rulesets, but here's the basic idea:
export class Person {}
ValidationRules.ensure(p => p.name).required().on(Person)
And elsewhere:
Rules.get(Person).ensure(p => p.foo).required().tag("foo");
And elsewhere:
Rules.get(Person).ensure(p => p.bar).required().tag("1234");
Then when it's time to validate:
const allRules = Rules.get(Person); // "1234" is included
const fooRules = ValidationRules.untaggedRules(allRules)
.concat(ValidationRules.taggedRules(allRules, "foo"); "1234" not included
vc.addObject(person);
vc.validate({ fooRules });
Or hand roll something
I've never actually used tags myself before and I've seen an issue or two regarding them. You could also do something similar yourself if you want more control/transparency:
export class Person {
public static scopedRules: { [scope: string]: any } = Object.create(null);
}
ValidationRules.ensure(p => p.name).required().on(Person)
And elsewhere:
Person.scopedRules.foo = Object.create(null);
ValidationRules.ensure(p => p.foo).required().on(Person.scopedRules.foo)
Then when it's time to validate:
const rules = Rules.get(Person).concat(Rules.get(Person.scopedRules.foo));
vc.addObject(person);
vc.validate({ rules });
Of course this is just a "simplest possible thing" example. In a real world scenario you'd probably have your rule storage/retrieval/merging etc tucked away somewhere.

How to keep some custom attributes when generating a proxy with svcutils?

I use the following command to generate a proxy class for a WCF service :
svcutil.exe" /out:C:\SomePath\.... /n:*,Internal.FooNameSpace
http://localhost/MyService.svc
The following class :
[ProtoContract]
[ServiceContract]
public class Foo
{
[ProtoMember(1)]
[DataMember(Order = 0)]
public string Bar { get; set; }
}
Becomes :
public partial class Foo : object, System.Runtime.Serialization.IExtensibleDataObject
{
private string BarField;
[System.Runtime.Serialization.DataMemberAttribute()]
public string Bar
{
get
{
return this.BarField;
}
set
{
this.BarField = value;
}
}
}
Is there a way to keep some specific attributes on the generated class ? (eg : ProtoMember in this case). I could off course hack the proxy but it create maintenance problems.
If you're adding that as a service reference, then nope: there's no way to retain that information - it simply isn't in the WCF endpoint.
IIRC, though, the WCF code-gen does actually come up with incremental Order values when you have multiple properties - i.e. the next property would be [System.Runtime.Serialization.DataMemberAttribute(Order = 1)], then 2 etc. So one option is to in a different file (the beauty of partial class), define (in the same namespace, etc) additional info about your type:
[ProtoContract(DataMemberOffset = 1)]
public partial class Foo { }
What this means is: when processing [DataMember], add 1 to every value - that means that you should get the required 1,2,3,4... and everything will be fine, and you haven't had to change the code.
Alternatively, you can be explicit:
[ProtoContract]
[ProtoPartialMember(1, nameof(Foo.Bar))]
[ProtoPartialMember(2, nameof(Foo.AnotherProp))]
public partial class Foo { }
This gives you a lot more flexibility to specify nuance about the properties.
As another alterative, you can configure everything at runtime:
RuntimeTypeModel.Default.Add(typeof(Foo), false)
.Add(1, nameof(Foo.Bar))
.Add(2, nameof(Foo.AnotherProp));
// or AddField to get the ValueMember that you can use to set
// fine-grained control
Finally, you can just ship the data contract dll, and tell svctil to use the types it already contains. You do this with the /reference:<file path> command-line switch, or there's a similar feature when using the UI tools (that lets you choose from the available dlls).
As a second "finally" (because one is not enough): you could describe the data instead as a .proto schema, and just tell the recipient to do the codegen locally and tell svcutil to exclude it (/excludeType: or /reference:). Note that the in progress rewrite of "protogen" does not currently include [DataContract]/[DataMember] attributes, but I could get that added today if it would be useful.

fluent nhibernate polymorphism. how to check for type of class

I have an Icon which has a Content (one to one) relationship.
public class Icon
{
public virtual Content Content {get; set;}
}
By default, it is lazy loaded which is what I want.
However, at some point in the code, I need to check what kind of Content is, Content being polymorphic, something like
if(icon.Content is TextContent)
{
...
}
Icon is part of another association and it is automatically obtained by the NHibernate, I do not get it manually.
What is the recommended way of checking for the actual type in this situation?
I can have a specific property like ContentType which will be an enum in order to identify the actual content type, but I am looking to know if there's a different way.
If you want to do that kind of check, you have to remove the proxy from the property.
There is a few ways to do it:
If you have access to the session call:
session.PersistenceContext.Unproxy(icon.Content);
Implement a virtual method (in a base class if possible) that forces the removal of the proxy by returning the instance with the proper type.
public virtual U As<U>() where U : YourType {
return this as U;
}
Disable the lazy initialization of the property.
This is very similar to another recent question.
To add to csanchez's list, a fourth method is to add a Self property to the Content base class that returns the un-proxied type:
public virtual void Self
{
get { return this; }
}
And a fifth method is to use 'lazy="no-proxy"` in the mapping as described on Ayende's blog.
Thanks for the suggestions but meanwhile I found an interesting solution, better I think.
Using the Visitor pattern, I can define an IconContent visitor and pass an Action to be executed to it.
For example, suppose there is a TextContent and an ImageContent, it will be something like this:
IconContentVisitor.Func(()=> { Console.WriteLine("this is TextContent"; }, ()=> { Console.WriteLine("this is ImageContent"));
Idea came from here: http://mookid.dk/oncode/archives/991

NHibernate: interview virtual and lazy loading in depth

I think it's a little bit ridiculous to ask that in an interview. But if the interviewer ask ... need to answer.
Explain in depth:
why properties and method must be virtual
how lazy loading works
Regards,
You will have to look at NHibernate source code for more details, but my understanding is following: lazy loading is implemented by substituting a class with a proxy generated at runtime. Proxy is inherited from the class, so that it can 'intercept' method calls and load the actual data lazily. This interception would only work if methods and properties are virtual, because the client code calls them through a reference to the class. Client code can be unaware of the fact that it really uses a proxy (derived from the class). The actual lazy loading logic is a lot more complex but this is roughly what is going on:
public class Customer {
public virtual String Name {
get { return _name; }
}
}
// code like this gets generated at runtime:
public class CustomerProxy7461293476123947123 : Customer {
private Customer _target;
public override String Name {
get {
if(_target == null){
_target = LoadFromDatabase();
}
return _target.Name;
}
}
}
This way the data would only get loaded when client actually calls 'Name':
Customer customer = Session.Load<Customer>(1); // <-- proxy is returned
// or
Customer customer = salesman.FavoriteCustomer; // <-- proxy is returned
...
String name = customer.Name; // <-- proxy's Name will be called, loading data
Similar mechanisms are used for collections except that collections don't need to be generated at runtime. NHibernate has built-in persistent collections that load items lazily.