You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by er...@apache.org on 2013/04/02 00:04:32 UTC

svn commit: r1463316 - in /lucene/dev/trunk: lucene/tools/junit4/ solr/core/src/java/org/apache/solr/cloud/ solr/core/src/java/org/apache/solr/core/ solr/core/src/java/org/apache/solr/handler/admin/ solr/core/src/test-files/solr/ solr/core/src/test/org...

Author: erick
Date: Mon Apr  1 22:04:32 2013
New Revision: 1463316

URL: http://svn.apache.org/r1463316
Log:
Fix for SOLR-4615, pull solr.properties out prior to deciding on the new mechanism

Added:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java   (contents, props changed)
      - copied, changed from r1459134, lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlBackCompat.java
    lucene/dev/trunk/solr/core/src/test-files/solr/solr-stress-new.xml   (with props)
    lucene/dev/trunk/solr/core/src/test-files/solr/solr-stress-old.xml   (props changed)
      - copied unchanged from r1459134, lucene/dev/trunk/solr/core/src/test-files/solr/solr-stress.xml
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java   (contents, props changed)
      - copied, changed from r1459134, lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrDiscoveryProperties.java
Removed:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlBackCompat.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrProperties.java
    lucene/dev/trunk/solr/core/src/test-files/solr/solr-shardhandler.properties
    lucene/dev/trunk/solr/core/src/test-files/solr/solr-stress.xml
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrDiscoveryProperties.java
Modified:
    lucene/dev/trunk/lucene/tools/junit4/cached-timehints.txt
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/Config.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolr.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestShardHandlerFactory.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java

Modified: lucene/dev/trunk/lucene/tools/junit4/cached-timehints.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/tools/junit4/cached-timehints.txt?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/tools/junit4/cached-timehints.txt (original)
+++ lucene/dev/trunk/lucene/tools/junit4/cached-timehints.txt Mon Apr  1 22:04:32 2013
@@ -929,7 +929,7 @@ org.apache.solr.core.TestQuerySenderList
 org.apache.solr.core.TestQuerySenderNoQuery=392,616,406,406,413,413,356
 org.apache.solr.core.TestSolrDeletionPolicy1=636,736,868,732,627,1449,788
 org.apache.solr.core.TestSolrDeletionPolicy2=377,450,376,388,413,459,373
-org.apache.solr.core.TestSolrDiscoveryProperties=1183,1243,5175,1041,1490,2090,1181
+org.apache.solr.core.TestCoreDiscovery=1183,1243,5175,1041,1490,2090,1181
 org.apache.solr.core.TestSolrIndexConfig=491,411,360,426,407,414,369
 org.apache.solr.core.TestSolrXMLSerializer=29,24,33,39,164,65,46
 org.apache.solr.core.TestXIncludeConfig=158,139,147,115,1494,112,318

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java Mon Apr  1 22:04:32 2013
@@ -21,8 +21,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.solr.common.cloud.OnReconnect;
 import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.core.ConfigSolr;
-import org.apache.solr.core.ConfigSolrXmlBackCompat;
-import org.apache.solr.core.SolrProperties;
+import org.apache.solr.core.ConfigSolrXml;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.zookeeper.KeeperException;
 import org.xml.sax.SAXException;
@@ -177,21 +176,12 @@ public class ZkCLI {
           solrHome = loader.getInstanceDir();
 
           File configFile = new File(solrHome, SOLR_XML);
-          boolean isXml = true;
-          if (! configFile.exists()) {
-            configFile = new File(solrHome, SolrProperties.SOLR_PROPERTIES_FILE);
-            isXml = false;
-          }
           InputStream is = new FileInputStream(configFile);
 
           ConfigSolr cfg;
 
           try {
-            if (isXml) {
-              cfg = new ConfigSolrXmlBackCompat(loader, null, is, null, false);
-            } else {
-              cfg = new SolrProperties(null, loader, is, null);
-            }
+            cfg = new ConfigSolrXml(loader, null, is, null, false, null);
           } finally {
             IOUtils.closeQuietly(is);
           }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/Config.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/Config.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/Config.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/Config.java Mon Apr  1 22:04:32 2013
@@ -84,7 +84,7 @@ public class Config {
    */
   @Deprecated
   public Config(SolrResourceLoader loader, Config cfg) throws TransformerException {
-    this(loader, null, ConfigSolrXmlBackCompat.copyDoc(cfg.getDocument()));
+    this(loader, null, ConfigSolrXml.copyDoc(cfg.getDocument()));
   }
 
   public Config(SolrResourceLoader loader, String name, InputSource is, String prefix) throws ParserConfigurationException, IOException, SAXException 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolr.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolr.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolr.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolr.java Mon Apr  1 22:04:32 2013
@@ -33,16 +33,16 @@ import java.util.Properties;
  * This is already deprecated, it's only intended to exist for while transitioning to properties-based replacement for
  * solr.xml
  *
- * @since solr 4.2
+ * @since solr 4.3
  */
-@Deprecated
 public interface ConfigSolr {
 
   public static enum ConfLevel {
     SOLR, SOLR_CORES, SOLR_CORES_CORE, SOLR_LOGGING, SOLR_LOGGING_WATCHER
-  }
+  };
 
-  ;
+  public final static String CORE_PROP_FILE = "core.properties";
+  public final static String SOLR_XML_FILE = "solr.xml";
 
   public int getInt(ConfLevel level, String tag, int def);
 

Copied: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java (from r1459134, lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlBackCompat.java)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java?p2=lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java&p1=lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlBackCompat.java&r1=1459134&r2=1463316&rev=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlBackCompat.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java Mon Apr  1 22:04:32 2013
@@ -17,6 +17,7 @@ package org.apache.solr.core;
  * limitations under the License.
  */
 
+import org.apache.commons.io.IOUtils;
 import org.apache.solr.cloud.ZkController;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.handler.component.HttpShardHandlerFactory;
@@ -45,6 +46,7 @@ import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpressionException;
 import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -55,21 +57,25 @@ import java.util.Map;
 import java.util.Properties;
 
 /**
- * ConfigSolrXmlBackCompat
+ * ConfigSolrXml
  * <p/>
  * This class is entirely to localize the backwards compatibility for dealing with specific issues when transitioning
  * from solr.xml to a solr.properties-based, enumeration/discovery of defined cores. See SOLR-4196 for background.
  * <p/>
- * As of Solr 5.0, solr.xml will be deprecated, use SolrProperties.
+ * @since solr 4.3
+ *
+ * It's a bit twisted, but we decided to NOT do the solr.properties switch. But since there's already an interface
+ * it makes sense to leave it in so we can use other methods of providing the Solr information that is contained
+ * in solr.xml. Perhapse something form SolrCloud in the future?
  *
- * @since solr 4.2
- * @deprecated use {@link org.apache.solr.core.SolrProperties} instead
  */
-@Deprecated
 
-public class ConfigSolrXmlBackCompat extends Config implements ConfigSolr {
+public class ConfigSolrXml extends Config implements ConfigSolr {
 
   private static Map<ConfLevel, String> prefixes;
+  private boolean isAutoDiscover = false;
+
+  private final Map<String, CoreDescriptorPlus> coreDescriptorPlusMap = new HashMap<String, CoreDescriptorPlus>();
   private NodeList coreNodes = null;
 
   static {
@@ -82,22 +88,31 @@ public class ConfigSolrXmlBackCompat ext
     prefixes.put(ConfLevel.SOLR_LOGGING_WATCHER, "solr/logging/watcher/@");
   }
 
-  public ConfigSolrXmlBackCompat(SolrResourceLoader loader, String name, InputStream is, String prefix,
-                                 boolean subProps) throws ParserConfigurationException, IOException, SAXException {
+  public ConfigSolrXml(SolrResourceLoader loader, String name, InputStream is, String prefix,
+                       boolean subProps, CoreContainer container) throws ParserConfigurationException, IOException, SAXException {
     super(loader, name, new InputSource(is), prefix, subProps);
-    coreNodes = (NodeList) evaluate("solr/cores/core",
-        XPathConstants.NODESET);
-
+    initCoreList(container);
   }
 
 
-  public ConfigSolrXmlBackCompat(SolrResourceLoader loader, Config cfg) throws TransformerException {
+  public ConfigSolrXml(SolrResourceLoader loader, Config cfg, CoreContainer container) throws TransformerException, IOException {
     super(loader, null, copyDoc(cfg.getDocument())); // Mimics a call from CoreContainer.
-    coreNodes = (NodeList) evaluate("solr/cores/core",
-        XPathConstants.NODESET);
-
+    initCoreList(container);
   }
 
+  public void initCoreList(CoreContainer container) throws IOException {
+    isAutoDiscover = getBool(ConfigSolr.ConfLevel.SOLR_CORES, "autoDiscoverCores", false);
+    if (isAutoDiscover) {
+      synchronized (coreDescriptorPlusMap) {
+        walkFromHere(new File(container.getSolrHome()), container);
+      }
+
+    } else {
+      coreNodes = (NodeList) evaluate("solr/cores/core",
+          XPathConstants.NODESET);
+    }
+
+  }
   public static Document copyDoc(Document doc) throws TransformerException {
     TransformerFactory tfactory = TransformerFactory.newInstance();
     Transformer tx = tfactory.newTransformer();
@@ -174,6 +189,9 @@ public class ConfigSolrXmlBackCompat ext
   public Map<String, String> readCoreAttributes(String coreName) {
     Map<String, String> attrs = new HashMap<String, String>();
 
+    if (isAutoDiscover) {
+      return attrs; // this is a no-op.... intentionally
+    }
     synchronized (coreNodes) {
       for (int idx = 0; idx < coreNodes.getLength(); ++idx) {
         Node node = coreNodes.item(idx);
@@ -185,7 +203,7 @@ public class ConfigSolrXmlBackCompat ext
             if (CoreDescriptor.CORE_DATADIR.equals(attribute.getNodeName()) ||
                 CoreDescriptor.CORE_INSTDIR.equals(attribute.getNodeName())) {
               if (val.indexOf('$') == -1) {
-                val = (val != null && !val.endsWith("/"))? val + '/' : val;
+                val = (val != null && !val.endsWith("/")) ? val + '/' : val;
               }
             }
             attrs.put(attribute.getNodeName(), val);
@@ -197,6 +215,51 @@ public class ConfigSolrXmlBackCompat ext
     return attrs;
   }
 
+  // Basic recursive tree walking, looking for "core.properties" files. Once one is found, we'll stop going any
+  // deeper in the tree.
+  //
+  // @param file - the directory we're to either read the properties file from or recurse into.
+  private void walkFromHere(File file, CoreContainer container) throws IOException {
+    log.info("Looking for cores in " + file.getAbsolutePath());
+    for (File childFile : file.listFiles()) {
+      // This is a little tricky, we are asking if core.properties exists in a child directory of the directory passed
+      // in. In other words we're looking for core.properties in the grandchild directories of the parameter passed
+      // in. That allows us to gracefully top recursing deep but continue looking wide.
+      File propFile = new File(childFile, CORE_PROP_FILE);
+      if (propFile.exists()) { // Stop looking after processing this file!
+        log.info("Discovered properties file {}, adding to cores", propFile.getAbsolutePath());
+        Properties propsOrig = new Properties();
+        InputStream is = new FileInputStream(propFile);
+        try {
+          propsOrig.load(is);
+        } finally {
+          IOUtils.closeQuietly(is);
+        }
+
+        Properties props = new Properties();
+        for (String prop : propsOrig.stringPropertyNames()) {
+          props.put(prop, PropertiesUtil.substituteProperty(propsOrig.getProperty(prop), null));
+        }
+
+        if (props.getProperty(CoreDescriptor.CORE_INSTDIR) == null) {
+          props.setProperty(CoreDescriptor.CORE_INSTDIR, childFile.getPath());
+        }
+
+        if (props.getProperty(CoreDescriptor.CORE_NAME) == null) {
+          // Should default to this directory
+          props.setProperty(CoreDescriptor.CORE_NAME, childFile.getName());
+        }
+        CoreDescriptor desc = new CoreDescriptor(container, props);
+        CoreDescriptorPlus plus = new CoreDescriptorPlus(propFile.getAbsolutePath(), desc, propsOrig);
+        coreDescriptorPlusMap.put(desc.getName(), plus);
+        continue; // Go on to the sibling directory
+      }
+      if (childFile.isDirectory()) {
+        walkFromHere(childFile, container);
+      }
+    }
+  }
+
   public IndexSchema getSchemaFromZk(ZkController zkController, String zkConfigName, String schemaName,
                                      SolrConfig config)
       throws KeeperException, InterruptedException {
@@ -226,7 +289,7 @@ public class ConfigSolrXmlBackCompat ext
   }
 
   static List<SolrXMLSerializer.SolrCoreXMLDef> solrCoreXMLDefs = new ArrayList<SolrXMLSerializer.SolrCoreXMLDef>();
-  // Do this when re-using a ConfigSolrXmlBackCompat.
+  // Do this when re-using a ConfigSolrXml.
 
   // These two methods are part of SOLR-4196 and are awkward, should go away with 5.0
   @Override
@@ -264,14 +327,11 @@ public class ConfigSolrXmlBackCompat ext
   @Override
   public String getCoreNameFromOrig(String origCoreName, SolrResourceLoader loader, String coreName) {
 
-    // look for an existing node
-    synchronized (coreNodes) {
+    if (isAutoDiscover) {
       // first look for an exact match
-      Node coreNode = null;
-      for (int i = 0; i < coreNodes.getLength(); i++) {
-        Node node = coreNodes.item(i);
+      for (Map.Entry<String, CoreDescriptorPlus> ent : coreDescriptorPlusMap.entrySet()) {
 
-        String name = DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null);
+        String name = ent.getValue().getCoreDescriptor().getProperty(CoreDescriptor.CORE_NAME, null);
         if (origCoreName.equals(name)) {
           if (coreName.equals(origCoreName)) {
             return name;
@@ -280,19 +340,47 @@ public class ConfigSolrXmlBackCompat ext
         }
       }
 
-      if (coreNode == null) {
+      for (Map.Entry<String, CoreDescriptorPlus> ent : coreDescriptorPlusMap.entrySet()) {
+        String name = ent.getValue().getCoreDescriptor().getProperty(CoreDescriptor.CORE_NAME, null);
         // see if we match with substitution
+        if (origCoreName.equals(PropertiesUtil.substituteProperty(name, loader.getCoreProperties()))) {
+          if (coreName.equals(origCoreName)) {
+            return name;
+          }
+          return coreName;
+        }
+      }
+    } else {
+      // look for an existing node
+      synchronized (coreNodes) {
+        // first look for an exact match
+        Node coreNode = null;
         for (int i = 0; i < coreNodes.getLength(); i++) {
           Node node = coreNodes.item(i);
+
           String name = DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null);
-          if (origCoreName.equals(PropertiesUtil.substituteProperty(name,
-              loader.getCoreProperties()))) {
+          if (origCoreName.equals(name)) {
             if (coreName.equals(origCoreName)) {
               return name;
             }
             return coreName;
           }
         }
+
+        if (coreNode == null) {
+          // see if we match with substitution
+          for (int i = 0; i < coreNodes.getLength(); i++) {
+            Node node = coreNodes.item(i);
+            String name = DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null);
+            if (origCoreName.equals(PropertiesUtil.substituteProperty(name,
+                loader.getCoreProperties()))) {
+              if (coreName.equals(origCoreName)) {
+                return name;
+              }
+              return coreName;
+            }
+          }
+        }
       }
     }
     return null;
@@ -301,10 +389,14 @@ public class ConfigSolrXmlBackCompat ext
   @Override
   public List<String> getAllCoreNames() {
     List<String> ret = new ArrayList<String>();
-    synchronized (coreNodes) {
-      for (int idx = 0; idx < coreNodes.getLength(); ++idx) {
-        Node node = coreNodes.item(idx);
-        ret.add(DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null));
+    if (isAutoDiscover) {
+      ret = new ArrayList<String>(coreDescriptorPlusMap.keySet());
+    } else {
+      synchronized (coreNodes) {
+        for (int idx = 0; idx < coreNodes.getLength(); ++idx) {
+          Node node = coreNodes.item(idx);
+          ret.add(DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null));
+        }
       }
     }
     return ret;
@@ -312,27 +404,41 @@ public class ConfigSolrXmlBackCompat ext
 
   @Override
   public String getProperty(String coreName, String property, String defaultVal) {
-    synchronized (coreNodes) {
-      for (int idx = 0; idx < coreNodes.getLength(); ++idx) {
-        Node node = coreNodes.item(idx);
-        if (coreName.equals(DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null))) {
-          return DOMUtil.getAttr(node, property, defaultVal);
+    if (isAutoDiscover) {
+      CoreDescriptorPlus plus = coreDescriptorPlusMap.get(coreName);
+      if (plus == null) return defaultVal;
+      CoreDescriptor desc = plus.getCoreDescriptor();
+      if (desc == null) return defaultVal;
+      return desc.getProperty(property, defaultVal);
+    } else {
+      synchronized (coreNodes) {
+        for (int idx = 0; idx < coreNodes.getLength(); ++idx) {
+          Node node = coreNodes.item(idx);
+          if (coreName.equals(DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null))) {
+            return DOMUtil.getAttr(node, property, defaultVal);
+          }
         }
       }
+      return defaultVal;
     }
-    return defaultVal;
   }
 
   @Override
   public Properties readCoreProperties(String coreName) {
-    synchronized (coreNodes) {
-      for (int idx = 0; idx < coreNodes.getLength(); ++idx) {
-        Node node = coreNodes.item(idx);
-        if (coreName.equals(DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null))) {
-          try {
-            return readProperties(node);
-          } catch (XPathExpressionException e) {
-            return null;
+    if (isAutoDiscover) {
+      CoreDescriptorPlus plus = coreDescriptorPlusMap.get(coreName);
+      if (plus == null) return null;
+      return new Properties(plus.getCoreDescriptor().getCoreProperties());
+    } else {
+      synchronized (coreNodes) {
+        for (int idx = 0; idx < coreNodes.getLength(); ++idx) {
+          Node node = coreNodes.item(idx);
+          if (coreName.equals(DOMUtil.getAttr(node, CoreDescriptor.CORE_NAME, null))) {
+            try {
+              return readProperties(node);
+            } catch (XPathExpressionException e) {
+              return null;
+            }
           }
         }
       }
@@ -340,6 +446,30 @@ public class ConfigSolrXmlBackCompat ext
     return null;
   }
 
+  static Properties getCoreProperties(String instanceDir, CoreDescriptor dcore) {
+    String file = dcore.getPropertiesName();
+    if (file == null) file = "conf" + File.separator + "solrcore.properties";
+    File corePropsFile = new File(file);
+    if (!corePropsFile.isAbsolute()) {
+      corePropsFile = new File(instanceDir, file);
+    }
+    Properties p = dcore.getCoreProperties();
+    if (corePropsFile.exists() && corePropsFile.isFile()) {
+      p = new Properties(dcore.getCoreProperties());
+      InputStream is = null;
+      try {
+        is = new FileInputStream(corePropsFile);
+        p.load(is);
+      } catch (IOException e) {
+        log.warn("Error loading properties ", e);
+      } finally {
+        IOUtils.closeQuietly(is);
+      }
+    }
+    return p;
+  }
+
+
   static void addPersistAllCoresStatic(Properties containerProperties, Map<String, String> rootSolrAttribs, Map<String, String> coresAttribs,
                                        File file) {
     SolrXMLSerializer.SolrXMLDef solrXMLDef = new SolrXMLSerializer.SolrXMLDef();
@@ -364,3 +494,34 @@ public class ConfigSolrXmlBackCompat ext
       + "  </cores>\n" + "</solr>";
 
 }
+
+// It's mightily convenient to have all of the original path names and property values when persisting cores, so
+// this little convenience class is just for that.
+// Also, let's keep track of anything we added here, especially the instance dir for persistence purposes. We don't
+// want, for instance, to persist instanceDir if it was not specified originally.
+//
+// I suspect that for persistence purposes, we may want to expand this idea to record, say, ${blah}
+class CoreDescriptorPlus {
+  private CoreDescriptor coreDescriptor;
+  private String filePath;
+  private Properties propsOrig;
+
+  CoreDescriptorPlus(String filePath, CoreDescriptor descriptor, Properties propsOrig) {
+    coreDescriptor = descriptor;
+    this.filePath = filePath;
+    this.propsOrig = propsOrig;
+  }
+
+  CoreDescriptor getCoreDescriptor() {
+    return coreDescriptor;
+  }
+
+  String getFilePath() {
+    return filePath;
+  }
+
+  Properties getPropsOrig() {
+    return propsOrig;
+  }
+}
+

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java Mon Apr  1 22:04:32 2013
@@ -131,11 +131,11 @@ public class CoreContainer
   private ShardHandlerFactory shardHandlerFactory;
   protected LogWatcher logging = null;
   private String zkHost;
+  private int transientCacheSize = Integer.MAX_VALUE;
 
   private String leaderVoteWait = LEADER_VOTE_WAIT;
   private int distribUpdateConnTimeout = 0;
   private int distribUpdateSoTimeout = 0;
-  protected int transientCacheSize = Integer.MAX_VALUE; // Use as a flag too, if transientCacheSize set in solr.xml this will be changed
   private int coreLoadThreads;
   private CloserThread backgroundCloser = null;
   
@@ -145,7 +145,7 @@ public class CoreContainer
 
   /**
    * Deprecated
-   * @deprecated use the single arg constructure with locateSolrHome()
+   * @deprecated use the single arg constructor with locateSolrHome()
    * @see SolrResourceLoader#locateSolrHome
    */
   @Deprecated
@@ -321,19 +321,14 @@ public class CoreContainer
       log.info("looking for solr config file: " + fconf.getAbsolutePath());
       cores = new CoreContainer(solrHome);
 
-      if (! fconf.exists()) {
-        if (StringUtils.isBlank(containerConfigFilename) || containerConfigFilename.endsWith(".xml")) {
-          fconf = new File(solrHome, SolrProperties.SOLR_PROPERTIES_FILE);
-        }
-      }
-      // Either we have a config file or not. If it ends in .properties, assume new-style.
+      // Either we have a config file or not.
       
       if (fconf.exists()) {
         cores.load(solrHome, fconf);
       } else {
-        log.info("no solr.xml or solr.properties file found - using default old-style solr.xml");
+        log.info("no solr.xml found. using default old-style solr.xml");
         try {
-          cores.load(solrHome, new ByteArrayInputStream(ConfigSolrXmlBackCompat.DEF_SOLR_XML.getBytes("UTF-8")), true, null);
+          cores.load(solrHome, new ByteArrayInputStream(ConfigSolrXml.DEF_SOLR_XML.getBytes("UTF-8")), null);
         } catch (Exception e) {
           throw new SolrException(ErrorCode.SERVER_ERROR,
               "CoreContainer.Initialize failed when trying to load default solr.xml file", e);
@@ -361,7 +356,7 @@ public class CoreContainer
     this.configFile = configFile;
     InputStream in = new FileInputStream(configFile);
     try {
-      this.load(dir, in, configFile.getName().endsWith(".xml"),  configFile.getName());
+      this.load(dir, in,  configFile.getName());
     } finally {
       IOUtils.closeQuietly(in);
     }
@@ -375,7 +370,7 @@ public class CoreContainer
    */
 
   // Let's keep this ugly boolean out of public circulation.
-  protected void load(String dir, InputStream is, boolean isXmlFile, String fileName)  {
+  protected void load(String dir, InputStream is, String fileName)  {
     ThreadPoolExecutor coreLoadExecutor = null;
     if (null == dir) {
       // don't rely on SolrResourceLoader(), determine explicitly first
@@ -389,16 +384,9 @@ public class CoreContainer
     ConfigSolr cfg;
     
     // keep orig config for persist to consult
-    //TODO 5.0: Remove this confusing junk, the properties file is so fast to read that there's no good reason
-    //          to add this stuff. Furthermore, it would be good to persist comments when saving.....
     try {
-      if (isXmlFile) {
-        cfg = new ConfigSolrXmlBackCompat(loader, null, is, null, false);
-        this.cfg = new ConfigSolrXmlBackCompat(loader, (ConfigSolrXmlBackCompat)cfg);
-      } else {
-        cfg = new SolrProperties(this, loader, is, fileName);
-        this.cfg = new SolrProperties(this, loader, (SolrProperties)cfg);
-      }
+      cfg = new ConfigSolrXml(loader, null, is, null, false, this);
+      this.cfg = new ConfigSolrXml(loader, (ConfigSolrXml) cfg, this);
     } catch (Exception e) {
       throw new SolrException(ErrorCode.SERVER_ERROR, "", e);
     }
@@ -479,13 +467,15 @@ public class CoreContainer
     host = cfg.get(ConfigSolr.ConfLevel.SOLR_CORES, "host", null);
     
     leaderVoteWait = cfg.get(ConfigSolr.ConfLevel.SOLR_CORES, "leaderVoteWait", LEADER_VOTE_WAIT);
-    
+
     if (shareSchema) {
       indexSchemaCache = new ConcurrentHashMap<String,IndexSchema>();
     }
     adminHandler = cfg.get(ConfigSolr.ConfLevel.SOLR_CORES, "adminHandler", null);
     managementPath = cfg.get(ConfigSolr.ConfLevel.SOLR_CORES, "managementPath", null);
-    
+
+    transientCacheSize = cfg.getInt(ConfigSolr.ConfLevel.SOLR_CORES, "transientCacheSize", Integer.MAX_VALUE);
+
     zkClientTimeout = Integer.parseInt(System.getProperty("zkClientTimeout",
         Integer.toString(zkClientTimeout)));
     initZooKeeper(zkHost, zkClientTimeout);
@@ -886,7 +876,8 @@ public class CoreContainer
         throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
             "Could not find config name for collection:" + collection);
       }
-      solrLoader = new ZkSolrResourceLoader(instanceDir, zkConfigName, libLoader, SolrProperties.getCoreProperties(instanceDir, dcore), zkController);
+      solrLoader = new ZkSolrResourceLoader(instanceDir, zkConfigName, libLoader,
+          ConfigSolrXml.getCoreProperties(instanceDir, dcore), zkController);
       config = getSolrConfigFromZk(zkConfigName, dcore.getConfigName(), solrLoader);
       schema = IndexSchemaFactory.buildIndexSchema(dcore.getSchemaName(), config);
       return new SolrCore(dcore.getName(), null, config, schema, dcore);
@@ -909,7 +900,7 @@ public class CoreContainer
     SolrResourceLoader solrLoader = null;
 
     SolrConfig config = null;
-    solrLoader = new SolrResourceLoader(instanceDir, libLoader, SolrProperties.getCoreProperties(instanceDir, dcore));
+    solrLoader = new SolrResourceLoader(instanceDir, libLoader, ConfigSolrXml.getCoreProperties(instanceDir, dcore));
     try {
       config = new SolrConfig(solrLoader, dcore.getConfigName(), null);
     } catch (Exception e) {
@@ -1066,7 +1057,7 @@ public class CoreContainer
                  cd.getName(), instanceDir.getAbsolutePath());
         SolrResourceLoader solrLoader;
         if(zkController == null) {
-          solrLoader = new SolrResourceLoader(instanceDir.getAbsolutePath(), libLoader, SolrProperties.getCoreProperties(instanceDir.getAbsolutePath(), cd));
+          solrLoader = new SolrResourceLoader(instanceDir.getAbsolutePath(), libLoader, ConfigSolrXml.getCoreProperties(instanceDir.getAbsolutePath(), cd));
         } else {
           try {
             String collection = cd.getCloudDescriptor().getCollectionName();
@@ -1079,7 +1070,7 @@ public class CoreContainer
                                            "Could not find config name for collection:" + collection);
             }
             solrLoader = new ZkSolrResourceLoader(instanceDir.getAbsolutePath(), zkConfigName, libLoader,
-                SolrProperties.getCoreProperties(instanceDir.getAbsolutePath(), cd), zkController);
+                ConfigSolrXml.getCoreProperties(instanceDir.getAbsolutePath(), cd), zkController);
           } catch (KeeperException e) {
             log.error("", e);
             throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
@@ -1229,7 +1220,24 @@ public class CoreContainer
   public String getAdminPath() {
     return adminPath;
   }
-  
+
+  public String getHostPort() {
+    return hostPort;
+  }
+
+  public String getHostContext() {
+    return hostContext;
+  }
+
+  public String getHost() {
+    return host;
+  }
+
+  public int getZkClientTimeout() {
+    return zkClientTimeout;
+  }
+
+
   public void setAdminPath(String adminPath) {
       this.adminPath = adminPath;
   }
@@ -1308,10 +1316,6 @@ public class CoreContainer
       coresAttribs.put("defaultCoreName", defaultCoreName);
     }
 
-    if (transientCacheSize != Integer.MAX_VALUE) {
-      coresAttribs.put("transientCacheSize", Integer.toString(transientCacheSize));
-    }
-    
     addCoresAttrib(coresAttribs, "hostPort", this.hostPort, DEFAULT_HOST_PORT);
     addCoresAttrib(coresAttribs, "zkClientTimeout",
         intToString(this.zkClientTimeout),
@@ -1319,6 +1323,10 @@ public class CoreContainer
     addCoresAttrib(coresAttribs, "hostContext", this.hostContext, DEFAULT_HOST_CONTEXT);
     addCoresAttrib(coresAttribs, "leaderVoteWait", this.leaderVoteWait, LEADER_VOTE_WAIT);
     addCoresAttrib(coresAttribs, "coreLoadThreads", Integer.toString(this.coreLoadThreads), Integer.toString(CORE_LOAD_THREADS));
+    if (transientCacheSize != Integer.MAX_VALUE) { // This test
+    // is a consequence of testing. I really hate it.
+      addCoresAttrib(coresAttribs, "transientCacheSize", Integer.toString(this.transientCacheSize), Integer.toString(Integer.MAX_VALUE));
+    }
 
     coreMaps.persistCores(cfg, containerProperties, rootSolrAttribs, coresAttribs, file, configFile, loader);
 
@@ -1402,8 +1410,6 @@ class CoreMaps {
 
   private final Map<String, CoreDescriptor> dynamicDescriptors = new LinkedHashMap<String, CoreDescriptor>();
 
-  private int transientCacheSize = Integer.MAX_VALUE;
-
   private Map<SolrCore, String> coreToOrigName = new ConcurrentHashMap<SolrCore, String>();
 
   private final CoreContainer container;
@@ -1423,7 +1429,7 @@ class CoreMaps {
   // Trivial helper method for load, note it implements LRU on transient cores. Also note, if
   // there is no setting for max size, nothing is done and all cores go in the regular "cores" list
   protected void allocateLazyCores(final ConfigSolr cfg, final SolrResourceLoader loader) {
-    transientCacheSize = cfg.getInt(ConfigSolr.ConfLevel.SOLR_CORES, "transientCacheSize", Integer.MAX_VALUE);
+    final int transientCacheSize = cfg.getInt(ConfigSolr.ConfLevel.SOLR_CORES, "transientCacheSize", Integer.MAX_VALUE);
     if (transientCacheSize != Integer.MAX_VALUE) {
       CoreContainer.log.info("Allocating transient cache for {} transient cores", transientCacheSize);
       transientCores = new LinkedHashMap<String, SolrCore>(transientCacheSize, 0.75f, true) {
@@ -1535,7 +1541,7 @@ class CoreMaps {
     CoreContainer.log.info("Opening transient core {}", name);
     synchronized (locker) {
       retCore = transientCores.put(name, core);
-  }
+    }
     return retCore;
   }
 
@@ -1745,10 +1751,10 @@ class CoreMaps {
     //
     synchronized (locker) {
       if (cfg == null) {
-        ConfigSolrXmlBackCompat.initPersistStatic();
+        ConfigSolrXml.initPersistStatic();
         persistCores(cfg, cores, loader);
         persistCores(cfg, transientCores, loader);
-        ConfigSolrXmlBackCompat.addPersistAllCoresStatic(containerProperties, rootSolrAttribs, coresAttribs,
+        ConfigSolrXml.addPersistAllCoresStatic(containerProperties, rootSolrAttribs, coresAttribs,
             (file == null ? configFile : file));
       } else {
         cfg.initPersist();
@@ -1907,7 +1913,7 @@ class CoreMaps {
       cfg.addPersistCore(coreName, persistProps, coreAttribs);
     } else {
       // Another awkward bit for back-compat for SOLR-4196
-      ConfigSolrXmlBackCompat.addPersistCore(persistProps, coreAttribs);
+      ConfigSolrXml.addPersistCore(persistProps, coreAttribs);
     }
   }
 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java Mon Apr  1 22:04:32 2013
@@ -134,7 +134,11 @@ public class CoreDescriptor {
   }
 
   public Properties initImplicitProperties() {
-    Properties implicitProperties = new Properties(coreContainer.getContainerProperties());
+
+    Properties implicitProperties = new Properties();
+    if (coreContainer != null && coreContainer.getContainerProperties() != null){
+      implicitProperties.putAll(coreContainer.getContainerProperties());
+    }
     implicitProperties.setProperty("solr.core.name", getName());
     implicitProperties.setProperty("solr.core.instanceDir", getInstanceDir());
     implicitProperties.setProperty("solr.core.dataDir", getDataDir());
@@ -203,6 +207,9 @@ public class CoreDescriptor {
       return SolrResourceLoader.normalizeDir(
           SolrResourceLoader.normalizeDir(instDir));
     }
+
+    if (coreContainer == null) return null;
+
     return SolrResourceLoader.normalizeDir(coreContainer.getSolrHome() +
         SolrResourceLoader.normalizeDir(instDir));
   }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java Mon Apr  1 22:04:32 2013
@@ -438,6 +438,18 @@ public class CoreAdminHandler extends Re
       if (opts != null)
         dcore.setUlogDir(opts);
 
+      opts = params.get(CoreAdminParams.LOAD_ON_STARTUP);
+      if (opts != null){
+        Boolean value = Boolean.valueOf(opts);
+        dcore.setLoadOnStartup(value);
+      }
+      
+      opts = params.get(CoreAdminParams.TRANSIENT);
+      if (opts != null){
+        Boolean value = Boolean.valueOf(opts);
+        dcore.setTransient(value);
+      }
+      
       CloudDescriptor cd = dcore.getCloudDescriptor();
       if (cd != null) {
         cd.setParams(req.getParams());
@@ -457,7 +469,7 @@ public class CoreAdminHandler extends Re
         opts = params.get(CoreAdminParams.CORE_NODE_NAME);
         if (opts != null)
           cd.setCoreNodeName(opts);
-        
+                        
         Integer numShards = params.getInt(ZkStateReader.NUM_SHARDS_PROP);
         if (numShards != null)
           cd.setNumShards(numShards);

Added: lucene/dev/trunk/solr/core/src/test-files/solr/solr-stress-new.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/solr-stress-new.xml?rev=1463316&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/solr-stress-new.xml (added)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/solr-stress-new.xml Mon Apr  1 22:04:32 2013
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ All (relative) paths are relative to the installation path
+
+  persistent: Save changes made via the API to this file
+  sharedLib: path to a lib directory that will be shared across all cores
+-->
+<solr persistent="${solr.xml.persist:true}">
+
+  <!--
+  adminPath: RequestHandler path to manage cores.
+    If 'null' (or absent), cores will not be manageable via request handler
+  -->
+  <cores adminPath="/admin/cores" defaultCoreName="collection1" host="127.0.0.1" hostPort="${hostPort:8983}"
+         hostContext="${hostContext:solr}" autoDiscoverCores="true" >
+    <shardHandlerFactory name="shardHandlerFactory" class="HttpShardHandlerFactory">
+      <int name="socketTimeout">${socketTimeout:120000}</int>
+      <int name="connTimeout">${connTimeout:15000}</int>
+    </shardHandlerFactory>
+  </cores>
+
+</solr>

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java Mon Apr  1 22:04:32 2013
@@ -215,11 +215,12 @@ public class OpenCloseCoreStressTest ext
 
   private void makeCores(File home, boolean oldStyle) throws Exception {
     File testSrcRoot = new File(SolrTestCaseJ4.TEST_HOME());
+    String srcSolrXml = "solr-stress-new.xml";
+
     if (oldStyle) {
-      FileUtils.copyFile(new File(testSrcRoot, "solr-stress.xml"), new File(home, "solr.xml"));
-    } else {
-      FileUtils.copyFile(new File(testSrcRoot, "solr-stress.properties"), new File(home, "solr.properties"));
+      srcSolrXml = "solr-stress-old.xml";
     }
+    FileUtils.copyFile(new File(testSrcRoot, srcSolrXml), new File(home, "solr.xml"));
 
     // create directories in groups of 100 until you have enough.
     for (int idx = 0; idx < numCores; ++idx) {

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java Mon Apr  1 22:04:32 2013
@@ -193,12 +193,11 @@ public class TestCoreContainer extends S
       assertEquals("cores not added?", 3, cores.getCoreNames().size());
       
       final File twoXml = new File(workDir, "2.solr.xml");
-      cores.transientCacheSize = 32;
 
       cores.persistFile(twoXml);
 
       assertXmlFile(twoXml, "/solr[@persistent='true']",
-          "/solr/cores[@defaultCoreName='collection1' and @transientCacheSize='32']",
+          "/solr/cores[@defaultCoreName='collection1']",
           "/solr/cores/core[@name='collection1' and @instanceDir='" + instDir
               + "']", "/solr/cores/core[@name='X' and @instanceDir='" + instDir
               + "' and @dataDir='" + dataX + "']",
@@ -271,7 +270,7 @@ public class TestCoreContainer extends S
       FileUtils.deleteDirectory(solrHomeDirectory);
       throw e;
     }
-    
+
     //init
     System.setProperty("solr.solr.home", solrHomeDirectory.getAbsolutePath());
     CoreContainer.Initializer init = new CoreContainer.Initializer();
@@ -293,8 +292,13 @@ public class TestCoreContainer extends S
       cores.register(newCore, false);
       
       //assert one registered core
+
       assertEquals("There core registered", 1, cores.getCores().size());
-      
+
+
+      assertXmlFile(new File(solrHomeDirectory, "solr.xml"),
+          "/solr/cores[@transientCacheSize='32']");
+
       newCore.close();
       cores.remove("core1");
       //assert cero cores
@@ -308,7 +312,7 @@ public class TestCoreContainer extends S
   
   private static final String EMPTY_SOLR_XML ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
       "<solr persistent=\"false\">\n" +
-      "  <cores adminPath=\"/admin/cores\">\n" +
+      "  <cores adminPath=\"/admin/cores\" transientCacheSize=\"32\" >\n" +
       "  </cores>\n" +
       "</solr>";
   

Copied: lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java (from r1459134, lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrDiscoveryProperties.java)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java?p2=lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java&p1=lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrDiscoveryProperties.java&r1=1459134&r2=1463316&rev=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrDiscoveryProperties.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java Mon Apr  1 22:04:32 2013
@@ -31,7 +31,7 @@ import java.io.StringReader;
 import java.util.Properties;
 import java.util.Set;
 
-public class TestSolrDiscoveryProperties extends SolrTestCaseJ4 {
+public class TestCoreDiscovery extends SolrTestCaseJ4 {
   private static String NEW_LINE = System.getProperty("line.separator");
 
   @BeforeClass
@@ -39,7 +39,7 @@ public class TestSolrDiscoveryProperties
     initCore();
   }
 
-  private final File solrHomeDirectory = new File(TEMP_DIR, "org.apache.solr.core.TestSolrDiscoveryProperties" + File.separator + "solrHome");
+  private final File solrHomeDirectory = new File(TEMP_DIR, "org.apache.solr.core.TestCoreDiscovery" + File.separator + "solrHome");
 
   private void setMeUp() throws Exception {
     if (solrHomeDirectory.exists()) {
@@ -49,24 +49,8 @@ public class TestSolrDiscoveryProperties
     System.setProperty("solr.solr.home", solrHomeDirectory.getAbsolutePath());
   }
 
-  private void addSolrPropertiesFile(String... extras) throws Exception {
-    File solrProps = new File(solrHomeDirectory, SolrProperties.SOLR_PROPERTIES_FILE);
-    Properties props = new Properties();
-    props.load(new StringReader(SOLR_PROPERTIES));
-    for (String extra : extras) {
-      String[] parts = extra.split("=");
-      props.put(parts[0], parts[1]);
-    }
-    FileOutputStream out = new FileOutputStream(solrProps.getAbsolutePath());
-    try {
-      props.store(out, null);
-    } finally {
-      out.close();
-    }
-  }
-
   private void addSolrXml() throws Exception {
-    File tmpFile = new File(solrHomeDirectory, SolrProperties.SOLR_XML_FILE);
+    File tmpFile = new File(solrHomeDirectory, ConfigSolr.SOLR_XML_FILE);
     FileUtils.write(tmpFile, SOLR_XML, IOUtils.CHARSET_UTF_8.toString());
   }
 
@@ -90,7 +74,7 @@ public class TestSolrDiscoveryProperties
   private void addCoreWithProps(Properties stockProps) throws Exception {
 
     File propFile = new File(solrHomeDirectory,
-        stockProps.getProperty(CoreDescriptor.CORE_NAME) + File.separator + SolrProperties.CORE_PROP_FILE);
+        stockProps.getProperty(CoreDescriptor.CORE_NAME) + File.separator + ConfigSolr.CORE_PROP_FILE);
     File parent = propFile.getParentFile();
     assertTrue("Failed to mkdirs for " + parent.getAbsolutePath(), parent.mkdirs());
 
@@ -132,12 +116,12 @@ public class TestSolrDiscoveryProperties
     }
   }
 
-  // Test the basic setup, create some dirs with core.properties files in them, but no solr.xml (a solr.properties
-  // instead) and insure that we find all the cores and can load them.
+  // Test the basic setup, create some dirs with core.properties files in them, but solr.xml has discoverCores
+  // set and insure that we find all the cores and can load them.
   @Test
   public void testPropertiesFile() throws Exception {
     setMeUp();
-    addSolrPropertiesFile();
+    addSolrXml();
     // name, isLazy, loadOnStartup
     addCoreWithProps(makeCorePropFile("core1", false, true));
     addCoreWithProps(makeCorePropFile("core2", false, false));
@@ -150,14 +134,12 @@ public class TestSolrDiscoveryProperties
     try {
       Properties props = cc.containerProperties;
 
-      assertEquals("/admin/cores/props", props.getProperty("cores.adminPath"));
-      assertEquals("/admin/cores/props", cc.getAdminPath());
-      assertEquals("defcore", props.getProperty("cores.defaultCoreName"));
+      assertEquals("/admin/cores", cc.getAdminPath());
       assertEquals("defcore", cc.getDefaultCoreName());
-      assertEquals("222.333.444.555", props.getProperty("host"));
-      assertEquals("6000", props.getProperty("port")); // getProperty actually looks at original props.
-      assertEquals("/solrprop", props.getProperty("cores.hostContext"));
-      assertEquals("20", props.getProperty("cores.zkClientTimeout"));
+      assertEquals("222.333.444.555", cc.getHost());
+      assertEquals("6000", cc.getHostPort());
+      assertEquals("solrprop", cc.getHostContext());
+      assertEquals(20, cc.getZkClientTimeout());
 
       TestLazyCores.checkInCores(cc, "core1");
       TestLazyCores.checkNotInCores(cc, "lazy1", "core2", "collection1");
@@ -194,7 +176,7 @@ public class TestSolrDiscoveryProperties
   @Test
   public void testPersistTrue() throws Exception {
     setMeUp();
-    addSolrPropertiesFile();
+    addSolrXml();
     System.setProperty("solr.persistent", "true");
 
     Properties special = makeCorePropFile("core1", false, true);
@@ -229,11 +211,6 @@ public class TestSolrDiscoveryProperties
       TestLazyCores.checkInCores(cc, "core1", "core2", "lazy2", "lazy3");
       TestLazyCores.checkNotInCores(cc, "lazy1");
 
-      checkSolrProperties(cc);
-
-      File xmlFile = new File(solrHomeDirectory, "solr.xml");
-      assertFalse("Solr.xml should NOT exist", xmlFile.exists());
-
       Properties orig = makeCorePropFile("core1", false, true);
       orig.put(CoreDescriptor.CORE_INSTDIR, "${core1inst:anothersillypath}");
       checkCoreProps(orig, "addedPropC1=addedC1", "addedPropC1B=foo", "addedPropC1C=bar");
@@ -267,7 +244,7 @@ public class TestSolrDiscoveryProperties
   @Test
   public void testPersistFalse() throws Exception {
     setMeUp();
-    addSolrPropertiesFile();
+    addSolrXml();
 
     addCoreWithProps(makeCorePropFile("core1", false, true));
     addCoreWithProps(makeCorePropFile("core2", false, false));
@@ -290,7 +267,7 @@ public class TestSolrDiscoveryProperties
 
     try {
       cc.persist();
-      checkSolrProperties(cc);
+//      checkSolrProperties(cc);
 
       checkCoreProps(makeCorePropFile("core1", false, true));
       checkCoreProps(makeCorePropFile("core2", false, false));
@@ -313,49 +290,13 @@ public class TestSolrDiscoveryProperties
     }
   }
 
-  // Insure that the solr.properties is as it should be after persisting _and_, in some cases, different than
-  // what's in memory
-  void checkSolrProperties(CoreContainer cc, String... checkMemPairs) throws Exception {
-    Properties orig = new Properties();
-    orig.load(new StringReader(SOLR_PROPERTIES));
-
-    Properties curr = cc.getContainerProperties();
-
-    Properties persisted = new Properties();
-    FileInputStream in = new FileInputStream(new File(solrHomeDirectory, SolrProperties.SOLR_PROPERTIES_FILE));
-    try {
-      persisted.load(in);
-    } finally {
-      in.close();
-    }
-
-    assertEquals("Persisted and original should be the same size", orig.size(), persisted.size());
-
-    for (String prop : orig.stringPropertyNames()) {
-      assertEquals("Values of original should match current", orig.getProperty(prop), persisted.getProperty(prop));
-    }
-
-    Properties specialProps = new Properties();
-    for (String special : checkMemPairs) {
-      String[] pair = special.split("=");
-      specialProps.put(pair[0], pair[1]);
-    }
-    // OK, current should match original except if the property is "special"
-    for (String prop : curr.stringPropertyNames()) {
-      String val = specialProps.getProperty(prop);
-      if (val != null) { // Compare curr and val
-        assertEquals("Modified property should be in current container properties", val, curr.getProperty(prop));
-      }
-    }
-  }
-
   // Insure that the properties in the core passed in are exactly what's in the default core.properties below plus
   // whatever extra is passed in.
   void checkCoreProps(Properties orig, String... extraProps) throws Exception {
     // Read the persisted file.
     Properties props = new Properties();
     File propParent = new File(solrHomeDirectory, orig.getProperty(CoreDescriptor.CORE_NAME));
-    FileInputStream in = new FileInputStream(new File(propParent, SolrProperties.CORE_PROP_FILE));
+    FileInputStream in = new FileInputStream(new File(propParent, ConfigSolr.CORE_PROP_FILE));
     try {
       props.load(in);
     } finally {
@@ -374,63 +315,9 @@ public class TestSolrDiscoveryProperties
     }
   }
 
-  // If there's a solr.xml AND a properties file, make sure that the xml file is loaded and the properties file
-  // is ignored.
-
-  @Test
-  public void testBackCompatXml() throws Exception {
-    setMeUp();
-    addSolrPropertiesFile();
-    addSolrXml();
-    addConfigsForBackCompat();
-
-    CoreContainer cc = init();
-    try {
-      Properties props = cc.getContainerProperties();
-
-      assertEquals("/admin/cores", cc.getAdminPath());
-      assertEquals("collectionLazy2", cc.getDefaultCoreName());
-
-      // Shouldn't get these in properties at this point
-      assertNull(props.getProperty("cores.adminPath"));
-      assertNull(props.getProperty("cores.defaultCoreName"));
-      assertNull(props.getProperty("host"));
-      assertNull(props.getProperty("port")); // getProperty actually looks at original props.
-      assertNull(props.getProperty("cores.hostContext"));
-      assertNull(props.getProperty("cores.zkClientTimeout"));
-
-      SolrCore core1 = cc.getCore("collection1");
-      CoreDescriptor desc = core1.getCoreDescriptor();
-
-      assertEquals("collection1", desc.getProperty("solr.core.name"));
-
-      // This is too long and ugly to put in. Besides, it varies.
-      assertNotNull(desc.getProperty("solr.core.instanceDir"));
-
-      assertEquals("data" + File.separator, desc.getProperty("solr.core.dataDir"));
-      assertEquals("solrconfig-minimal.xml", desc.getProperty("solr.core.configName"));
-      assertEquals("schema-tiny.xml", desc.getProperty("solr.core.schemaName"));
-      core1.close();
-    } finally {
-      cc.shutdown();
-    }
-  }
-
-  // For this test I want some of these to be different than what would be in solr.xml by default.
-  private final static String SOLR_PROPERTIES =
-      "persistent=${persistent:false}" + NEW_LINE +
-          "cores.adminPath=/admin/cores/props" + NEW_LINE +
-          "cores.defaultCoreName=defcore" + NEW_LINE +
-          "host=222.333.444.555" + NEW_LINE +
-          "port=6000" + NEW_LINE +
-          "cores.hostContext=/solrprop" + NEW_LINE +
-          "cores.zkClientTimeout=20" + NEW_LINE +
-          "cores.transientCacheSize=2";
-
   // For testing whether finding a solr.xml overrides looking at solr.properties
-  private final static String SOLR_XML = " <solr persistent=\"false\"> " +
-      "<cores adminPath=\"/admin/cores\" defaultCoreName=\"collectionLazy2\" transientCacheSize=\"4\">  " +
-      "<core name=\"collection1\" instanceDir=\"collection1\" config=\"solrconfig-minimal.xml\" schema=\"schema-tiny.xml\" /> " +
-      "</cores> " +
+  private final static String SOLR_XML = " <solr persistent=\"${persistent:false}\"> " +
+      "<cores autoDiscoverCores=\"true\" adminPath=\"/admin/cores\" defaultCoreName=\"defcore\" transientCacheSize=\"2\" " +
+       " hostContext=\"solrprop\" zkClientTimeout=\"20\" host=\"222.333.444.555\" hostPort=\"6000\" />  " +
       "</solr>";
 }

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestShardHandlerFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestShardHandlerFactory.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestShardHandlerFactory.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestShardHandlerFactory.java Mon Apr  1 22:04:32 2013
@@ -38,15 +38,4 @@ public class TestShardHandlerFactory ext
     factory.close();
     cc.shutdown();
   }
-  
-  public void testProperties() throws Exception {
-    CoreContainer cc = new CoreContainer(TEST_HOME());
-    cc.load(TEST_HOME(), new File(TEST_HOME(), "solr-shardhandler.properties"));
-    ShardHandlerFactory factory = cc.getShardHandlerFactory();
-    assertTrue(factory instanceof MockShardHandlerFactory);
-    NamedList args = ((MockShardHandlerFactory)factory).args;
-    assertEquals("myMagicRequiredValue", args.get("myMagicRequiredParameter"));
-    factory.close();
-    cc.shutdown();
-  }
 }

Modified: lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java (original)
+++ lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java Mon Apr  1 22:04:32 2013
@@ -57,6 +57,8 @@ public class CoreAdminRequest extends So
     private String shardId;
     private String roles;
     private String coreNodeName;
+    private Boolean loadOnStartup;
+    private Boolean isTransient;
 
     public Create() {
       action = CoreAdminAction.CREATE;
@@ -72,7 +74,9 @@ public class CoreAdminRequest extends So
     public void setShardId(String shardId) {this.shardId = shardId;}
     public void setRoles(String roles) {this.roles = roles;}
     public void setCoreNodeName(String coreNodeName) {this.coreNodeName = coreNodeName;}
-    
+    public void setIsTransient(Boolean isTransient) { this.isTransient = isTransient; }
+    public void setIsLoadOnStartup(Boolean loadOnStartup) { this.loadOnStartup = loadOnStartup;}
+
     public String getInstanceDir() { return instanceDir; }
     public String getSchemaName()  { return schemaName; }
     public String getConfigName()  { return configName; }
@@ -82,7 +86,9 @@ public class CoreAdminRequest extends So
     public String getShardId() { return shardId; }
     public String getRoles() { return roles; }
     public String getCoreNodeName() { return coreNodeName; }
-    
+    public Boolean getIsLoadOnStartup() { return loadOnStartup; }
+    public Boolean getIsTransient() { return isTransient; }
+
     @Override
     public SolrParams getParams() {
       if( action == null ) {
@@ -123,6 +129,14 @@ public class CoreAdminRequest extends So
       if (coreNodeName != null) {
         params.set( CoreAdminParams.CORE_NODE_NAME, coreNodeName);
       }
+
+      if (isTransient != null) {
+        params.set(CoreAdminParams.TRANSIENT, isTransient);
+      }
+
+      if (loadOnStartup != null) {
+        params.set(CoreAdminParams.LOAD_ON_STARTUP, loadOnStartup);
+      }
       return params;
     }
 
@@ -151,11 +165,11 @@ public class CoreAdminRequest extends So
     public String getCoreNodeName() {
       return coreNodeName;
     }
-    
+
     public void setCoreNodeName(String coreNodeName) {
       this.coreNodeName = coreNodeName;
     }
-    
+
     public String getState() {
       return state;
     }

Modified: lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java (original)
+++ lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java Mon Apr  1 22:04:32 2013
@@ -88,6 +88,9 @@ public interface CoreAdminParams 
 
   public static final String DELETE_INSTANCE_DIR = "deleteInstanceDir";
 
+  public static final String LOAD_ON_STARTUP = "loadOnStartup";
+  
+  public static final String TRANSIENT = "transient";
 
   public enum CoreAdminAction {
     STATUS,  
@@ -104,7 +107,9 @@ public interface CoreAdminParams 
     REQUESTRECOVERY, 
     REQUESTSYNCSHARD,
     CREATEALIAS,
-    DELETEALIAS;
+    DELETEALIAS,
+    LOAD_ON_STARTUP,
+    TRANSIENT;
     
     public static CoreAdminAction get( String p )
     {

Modified: lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java?rev=1463316&r1=1463315&r2=1463316&view=diff
==============================================================================
--- lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java (original)
+++ lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java Mon Apr  1 22:04:32 2013
@@ -83,13 +83,29 @@ public class TestCoreAdmin extends Abstr
     req.setInstanceDir(newCoreInstanceDir.getAbsolutePath() + File.separator + "newcore");
     req.setDataDir(dataDir.getAbsolutePath());
     req.setUlogDir(new File(dataDir, "ulog").getAbsolutePath());
+
+    // These should be the inverse of defaults.
+    req.setIsLoadOnStartup(false);
+    req.setIsTransient(true);
     req.process(server);
-    
+
+    // Show that the newly-created core has values for load on startup and transient different than defaults due to the
+    // above.
+
+    SolrCore coreProveIt = cores.getCore("collection1");
     SolrCore core = cores.getCore("newcore");
+
+    assertTrue(core.getCoreDescriptor().isTransient());
+    assertFalse(coreProveIt.getCoreDescriptor().isTransient());
+
+    assertFalse(core.getCoreDescriptor().isLoadOnStartup());
+    assertTrue(coreProveIt.getCoreDescriptor().isLoadOnStartup());
+
     File logDir;
     try {
       logDir = core.getUpdateHandler().getUpdateLog().getLogDir();
     } finally {
+      coreProveIt.close();
       core.close();
     }
     assertEquals(new File(dataDir, "ulog" + File.separator + "tlog").getAbsolutePath(), logDir.getAbsolutePath());