Spring boot external configuration from windows fileSystem to HashMap - java

I'm trying to map a configuration file that is located on the Windows FileSystem and populate a Hashmap with that information.
Following Spring documentation and tutorials I have the following:
A Spring bean with the configuration annotations
#Configuration
#ConfigurationProperties(prefix="contact")
#PropertySource("file:///E:/desarrollo/backend/java/proyectos/IW/contact.properties")
public class ContactConfig {
private Map<String, String> groups = new HashMap<>();
public Map<String, String> getContactGroups() {
return this.groups;
}
}
This is my configuration file:
contact.groups.Brasil = brasil
contact.groups.Argentina = argentina
contact.groups.Chile = chile
contact.groups.Spain = espaƱa
contact.groups.Germany = alemania
contact.groups.Colombia = colombia
contact.groups.CostaRica = costa_rica
contact.groups.Ecuador = ecuador
contact.groups.Guatemala = guatemala
contact.groups.Mexico = mexico
contact.groups.Nicaragua = nicaragua
contact.groups.Panama = panama
contact.groups.Peru = peru
contact.groups.ElSalvador = el_salvador
contact.groups.Uruguay = uruguay
contact.groups.IZZIQoE = izzi_mexico
The application compiles but when I debug the Hashmap always come empty, I have tried with different config.properties formats but none of them works.

I fixed it adding a setter method, now the hashmap gets the value from the property file.

Related

How to create a Map from YAML configuation in spring boot?

I want to create a map of type Map> in spring boot , below is the thing i configured in my application.yml and related java class
labels:
nodetypes:
payment:
- customerId
- emailId
- movileNumber
profile:
loyality:
#Data
#ConfigurationProperties(prefix = "labels")
#Component
public class NodeTypeToResponseProps {
Map<String, List<String>> nodetypes = new HashMap<>();
}
but map is not creating , i am expecting , a map will get created with below data in it
{payment : [customerId,emailId,movileNumber] ,profile:[] ,loyality:[] }
any help on this please ?
Thanks to everyone , who tried to help me in solving the issue , i found the solution for this plugin in my build.gradle
id 'io.freefair.lombok' version '3.8.4'
it is working fine now .
You have to create Arraylists int this YAML configuration which has the name of the attributes. Than your essential able to call your Object by only calling the attribute.
Example:
YamlConfiguration yaml = new YamlConfiguration();
HashMap<String, List<String>> nodetypes = new HashMap<>();
//setter
for(String key :nodetypes.keySet())
yaml.set("path."+key, nodetypes.get(key));
yaml.set("path."+new String("keys"), nodetypes.keySet());
//getter
HashMap<String, List<String>> cp = new HashMap<>();
for(String key:yaml.getStringList("path."+new String("keys")))
cp.put(key, yaml.getStringList("path."+key));
You can trying put #Component before that #ConrigurationProerties

Hibernate search custom stop words list

I need to customize stopwords list for search by Document title.
I have the following mapping:
#Entity
#Indexed
#AnalyzerDef(
name = "documentAnalyzer",
tokenizer = #TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
#TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),
#TokenFilterDef(factory = LowerCaseFilterFactory.class),
#TokenFilterDef(
factory = StopFilterFactory.class,
params = {
#Parameter(name = "words", value = "stoplist.properties"),
#Parameter(name = "ignoreCase", value = "true")
}
)
}
)
public class Document {
...
#Field(analyzer = #Analyzer(definition = "documentAnalyzer"))
private String title;
...
}
stoplist.properties file is in resources directory and contains stopwords that are different from StandardAnalyzer defaults.
But the search doesn't return any results if I use stopwords that are enabled by default but don't exist in my stoplist.properties file, e.g. the word will.
What is wrong with current configuration?
How can I make hibernate search use custom stopwords list?
I use hibernate-search-orm 5.6.1 version.
Results are validated in an integration test with index created on-the-fly:
#Before
public void setUpLuceneIndex() throws InterruptedException {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
fullTextEntityManager.createIndexer().startAndWait();
}
Your configuration looks sane as far as I can see.
Did you reindex your entities after having changed the stop words configuration? You need that for the new configuration to be taken into account at index time.
If you did and it still does not work, try to add a breakpoint in StopFilterFactory constructor and inform method to see what's going on!

alfresco buildonly indexer for searching the properties created on the fly

