blob: d91d4625ccf970b33d33eac653950e99830cde5e [file] [log] [blame]
/*-
* 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.arbiter.impl;
import java.io.IOException;
import java.util.logging.Logger;
import com.sleepycat.je.JEVersion;
import com.sleepycat.je.log.LogEntryType;
import com.sleepycat.je.rep.impl.BinaryNodeStateProtocol;
import com.sleepycat.je.rep.impl.BinaryNodeStateProtocol.BinaryNodeStateRequest;
import com.sleepycat.je.rep.impl.BinaryNodeStateProtocol.BinaryNodeStateResponse;
import com.sleepycat.je.rep.impl.node.NameIdPair;
import com.sleepycat.je.rep.net.DataChannel;
import com.sleepycat.je.rep.utilint.BinaryProtocol.ProtocolException;
import com.sleepycat.je.rep.utilint.ServiceDispatcher;
import com.sleepycat.je.rep.utilint.ServiceDispatcher.ExecutingService;
import com.sleepycat.je.utilint.LoggerUtils;
import com.sleepycat.je.utilint.JVMSystemUtils;
/**
* The service registered by an Arbiter to answer the state request.
*
* To support the new BinaryStateProtocol, we introduce this new
* BinaryNodeStateService, it's used by "Ping" command.
*
*/
public class ArbBinaryStateService extends ExecutingService {
private final ArbiterImpl arbImpl;
private final ServiceDispatcher dispatcher;
private final Logger logger;
/* Identifies the Node State querying Service. */
public static final String SERVICE_NAME = "BinaryNodeState";
public ArbBinaryStateService(ServiceDispatcher dispatcher,
ArbiterImpl arbImpl) {
super(SERVICE_NAME, dispatcher);
this.arbImpl = arbImpl;;
this.dispatcher = dispatcher;
this.logger = LoggerUtils.getLogger(getClass());
dispatcher.register(this);
}
public void shutdown() {
dispatcher.cancel(SERVICE_NAME);
}
@Override
public Runnable getRunnable(DataChannel dataChannel) {
return new NodeStateServiceRunnable(dataChannel);
}
class NodeStateServiceRunnable implements Runnable {
private final DataChannel channel;
NodeStateServiceRunnable(DataChannel channel) {
this.channel = channel;
}
/* Create the NodeState for the request. */
private BinaryNodeStateResponse createResponse
(BinaryNodeStateProtocol protocol) {
long joinTime = arbImpl.getJoinGroupTime();
long vlsnValue = (arbImpl.getArbiterVLSNTracker().get() == null ?
0L : arbImpl.getArbiterVLSNTracker().get().getSequence());
return protocol.new BinaryNodeStateResponse(
arbImpl.getNameIdPair().getName(),
arbImpl.getGroupName(),
arbImpl.getMasterStatus().getNodeMasterNameId().getName(),
JEVersion.CURRENT_VERSION, joinTime,
arbImpl.getNodeState(),
vlsnValue, vlsnValue,
0, LogEntryType.LOG_VERSION,
null, JVMSystemUtils.getSystemLoad());
}
@Override
public void run() {
BinaryNodeStateProtocol protocol = null;
ensureChannelBlocking(channel);
try {
protocol = new BinaryNodeStateProtocol(NameIdPair.NOCHECK,
arbImpl.getRepImpl());
try {
BinaryNodeStateRequest msg =
protocol.read(channel, BinaryNodeStateRequest.class);
/*
* Response a protocol error if the group name doesn't
* match.
*/
final String groupName = msg.getGroupName();
if (!arbImpl.getGroupName().equals(groupName) ||
!arbImpl.getNameIdPair().getName().
equals(msg.getNodeName())) {
throw new ProtocolException("Sending the request to" +
" a wrong group or a wrong node.");
}
/* Write the response the requested node. */
BinaryNodeStateResponse response =
createResponse(protocol);
protocol.write(response, channel);
LoggerUtils.finest(logger, arbImpl.getRepImpl(),
"Deal with a node state request successfully.");
} catch (ProtocolException e) {
LoggerUtils.info(logger, arbImpl.getRepImpl(),
"Get a ProtocolException with message: " +
LoggerUtils.exceptionTypeAndMsg(e) +
" while dealing with a node state request.");
protocol.write
(protocol.new ProtocolError(e.getMessage()), channel);
} catch (Exception e) {
LoggerUtils.info(logger, arbImpl.getRepImpl(),
"Unexpected exception: " +
LoggerUtils.exceptionTypeAndMsg(e));
protocol.write
(protocol.new ProtocolError(e.getMessage()), channel);
} finally {
if (channel.isOpen()) {
channel.close();
}
}
} catch (IOException e) {
/*
* Channel has already been closed, or the close itself
* failed.
*/
}
}
}
}