org.apache.solr.common.cloud.Replica.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.solr.common.cloud.Replica.java

Source

/*
 * 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.
 */
package org.apache.solr.common.cloud;

import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.solr.common.util.Utils;

public class Replica extends ZkNodeProps {

    /**
     * The replica's state. In general, if the node the replica is hosted on is
     * not under {@code /live_nodes} in ZK, the replica's state should be
     * discarded.
     */
    public enum State {

        /**
         * The replica is ready to receive updates and queries.
         * <p>
         * <b>NOTE</b>: when the node the replica is hosted on crashes, the
         * replica's state may remain ACTIVE in ZK. To determine if the replica is
         * truly active, you must also verify that its {@link Replica#getNodeName()
         * node} is under {@code /live_nodes} in ZK (or use
         * {@link ClusterState#liveNodesContain(String)}).
         * </p>
         */
        ACTIVE,

        /**
         * The first state before {@link State#RECOVERING}. A node in this state
         * should be actively trying to move to {@link State#RECOVERING}.
         * <p>
         * <b>NOTE</b>: a replica's state may appear DOWN in ZK also when the node
         * it's hosted on gracefully shuts down. This is a best effort though, and
         * should not be relied on.
         * </p>
         */
        DOWN,

        /**
         * The node is recovering from the leader. This might involve peer-sync,
         * full replication or finding out things are already in sync.
         */
        RECOVERING,

        /**
         * Recovery attempts have not worked, something is not right.
         * <p>
         * <b>NOTE</b>: This state doesn't matter if the node is not part of
         * {@code /live_nodes} in ZK; in that case the node is not part of the
         * cluster and it's state should be discarded.
         * </p>
         */
        RECOVERY_FAILED;

        @Override
        public String toString() {
            return super.toString().toLowerCase(Locale.ROOT);
        }

        /** Converts the state string to a State instance. */
        public static State getState(String stateStr) {
            return stateStr == null ? null : State.valueOf(stateStr.toUpperCase(Locale.ROOT));
        }
    }

    public enum Type {
        /**
         * Writes updates to transaction log and indexes locally. Replicas of type {@link Type#NRT} support NRT (soft commits) and RTG. 
         * Any {@link Type#NRT} replica can become a leader. A shard leader will forward updates to all active {@link Type#NRT} and
         * {@link Type#TLOG} replicas. 
         */
        NRT,
        /**
         * Writes to transaction log, but not to index, uses replication. Any {@link Type#TLOG} replica can become leader (by first
         * applying all local transaction log elements). If a replica is of type {@link Type#TLOG} but is also the leader, it will behave 
         * as a {@link Type#NRT}. A shard leader will forward updates to all active {@link Type#NRT} and {@link Type#TLOG} replicas.
         */
        TLOG,
        /**
         * Doesnt index or writes to transaction log. Just replicates from {@link Type#NRT} or {@link Type#TLOG} replicas. {@link Type#PULL}
         * replicas cant become shard leaders (i.e., if there are only pull replicas in the collection at some point, updates will fail
         * same as if there is no leaders, queries continue to work), so they dont even participate in elections.
         */
        PULL;

        public static Type get(String name) {
            return name == null ? Type.NRT : Type.valueOf(name.toUpperCase(Locale.ROOT));
        }
    }

    private final String name;
    private final String nodeName;
    private final State state;
    private final Type type;
    public final String slice, collection;

    public Replica(String name, Map<String, Object> propMap, String collection, String slice) {
        super(propMap);
        this.collection = collection;
        this.slice = slice;
        this.name = name;
        this.nodeName = (String) propMap.get(ZkStateReader.NODE_NAME_PROP);
        if (propMap.get(ZkStateReader.STATE_PROP) != null) {
            this.state = State.getState((String) propMap.get(ZkStateReader.STATE_PROP));
        } else {
            this.state = State.ACTIVE; //Default to ACTIVE
            propMap.put(ZkStateReader.STATE_PROP, state.toString());
        }
        type = Type.get((String) propMap.get(ZkStateReader.REPLICA_TYPE));
    }

    public String getCollection() {
        return collection;
    }

    public String getSlice() {
        return slice;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        if (!super.equals(o))
            return false;

        Replica replica = (Replica) o;

        return name.equals(replica.name);
    }

    /** Also known as coreNodeName. */
    public String getName() {
        return name;
    }

    public String getCoreUrl() {
        return ZkCoreNodeProps.getCoreUrl(getStr(ZkStateReader.BASE_URL_PROP),
                getStr(ZkStateReader.CORE_NAME_PROP));
    }

    public String getBaseUrl() {
        return getStr(ZkStateReader.BASE_URL_PROP);
    }

    /** SolrCore name. */
    public String getCoreName() {
        return getStr(ZkStateReader.CORE_NAME_PROP);
    }

    /** The name of the node this replica resides on */
    public String getNodeName() {
        return nodeName;
    }

    /** Returns the {@link State} of this replica. */
    public State getState() {
        return state;
    }

    public boolean isActive(Set<String> liveNodes) {
        return this.nodeName != null && liveNodes.contains(this.nodeName) && this.state == State.ACTIVE;
    }

    public Type getType() {
        return this.type;
    }

    public String getProperty(String propertyName) {
        final String propertyKey;
        if (!propertyName.startsWith(ZkStateReader.PROPERTY_PROP_PREFIX)) {
            propertyKey = ZkStateReader.PROPERTY_PROP_PREFIX + propertyName;
        } else {
            propertyKey = propertyName;
        }
        final String propertyValue = getStr(propertyKey);
        return propertyValue;
    }

    @Override
    public String toString() {
        return name + ':' + Utils.toJSONString(propMap); // small enough, keep it on one line (i.e. no indent)
    }
}