I am using the latest version of alfresco 5.1 version.
one of my requirement is to create properties (key / value) where user enter the key as well as the value.
so I have done that like this
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(QName.createQName("customProp1"), "prop1");
props.put(QName.createQName("customProp2"), "prop2");
ChildAssociationRef associationRef = nodeService.createNode(nodeService.getRootNode(storeRef), ContentModel.ASSOC_CHILDREN, QName.createQName(GUID.generate()), ContentModel.TYPE_CMOBJECT, props);
Now what I want to do is search the nodes with these newly created properties. I was able to search the newly created property like this.
public List<NodeRef> findNodes() throws Exception {
authenticate("admin", "admin");
StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
List<NodeRef> nodeList = null;
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(QName.createQName("customProp1"), "prop1");
props.put(QName.createQName("customProp2"), "prop2");
ChildAssociationRef associationRef = nodeService.createNode(nodeService.getRootNode(storeRef), ContentModel.ASSOC_CHILDREN, QName.createQName(GUID.generate()), ContentModel.TYPE_CMOBJECT, props);
NodeRef nodeRef = associationRef.getChildRef();
String query = "#cm\\:customProp1:\"prop1\"";
SearchParameters sp = new SearchParameters();
sp.addStore(storeRef);
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(query);
try {
ResultSet results = serviceRegistry.getSearchService().query(sp);
nodeList = new ArrayList<NodeRef>();
for (ResultSetRow row : results) {
nodeList.add(row.getNodeRef());
System.out.println(row.getNodeRef());
}
System.out.println(nodeList.size());
} catch (Exception e) {
e.printStackTrace();
}
return nodeList;
}
The alfresco-global.properties indexer configuration is
index.subsystem.name=buildonly
index.recovery.mode=AUTO
dir.keystore=${dir.root}/keystore
Now my question is
Is it possible to achieve the same using the solr4 indexer ?
Or Is there any way to use buildonly indexer for a particular query ?
In your query
String query = "#cm\\:customProp1:\"prop1\"";
remove cm as you are building the QName on the fly so it does not come under cm i.e. (ContentModel) properties. So your query will be
String query = "#\\:customProp1:\"prop1\"";
Hope this will work for you
First, double check if you're simply experiencing eventual consistency, as described below. If you are, and if this presents a problem for you, consider switching to CMIS queries while staying on SOLR.
http://docs.alfresco.com/5.1/concepts/solr-event-consistency.html
Other than this, check if the node has been indexed at all. If it has, take a closer look at how you build your query.
How to find List of unindexed file in alfresco

Get list of all values that #Value could use in a Spring Boot App

After switching to Spring Boot, I'm having an issue getting the list of properties available for #Value lookup.
I'm using multiple properties files (classpath:application.context, and /config/applicaton.context for overrrides). That means that reading the classpath:application.context file isn't an option because of the overrides.
classpath:application.properties:
foo.bar.someProp=apple
bar.baz.someProp=peaches
baz.foo.someProp=pumpkin
/config/application.properties:
bar.baz.someProp=cheese
Application.java:
public class Application {
#Value("${foo.bar.someProp}")
private String someProp;
#Value("${bar.baz.someProp}")
private String someProp2;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
...
}
There's no way for me to know that the value of bar.baz.someProp is "cheese" or that baz.foo.someProp exists.
I've seen examples using #ConfigurationProperties but I'd have to know the properties in advance, which I don't.
Ideally I'd just like a map of the properties available to #Value lookups that I've added with the properties files.
I know the management console can show the values of individual properties files, but I can't (not allowed to) activate it and I can't figure out how it's getting the list of properties to mimic the behavior.
Thanks!
Update: 2015-09-08
Ideally there would be a method like this:
public Map<String,Object) getEffectiveProperties() {
....
}
Map<String, Object> allProperties = getEffectiveProperties();
for (Map.Entry<String, Integer> entry : allProperties.entrySet()) {
String key = entry.getKey().toString();
Object value = entry.getValue();
System.out.println("key: " + key + ", value: " + value.toString() );
}
The output would be:
key: foo.bar.someProp, val: apple
key: bar.baz.someProp, val: cheese
key: baz.foo.someProp, val: pumpkin

Java properties containing dollar delimited variables

I'm storing my app settings in properties file that I use in Ant and in the Java app. Maybe it's not good pratice, but I find it very handy to avoid duplications. The file contains variables such as:
usefulstuff.dir = ${user.home}/usefulstuff
So that other people can run the program on *nix systems, provided that they have the usefulstuff folder in their home directory.
Now, the fascinating thing is that this properties file works fine in Ant (the variable gets resolved to /home/username), while when I load the same file directly in the Java app, I get a string containing ${user.home}/usefulstuff, which is not very useful indeed.
I load the props with this code in Ant:
<loadproperties srcFile="myProps.properties"/>
And in the Java app:
FileInputStream ins = new FileInputStream(propFilePath);
myProps.load(ins);
ins.close();
Am I missing anything? Maybe is there a better way to load properties in a Java app than load()?
I don't think it's particularly "fascinating" that this works in Ant - Ant is deliberately written to do so:
Properties are key-value-pairs where Apache Ant tries to expand ${key} to value at runtime.
and
Ant provides access to all system properties as if they had been defined using a <property> task. For example, ${os.name} expands to the name of the operating system.
If you want the same behaviour, you'll need to implement the same sort of logic. It's possible that you could use the classes from Ant directly, if they do what you want - and if you're happy to ship the relevant binaries (and abide by the licence).
Otherwise, you might want to use a regular expression to find all the matches - or (probably simpler) iterate over all of the system properties and do a simple replacement on them.
As Jon said, it should be straighforward to write the property handling yourself. For eg:
import java.util.*;
public class PropertiesTest
{
public static void main(String[] args)
{
Properties props = new Properties();
props.setProperty("foo", "foo/${os.name}/baz/${os.version}");
props.setProperty("bar", "bar/${user.country}/baz/${user.country}");
System.out.println("BEFORE:");
printProperties(props);
resolveSystemProperties(props);
System.out.println("\n\nAFTER:");
printProperties(props);
}
static void resolveSystemProperties(Properties props)
{
Map<String, String> sysProps = readSystemProperties();
Set<String> sysPropRefs = sysProps.keySet();
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
for (String ref : sysPropRefs)
{
if (value.contains(ref))
{
value = value.replace(ref, sysProps.get(ref));
}
}
props.setProperty(name, value);
}
}
static Map<String, String> readSystemProperties()
{
Properties props = System.getProperties();
Map<String, String> propsMap =
new HashMap<String, String>(props.size());
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
propsMap.put("${" + name + "}", props.getProperty(name));
}
return propsMap;
}
static void printProperties(Properties props)
{
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
System.out.println(name + " => " + value);
}
}
}

Categories