package org.apache.solr.common.cloud;
/**
* 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.
*/
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// immutable
public class CloudState {
protected static Logger log = LoggerFactory.getLogger(CloudState.class);
private final Map<String,Map<String,Slice>> collectionStates;
private final Set<String> liveNodes;
public CloudState(Set<String> liveNodes, Map<String,Map<String,Slice>> collectionStates) {
this.liveNodes = liveNodes;
this.collectionStates = collectionStates;
}
public Map<String,Slice> getSlices(String collection) {
Map<String,Slice> collectionState = collectionStates.get(collection);
if(collectionState == null) {
return null;
}
return Collections.unmodifiableMap(collectionState);
}
public Set<String> getCollections() {
return Collections.unmodifiableSet(collectionStates.keySet());
}
public Map<String,Map<String,Slice>> getCollectionStates() {
return Collections.unmodifiableMap(collectionStates);
}
public Set<String> getLiveNodes() {
return Collections.unmodifiableSet(liveNodes);
}
public boolean liveNodesContain(String name) {
return liveNodes.contains(name);
}
public static CloudState buildCloudState(SolrZkClient zkClient, CloudState oldCloudState, boolean onlyLiveNodes) throws KeeperException, InterruptedException, IOException {
Map<String,Map<String,Slice>> collectionStates;
if (!onlyLiveNodes) {
List<String> collections = zkClient.getChildren(
ZkStateReader.COLLECTIONS_ZKNODE, null);
collectionStates = new HashMap<String,Map<String,Slice>>();
for (String collection : collections) {
String shardIdPaths = ZkStateReader.COLLECTIONS_ZKNODE + "/"
+ collection + ZkStateReader.SHARDS_ZKNODE;
List<String> shardIdNames;
try {
shardIdNames = zkClient.getChildren(shardIdPaths, null);
} catch (KeeperException.NoNodeException e) {
// node is not valid currently
continue;
}
Map<String,Slice> slices = new HashMap<String,Slice>();
for (String shardIdZkPath : shardIdNames) {
Map<String,ZkNodeProps> shardsMap = readShards(zkClient, shardIdPaths
+ "/" + shardIdZkPath);
Slice slice = new Slice(shardIdZkPath, shardsMap);
slices.put(shardIdZkPath, slice);
}
collectionStates.put(collection, slices);
}
} else {
collectionStates = oldCloudState.getCollectionStates();
}
CloudState cloudInfo = new CloudState(getLiveNodes(zkClient), collectionStates);
return cloudInfo;
}
/**
* @param zkClient
* @param shardsZkPath
* @return
* @throws KeeperException
* @throws InterruptedException
* @throws IOException
*/
private static Map<String,ZkNodeProps> readShards(SolrZkClient zkClient, String shardsZkPath)
throws KeeperException, InterruptedException, IOException {
Map<String,ZkNodeProps> shardNameToProps = new HashMap<String,ZkNodeProps>();
if (zkClient.exists(shardsZkPath, null) == null) {
throw new IllegalStateException("Cannot find zk shards node that should exist:"
+ shardsZkPath);
}
List<String> shardZkPaths = zkClient.getChildren(shardsZkPath, null);
for(String shardPath : shardZkPaths) {
byte[] data = zkClient.getData(shardsZkPath + "/" + shardPath, null,
null);
ZkNodeProps props = new ZkNodeProps();
props.load(data);
shardNameToProps.put(shardPath, props);
}
return Collections.unmodifiableMap(shardNameToProps);
}
private static Set<String> getLiveNodes(SolrZkClient zkClient) throws KeeperException, InterruptedException {
List<String> liveNodes = zkClient.getChildren(ZkStateReader.LIVE_NODES_ZKNODE, null);
Set<String> liveNodesSet = new HashSet<String>(liveNodes.size());
liveNodesSet.addAll(liveNodes);
return liveNodesSet;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("live nodes:" + liveNodes);
sb.append(" collections:" + collectionStates);
return sb.toString();
}
}