All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.je.rep.monitor.Protocol Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */
package com.sleepycat.je.rep.monitor;

import com.sleepycat.je.rep.impl.RepGroupImpl;
import com.sleepycat.je.rep.impl.RepImpl;
import com.sleepycat.je.rep.impl.RepParams;
import com.sleepycat.je.rep.impl.TextProtocol;
import com.sleepycat.je.rep.impl.node.NameIdPair;
import com.sleepycat.je.rep.monitor.GroupChangeEvent.GroupChangeType;
import com.sleepycat.je.rep.monitor.LeaveGroupEvent.LeaveReason;
import com.sleepycat.je.rep.net.DataChannelFactory;

/**
 * @hidden
 * For internal use only.
 *
 * Defines the protocol used by the Monitor to keep informed about group
 * changes, and a node joins/leaves the group. The Master uses the protocol to
 * inform all Monitors about group change and node join/leave change.
 *
 * {@literal
 * GCHG -> no response expected from the monitor.
 * JoinGroup -> no response expected from the monitor.
 * LeaveGroup -> no response expected from the monitor.
 * }
 */
public class Protocol extends TextProtocol {

    /** The latest protocol version. */
    public static final String VERSION = "2.0";

    /** The protocol version introduced to support RepGroupImpl version 3. */
    static final String REP_GROUP_V3_VERSION = "2.0";

    /** The protocol version used with RepGroupImpl version 2. */
    static final String REP_GROUP_V2_VERSION = "1.0";

    /* The messages defined by this class. */
    public final MessageOp GROUP_CHANGE_REQ =
        new MessageOp("GCHG", GroupChange.class);

    public final MessageOp JOIN_GROUP_REQ =
        new MessageOp("JG", JoinGroup.class);

    public final MessageOp LEAVE_GROUP_REQ =
        new MessageOp("LG", LeaveGroup.class);

    /**
     * Creates an instance of this class using the current protocol version.
     */
    public Protocol(String groupName, NameIdPair nameIdPair, RepImpl repImpl,
                    DataChannelFactory channelFactory) {
        this(VERSION, groupName, nameIdPair, repImpl, channelFactory);
    }

    /**
     * Creates an instance of this class using the specified protocol version.
     */
    Protocol(String version,
             String groupName,
             NameIdPair nameIdPair,
             RepImpl repImpl,
             DataChannelFactory channelFactory) {

        super(version, groupName, nameIdPair, repImpl, channelFactory);

        initializeMessageOps(new MessageOp[] {
            GROUP_CHANGE_REQ,
            JOIN_GROUP_REQ,
            LEAVE_GROUP_REQ
        });

        setTimeouts(repImpl,
                    RepParams.MONITOR_OPEN_TIMEOUT,
                    RepParams.MONITOR_READ_TIMEOUT);
    }

    private abstract class ChangeEvent extends RequestMessage {
        /* Name of node which this change event happens on. */
        private final String nodeName;

        public ChangeEvent(String nodeName) {
            this.nodeName = nodeName;
        }

        public ChangeEvent(String line, String[] tokens)
            throws InvalidMessageException {

            super(line, tokens);
            nodeName = nextPayloadToken();
        }

        public String getNodeName() {
            return nodeName;
        }

        @Override
        protected String getMessagePrefix() {
            return messagePrefixNocheck;
        }

        @Override
        public String wireFormat() {
            return wireFormatPrefix() + SEPARATOR + nodeName + SEPARATOR;
        }
    }

    public class GroupChange extends ChangeEvent {
        private final RepGroupImpl group;
        /* Represents it's a ADD or REMOVE change event. */
        private final GroupChangeType opType;

        public GroupChange(RepGroupImpl group,
                           String nodeName,
                           GroupChangeType opType) {
            super(nodeName);
            this.group = group;
            this.opType = opType;
        }

        public GroupChange(String line, String[] tokens)
            throws InvalidMessageException {

            super(line, tokens);
            opType = GroupChangeType.valueOf(nextPayloadToken());
            group = RepGroupImpl.deserializeHex
                (tokens, getCurrentTokenPosition());
        }

        public RepGroupImpl getGroup() {
            return group;
        }

        public GroupChangeType getOpType() {
            return opType;
        }

        @Override
        public MessageOp getOp() {
            return GROUP_CHANGE_REQ;
        }

        @Override
        public String wireFormat() {
            final int repGroupVersion =
                (Double.parseDouble(sendVersion) <=
                 Double.parseDouble(REP_GROUP_V2_VERSION)) ?
                RepGroupImpl.FORMAT_VERSION_2 :
                RepGroupImpl.MAX_FORMAT_VERSION;
            return super.wireFormat() +
                   opType.toString() + SEPARATOR +
                   group.serializeHex(repGroupVersion);
        }
    }

    private abstract class MemberEvent extends ChangeEvent {
        private final String masterName;
        private final long joinTime;

        public MemberEvent(String nodeName, String masterName, long joinTime) {
            super(nodeName);
            this.masterName = masterName;
            this.joinTime = joinTime;
        }

        public MemberEvent(String line, String[] tokens)
            throws InvalidMessageException {

            super(line, tokens);
            masterName = nextPayloadToken();
            joinTime = Long.parseLong(nextPayloadToken());
        }

        public long getJoinTime() {
            return joinTime;
        }

        public String getMasterName() {
            return masterName;
        }

        @Override
        public String wireFormat() {
            return super.wireFormat() +
                   masterName + SEPARATOR +
                   Long.toString(joinTime);
        }
    }

    /* Represents the event that a node joins the group. */
    public class JoinGroup extends MemberEvent {
        public JoinGroup(String nodeName, String masterName, long joinTime) {
            super(nodeName, masterName, joinTime);
        }

        public JoinGroup(String line, String[] tokens)
            throws InvalidMessageException {

            super(line, tokens);
        }

        @Override
        public MessageOp getOp() {
            return JOIN_GROUP_REQ;
        }
    }

    /* Represents the event that a node leaves the group. */
    public class LeaveGroup extends MemberEvent {
        private final LeaveReason leaveReason;
        private final long leaveTime;

        public LeaveGroup(String nodeName,
                          String masterName,
                          LeaveReason leaveReason,
                          long joinTime,
                          long leaveTime) {
            super(nodeName, masterName, joinTime);
            this.leaveReason = leaveReason;
            this.leaveTime = leaveTime;
        }

        public LeaveGroup(String line, String[] tokens)
            throws InvalidMessageException {

            super(line, tokens);
            leaveReason = LeaveReason.valueOf(nextPayloadToken());
            leaveTime = Long.parseLong(nextPayloadToken());
        }

        public LeaveReason getLeaveReason() {
            return leaveReason;
        }

        public long getLeaveTime() {
            return leaveTime;
        }

        @Override
        public MessageOp getOp() {
            return LEAVE_GROUP_REQ;
        }

        @Override
        public String wireFormat() {
            return super.wireFormat() + SEPARATOR +
                   leaveReason.toString() + SEPARATOR +
                   Long.toString(leaveTime);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy