Uploaded image for project: 'Solr'
  1. Solr
  2. SOLR-1007

Use property values immediately after definition in every configuration files

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Minor
    • Resolution: Won't Fix
    • 1.3
    • None
    • None
    • None
    • sun-jre-1.6.0_01, apache-tomcat-6.0, apache-solr-1.3.0

    Description

      Requirement & Target

      the follwing code cause a "No system property or default value specified" exception:

      solr_home/solr.xml
      <solr>
        <property name="foo" value="blah" />
        <property name="bar" value="${foo}" />
      </solr>
      

      because the property foo won't be appended to context until method CoreContainer#readProperties(Config cfg, Node node) has been accomplished,
      the method can't used it to fill the value of property bar.

      The patch allow configuration files use defined property values immediately in the next property definition.
      Also, base on the patch for issue SOLR-336, the mechanism works in every configuration files like solr.xml, and solrconfig.xml

      Use cases:

      • define some long base dir at the begining of a configuration file
      • maps some JNDI values and refer them in other properties

      Usage:

      define two main cores and some test cores, two main cores share a same configuration, and test cores share another one.

      solr_home/solr.xml
      <solr persistent="true" sharedLib="lib">
      
        <property name="solr.solr.home" value="java:comp/env/solr/home" />
      
        <property name="mainDir" value="${solr.solr.home:./solr}/cores/main/" />
        <property name="testDir" value="${solr.solr.home:./solr}/cores/test/" />
      	
        <cores adminPath="/admin/cores">
          <core name="core1" instanceDir="${mainDir}" />
          <core name="core2" instanceDir="${mainDir}" />
          <core name="testcore1" instanceDir="${testDir}" />
          ...
        </cores>
      
      </solr>
      
      solr_home/cores/main/conf/solrconfig.xml
      <config>
        <!-- this will create two data dirs: solr_home/cores/main/data/core1 & solr_home/cores/main/data/core2 -->
        <dataDir>${solr.core.instanceDir}/data/${solr.core.name}</dataDir>
        ...
      </config>
      

      Coding notes: (including changes from issue SOLR-336)

      • DOMUtil.java
        public method substituteProperty(String value, Properties coreProperties)

        method readProperties(Config cfg, Node node) use it to convert property values

      • CoreContainer.java
        move method readProperties(Config cfg, Node node) to Config.java

        the moved method got a Config for the first argument already... so I think that will be ok

      • Config.java
        .
        • public Properties readProperties(Node node)
          create a context properties including just parsed properties, default JNDI properties and loader's core properties.
          each property value must be converted by this using DOMUtil#substituteProperty and substituteJNDIProperties
          before being appended to just parsed properties.
          .
        • public Config(SolrResourceLoader loader, String name, InputStream is, String prefix)
          create a config properties base on loader.getCoreProperties(), overwrite JNDI properties and read properties onto it
          and pass it to DOMUtil.substituteProperties(doc, properties) instead of loader.getCoreProperties()

          this ensure the properties defined in a configuration file only works in the same configuration file.
          I didn't change the core properties itself because I'm not very sure about its influence...
          properties inheriting between files can be implemented by other patches like SOLR-646

        • static final Properties DEFAULT_JNDI_PROPERTIES
          default JNDI mappings. just mapped solr/home to solr.solr.home currently.
          .
        • private String substituteJNDIProperty(String value)
          convert a value string in JNDI format like java:comp/env/xxx into real value

          but if you don't want it to be convert... I write ${:java:comp/env/xxx} now. ugly... any better solution?

        • private Properties substituteJNDIProperties(Properties jndiProps)
          convert all JNDI values in a Properties object
          .

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              withinsea Mo Chen
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: