lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mikemcc...@apache.org
Subject svn commit: r1700800 [17/24] - in /lucene/dev/branches/lucene6699: ./ dev-tools/ dev-tools/eclipse/ dev-tools/idea/.idea/ dev-tools/scripts/ lucene/ lucene/analysis/ lucene/analysis/common/ lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/...
Date Wed, 02 Sep 2015 13:06:22 GMT
Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java Wed Sep  2 13:06:13 2015
@@ -21,8 +21,8 @@ import java.io.Closeable;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -120,7 +120,7 @@ public class ZkStateReader implements Cl
   private final ConcurrentHashMap<String, DocCollection> watchedCollectionStates = new ConcurrentHashMap<String, DocCollection>();
 
   /** Collections with format2 state.json, not "interesting" and not actively watched. */
-  private volatile Map<String, ClusterState.CollectionRef> lazyCollectionStates = new HashMap<>();
+  private final ConcurrentHashMap<String, LazyCollectionRef> lazyCollectionStates = new ConcurrentHashMap<String, LazyCollectionRef>();
 
   private volatile Set<String> liveNodes = emptySet();
 
@@ -254,11 +254,13 @@ public class ZkStateReader implements Cl
       }
       // No need to set watchers because we should already have watchers registered for everything.
       refreshLegacyClusterState(null);
-      for (String coll : watchedCollectionStates.keySet()) {
+      // Need a copy so we don't delete from what we're iterating over.
+      Collection<String> safeCopy = new ArrayList<>(watchedCollectionStates.keySet());
+      for (String coll : safeCopy) {
         DocCollection newState = fetchCollectionState(coll, null);
         updateWatchedCollection(coll, newState);
       }
-      refreshLazyFormat2Collections(true);
+      refreshCollectionList(null);
       refreshLiveNodes(null);
       constructState();
     }
@@ -310,7 +312,7 @@ public class ZkStateReader implements Cl
     // on reconnect of SolrZkClient force refresh and re-add watches.
     refreshLegacyClusterState(new LegacyClusterStateWatcher());
     refreshStateFormat2Collections();
-    refreshLazyFormat2Collections(true);
+    refreshCollectionList(new CollectionsChildWatcher());
     refreshLiveNodes(new LiveNodeWatcher());
 
     synchronized (ZkStateReader.this.getUpdateLock()) {
@@ -372,6 +374,7 @@ public class ZkStateReader implements Cl
           securityNodeListener.run();
         }
       });
+      securityData = getSecurityProps(true);
     }
   }
 
@@ -445,11 +448,18 @@ public class ZkStateReader implements Cl
     }
 
     // Finally, add any lazy collections that aren't already accounted for.
-    for (Map.Entry<String, ClusterState.CollectionRef> entry : lazyCollectionStates.entrySet()) {
+    for (Map.Entry<String, LazyCollectionRef> entry : lazyCollectionStates.entrySet()) {
       result.putIfAbsent(entry.getKey(), entry.getValue());
     }
 
     this.clusterState = new ClusterState(liveNodes, result, legacyClusterStateVersion);
+    log.debug("clusterStateSet: version {} legacy {} interesting {} watched {} lazy {} total {}",
+        clusterState.getZkClusterStateVersion(),
+        legacyCollectionStates.keySet(),
+        interestingCollections,
+        watchedCollectionStates.keySet(),
+        lazyCollectionStates.keySet(),
+        clusterState.getCollections());
   }
 
   /**
@@ -486,78 +496,69 @@ public class ZkStateReader implements Cl
 
   /**
    * Search for any lazy-loadable state format2 collections.
+   *
+   * A stateFormat=1 collection which is not interesting to us can also
+   * be put into the {@link #lazyCollectionStates} map here. But that is okay
+   * because {@link #constructState()} will give priority to collections in the
+   * shared collection state over this map.
+   * In fact this is a clever way to avoid doing a ZK exists check on
+   * the /collections/collection_name/state.json znode
+   * Such an exists check is done in {@link ClusterState#hasCollection(String)} and
+   * {@link ClusterState#getCollections()} method as a safeguard against exposing wrong collection names to the users
    */
-  private void refreshLazyFormat2Collections(boolean fullRefresh) throws KeeperException, InterruptedException {
+  private void refreshCollectionList(Watcher watcher) throws KeeperException, InterruptedException {
     List<String> children = null;
     try {
-      children = zkClient.getChildren(COLLECTIONS_ZKNODE, null, true);
+      children = zkClient.getChildren(COLLECTIONS_ZKNODE, watcher, true);
     } catch (KeeperException.NoNodeException e) {
       log.warn("Error fetching collection names");
       // fall through
     }
     if (children == null || children.isEmpty()) {
-      synchronized (getUpdateLock()) {
-        this.lazyCollectionStates = new HashMap<>();
-      }
+      lazyCollectionStates.clear();
       return;
     }
 
-    Map<String, ClusterState.CollectionRef> result = new HashMap<>();
-    for (String collName : children) {
-      if (interestingCollections.contains(collName)) {
-        // We will create an eager collection for any interesting collections.
-        continue;
-      }
+    // Don't mess with watchedCollections, they should self-manage.
 
-      if (!fullRefresh) {
-        // Try to use an already-created lazy collection if it's not a full refresh.
-        ClusterState.CollectionRef existing = lazyCollectionStates.get(collName);
-        if (existing != null) {
-          result.put(collName, existing);
-          continue;
+    // First, drop any children that disappeared.
+    this.lazyCollectionStates.keySet().retainAll(children);
+    for (String coll : children) {
+      // We will create an eager collection for any interesting collections, so don't add to lazy.
+      if (!interestingCollections.contains(coll)) {
+        // Double check contains just to avoid allocating an object.
+        LazyCollectionRef existing = lazyCollectionStates.get(coll);
+        if (existing == null) {
+          lazyCollectionStates.putIfAbsent(coll, new LazyCollectionRef(coll));
         }
       }
-
-      ClusterState.CollectionRef lazyCollectionState = tryMakeLazyCollectionStateFormat2(collName);
-      if (lazyCollectionState != null) {
-        result.put(collName, lazyCollectionState);
-      }
-    }
-
-    synchronized (getUpdateLock()) {
-      this.lazyCollectionStates = result;
     }
   }
 
-  private ClusterState.CollectionRef tryMakeLazyCollectionStateFormat2(final String collName) {
-    boolean exists = false;
-    try {
-      exists = zkClient.exists(getCollectionPath(collName), true);
-    } catch (Exception e) {
-      log.warn("Error reading collections nodes", e);
-    }
-    if (!exists) {
-      return null;
+  private class LazyCollectionRef extends ClusterState.CollectionRef {
+
+    private final String collName;
+
+    public LazyCollectionRef(String collName) {
+      super(null);
+      this.collName = collName;
     }
 
-    // if it is not collection, then just create a reference which can fetch
-    // the collection object just in time from ZK
-    return new ClusterState.CollectionRef(null) {
-      @Override
-      public DocCollection get() {
-        return getCollectionLive(ZkStateReader.this, collName);
-      }
+    @Override
+    public DocCollection get() {
+      // TODO: consider limited caching
+      return getCollectionLive(ZkStateReader.this, collName);
+    }
 
-      @Override
-      public boolean isLazilyLoaded() {
-        return true;
-      }
+    @Override
+    public boolean isLazilyLoaded() {
+      return true;
+    }
 
-      @Override
-      public String toString() {
-        return "lazy DocCollection(" + collName + ")";
-      }
-    };
+    @Override
+    public String toString() {
+      return "LazyCollectionRef(" + collName + ")";
+    }
   }
 
   /**
@@ -643,7 +644,7 @@ public class ZkStateReader implements Cl
   public static String getShardLeadersPath(String collection, String shardId) {
     return COLLECTIONS_ZKNODE + "/" + collection + "/"
         + SHARD_LEADERS_ZKNODE + (shardId != null ? ("/" + shardId)
-        : "");
+        : "") + "/leader";
   }
 
   /**
@@ -916,9 +917,6 @@ public class ZkStateReader implements Cl
     public void refreshAndWatch() {
       try {
         refreshLegacyClusterState(this);
-        // Changes to clusterstate.json signal global state changes.
-        // TODO: get rid of clusterstate.json as a signaling mechanism.
-        refreshLazyFormat2Collections(false);
       } catch (KeeperException.NoNodeException e) {
         throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE,
                 "Cannot connect to cluster at " + zkClient.getZkServerAddress() + ": cluster not found/not ready");
@@ -939,6 +937,44 @@ public class ZkStateReader implements Cl
     }
   }
 
+  /** Watches /collections children . */
+  class CollectionsChildWatcher implements Watcher {
+
+    @Override
+    public void process(WatchedEvent event) {
+      // session events are not change events,
+      // and do not remove the watcher
+      if (EventType.None.equals(event.getType())) {
+        return;
+      }
+      log.info("A collections change: {}, has occurred - updating...", (event));
+      refreshAndWatch();
+      synchronized (getUpdateLock()) {
+        constructState();
+      }
+    }
+
+    /** Must hold {@link #getUpdateLock()} before calling this method. */
+    public void refreshAndWatch() {
+      try {
+        refreshCollectionList(this);
+      } catch (KeeperException e) {
+        if (e.code() == KeeperException.Code.SESSIONEXPIRED
+            || e.code() == KeeperException.Code.CONNECTIONLOSS) {
+          log.warn("ZooKeeper watch triggered, but Solr cannot talk to ZK");
+          return;
+        }
+        log.error("", e);
+        throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
+            "", e);
+      } catch (InterruptedException e) {
+        // Restore the interrupted status
+        Thread.currentThread().interrupt();
+        log.warn("", e);
+      }
+    }
+  }
+
   /** Watches the live_nodes and syncs changes. */
   class LiveNodeWatcher implements Watcher {
 
@@ -953,7 +989,6 @@ public class ZkStateReader implements Cl
       refreshAndWatch();
     }
 
-    /** Must hold {@link #getUpdateLock()} before calling this method. */
     public void refreshAndWatch() {
       try {
         refreshLiveNodes(this);
@@ -1023,35 +1058,43 @@ public class ZkStateReader implements Cl
       return;
     }
 
-    log.info("Updating data for {} to ver {} ", coll, newState.getZNodeVersion());
     // CAS update loop
     while (true) {
+      if (!interestingCollections.contains(coll)) {
+        break;
+      }
       DocCollection oldState = watchedCollectionStates.get(coll);
       if (oldState == null) {
         if (watchedCollectionStates.putIfAbsent(coll, newState) == null) {
+          log.info("Add data for {} ver {} ", coll, newState.getZNodeVersion());
           break;
         }
       } else {
         if (oldState.getZNodeVersion() >= newState.getZNodeVersion()) {
           // Nothing to do, someone else updated same or newer.
-          return;
+          break;
         }
         if (watchedCollectionStates.replace(coll, oldState, newState)) {
+          log.info("Updating data for {} from {} to {} ", coll, oldState.getZNodeVersion(), newState.getZNodeVersion());
           break;
         }
       }
     }
+
+    // Resolve race with removeZKWatch.
+    if (!interestingCollections.contains(coll)) {
+      watchedCollectionStates.remove(coll);
+      log.info("Removing uninteresting collection {}", coll);
+    }
   }
   
   /** This is not a public API. Only used by ZkController */
   public void removeZKWatch(String coll) {
+    log.info("Removing watch for uninteresting collection {}", coll);
     interestingCollections.remove(coll);
     watchedCollectionStates.remove(coll);
-    ClusterState.CollectionRef lazyCollectionStateFormat2 = tryMakeLazyCollectionStateFormat2(coll);
+    lazyCollectionStates.put(coll, new LazyCollectionRef(coll));
     synchronized (getUpdateLock()) {
-      if (lazyCollectionStateFormat2 != null) {
-        this.lazyCollectionStates.put(coll, lazyCollectionStateFormat2);
-      }
       constructState();
     }
   }

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java Wed Sep  2 13:06:13 2015
@@ -163,6 +163,12 @@ public interface CommonParams {
 
   /** include header in the response */
   public static final String OMIT_HEADER = "omitHeader";
+  public static final String CORES_HANDLER_PATH = "/admin/cores";
+  public static final String COLLECTIONS_HANDLER_PATH = "/admin/collections";
+  public static final String INFO_HANDLER_PATH = "/admin/info";
+  public static final String CONFIGSETS_HANDLER_PATH = "/admin/configs";
+  public static final String AUTHZ_PATH = "/admin/authorization";
+  public static final String AUTHC_PATH = "/admin/authentication";
 
   /** valid values for: <code>echoParams</code> */
   public enum EchoParamStyle {

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/params/SolrParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/params/SolrParams.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/params/SolrParams.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/params/SolrParams.java Wed Sep  2 13:06:13 2015
@@ -316,6 +316,13 @@ public abstract class SolrParams impleme
       Object val = params.getVal(i);
       if (val instanceof String[]) {
         MultiMapSolrParams.addParam(name, (String[]) val, map);
+      } else if (val instanceof List) {
+        List l = (List) val;
+        String[] s = new String[l.size()];
+        for (int j = 0; j < l.size(); j++) {
+          s[j] = l.get(j) == null ? null : String.valueOf(l.get(j));
+        }
+        MultiMapSolrParams.addParam(name, s, map);
       } else {
         MultiMapSolrParams.addParam(name, val.toString(), map);
       }

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java Wed Sep  2 13:06:13 2015
@@ -78,22 +78,43 @@ public class ExecutorUtil {
     public void clean(AtomicReference<?> ctx);
   }
 
-  // this will interrupt the threads! Lucene and Solr do not like this because it can close channels, so only use
-  // this if you know what you are doing - you probably want shutdownAndAwaitTermination
-  public static void shutdownNowAndAwaitTermination(ExecutorService pool) {
+  // ** This will interrupt the threads! ** Lucene and Solr do not like this because it can close channels, so only use
+  // this if you know what you are doing - you probably want shutdownAndAwaitTermination.
+  // Marked as Deprecated to discourage use.
+  @Deprecated
+  public static void shutdownWithInterruptAndAwaitTermination(ExecutorService pool) {
+    pool.shutdownNow(); // Cancel currently executing tasks - NOTE: this interrupts!
+    boolean shutdown = false;
+    while (!shutdown) {
+      try {
+        // Wait a while for existing tasks to terminate
+        shutdown = pool.awaitTermination(60, TimeUnit.SECONDS);
+      } catch (InterruptedException ie) {
+        // Preserve interrupt status
+        Thread.currentThread().interrupt();
+      }
+    }
+  }
+  
+  // ** This will interrupt the threads! ** Lucene and Solr do not like this because it can close channels, so only use
+  // this if you know what you are doing - you probably want shutdownAndAwaitTermination.
+  // Marked as Deprecated to discourage use.
+  @Deprecated
+  public static void shutdownAndAwaitTerminationWithInterrupt(ExecutorService pool) {
     pool.shutdown(); // Disable new tasks from being submitted
-    pool.shutdownNow(); // Cancel currently executing tasks  - NOTE: this interrupts!
     boolean shutdown = false;
+    boolean interrupted = false;
     while (!shutdown) {
       try {
         // Wait a while for existing tasks to terminate
-        shutdown = pool.awaitTermination(1, TimeUnit.SECONDS);
+        shutdown = pool.awaitTermination(60, TimeUnit.SECONDS);
       } catch (InterruptedException ie) {
         // Preserve interrupt status
         Thread.currentThread().interrupt();
       }
-      if (!shutdown) {
+      if (!shutdown && !interrupted) {
         pool.shutdownNow(); // Cancel currently executing tasks - NOTE: this interrupts!
+        interrupted = true;
       }
     }
   }
@@ -104,7 +125,7 @@ public class ExecutorUtil {
     while (!shutdown) {
       try {
         // Wait a while for existing tasks to terminate
-        shutdown = pool.awaitTermination(1, TimeUnit.SECONDS);
+        shutdown = pool.awaitTermination(60, TimeUnit.SECONDS);
       } catch (InterruptedException ie) {
         // Preserve interrupt status
         Thread.currentThread().interrupt();

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java Wed Sep  2 13:06:13 2015
@@ -614,7 +614,7 @@ public class JavaBinCodec {
       return;
     }
     int end = s.length();
-    int maxSize = end * 4;
+    int maxSize = end * 3; // 3 is enough, see SOLR-7971
     if (bytes == null || bytes.length < maxSize) bytes = new byte[maxSize];
     int sz = ByteUtils.UTF16toUTF8(s, 0, end, bytes, 0);
 

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/RetryUtil.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/RetryUtil.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/RetryUtil.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/RetryUtil.java Wed Sep  2 13:06:13 2015
@@ -1,5 +1,8 @@
 package org.apache.solr.common.util;
 
+import java.util.Collections;
+import java.util.Set;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -19,18 +22,34 @@ package org.apache.solr.common.util;
 
 import java.util.concurrent.TimeUnit;
 
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class RetryUtil {
+  private static final Logger log = LoggerFactory.getLogger(RetryUtil.class);
+  
   public static interface RetryCmd {
     public void execute() throws Throwable;
   }
   
+  public static interface BooleanRetryCmd {
+    public boolean execute();
+  }
+  
   public static void retryOnThrowable(Class clazz, long timeoutms, long intervalms, RetryCmd cmd) throws Throwable {
+    retryOnThrowable(Collections.singleton(clazz), timeoutms, intervalms, cmd);
+  }
+  
+  public static void retryOnThrowable(Set<Class> classes, long timeoutms, long intervalms, RetryCmd cmd) throws Throwable {
     long timeout = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeoutms, TimeUnit.MILLISECONDS);
     while (true) {
       try {
         cmd.execute();
       } catch (Throwable t) {
-        if (clazz.isInstance(t) && System.nanoTime() < timeout) {
+        if (isInstanceOf(classes, t) && System.nanoTime() < timeout) {
+          log.info("Retry due to Throwable, " + t.getClass().getName() + " " + t.getMessage());
           Thread.sleep(intervalms);
           continue;
         }
@@ -40,4 +59,29 @@ public class RetryUtil {
       break;
     }
   }
+  
+  private static boolean isInstanceOf(Set<Class> classes, Throwable t) {
+    for (Class c : classes) {
+      if (c.isInstance(t)) {
+        return true;
+      }
+    }
+    return false;
+  }
+  
+  public static void retryOnBoolean(long timeoutms, long intervalms, BooleanRetryCmd cmd) {
+    long timeout = System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeoutms, TimeUnit.MILLISECONDS);
+    while (true) {
+      boolean resp = cmd.execute();
+      if (!resp && System.nanoTime() < timeout) {
+        continue;
+      } else if (System.nanoTime() >= timeout) {
+        throw new SolrException(ErrorCode.SERVER_ERROR, "Timed out while retrying operation");
+      }
+      
+      // success
+      break;
+    }
+  }
+  
 }

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/Utils.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/Utils.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/java/org/apache/solr/common/util/Utils.java Wed Sep  2 13:06:13 2015
@@ -84,7 +84,7 @@ public class Utils {
   }
 
   public static byte[] toUTF8(CharArr out) {
-    byte[] arr = new byte[out.size() << 2]; // is 4x the real worst-case upper-bound?
+    byte[] arr = new byte[out.size() * 3];
     int nBytes = ByteUtils.UTF16toUTF8(out, 0, out.size(), arr, 0);
     return Arrays.copyOf(arr, nBytes);
   }

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/test-files/solrj/docs2.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/test-files/solrj/docs2.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/test-files/solrj/docs2.xml (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/test-files/solrj/docs2.xml Wed Sep  2 13:06:13 2015
@@ -24,7 +24,7 @@
   <field name="manu_id_s">corsair</field>
   <field name="cat">electronics</field>
   <field name="cat">memory</field>
-  <field name="features">CAS latency 2,	2-3-3-6 timing, 2.75v, unbuffered, heat-spreader</field>
+  <field name="features">CAS latency 2,  2-3-3-6 timing, 2.75v, unbuffered, heat-spreader</field>
   <field name="price">185</field>
   <field name="popularity">5</field>
   <field name="inStock">true</field>
@@ -62,7 +62,7 @@
   <field name="manu_id_s">corsair</field>
   <field name="cat">electronics</field>
   <field name="cat">memory</field>
-  <field name="features">CAS latency 3,	 2.7v</field>
+  <field name="features">CAS latency 3,   2.7v</field>
   <!-- note: price & popularity is missing on this one -->
   <field name="popularity">0</field>
   <field name="inStock">true</field>

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/test-files/solrj/solr/collection1/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/test-files/solrj/solr/collection1/conf/schema.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/test-files/solrj/solr/collection1/conf/schema.xml (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/test-files/solrj/solr/collection1/conf/schema.xml Wed Sep  2 13:06:13 2015
@@ -430,7 +430,7 @@
    <field name="standardfilt" type="standardfilt" indexed="true" stored="true"/>
    <field name="lowerfilt" type="lowerfilt" indexed="true" stored="true"/>
    <field name="lowerfilt1" type="lowerfilt" indexed="true" stored="true"/>
-	 <field name="lowerfilt1and2" type="lowerfilt" indexed="true" stored="true"/>
+   <field name="lowerfilt1and2" type="lowerfilt" indexed="true" stored="true"/>
    <field name="patterntok" type="patterntok" indexed="true" stored="true"/>
    <field name="patternreplacefilt" type="patternreplacefilt" indexed="true" stored="true"/>
    <field name="porterfilt" type="porterfilt" indexed="true" stored="true"/>
@@ -549,15 +549,15 @@
    <copyField source="title" dest="title_lettertok"/>
 
    <copyField source="title" dest="text"/>
-	 <copyField source="subject" dest="text"/>
+   <copyField source="subject" dest="text"/>
 
-	 <copyField source="lowerfilt1" dest="lowerfilt1and2"/>
-	 <copyField source="lowerfilt" dest="lowerfilt1and2"/>
+   <copyField source="lowerfilt1" dest="lowerfilt1and2"/>
+   <copyField source="lowerfilt" dest="lowerfilt1and2"/>
 
-	 <copyField source="*_t" dest="text"/>
+   <copyField source="*_t" dest="text"/>
 
-	 <copyField source="id"            dest="range_facet_l"/>
-	 <copyField source="range_facet_f" dest="range_facet_d"/>
+   <copyField source="id"            dest="range_facet_l"/>
+   <copyField source="range_facet_f" dest="range_facet_d"/>
 
    <!-- dynamic destination -->
    <copyField source="*_dynamic" dest="dynamic_*"/>

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/JettyWebappTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/JettyWebappTest.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/JettyWebappTest.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/JettyWebappTest.java Wed Sep  2 13:06:13 2015
@@ -19,11 +19,17 @@ package org.apache.solr.client.solrj.emb
 
 import java.io.File;
 import java.net.URL;
+import java.util.Locale;
 import java.util.Random;
 
+import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
 import org.apache.commons.io.IOUtils;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.impl.client.HttpClients;
 import org.apache.solr.SolrJettyTestBase;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.util.ExternalPaths;
@@ -37,8 +43,6 @@ import org.junit.Rule;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
 
-import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
-
 /**
  *
  * @since solr 1.3
@@ -53,9 +57,9 @@ public class JettyWebappTest extends Sol
     RuleChain.outerRule(new SystemPropertiesRestoreRule());
 
   Server server;
-  
+
   @Override
-  public void setUp() throws Exception 
+  public void setUp() throws Exception
   {
     super.setUp();
     System.setProperty("solr.solr.home", SolrJettyTestBase.legacyExampleCollection1SolrHome());
@@ -84,7 +88,7 @@ public class JettyWebappTest extends Sol
   }
 
   @Override
-  public void tearDown() throws Exception 
+  public void tearDown() throws Exception
   {
     try {
       server.stop();
@@ -102,5 +106,13 @@ public class JettyWebappTest extends Sol
     String adminPath = "http://127.0.0.1:"+port+context+"/";
     byte[] bytes = IOUtils.toByteArray( new URL(adminPath).openStream() );
     assertNotNull( bytes ); // real error will be an exception
+
+    HttpClient client = HttpClients.createDefault();
+    HttpRequestBase m = new HttpGet(adminPath);
+    HttpResponse response = client.execute(m);
+    assertEquals(200, response.getStatusLine().getStatusCode());
+    Header header = response.getFirstHeader("X-Frame-Options");
+    assertEquals("DENY", header.getValue().toUpperCase(Locale.ROOT));
+    m.releaseConnection();
   }
 }

Modified: lucene/dev/branches/lucene6699/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClientUtilTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClientUtilTest.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClientUtilTest.java (original)
+++ lucene/dev/branches/lucene6699/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClientUtilTest.java Wed Sep  2 13:06:13 2015
@@ -18,11 +18,13 @@ package org.apache.solr.client.solrj.imp
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.http.auth.AuthScope;
+import org.apache.http.client.config.AuthSchemes;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.params.ClientPNames;
 import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
@@ -30,6 +32,7 @@ import org.apache.http.conn.ssl.BrowserC
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.conn.ssl.X509HostnameVerifier;
 import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.AbstractHttpClient;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.conn.PoolingClientConnectionManager;
 import org.apache.http.params.HttpConnectionParams;
@@ -73,7 +76,21 @@ public class HttpClientUtilTest {
       client.close();
     }
   }
-  
+
+  @Test
+  public void testAuthSchemeConfiguration() {
+    System.setProperty(Krb5HttpClientConfigurer.LOGIN_CONFIG_PROP, "test");
+    try {
+      HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());
+      AbstractHttpClient client = (AbstractHttpClient)HttpClientUtil.createClient(null);
+      assertEquals(1, client.getAuthSchemes().getSchemeNames().size());
+      assertTrue(AuthSchemes.SPNEGO.equalsIgnoreCase(client.getAuthSchemes().getSchemeNames().get(0)));
+    } finally {
+      //Cleanup the system property.
+      System.clearProperty(Krb5HttpClientConfigurer.LOGIN_CONFIG_PROP);
+    }
+  }
+
   @Test
   public void testReplaceConfigurer() throws IOException{
     

Modified: lucene/dev/branches/lucene6699/solr/test-framework/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/test-framework/build.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/test-framework/build.xml (original)
+++ lucene/dev/branches/lucene6699/solr/test-framework/build.xml Wed Sep  2 13:06:13 2015
@@ -63,19 +63,19 @@
     <sequential>
       <mkdir dir="${javadoc.dir}/${name}"/>
       <!-- NOTE: explicitly not using solr-invoke-javadoc, or attempting to 
-	   link to lucene-test-framework because if we did javadoc would 
-	   attempt to link class refs in in org.apache.lucene, causing 
-	   broken links. (either broken links to things like "Directory" if 
-	   lucene-test-framework was first, or broken links to things like 
-	   LuceneTestCase if lucene-core was first)
+     link to lucene-test-framework because if we did javadoc would 
+     attempt to link class refs in in org.apache.lucene, causing 
+     broken links. (either broken links to things like "Directory" if 
+     lucene-test-framework was first, or broken links to things like 
+     LuceneTestCase if lucene-core was first)
       -->
       <invoke-javadoc destdir="${javadoc.dir}/${name}" 
-		      title="${Name} ${version} Test Framework API">
-	<sources>
-	  <link offline="true" href="${javadoc.link.junit}"
-		packagelistLoc="${javadoc.packagelist.dir}/junit"/>
-	  <packageset dir="${src.dir}"/>
-	</sources>
+          title="${Name} ${version} Test Framework API">
+  <sources>
+    <link offline="true" href="${javadoc.link.junit}"
+    packagelistLoc="${javadoc.packagelist.dir}/junit"/>
+    <packageset dir="${src.dir}"/>
+  </sources>
       </invoke-javadoc>
       <solr-jarify basedir="${javadoc.dir}/${name}" destfile="${build.dir}/${final.name}-javadoc.jar"/>
     </sequential>
@@ -107,11 +107,11 @@
     <mkdir  dir="${dist}/test-framework" />
     <copy todir="${dist}/test-framework">
       <fileset dir="${build.dir}">
-	<include name="lucene-libs/*.jar" />
+  <include name="lucene-libs/*.jar" />
       </fileset>
       <fileset dir=".">
-	<include name="lib/*" />
-	<include name="README.txt" />
+  <include name="lib/*" />
+  <include name="README.txt" />
       </fileset>
     </copy>
   </target>

Modified: lucene/dev/branches/lucene6699/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java (original)
+++ lucene/dev/branches/lucene6699/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java Wed Sep  2 13:06:13 2015
@@ -64,6 +64,7 @@ public class MiniSolrCloudCluster {
   private static Logger log = LoggerFactory.getLogger(MiniSolrCloudCluster.class);
 
   private final ZkTestServer zkServer;
+  private final boolean externalZkServer;
   private final List<JettySolrRunner> jettys = new LinkedList<>();
   private final File testDir;
   private final CloudSolrClient solrClient;
@@ -125,15 +126,34 @@ public class MiniSolrCloudCluster {
    * @throws Exception if there was an error starting the cluster
    */
   public MiniSolrCloudCluster(int numServers, File baseDir, File solrXml, JettyConfig jettyConfig) throws Exception {
+    this(numServers, baseDir, solrXml, jettyConfig, null);
+  }
+
+  /**
+   * Create a MiniSolrCloudCluster
+   *
+   * @param numServers number of Solr servers to start
+   * @param baseDir base directory that the mini cluster should be run from
+   * @param solrXml solr.xml file to be uploaded to ZooKeeper
+   * @param jettyConfig Jetty configuration
+   * @param zkTestServer ZkTestServer to use.  If null, one will be created
+   *
+   * @throws Exception if there was an error starting the cluster
+   */
+  public MiniSolrCloudCluster(int numServers, File baseDir, File solrXml, JettyConfig jettyConfig, ZkTestServer zkTestServer) throws Exception {
 
     this.testDir = baseDir;
     this.jettyConfig = jettyConfig;
 
-    String zkDir = testDir.getAbsolutePath() + File.separator
-      + "zookeeper/server1/data";
-    zkServer = new ZkTestServer(zkDir);
-    zkServer.run();
-    
+    this.externalZkServer = zkTestServer != null;
+    if (!externalZkServer) {
+      String zkDir = testDir.getAbsolutePath() + File.separator
+        + "zookeeper/server1/data";
+      zkTestServer = new ZkTestServer(zkDir);
+      zkTestServer.run();
+    }
+    this.zkServer = zkTestServer;
+
     try(SolrZkClient zkClient = new SolrZkClient(zkServer.getZkHost(),
         AbstractZkTestCase.TIMEOUT, 45000, null)) {
       zkClient.makePath("/solr/solr.xml", solrXml, false, true);
@@ -375,7 +395,9 @@ public class MiniSolrCloudCluster {
       executor.shutdown();
       executor.awaitTermination(2, TimeUnit.SECONDS);
       try {
-        zkServer.shutdown();
+        if (!externalZkServer) {
+          zkServer.shutdown();
+        }
       } finally {
         System.clearProperty("zkHost");
       }

Modified: lucene/dev/branches/lucene6699/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java (original)
+++ lucene/dev/branches/lucene6699/solr/test-framework/src/java/org/apache/solr/cloud/ZkTestServer.java Wed Sep  2 13:06:13 2015
@@ -448,6 +448,14 @@ public class ZkTestServer {
     });
   }
 
+  public ZKDatabase getZKDatabase() {
+    return zkServer.zooKeeperServer.getZKDatabase();
+  }
+
+  public void setZKDatabase(ZKDatabase zkDb) {
+    zkServer.zooKeeperServer.setZKDatabase(zkDb);
+  }
+
   public void run() throws InterruptedException {
     log.info("STARTING ZK TEST SERVER");
     // we don't call super.distribSetUp

Modified: lucene/dev/branches/lucene6699/solr/webapp/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/build.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/build.xml (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/build.xml Wed Sep  2 13:06:13 2015
@@ -24,7 +24,7 @@
   <import file="../common-build.xml"/>
 
   <property name="exclude.from.webapp" value="*slf4j*,log4j-*,*javax.servlet*" />
-	
+  
   <!-- this module has no javadocs -->
   <target name="javadocs"/>
 

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/WEB-INF/weblogic.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/WEB-INF/weblogic.xml?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/WEB-INF/weblogic.xml (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/WEB-INF/weblogic.xml Wed Sep  2 13:06:13 2015
@@ -21,7 +21,7 @@
     xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
 
     <container-descriptor>
-	<filter-dispatched-requests-enabled>false</filter-dispatched-requests-enabled>
+      <filter-dispatched-requests-enabled>false</filter-dispatched-requests-enabled>
     </container-descriptor>
 
 </weblogic-web-app>

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/css/angular/menu.css
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/css/angular/menu.css?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/css/angular/menu.css (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/css/angular/menu.css Wed Sep  2 13:06:13 2015
@@ -43,29 +43,33 @@ limitations under the License.
   text-overflow: ellipsis;
 }
 
-#core-selector
+#core-selector,#collection-selector
 {
   margin-top: 20px;
   padding-right: 10px;
 }
 
-#core-selector a
+#core-selector a,
+#collection-selector a
 {
   padding: 0;
   padding-left: 8px;
 }
 
-#core-selector select
+#core-selector select,
+#collection-selector select
 {
   width: 100%;
 }
 
-#core-selector #has-no-cores a
+#core-selector #has-no-cores a,
+#collection-selector #has-no-collections a
 {
   background-image: url( ../../img/ico/database--plus.png );
 }
 
-#core-selector #has-no-cores span
+#core-selector #has-no-cores span,
+#collection-selector #has-no-collections span
 {
   color: #c0c0c0;
   display: block;
@@ -172,34 +176,34 @@ limitations under the License.
 {
 }
 
-#core-menu p
+.sub-menu p
 {
   border-top: 1px solid #f0f0f0;
 }
 
-#core-menu li:first-child p
+.sub-menu li:first-child p
 {
   border-top: 0;
 }
 
-#core-menu p a
+.sub-menu p a
 {
   background-image: url( ../../img/ico/status-offline.png );
 }
 
-#core-menu .active p a
+.sub-menu .active p a
 {
   background-image: url( ../../img/ico/box.png );
 }
 
-#core-menu ul,
+.sub-menu ul,
 #menu ul
 {
   padding-top: 5px;
   padding-bottom: 10px;
 }
 
-#core-menu .active ul,
+.sub-menu .active ul,
 #menu .active ul
 {
   display: block;
@@ -211,6 +215,7 @@ limitations under the License.
 }
 
 #core-menu ul li a,
+#collection-menu ul li a,
 #menu ul li a
 {
   background-position: 7px 50%;
@@ -220,20 +225,20 @@ limitations under the License.
   padding-left: 26px;
 }
 
-#core-menu ul li:last-child a,
+.sub-menu ul li:last-child a,
 #menu ul li:last-child a
 {
   border-bottom: 0;
 }
 
-#core-menu ul li a:hover,
+.sub-menu ul li a:hover,
 #menu ul li a:hover
 {
   background-color: #f0f0f0;
   color: #333;
 }
 
-#core-menu ul li.active a,
+.sub-menu ul li.active a,
 #menu ul li.active a
 {
   background-color: #d0d0d0;
@@ -258,7 +263,7 @@ limitations under the License.
 #menu #cloud.global .rgraph a { background-image: url( ../../img/ico/asterisk.png ); }
 #menu #cloud.global .dump a { background-image: url( ../../img/ico/download-cloud.png ); }
 
-#core-menu .ping.error a
+.sub-menu .ping.error a
 {
   
   background-color: #ffcccc;
@@ -267,19 +272,19 @@ limitations under the License.
   cursor: help;
 }
 
-#core-menu .overview a { background-image: url( ../../img/ico/home.png ); }
-#core-menu .query a { background-image: url( ../../img/ico/magnifier.png ); }
-#core-menu .analysis a { background-image: url( ../../img/ico/funnel.png ); }
-#core-menu .documents a { background-image: url( ../../img/ico/documents-stack.png ); }
-#core-menu .files a { background-image: url( ../../img/ico/folder.png ); }
-#core-menu .schema-browser a { background-image: url( ../../img/ico/book-open-text.png ); }
-#core-menu .replication a { background-image: url( ../../img/ico/node.png ); }
-#core-menu .distribution a { background-image: url( ../../img/ico/node-select.png ); }
-#core-menu .ping a { background-image: url( ../../img/ico/system-monitor.png ); }
-#core-menu .logging a { background-image: url( ../../img/ico/inbox-document-text.png ); }
-#core-menu .plugins a { background-image: url( ../../img/ico/block.png ); }
-#core-menu .dataimport a { background-image: url( ../../img/ico/document-import.png ); }
-#core-menu .segments a { background-image: url( ../../img/ico/construction.png ); }
+.sub-menu .overview a { background-image: url( ../../img/ico/home.png ); }
+.sub-menu .query a { background-image: url( ../../img/ico/magnifier.png ); }
+.sub-menu .analysis a { background-image: url( ../../img/ico/funnel.png ); }
+.sub-menu .documents a { background-image: url( ../../img/ico/documents-stack.png ); }
+.sub-menu .files a { background-image: url( ../../img/ico/folder.png ); }
+.sub-menu .schema-browser a { background-image: url( ../../img/ico/book-open-text.png ); }
+.sub-menu .replication a { background-image: url( ../../img/ico/node.png ); }
+.sub-menu .distribution a { background-image: url( ../../img/ico/node-select.png ); }
+.sub-menu .ping a { background-image: url( ../../img/ico/system-monitor.png ); }
+.sub-menu .logging a { background-image: url( ../../img/ico/inbox-document-text.png ); }
+.sub-menu .plugins a { background-image: url( ../../img/ico/block.png ); }
+.sub-menu .dataimport a { background-image: url( ../../img/ico/document-import.png ); }
+.sub-menu .segments a { background-image: url( ../../img/ico/construction.png ); }
 
 
 #content #navigation

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/css/angular/segments.css
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/css/angular/segments.css?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/css/angular/segments.css (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/css/angular/segments.css Wed Sep  2 13:06:13 2015
@@ -52,7 +52,7 @@ limitations under the License.
 
 #content #segments #result #response
 {
-	margin-left: 25px;
+  margin-left: 25px;
 }
 
 #content #segments .segments-holder ul {
@@ -65,7 +65,7 @@ limitations under the License.
 }
 
 #content #segments .segments-holder li .tooltip {
-	display: none;
+  display: none;
     background: #C8C8C8;
     position: absolute;
     z-index: 1000;
@@ -79,13 +79,13 @@ limitations under the License.
 }
 
 #content #segments .segments-holder li .tooltip .label {
-	float: left;
-	width: 20%;	
-	opacity: 1;
+  float: left;
+  width: 20%;  
+  opacity: 1;
 }
 
 #content #segments .segments-holder li:hover .tooltip {
-	display:block;	
+  display:block;  
 }
 
 #content #segments .segments-holder li dl, 
@@ -122,26 +122,26 @@ limitations under the License.
 }
 
 #content #segments .segments-holder li dd div.live {
-	background-color: #DDDDDD;
-	float: left;	
+  background-color: #DDDDDD;
+  float: left;  
 }
 
 #content #segments .segments-holder li dd div.start {
-	float: left;
-	width: 20%;
+  float: left;
+  width: 20%;
 }
 
 #content #segments .segments-holder li dd div.end {
-	text-align: right;
+  text-align: right;
 }
 
 .merge-candidate {
-	background-color: #FFC9F9 !important;
+  background-color: #FFC9F9 !important;
 }
 
 #content #segments .segments-holder li dd div.w5 {
-	width: 20%;
-	float: left;
+  width: 20%;
+  float: left;
 }
 
 #content #segments #auto-refresh {

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/css/chosen.css
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/css/chosen.css?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/css/chosen.css (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/css/chosen.css Wed Sep  2 13:06:13 2015
@@ -81,7 +81,7 @@ THE SOFTWARE.
   text-decoration: none;
 }
 .chzn-container-single .chzn-default {
-	color: #999;
+  color: #999;
 }
 .chzn-container-single .chzn-single span {
   margin-right: 26px;

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/css/styles/segments.css
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/css/styles/segments.css?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/css/styles/segments.css (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/css/styles/segments.css Wed Sep  2 13:06:13 2015
@@ -52,7 +52,7 @@ limitations under the License.
 
 #content #segments #result #response
 {
-	margin-left: 25px;
+  margin-left: 25px;
 }
 
 #content #segments .segments-holder ul {
@@ -65,7 +65,7 @@ limitations under the License.
 }
 
 #content #segments .segments-holder li .toolitp {
-	display: none;
+  display: none;
     background: #C8C8C8;
     position: absolute;
     z-index: 1000;
@@ -79,13 +79,13 @@ limitations under the License.
 }
 
 #content #segments .segments-holder li .toolitp .label {
-	float: left;
-	width: 20%;	
-	opacity: 1;
+  float: left;
+  width: 20%;  
+  opacity: 1;
 }
 
 #content #segments .segments-holder li:hover .toolitp {
-	display:block;	
+  display:block;  
 }
 
 #content #segments .segments-holder li dl, 
@@ -122,24 +122,24 @@ limitations under the License.
 }
 
 #content #segments .segments-holder li dd div.live {
-	background-color: #DDDDDD;
-	float: left;	
+  background-color: #DDDDDD;
+  float: left;  
 }
 
 #content #segments .segments-holder li dd div.start {
-	float: left;
-	width: 20%;
+  float: left;
+  width: 20%;
 }
 
 #content #segments .segments-holder li dd div.end {
-	text-align: right;
+  text-align: right;
 }
 
 .merge-candidate {
-	background-color: #FFC9F9 !important;
+  background-color: #FFC9F9 !important;
 }
 
 #content #segments .segments-holder li dd div.w5 {
-	width: 20%;
-	float: left;
+  width: 20%;
+  float: left;
 }
\ No newline at end of file

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/index.html
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/index.html?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/index.html (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/index.html Wed Sep  2 13:06:13 2015
@@ -27,7 +27,7 @@ limitations under the License.
   <link rel="stylesheet" type="text/css" href="css/angular/analysis.css?_=${version}">
   <link rel="stylesheet" type="text/css" href="css/angular/cloud.css?_=${version}">
   <link rel="stylesheet" type="text/css" href="css/angular/cores.css?_=${version}">
-  <link rel="stylesheet" type="text/css" href="css/styles/dashboard.css?_=${version}">
+  <link rel="stylesheet" type="text/css" href="css/angular/dashboard.css?_=${version}">
   <link rel="stylesheet" type="text/css" href="css/angular/dataimport.css?_=${version}">
   <link rel="stylesheet" type="text/css" href="css/angular/files.css?_=${version}">
   <link rel="stylesheet" type="text/css" href="css/angular/index.css?_=${version}">
@@ -64,6 +64,7 @@ limitations under the License.
   <script src="js/angular/controllers/threads.js"></script>
   <script src="js/angular/controllers/java-properties.js"></script>
   <script src="js/angular/controllers/core-overview.js"></script>
+  <script src="js/angular/controllers/collection-overview.js"></script>
   <script src="js/angular/controllers/analysis.js"></script>
   <script src="js/angular/controllers/dataimport.js"></script>
   <script src="js/angular/controllers/documents.js"></script>
@@ -107,16 +108,16 @@ limitations under the License.
           <h2>Connection to Solr lost</h2>
           <p>Please check the Solr instance.</p>
         </div>
-	<div class="connection-status header-message" id="connection-status-recovered"  ng-show="connectionRecovered">
-	  <h2>Connection recovered...</h2>
-	  <p>Continuing to load data...</p>
-	</div>
+  <div class="connection-status header-message" id="connection-status-recovered"  ng-show="connectionRecovered">
+    <h2>Connection recovered...</h2>
+    <p>Continuing to load data...</p>
+  </div>
       </div>
 
       <div id="http-exception" class="header-message" ng-show="exception">
         <h2>Exception</h2>
-	<p>{{exception}}</p>
-	<a ng-click="hideException()">hide exception</a>
+  <p>{{exception}}</p>
+  <a ng-click="hideException()">hide exception</a>
       </div>
 
       <div id="content-wrapper">
@@ -155,11 +156,36 @@ limitations under the License.
 
           </ul>
 
+          <div id="collection-selector" ng-show="isCloudEnabled">
+            <div id="has-collections" ng-show="collections.length!=0">
+              <select data-placeholder="Collection Selector"
+                      ng-model="currentCollection"
+                      chosen
+                      ng-change="showCollection(currentCollection)"
+                      ng-options="collection.name for collection in collections"></select>
+            </div>
+            <p id="has-no-collections" ng-show="collections.length==0"><a href="#/~collections">
+              No collections available
+              <span>Go and create one</span>
+            </a></p>
+          </div>
+          <div id="collection-menu" class="sub-menu" ng-show="currentCollection">
+            <ul>
+              <li class="overview" ng-class="{active:page=='collection-overview'}"><a href="#/{{currentCore.name}}/collection-overview"><span>Overview</span></a></li>
+              <li class="analysis" ng-class="{active:page=='analysis'}"><a href="#/{{currentCollection.name}}/analysis"><span>Analysis</span></a></li>
+              <li class="dataimport" ng-class="{active:page=='dataimport'}"><a href="#/{{currentCollection.name}}/dataimport"><span>Dataimport</span></a></li>
+              <li class="documents" ng-class="{active:page=='documents'}"><a href="#/{{currentCollection.name}}/documents"><span>Documents</span></a></li>
+              <li class="files" ng-class="{active:page=='files'}"><a href="#/{{currentCollection.name}}/files"><span>Files</span></a></li>
+              <li class="query" ng-class="{active:page=='query'}"><a href="#/{{currentCollection.name}}/query"><span>Query</span></a></li>
+              <li class="schema-browser" ng-class="{active:page=='schema-browser'}"><a href="#/{{currentCollection.name}}/schema-browser"><span>Schema Browser</span></a></li>
+        </ul>
+          </div>
           <div id="core-selector">
             <div id="has-cores" ng-show="cores.length!=0">
               <select data-placeholder="Core Selector"
                       ng-model="currentCore"
                       chosen
+                      ng-change="showCore(currentCore)"
                       ng-options="core.name for core in cores"></select>
             </div>
             <p id="has-no-cores" ng-show="cores.length==0"><a href="#/~cores">
@@ -167,20 +193,20 @@ limitations under the License.
               <span>Go and create one</span>
             </a></p>
           </div>
-          <div id="core-menu" ng-show="currentCore">
+          <div id="core-menu" class="sub-menu" ng-show="currentCore">
             <ul>
               <li class="overview" ng-class="{active:page=='overview'}"><a href="#/{{currentCore.name}}"><span>Overview</span></a></li>
-              <li class="analysis" ng-class="{active:page=='analysis'}"><a href="#/{{currentCore.name}}/analysis"><span>Analysis</span></a></li>
-              <li class="dataimport" ng-class="{active:page=='dataimport'}"><a href="#/{{currentCore.name}}/dataimport"><span>Dataimport</span></a></li>
-              <li class="documents" ng-class="{active:page=='documents'}"><a href="#/{{currentCore.name}}/documents"><span>Documents</span></a></li>
-              <li class="files" ng-class="{active:page=='files'}"><a href="#/{{currentCore.name}}/files"><span>Files</span></a></li>
+              <li ng-hide="isCloudEnabled" class="analysis" ng-class="{active:page=='analysis'}"><a href="#/{{currentCore.name}}/analysis"><span>Analysis</span></a></li>
+              <li ng-hide="isCloudEnabled" class="dataimport" ng-class="{active:page=='dataimport'}"><a href="#/{{currentCore.name}}/dataimport"><span>Dataimport</span></a></li>
+              <li ng-hide="isCloudEnabled" class="documents" ng-class="{active:page=='documents'}"><a href="#/{{currentCore.name}}/documents"><span>Documents</span></a></li>
+              <li ng-hide="isCloudEnabled" class="files" ng-class="{active:page=='files'}"><a href="#/{{currentCore.name}}/files"><span>Files</span></a></li>
               <li class="ping" ng-class="{active:page=='ping'}"><a ng-click="ping()"><span>Ping</span><small class="qtime" ng-show="pingMS"> (<span>{{pingMS}}ms</span>)</small></a></li>
               <li class="plugins" ng-class="{active:page=='plugins'}"><a href="#/{{currentCore.name}}/plugins"><span>Plugins / Stats</span></a></li>
-              <li class="query" ng-class="{active:page=='query'}"><a href="#/{{currentCore.name}}/query"><span>Query</span></a></li>
+              <li ng-hide="isCloudEnabled" class="query" ng-class="{active:page=='query'}"><a href="#/{{currentCore.name}}/query"><span>Query</span></a></li>
               <li class="replication" ng-class="{active:page=='replication'}"><a href="#/{{currentCore.name}}/replication"><span>Replication</span></a></li>
-              <li class="schema-browser" ng-class="{active:page=='schema-browser'}"><a href="#/{{currentCore.name}}/schema-browser"><span>Schema Browser</span></a></li>
+              <li ng-hide="isCloudEnabled" class="schema-browser" ng-class="{active:page=='schema-browser'}"><a href="#/{{currentCore.name}}/schema-browser"><span>Schema Browser</span></a></li>
               <li class="segments" ng-class="{active:page=='segments'}"><a href="#/{{currentCore.name}}/segments"><span>Segments info</span></a></li>
-	    </ul>
+      </ul>
           </div>
 
         </div>

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/app.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/app.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/app.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/app.js Wed Sep  2 13:06:13 2015
@@ -63,6 +63,10 @@ solrAdminApp.config([
         templateUrl: 'partials/core_overview.html',
         controller: 'CoreOverviewController'
       }).
+      when('/:core/collection-overview', {
+        templateUrl: 'partials/collection_overview.html',
+        controller: 'CollectionOverviewController'
+      }).
       when('/:core/analysis', {
         templateUrl: 'partials/analysis.html',
         controller: 'AnalysisController'
@@ -121,6 +125,11 @@ solrAdminApp.config([
         redirectTo: '/'
       });
 }])
+.constant('Constants', {
+  IS_ROOT_PAGE: 1,
+  IS_CORE_PAGE: 2,
+  IS_COLLECTION_PAGE: 3
+})
 .filter('highlight', function($sce) {
   return function(input, lang) {
     if (lang && input && lang!="text") return hljs.highlight(lang, input).value;
@@ -319,9 +328,17 @@ solrAdminApp.config([
     };
 });
 
-solrAdminApp.controller('MainController', function($scope, $route, $rootScope, $location, Cores, System, Ping) {
+solrAdminApp.controller('MainController', function($scope, $route, $rootScope, $location, Cores, Collections, System, Ping, Constants) {
+
   $rootScope.hideException = function() {delete $rootScope.exception};
+
   $scope.refresh = function() {
+      $scope.cores = [];
+      $scope.collections = [];
+  }
+
+  $scope.refresh();
+  $scope.resetMenu = function(page, pageType) {
     Cores.list(function(data) {
       $scope.cores = [];
       var currentCoreName = $route.current.params.core;
@@ -329,22 +346,35 @@ solrAdminApp.controller('MainController'
       for (key in data.status) {
         var core = data.status[key];
         $scope.cores.push(core);
-        if (core.name == currentCoreName) {
+        if ((!$scope.isSolrCloud || pageType == Constants.IS_CORE_PAGE) && core.name == currentCoreName) {
             $scope.currentCore = core;
         }
       }
     });
+
     System.get(function(data) {
-      $scope.isCloudEnabled = data.mode.match( /solrcloud/i )
+      $scope.isCloudEnabled = data.mode.match( /solrcloud/i );
+
+      if ($scope.isCloudEnabled) {
+        Collections.list(function (data) {
+          $scope.collections = [];
+          var currentCollectionName = $route.current.params.core;
+          delete $scope.currentCollection;
+          for (key in data.collections) {
+            var collection = {name: data.collections[key]};
+            $scope.collections.push(collection);
+            if (pageType == Constants.IS_COLLECTION_PAGE && collection.name == currentCollectionName) {
+              $scope.currentCollection = collection;
+            }
+          }
+        })
+      }
+
     });
-  };
-  $scope.refresh();
 
-  $scope.resetMenu = function(page, isMainPage) {
     $scope.showingLogging = page.lastIndexOf("logging", 0) === 0;
     $scope.showingCloud = page.lastIndexOf("cloud", 0) === 0;
     $scope.page = page;
-    if (isMainPage) delete $scope.currentCore;
   };
 
   $scope.ping = function() {
@@ -357,8 +387,16 @@ solrAdminApp.controller('MainController'
   $scope.dumpCloud = function() {
       $scope.$broadcast("cloud-dump");
   }
-});
 
+  $scope.showCore = function(core) {
+    $location.url("/" + core.name);
+  }
+
+  $scope.showCollection = function(collection) {
+    $location.url("/" + collection.name + "/collection-overview")
+  }
+
+});
 
 
 (function(window, angular, undefined) {

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/analysis.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/analysis.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/analysis.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/analysis.js Wed Sep  2 13:06:13 2015
@@ -16,8 +16,8 @@
 */
 
 solrAdminApp.controller('AnalysisController',
-  function($scope, $location, $routeParams, Luke, Analysis) {
-      $scope.resetMenu("analysis");
+  function($scope, $location, $routeParams, Luke, Analysis, Constants) {
+      $scope.resetMenu("analysis", Constants.IS_COLLECTION_PAGE);
 
       $scope.refresh = function() {
         Luke.schema({core: $routeParams.core}, function(data) {

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/cloud.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/cloud.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/cloud.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/cloud.js Wed Sep  2 13:06:13 2015
@@ -16,7 +16,7 @@
 */
 
 solrAdminApp.controller('CloudController',
-    function($scope, $location, Zookeeper) {
+    function($scope, $location, Zookeeper, Constants) {
 
         $scope.showDebug = false;
 
@@ -30,13 +30,13 @@ solrAdminApp.controller('CloudController
 
         var view = $location.search().view ? $location.search().view : "graph";
         if (view == "tree") {
-            $scope.resetMenu("cloud-tree", true);
+            $scope.resetMenu("cloud-tree", Constants.IS_ROOT_PAGE);
             treeSubController($scope, Zookeeper);
         } else if (view == "rgraph") {
-            $scope.resetMenu("cloud-rgraph", true);
+            $scope.resetMenu("cloud-rgraph", Constants.IS_ROOT_PAGE);
             graphSubController($scope, Zookeeper, true);
         } else if (view == "graph") {
-            $scope.resetMenu("cloud-graph", true);
+            $scope.resetMenu("cloud-graph", Constants.IS_ROOT_PAGE);
             graphSubController($scope, Zookeeper, false);
         }
     }

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/core-overview.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/core-overview.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/core-overview.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/core-overview.js Wed Sep  2 13:06:13 2015
@@ -16,8 +16,8 @@
 */
 
 solrAdminApp.controller('CoreOverviewController',
-function($scope, $rootScope, $routeParams, Luke, CoreSystem, Update, Replication, Ping) {
-  $scope.resetMenu("overview");
+function($scope, $rootScope, $routeParams, Luke, CoreSystem, Update, Replication, Ping, Constants) {
+  $scope.resetMenu("overview", Constants.IS_CORE_PAGE);
   $scope.refreshIndex = function() {
     Luke.index({core: $routeParams.core},
       function(data) {

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/cores.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/cores.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/cores.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/cores.js Wed Sep  2 13:06:13 2015
@@ -17,30 +17,27 @@
 
 // @todo test optimize (delete stuff, watch button appear, test button/form)
 solrAdminApp.controller('CoreAdminController',
-  ['$scope', '$routeParams', '$location', '$timeout', 'Cores', 'Update',
-    function($scope, $routeParams, $location, $timeout, Cores, Update){
-      $scope.resetMenu("cores", true);
-      $scope.currentCore = $routeParams.corename; // use 'corename' not 'core' to distinguish from /solr/:core/
+    function($scope, $routeParams, $location, $timeout, Cores, Update, Constants){
+      $scope.resetMenu("cores", Constants.IS_ROOT_PAGE);
+      $scope.selectedCore = $routeParams.corename; // use 'corename' not 'core' to distinguish from /solr/:core/
       $scope.refresh = function() {
         Cores.get(function(data) {
           var coreCount = 0;
           for (_obj in data.status) coreCount++;
           $scope.hasCores = coreCount >0;
-          if (!$scope.currentCore && coreCount==0) {
+          if (!$scope.selectedCore && coreCount==0) {
             $scope.showAddCore();
             return;
-          } else if (!$scope.currentCore) {
+          } else if (!$scope.selectedCore) {
             for (firstCore in data.status) break;
-            $scope.currentCore = firstCore;
-            $location.path("/~cores/" + $scope.currentCore).replace();
+            $scope.selectedCore = firstCore;
+            $location.path("/~cores/" + $scope.selectedCore).replace();
           }
-          $scope.core = data.status[$scope.currentCore];
-          var cores = [];
+          $scope.core = data.status[$scope.selectedCore];
+          $scope.corelist = [];
           for (var core in data.status) {
-             cores.push(data.status[core]);
+             $scope.corelist.push(data.status[core]);
           }
-          $scope.cores = cores;
-          $scope.$parent.refresh();
         });
       };
       $scope.showAddCore = function() {
@@ -87,9 +84,9 @@ solrAdminApp.controller('CoreAdminContro
       };
 
       $scope.unloadCore = function() {
-        var answer = confirm( 'Do you really want to unload Core "' + $scope.currentCore + '"?' );
+        var answer = confirm( 'Do you really want to unload Core "' + $scope.selectedCore + '"?' );
         if( !answer ) return;
-        Cores.unload({core: $scope.currentCore}, function(data) {
+        Cores.unload({core: $scope.selectedCore}, function(data) {
           $location.path("/~cores");
         });
       };
@@ -101,11 +98,11 @@ solrAdminApp.controller('CoreAdminContro
 
       $scope.renameCore = function() {
         if (!$scope.other) {
-          $scope.renameMessage = "Please provide a new name for the " + $scope.currentCore + " core";
-        } else if ($scope.other == $scope.currentCore) {
+          $scope.renameMessage = "Please provide a new name for the " + $scope.selectedCore + " core";
+        } else if ($scope.other == $scope.selectedCore) {
           $scope.renameMessage = "New name must be different from the current one";
         } else {
-          Cores.rename({core:$scope.currentCore, other: $scope.other}, function(data) {
+          Cores.rename({core:$scope.selectedCore, other: $scope.other}, function(data) {
             $location.path("/~cores/" + $scope.other);
             $scope.cancelRename();
           });
@@ -126,10 +123,10 @@ solrAdminApp.controller('CoreAdminContro
       $scope.swapCores = function() {
         if ($scope.swapOther) {
           $swapMessage = "Please select a core to swap with";
-        } else if ($scope.swapOther == $scope.currentCore) {
+        } else if ($scope.swapOther == $scope.selectedCore) {
           $swapMessage = "Cannot swap with the same core";
         } else {
-          Cores.swap({core: $scope.currentCore, other: $scope.swapOther}, function(data) {
+          Cores.swap({core: $scope.selectedCore, other: $scope.swapOther}, function(data) {
             $location.path("/~cores/" + $scope.swapOther);
             delete $scope.swapOther;
             $scope.cancelSwap();
@@ -143,7 +140,7 @@ solrAdminApp.controller('CoreAdminContro
       }
 
       $scope.reloadCore = function() {
-        Cores.reload({core: $scope.currentCore},
+        Cores.reload({core: $scope.selectedCore},
           function(successData) {
             $scope.reloadSuccess = true;
             $timeout(function() {$scope.reloadSuccess=false}, 1000);
@@ -151,7 +148,7 @@ solrAdminApp.controller('CoreAdminContro
           function(failureData) {
             $scope.reloadFailure = true;
             $timeout(function() {$scope.reloadFailure=false}, 1000);
-            $scope.currentCore = null;
+            $scope.selectedCore = null;
             $scope.refresh();
             $location.path("/~cores");
           });
@@ -164,7 +161,7 @@ solrAdminApp.controller('CoreAdminContro
       };
 
       $scope.optimizeCore = function() {
-        Update.optimize({core: $scope.currentCore},
+        Update.optimize({core: $scope.selectedCore},
           function(successData) {
             $scope.optimizeSuccess = true;
             $timeout(function() {$scope.optimizeSuccess=false}, 1000);
@@ -179,7 +176,7 @@ solrAdminApp.controller('CoreAdminContro
 
       $scope.refresh();
     }
-]);
+);
 
 /**************
   'cores_load_data',

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/dataimport.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/dataimport.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/dataimport.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/dataimport.js Wed Sep  2 13:06:13 2015
@@ -18,8 +18,8 @@
 var dataimport_timeout = 2000;
 
 solrAdminApp.controller('DataImportController',
-    function($scope, $rootScope, $routeParams, $location, $timeout, $interval, $cookies, Mbeans, DataImport) {
-        $scope.resetMenu("dataimport");
+    function($scope, $rootScope, $routeParams, $location, $timeout, $interval, $cookies, Mbeans, DataImport, Constants) {
+        $scope.resetMenu("dataimport", Constants.IS_COLLECTION_PAGE);
 
         $scope.refresh = function () {
             Mbeans.info({core: $routeParams.core, cat: 'QUERYHANDLER'}, function (data) {

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/documents.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/documents.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/documents.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/documents.js Wed Sep  2 13:06:13 2015
@@ -24,8 +24,8 @@ var DOC_PLACEHOLDER = '<doc>\n' +
 var ADD_PLACEHOLDER = '<add>\n' + DOC_PLACEHOLDER + '</add>\n';
 
 solrAdminApp.controller('DocumentsController',
-    function($scope, $rootScope, $routeParams, $location, Luke, Update, FileUpload) {
-        $scope.resetMenu("documents");
+    function($scope, $rootScope, $routeParams, $location, Luke, Update, FileUpload, Constants) {
+        $scope.resetMenu("documents", Constants.IS_COLLECTION_PAGE);
 
         $scope.refresh = function () {
             Luke.schema({core: $routeParams.core}, function(data) {

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/files.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/files.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/files.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/files.js Wed Sep  2 13:06:13 2015
@@ -19,8 +19,8 @@ var contentTypeMap = { xml : 'text/xml',
 var languages = {js: "javascript", xml:"xml", xsl:"xml", vm: "xml", html: "xml", json: "text", css: "css"};
 
 solrAdminApp.controller('FilesController',
-    function($scope, $rootScope, $routeParams, $location, Files) {
-        $scope.resetMenu("files");
+    function($scope, $rootScope, $routeParams, $location, Files, Constants) {
+        $scope.resetMenu("files", Constants.IS_COLLECTION_PAGE);
 
         $scope.file = $location.search().file;
         $scope.content = null;

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/index.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/index.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/index.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/index.js Wed Sep  2 13:06:13 2015
@@ -15,8 +15,8 @@ See the License for the specific languag
 limitations under the License.
 */
 
-solrAdminApp.controller('IndexController', ['$scope', 'System', 'Cores', function($scope, System, Cores) {
-  $scope.resetMenu("index", true);
+solrAdminApp.controller('IndexController', function($scope, System, Cores, Constants) {
+  $scope.resetMenu("index", Constants.IS_ROOT_PAGE);
   $scope.reload = function() {
     System.get(function(data) {
       $scope.system = data;
@@ -67,7 +67,7 @@ solrAdminApp.controller('IndexController
     });
   };
   $scope.reload();
-}]);
+});
 
 var parse_memory_value = function( value ) {
   if( value !== Number( value ) )

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/java-properties.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/java-properties.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/java-properties.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/java-properties.js Wed Sep  2 13:06:13 2015
@@ -16,8 +16,8 @@
 */
 
 solrAdminApp.controller('JavaPropertiesController',
-  function($scope, Properties){
-    $scope.resetMenu("java-props", true);
+  function($scope, Properties, Constants){
+    $scope.resetMenu("java-props", Constants.IS_ROOT_PAGE);
     $scope.refresh = function() {
       Properties.get(function(data) {
         var sysprops = data["system.properties"];

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/logging.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/logging.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/logging.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/logging.js Wed Sep  2 13:06:13 2015
@@ -24,8 +24,8 @@ var format_time_content = function( time
 }
 
 solrAdminApp.controller('LoggingController',
-  function($scope, $timeout, $cookies, Logging){
-    $scope.resetMenu("logging", true);
+  function($scope, $timeout, $cookies, Logging, Constants){
+    $scope.resetMenu("logging", Constants.IS_ROOT_PAGE);
     $scope.timezone = $cookies.logging_timezone || "Local";
     $scope.refresh = function() {
       Logging.events(function(data) {

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/plugins.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/plugins.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/plugins.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/plugins.js Wed Sep  2 13:06:13 2015
@@ -16,8 +16,8 @@
 */
 
 solrAdminApp.controller('PluginsController',
-    function($scope, $rootScope, $routeParams, $location, Mbeans) {
-        $scope.resetMenu("plugins");
+    function($scope, $rootScope, $routeParams, $location, Mbeans, Constants) {
+        $scope.resetMenu("plugins", Constants.IS_CORE_PAGE);
 
         if ($routeParams.legacytype) {
             // support legacy URLs. Angular cannot change #path without reloading controller

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/query.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/query.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/query.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/query.js Wed Sep  2 13:06:13 2015
@@ -16,8 +16,8 @@
 */
 
 solrAdminApp.controller('QueryController',
-  function($scope, $routeParams, $location, Query){
-    $scope.resetMenu("query");
+  function($scope, $routeParams, $location, Query, Constants){
+    $scope.resetMenu("query", Constants.IS_COLLECTION_PAGE);
 
     // @todo read URL parameters into scope
     $scope.query = {wt: 'json', q:'*:*', indent:'on'};

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/replication.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/replication.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/replication.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/replication.js Wed Sep  2 13:06:13 2015
@@ -16,8 +16,8 @@
 */
 
 solrAdminApp.controller('ReplicationController',
-    function($scope, $rootScope, $routeParams, $interval, $timeout, Replication) {
-        $scope.resetMenu("replication");
+    function($scope, $rootScope, $routeParams, $interval, $timeout, Replication, Constants) {
+        $scope.resetMenu("replication", Constants.IS_CORE_PAGE);
 
         $scope.iterationCount = 1;
 

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/schema-browser.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/schema-browser.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/schema-browser.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/schema-browser.js Wed Sep  2 13:06:13 2015
@@ -18,8 +18,8 @@
 var cookie_schema_browser_autoload = 'schema-browser_autoload';
 
 solrAdminApp.controller('SchemaBrowserController',
-    function($scope, $routeParams, $location, $cookies, Luke) {
-        $scope.resetMenu("schema-browser");
+    function($scope, $routeParams, $location, $cookies, Luke, Constants) {
+        $scope.resetMenu("schema-browser", Constants.IS_COLLECTION_PAGE);
 
         $scope.refresh = function () {
             Luke.schema({core: $routeParams.core}, function (schema) {

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/segments.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/segments.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/segments.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/segments.js Wed Sep  2 13:06:13 2015
@@ -17,8 +17,8 @@
 
 var MB_FACTOR = 1024*1024;
 
-solrAdminApp.controller('SegmentsController', function($scope, $routeParams, $interval, Segments) {
-    $scope.resetMenu("segments");
+solrAdminApp.controller('SegmentsController', function($scope, $routeParams, $interval, Segments, Constants) {
+    $scope.resetMenu("segments", Constants.IS_CORE_PAGE);
 
     $scope.refresh = function() {
 

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/threads.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/threads.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/threads.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/controllers/threads.js Wed Sep  2 13:06:13 2015
@@ -16,9 +16,8 @@
 */
 
 solrAdminApp.controller('ThreadsController',
-  ["$scope", "Threads",
-  function($scope, Threads){
-    $scope.resetMenu("threads", true);
+  function($scope, Threads, Constants){
+    $scope.resetMenu("threads", Constants.IS_ROOT_PAGE);
     $scope.refresh = function() {
       Threads.get(function(data) {
         var threadDump = data.system.threadDump;
@@ -48,4 +47,4 @@ solrAdminApp.controller('ThreadsControll
       }
     };
     $scope.refresh();
-}]);
+});

Modified: lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/services.js
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/services.js?rev=1700800&r1=1700799&r2=1700800&view=diff
==============================================================================
--- lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/services.js (original)
+++ lucene/dev/branches/lucene6699/solr/webapp/web/js/angular/services.js Wed Sep  2 13:06:13 2015
@@ -35,6 +35,15 @@ solrAdminServices.factory('System',
     "optimize": {params:{}}
     });
   }])
+.factory('Collections',
+  ['$resource', function($resource) {
+    return $resource('/solr/admin/collections',
+      {wt: 'json', _:Date.now()}, {
+        "list": {params:{action: "LIST"}},
+        "status": {params:{action: "CLUSTERSTATUS"}}
+      }
+    )
+  }])
 .factory('Logging',
   ['$resource', function($resource) {
     return $resource('/solr/admin/info/logging', {'wt':'json', '_':Date.now()}, {



Mime
View raw message