Configuration properties cannot be loaded in a multiple-module project - java

I am trying to build up a multiple-module project, every module would be loaded by executing the PropertyPlaceholderConfigure properties, then I found the properties were not injected when I started to run. Instead, it's still using the default property, for example, I configure the input expression in the main class as Value("${esb.mas.path:/home/mas}")
, and define esb.mas.path=/home/vfs/mas in the corresponding module property file, but the modified values were never used.
By debugging and tracing the code, I found the problem, but I am still not sure if this is a bug from spring framework, in the following lines,
public String org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(String value) {
String result = value;
for (StringValueResolver resolver : this.embeddedValueResolvers) {
if (result == null) {
return null;
}
result = resolver.resolveStringValue(result);
}
return result;
}
I noticed that if the value of first place of embeddedValueResolvers list cannot be caught, they would use the default /home/mas, when continually resolving the embeddedValueResolvers, the parameter for method of resolveStringValue is the returned default value which is /home/mas, the real value of esb.mas.path was not used.
org.springframework.util.PropertyPlaceholderHelper.parseStringValue(String, PlaceholderResolver, Set<String>)

Related

Spring Boot reading property which is not present

I have a Spring Boot Application where one of the property in application.properties file is:
pro.perty=no
We read this value in a class and print values based on this properties value:
#Service
class MyClass {
private String property;
public MyClass(#Value("${pro.perty}") String property) {
this.property = property;
}
public void display() {
if(property.equals("yes")) {
System.out.println("Today");
} else {
System.out.println("Tomorrow");
}
}
}
value of pro.perty is "no" in the local application property file. But on Pivotal Cloud Foundry(PCF), where it is deployed, I have set the value of this property to "yes". As external property variables (external to jar) have higher priority than inner ones, so it prints "Today". This works fine.
Yesterday mistakenly, I changed the key of property in PCF to "pro_perty=yes" instead of "pro.perty=yes". Now, the code should print "Tomorrow" as it is not getting any key named "pro.perty" in PCF variables. It only has that key in local application properties file where it is set to "no".
However, it is still printing "Today". How is it able to read "pro_perty" when what it expects is "pro.perty"?

Dynamic PropertyInjection in an Apache Camel Bean

I'm using the #PropertyInject annotation to get properties from the application.properties file to use in my beans.
This normally works fine, but now I need to be able to change the injected property based on a header value.
In my head it looks something like this:
#PropertyInject(PROPERTY_NAME)
private String property;
public void pickProperty(String msgVersion) {
if (msgVersion.equals("A")) {
PROPERTY_NAME = "property.firstType.name";
} else {
PROPERTY_NAME = "property.secondType.name";
}
}
I've considered just injecting both properties and deciding in the main method which one to use, but that seems like a roundabout way of doing things and will get a bit bloated if more versions are added.
Is there an easy way this can be done?
now I need to be able to change the injected property based on a header value
Properties and Beans are created on application startup and typically do not change while the application is running. They both have application scope.
Header values on the other hand can change for every message that is processed by your application.
As you suggested yourself: You can inject both properties into the Bean and provide a method that is called once per message to get the correct value
#PropertyInject(PROPERTY_A)
private String propertyA;
#PropertyInject(PROPERTY_B)
private String propertyB;
// called for every message processing
public String pickProperty(#Header("msgVersion") String msgVersion) {
if (msgVersion.equals("A")) {
return propertyA;
} else {
return propertyB;
}
}
This is not at all a workaround, but simply a method that returns a different result based on the input.

How to create custom user in esapi

How can I create my own user class with additional properties in it?
I tried to create my own user class by implementing org.owasp.esapi.User interface and added some extra properties.
public class MyUserClass implements User{
then I tried this
MyUserClass userClass=(MyUserClass) ESAPI.authenticator().getCurrentUser();
But getting this exception:
SecurityConfiguration for Logger.LogEncodingRequired not found in ESAPI.properties. Using default: false
java.lang.ClassCastException: org.owasp.esapi.reference.DefaultUser cannot be cast to com.bean.MyUserClass
I also tried to extend DefaultUser class but error was same.
The "exception" you are posting is actually two different items: (1) a log message, and (2) an actual exception. And while these are different items altogether, they still stem from the same underlying issue.
Short answer: You are forgetting to set your security configuration system property when your app initializes. It should look something like this:
System.setProperty("org.owasp.esapi.SecurityConfiguration",
"org.you.yourapp.YourAppSecurityConfiguration");
Where org.you.yourapp.YourAppSecurityConfiguration is the name of a class you'll write that implements SecurityConfiguration. Because you are failing to set this system property, when the following ESAPI code runs:
private static String securityConfigurationImplName =
System.getProperty("org.owasp.esapi.SecurityConfiguration",
"org.owasp.esapi.reference.DefaultSecurityConfiguration");
...then since you never set the property, ESAPI is selecting the DefaultSecurityConfiguration for you.
When this DefaultSecurityConfiguration goes to initialize ESAPI's internal logging system, the following method is called:
protected String getESAPIProperty( String key, String def ) {
String value = properties.getProperty(key);
if ( value == null ) {
logSpecial( "SecurityConfiguration for " + key + " not found in ESAPI.properties. Using default: " + def, null );
return def;
}
return value;
}
The property it's looking for here is a boolean called Logger.LogEncodingRequired. So if you want this first message to go away, you need something like:
boolean logEncodingRequired = true; // or false, your choice
System.setProperty("Logger.LogEncodingRequired", logEncodingRequired);
That takes care of your first issue:
SecurityConfiguration for Logger.LogEncodingRequired not found in ESAPI.properties. Using default: false
Your second issue is also a result of ESAPI choosing a DefaultSecurityConfiguration for you. This default configuration has an authenticator() method that returns an instance of FileBasedAuthenticator. And as that javadoc link explains, you need to have a users.txt file on your runtime classpath that contains all the serialized information about your users. And, of course, the FileBasedAuthenticator returns instances of DefaultUser which is why you're getting the 2nd issue (which is an actual exception):
java.lang.ClassCastException: org.owasp.esapi.reference.DefaultUser cannot be cast to com.bean.MyUserClass.
Because you can't cast the DefaultUser (passed back from the FileBasedAuthenticator) to your own MyUser class.
Confused? It's really not so bad. Just implement your own SecurityConfiguration and set it as a system property, and you will be all set. HTH.

Spring Web Flow Converter

I have a Spring MVC and Web Flow 2.3 application.
All I would like to know is how you have a select box in SWF with some default value say, for example, 'Please Select' that is not bound to any value in the backing list.
In line with the docs I have created a conversion service:
public class ApplicationConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean {
// formatters
registry.addFormatter(...);
// converters
registry.addConverter(...);
}
This all works unless I want to perform what would seem to be a perfectly simple task of having 'Please Select' in a select box.
A formatter cannot return null from its Parse Method so you cannot use that. Switching from a formatter to a one-way converter (String > Object) fixes then issue in the MVC stuff however the SWF still complains about missing converter for Object > String. Using this setup do I actually need to create another converter implementation for Object > String (essentially have two converters for every conversion).
Yes, there are other converters TwoWayConverter, ObjectToString etc. etc. however I do not see that these can be added in the above as they are all all the wrong type to be added using:
registry.addConverter(...);
The documentation around conversion is confusing to say the least:
http://docs.spring.io/spring-webflow/docs/2.3.x/reference/htmlsingle/spring-webflow-reference.html#converter-options
You can do atleast adding binding null value or empty string to your model. So you can use default value for select one menu. Like this:
<sf:option value="">Please select...</sf:option>
But in your Formatter or Converter, you should check your model property is null or empty String and if so return null or empty String as you like. Like this:
public YourEnum parse(String value, Locale local) throws ParseException {
if(YourEnum.valueOf(YourEnum.class, value.toUpperCase()) == YourEnum.VALUEONE) {
return YourEnum.VALUEONE;
} else if(YourEnum.valueOf(YourEnum.class, value.toUpperCase()) == YourEnum.VALUETWO) {
return YourEnum.VALUETWO;
} else {
return null;
}
}

Can I access property keys with Selenium on a wicket generated html page?

I am trying to automate frontend tests with Selenium for a wicket based web application.
Therefore I have:
- Different languages
- language property files (submit.signup.form=Submit) and wicket messages () using them
- HTML pages which are generated by wicket (input type:button and value:Submit)
If I go ahead and automate a test case with that, it will work properly.
The problems start when somebody decides to change the property file to f.i. submit.signup.form=Send.
If that happens I will have to adjust all Selenium tests to check for the correct label again to make a test successful (this is not really applicalbe for that example but for error messages it will be a problem)
Now the question:
Is there a way to make wicket to put the property key onto/into the generated html files?
Desired benefit:
I can use Java and make Selenium take the property ke and check the property file for the text. That way a change of a label in the property file would not effect the Selenium tests at all and would make it much more easy to handle.
I am grateful for any answer. :)
Best regards
By default, Wicket starts in development mode. In development mode you should see the wicket tags, you should take a look in to IDebugSettings
, however you will not see the properties gathered from the java code, but you can add the key as attribute, for example
new Label(getString("propertieKey")).add(new AttributeAppender("key","propertieKey"))
It's quite easy to do actually.
Put in your application init method:
getResourceSettings().getStringResourceLoaders().add(0, new NoResourceLoader());
Implement NoResourceLoader:
public class NoResourceLoader implements IStringResourceLoader {
#Override
public String loadStringResource(Class<?> clazz, String key, Locale locale, String style, String variation) {
if ("noProperties".equals(style)) {
return key;
}
return null;
}
#Override
public String loadStringResource(Component component, String key, Locale locale, String style, String variation) {
if ("noProperties".equals(style)) {
return key;
}
return null;
}
}
This resource loader just returns the key if the style is set to noProperties. As it returns null, the localizer will try the next resourceloader for any other invocation.
In order to set style to "noProperties" I'd suggest adding a parameter check to your pages' constructor that would set the style on the session object when you call your application with the parameter.
public BasePage(PageParameters pp) {
String style = pp.get("st").toOptionalString();
if (style != null) {
getSession().setStyle("noProperties");
}
It would be enough to call your first url with this parameter set, then you should walk through the whole session with property keys instead of values in the html. I'd also disable this check when the app is running in production.

Categories

Resources