
oracle.kv.impl.sna.StorageNodeAgentImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oracle-nosql-server Show documentation
Show all versions of oracle-nosql-server Show documentation
NoSQL Database Server - supplies build and runtime support for the server (store) side of the Oracle NoSQL Database.
The newest version!
/*-
* Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle NoSQL
* Database made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle NoSQL Database for a copy of the license and
* additional information.
*/
package oracle.kv.impl.sna;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.rmi.RemoteException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import oracle.kv.impl.admin.CommandResult;
import oracle.kv.impl.admin.param.AdminParams;
import oracle.kv.impl.admin.param.ArbNodeParams;
import oracle.kv.impl.admin.param.GlobalParams;
import oracle.kv.impl.admin.param.RepNodeParams;
import oracle.kv.impl.admin.param.SecurityParams.KrbPrincipalInfo;
import oracle.kv.impl.admin.param.StorageNodeParams;
import oracle.kv.impl.fault.ProcessFaultHandler;
import oracle.kv.impl.metadata.Metadata;
import oracle.kv.impl.metadata.MetadataInfo;
import oracle.kv.impl.param.LoadParameters;
import oracle.kv.impl.param.ParameterMap;
import oracle.kv.impl.security.AuthContext;
import oracle.kv.impl.security.KVStorePrivilegeLabel;
import oracle.kv.impl.security.annotations.PublicMethod;
import oracle.kv.impl.security.annotations.SecureAPI;
import oracle.kv.impl.security.annotations.SecureAutoMethod;
import oracle.kv.impl.security.annotations.SecureR2Method;
import oracle.kv.impl.test.RemoteTestInterface;
import oracle.kv.impl.topo.AdminId;
import oracle.kv.impl.topo.ArbNodeId;
import oracle.kv.impl.topo.RepNode;
import oracle.kv.impl.topo.RepNodeId;
import oracle.kv.impl.topo.ResourceId;
import oracle.kv.impl.topo.StorageNode;
import oracle.kv.impl.topo.StorageNodeId;
import oracle.kv.impl.topo.Topology;
import oracle.kv.impl.util.CommandParser;
import oracle.kv.impl.util.ConfigUtils;
import oracle.kv.impl.util.ConfigurableService.ServiceStatus;
import oracle.kv.impl.util.JsonUtils;
import oracle.kv.impl.util.SerialVersion;
import oracle.kv.impl.util.registry.VersionedRemoteImpl;
import oracle.kv.impl.util.server.LoggerUtils;
import oracle.kv.util.ErrorMessage;
import oracle.kv.util.shell.Shell;
import oracle.kv.util.shell.ShellCommandResult;
import org.codehaus.jackson.node.ObjectNode;
/**
* The class that implements the StorageNodeAgentInterface (SNA) interface used
* to manage all processes on a physical machine (Storage Node, or SN). The
* SNA is responsible for
*
* 1. Hosting the RMI registry for processes on the SN
* 2. Configuring and starting processes on the SN (RepNode and Admin)
* 3. Monitoring process state and restarting them if necessary
* 4. Terminating processes if requested, gracefully if possible.
*
* Once provisioned, the process that hosts this object is intended to be
* started automatically by the Operating System though a mechanism such as
* /etc/init on *nix. There is one instance of this object for each KVStore
* provisioned on a Storage Node, most likely hosted by independent processes.
*
* This is the interface class. Most of the work is done in the
* StorageNodeAgent class.
*/
@SecureAPI
public final class StorageNodeAgentImpl
extends VersionedRemoteImpl implements StorageNodeAgentInterface {
private final StorageNodeAgent sna;
private final SNAFaultHandler faultHandler;
/**
* A conditional instance, created if the class can be found.
*/
private RemoteTestInterface rti;
private static final String TEST_INTERFACE_NAME =
"oracle.kv.impl.sna.StorageNodeAgentTestInterface";
public StorageNodeAgentImpl() {
this(false);
}
/**
* A constructor that allows the caller to indicate that the bootstrap
* admin service should or should not be started.
*/
public StorageNodeAgentImpl(boolean createBootstrapAdmin) {
sna = new StorageNodeAgent(this, createBootstrapAdmin);
faultHandler = new SNAFaultHandler(this);
rti = null;
}
public StorageNodeAgent getStorageNodeAgent() {
return sna;
}
public SNAFaultHandler getFaultHandler() {
return faultHandler;
}
/**
* A bunch of pass-through methods do the StorageNodeAgent methods.
*/
public Logger getLogger() {
return sna.getLogger();
}
public void parseArgs(String args[]) {
sna.parseArgs(args);
}
public void start()
throws IOException {
sna.start();
}
public void addShutdownHook() {
sna.addShutdownHook();
}
public boolean isRegistered() {
return sna.isRegistered();
}
public String getStoreName() {
return sna.getStoreName();
}
public int getRegistryPort() {
return sna.getRegistryPort();
}
/**
* Can the test interface be created?
*/
public void startTestInterface() {
try {
Class> cl = Class.forName(TEST_INTERFACE_NAME);
Constructor> c = cl.getConstructor(getClass());
rti = (RemoteTestInterface) c.newInstance(this);
rti.start(SerialVersion.CURRENT);
} catch (Exception ignored) {
}
}
public void stopTestInterface()
throws RemoteException {
if (rti != null) {
rti.stop(SerialVersion.CURRENT);
}
}
private void checkRegistered(String method) {
sna.checkRegistered(method);
}
private void logInfo(String msg) {
sna.getLogger().info(msg);
}
private void logFine(String msg) {
sna.getLogger().fine(msg);
}
/**
* Begin StorageNodeAgentInterface
*
* General considerations:
* o Only one register() call during the lifetime of the agent.
* o Single-thread the state-changing calls.
* o Ensure that services never see or read an inconsistent configuration
* file.
*/
@Override
@PublicMethod
public StorageNodeStatus ping(short serialVersion) {
return ping(null, serialVersion);
}
@Override
@PublicMethod
public StorageNodeStatus ping(AuthContext authCtx,
short serialVersion) {
return faultHandler.execute
((ProcessFaultHandler.SimpleOperation)() ->
sna.getStatus());
}
@Override
@SecureR2Method
public List register(final ParameterMap gpMap,
final ParameterMap snpMap,
final boolean hostingAdmin,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized List register(final ParameterMap gpMap,
final ParameterMap snpMap,
final boolean hostingAdmin,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.
Operation, RemoteException>)() -> {
GlobalParams gp = new GlobalParams(gpMap);
StorageNodeParams snp = new StorageNodeParams(snpMap);
return sna.register(gp, snp, hostingAdmin);
});
}
@SecureR2Method
@Override
public void shutdown(final boolean stopServices,
final boolean force,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Stops a running Storage Node Agent and maybe all running services.
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void shutdown(final boolean stopServices,
final boolean force,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
sna.shutdown(stopServices, force);
});
}
@Override
@SecureR2Method
public boolean createAdmin(final ParameterMap adminParams,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Create and start a Admin instance. If this SN is hosting the primary
* Admin and this method is called the Admin is not started. It is assumed
* to be already managed.
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean createAdmin(final ParameterMap adminParams,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() ->
sna.createAdmin(new AdminParams(adminParams)));
}
@Override
@SecureR2Method
public boolean startAdmin(short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Start an already-created Admin instance
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean startAdmin(AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("startAdmin");
logInfo("startAdmin called");
AdminParams ap =
ConfigUtils.getAdminParams(sna.getKvConfigFile());
if (ap == null) {
String msg =
"Attempt to start an Admin when none is configured";
logInfo(msg);
throw new IllegalStateException(msg);
}
return sna.startAdmin(ap);
});
}
@Override
@SecureR2Method
public boolean stopAdmin(final boolean force,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Stop the running Admin instance
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean stopAdmin(final boolean force,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("stopAdmin");
return sna.stopAdmin(null, force);
});
}
@Override
@SecureR2Method
public boolean destroyAdmin(final AdminId adminId,
final boolean deleteData,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Destroy the Admin instance. After this it will be necessary to use
* createAdmin() if another Admin is required.
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean destroyAdmin(final AdminId adminId,
final boolean deleteData,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("destroyAdmin");
return sna.destroyAdmin(adminId, deleteData);
});
}
@Override
@SecureR2Method
public boolean repNodeExists(final RepNodeId repNodeId,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Does this RepNode exist in the configuration file?
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean repNodeExists(final RepNodeId repNodeId,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("repNodeExists");
if (sna.lookupRepNode(repNodeId) != null) {
return true;
}
return false;
});
}
/**
* Create a new RepNode instance based on the configuration information.
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean
createRepNode(final ParameterMap params,
final Set> metadataSet,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("createRepNode");
RepNodeParams repNodeParams = new RepNodeParams(params);
return sna.createRepNode(repNodeParams, metadataSet);
});
}
@Deprecated
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public boolean createRepNode(ParameterMap repNodeParams,
Topology topology,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
final Set> metadataSet =
new HashSet<>(1);
metadataSet.add(topology);
return createRepNode(repNodeParams,
metadataSet,
authCtx, serialVersion);
}
@Deprecated
@Override
@SecureR2Method
public boolean createRepNode(final ParameterMap params,
final Topology topology,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureR2Method
public boolean startRepNode(final RepNodeId repNodeId,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Start an already-create RepNode. This implicitly sets its state to
* active.
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean startRepNode(final RepNodeId repNodeId,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("startRepNode");
return sna.startRepNode(repNodeId);
});
}
@Override
@SecureR2Method
public boolean stopRepNode(final RepNodeId rnid,
final boolean force,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Stop a running RepNode
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean stopRepNode(final RepNodeId rnid,
final boolean force,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("stopRepNode");
return sna.stopRepNode(rnid, force);
});
}
@Override
@SecureR2Method
public boolean destroyRepNode(final RepNodeId rnid,
final boolean deleteData,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Stop and destroy a RepNode. After this it will be necessary to
* re-create the instance using createRepNode().
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean destroyRepNode(final RepNodeId rnid,
final boolean deleteData,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("destroyRepNode");
String serviceName = rnid.getFullName();
logInfo(serviceName + ": destroyRepNode called");
/**
* Ignore the return value from stopRepNode. The node may
* be running or not, it doesn't matter.
*/
final boolean retval;
try {
sna.stopRepNode(rnid, true);
} finally {
retval =
sna.removeConfigurable(rnid, null, deleteData);
}
return retval;
});
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public void checkParameters(ParameterMap params, ResourceId id,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("checkParameters");
logInfo("checkParameters called");
sna.checkParams(params, id);
});
}
@Override
@SecureR2Method
public void newRepNodeParameters(final ParameterMap params,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Only write the new parameters. The admin will notify the RepNode or
* restart it if that is required. Allow this call to be made for RepNodes
* that are not running. The parameters are a full replacement, not a merge
* set.
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void newRepNodeParameters(final ParameterMap params,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("newRepNodeParameters");
RepNodeParams repNodeParams = new RepNodeParams(params);
String serviceName =
repNodeParams.getRepNodeId().getFullName();
logInfo(serviceName + ": newRepNodeParameters called");
/**
* Change the config file so the RN can see the state.
*/
sna.replaceRepNodeParams(repNodeParams);
});
}
@Override
@SecureR2Method
public void newAdminParameters(final ParameterMap params,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
/**
* Only write the new parameters. The admin will notify the Admin or
* restart it if that is required. Allow this call to be made for Admin
* instances that are not running. The parameters are a full replacement,
* not a merge set.
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void newAdminParameters(final ParameterMap params,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("newAdminParameters");
AdminId adminId = new AdminParams(params).getAdminId();
logInfo(adminId.getFullName() +
": newAdminParameters called");
/**
* Change the config file so the Admin can see the state.
*/
sna.replaceAdminParams(adminId, params);
});
}
@Override
@SecureR2Method
public void newStorageNodeParameters(final ParameterMap params,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void newStorageNodeParameters
(final ParameterMap params,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("newStorageNodeParameters");
logInfo("newStorageNodeParameters called");
sna.replaceStorageNodeParams(params);
});
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public void newGlobalParameters(final ParameterMap params,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("newGlobalParameters");
final GlobalParams globalParams = new GlobalParams(params);
logInfo("newGlobalParameters called");
/*
* Change the config file so the admin and repnode can see the
* state
*/
sna.replaceGlobalParams(globalParams);
});
}
/**
* Snapshot methods
*/
@Override
@SecureR2Method
public void createSnapshot(final RepNodeId rnid,
final String name,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void createSnapshot(final RepNodeId rnid,
final String name,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("snapshot RepNode");
logInfo("createSnapshot called for " + rnid +
", snapshot name: " + name);
sna.snapshotRepNode(rnid, name);
});
}
@Override
@SecureR2Method
public void removeSnapshot(final RepNodeId rnid,
final String name,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void removeSnapshot(final RepNodeId rnid,
final String name,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("removeSnapshot");
logInfo("removeSnapshot called, name is " + name);
sna.removeSnapshot(rnid, name);
});
}
@Override
@SecureR2Method
public void removeAllSnapshots(final RepNodeId rnid,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void removeAllSnapshots(final RepNodeId rnid,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("removeAllSnapshots");
logInfo("removeAllSnapshots called");
sna.removeSnapshot(rnid, null);
});
}
@Override
@SecureR2Method
public void createSnapshot(final AdminId aid,
final String name,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void createSnapshot(final AdminId aid,
final String name,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("snapshot Admin");
logInfo("createSnapshot called for " + aid +
", snapshot name: " + name);
sna.snapshotAdmin(aid, name);
});
}
@Override
@SecureR2Method
public void removeSnapshot(final AdminId aid,
final String name,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void removeSnapshot(final AdminId aid,
final String name,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("removeSnapshot");
logInfo("removeSnapshot called, name is " + name);
sna.removeSnapshot(aid, name);
});
}
@Override
@SecureR2Method
public void removeAllSnapshots(final AdminId aid,
short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void removeAllSnapshots(final AdminId aid,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("removeAllSnapshots");
logInfo("removeAllSnapshots called");
sna.removeSnapshot(aid, null);
});
}
@Override
@SecureR2Method
public String [] listSnapshots(short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public String [] listSnapshots(AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("listSnapshots");
logInfo("listSnapshots called");
return sna.listSnapshots();
});
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public void createSnapshotConfig(String snapshotName,
AuthContext nullCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("createSnapshotConfig");
logInfo(
"createSnapshotConfig called, snapshot name: " +
snapshotName);
sna.createSnapshotConfig(snapshotName);
});
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void removeSnapshotConfig(final String snapshotName,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("removeSnapshotConfig");
logInfo(
"removeSnapshotConfig called, snapshot name: " +
snapshotName);
sna.removeSnapshotConfig(snapshotName);
});
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized void removeAllSnapshotConfigs(AuthContext authCtx,
short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("removeSnapshotConfig");
logInfo("removeSnapshotConfig called, snapshot name");
sna.removeSnapshotConfig(null);
});
}
@Override
@SecureR2Method
public LoadParameters getParams(short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public LoadParameters getParams(AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.SimpleOperation)() ->
sna.getParams());
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public StorageNodeInfo getInfo(AuthContext authCtx, short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.SimpleOperation)() ->
sna.getInfo());
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public KrbPrincipalInfo getKrbPrincipalInfo(AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.SimpleOperation)() ->
sna.getKrbPrincipalInfo());
}
@Override
@SecureR2Method
public StringBuilder getStartupBuffer(final ResourceId rid,
final short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public StringBuilder getStartupBuffer(final ResourceId rid,
AuthContext authCtx,
final short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.SimpleOperation)() -> {
checkRegistered("getStartupBuffer");
return sna.getStartupBuffer(rid);
});
}
/**
* End StorageNodeAgentInterface
*/
/**
* The Storage Node Agent main. It requires two arguments:
* -root
* This is the directory in which the SNA looks for a bootstrap
* configuration file. It is not the KV store root but could be if
* desired.
* -config
* This is the file that contains the bootstrap parameters required by
* BootstrapParams. It has a specific format.
* [-threads ] If present this argument means "run in thread mode" which
* causes the SNA to create threads instead of processes for its managed
* services.
*
* The following two options control the operation of the SNA:
* -shutdown
* This will stop the SNA if it is running.
* -disable-services
* This will disable the services managed by the SNA. If specified
* without the -shutdown option, all services will be disabled before
* the SNA starts. If the SNA is already running an attempt to start
* the SNA with the -disable-services option will fail without disabling
* services. If the disabling services fail for any reason, the SNA will
* not start.
* If the -shutdown option is specified, the SNA is first shutdown
* (if running) then the SNA's services are disabled.
*/
public static void main(String[] args) {
try {
new Main().doMain(args);
} catch (Throwable e) {
System.exit(1);
}
}
/**
* Use a separate class to implement the main method, to simplify testing.
*/
static class Main {
private final StorageNodeAgentImpl snai = new StorageNodeAgentImpl();
private final StorageNodeAgent sna = snai.getStorageNodeAgent();
/**
* Perform the main operation, throwing a RuntimeException that
* contains an appropriate message and the underlying cause if the
* operation fails.
*/
void doMain(String... args) {
try {
sna.parseArgs(args);
final File configPath = new File(sna.getBootstrapDir(),
sna.getBootstrapFile());
if (sna.getSNAParser().getShutdown()) {
if (!configPath.exists()) {
throw new IllegalStateException(
"Bootstrap config file " + configPath +
" does not exist");
}
printlnVerbose("Stopping SNA based on " + configPath);
/* Try telling the SNA to stop. */
try {
sna.stopRunningAgent();
} catch (RuntimeException e) {
printlnVerbose(e.getMessage());
/*
* This code will run if there is a problem shutting
* down the SNA above.
*/
printlnVerbose(
"Attempting to stop all SNAs in root directory " +
sna.getBootstrapDir());
/*
* Kill processes related to the target kvRoot.
*/
final String rootPath = CommandParser.ROOT_FLAG + " " +
sna.getBootstrapDir();
ManagedService.killManagedProcesses(
"StorageNodeAgentImpl", rootPath, null,
sna.getLogger());
ManagedService.killManagedProcesses
(rootPath, null, sna.getLogger());
}
if (sna.getSNAParser().getDisableServices()) {
printlnVerbose("Disabling services");
sna.disableServices();
}
} else if (sna.getSNAParser().getStatus()) {
ServiceStatus status = sna.getRunningAgentStatus();
String message;
CommandResult result;
if (status == ServiceStatus.UNREACHABLE) {
message = "Cannot contact SNA";
result = new CommandResult.CommandFails
(message, ErrorMessage.NOSQL_5300,
CommandResult.NO_CLEANUP_JOBS);
} else {
ObjectNode returnValue = JsonUtils.createObjectNode();
returnValue.put("sna_status", status.name());
message = "SNA Status : " + status.name();
result = new CommandResult.CommandSucceeds
(returnValue.toString());
}
if (sna.getJsonVersion() == CommandParser.JSON_V2) {
System.out.println(
ShellCommandResult.toJsonReport(
sna.getSNAParser().getCommand(), result));
} else if (sna.getJsonVersion() == CommandParser.JSON_V1) {
System.out.println(
Shell.toJsonReport(
sna.getSNAParser().getCommand(), result));
} else {
System.out.println(message);
}
} else {
if (sna.getSNAParser().getDisableServices()) {
printlnVerbose("Disabling services before starting");
sna.disableServices();
}
sna.addShutdownHook();
printlnVerbose("Starting SNA based on " + configPath);
sna.start();
}
} catch (Throwable e) {
String command = sna.getSNAParser().getCommand();
String message = "Failed to " + command + ": " + e.getMessage();
if (sna.getLogger() != null) {
sna.getLogger().severe(
message + "\n" + LoggerUtils.getStackTrace(e));
}
if (sna.getJsonVersion() == CommandParser.JSON_V2) {
CommandResult result =
new CommandResult.CommandFails
(message, ErrorMessage.NOSQL_5300,
CommandResult.NO_CLEANUP_JOBS);
System.err.println(
ShellCommandResult.toJsonReport(command, result));
} else if (sna.getJsonVersion() == CommandParser.JSON_V1) {
CommandResult result =
new CommandResult.CommandFails
(message, ErrorMessage.NOSQL_5300,
CommandResult.NO_CLEANUP_JOBS);
System.err.println(Shell.toJsonReport(command, result));
} else {
System.err.println(message);
}
throw new RuntimeException(message, e);
}
}
/**
* Print a message to standard error if verbose output is enabled.
* Can be overridden for testing. Disabled when the -json flag is
* specified, because the verbose text output would result in invalid
* json output.
*/
void printlnVerbose(String message) {
if (sna.verbose() && sna.getJsonVersion() == -1) {
System.err.println(message);
}
}
}
/**
* Begin MasterBalancingInterface
*/
@Override
@SecureR2Method
public void noteState(final StateInfo stateInfo,
final short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public void noteState(final StateInfo stateInfo,
final AuthContext authCtx,
final short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("noteState");
logInfo("noteState called");
sna.getMasterBalanceManager().
noteState(stateInfo, authCtx, serialVersion);
});
}
@Override
@SecureR2Method
public MDInfo getMDInfo(final short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public MDInfo getMDInfo(final AuthContext authCtx,
final short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("getMD");
logFine("getMD called");
return sna.getMasterBalanceManager().getMDInfo(authCtx,
serialVersion);
});
}
@Override
@SecureR2Method
public boolean getMasterLease(final MasterLeaseInfo masterLease,
final short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public boolean getMasterLease(final MasterLeaseInfo masterLease,
final AuthContext authCtx,
final short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("lease");
logFine("Master lease called");
return sna.getMasterBalanceManager().
getMasterLease(masterLease, authCtx, serialVersion);
});
}
@Override
@SecureR2Method
public boolean cancelMasterLease(final StorageNode lesseeSN,
final RepNode rn,
final short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public boolean cancelMasterLease(final StorageNode lesseeSN,
final RepNode rn,
final AuthContext authCtx,
final short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("cancelLease");
logFine("cancelLease called");
return sna.getMasterBalanceManager().
cancelMasterLease(lesseeSN, rn, authCtx, serialVersion);
});
}
@Override
@SecureR2Method
public void overloadedNeighbor(final StorageNodeId storageNodeId,
final short serialVersion)
throws RemoteException {
throw invalidR2MethodException();
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public void overloadedNeighbor(final StorageNodeId storageNodeId,
final AuthContext authCtx,
final short serialVersion)
throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
sna.getMasterBalanceManager().
overloadedNeighbor(storageNodeId, authCtx, serialVersion);
});
}
/**
* Does this ArbNode exist in the configuration file?
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean arbNodeExists(final ArbNodeId arbNodeId,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("arbNodeExists");
return sna.lookupArbNode(arbNodeId) != null;
});
}
/**
* Create a new ArbNode instance based on the configuration information.
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean
createArbNode(final ParameterMap params,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("createArbNode");
ArbNodeParams arbNodeParams = new ArbNodeParams(params);
return sna.createArbNode(arbNodeParams);
});
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public boolean startArbNode(final ArbNodeId arbNodeId, AuthContext authCtx,
short serialVersion) throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("startArbNode");
return sna.startArbNode(arbNodeId);
});
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public boolean stopArbNode(final ArbNodeId arbNodeId, final boolean force,
AuthContext authCtx, short serialVersion) throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("stopArbNode");
return sna.stopArbNode(arbNodeId, force);
});
}
/**
* Stop and destroy a ArbNode. After this it will be necessary to
* re-create the instance using createArbNode().
*/
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public synchronized boolean destroyArbNode(final ArbNodeId anid,
final boolean deleteData,
AuthContext authCtx,
short serialVersion)
throws RemoteException {
return faultHandler.execute
((ProcessFaultHandler.Operation)() -> {
checkRegistered("destroyArbNode");
String serviceName = anid.getFullName();
logInfo(serviceName + ": destroyArbNode called");
/**
* Ignore the return value from stopArbNode. The node may
* be running or not, it doesn't matter.
*/
final boolean retval;
try {
sna.stopArbNode(anid, true);
} finally {
retval =
sna.removeConfigurable(anid, null, deleteData);
}
return retval;
});
}
@Override
@SecureAutoMethod(privileges = { KVStorePrivilegeLabel.INTLOPER })
public void newArbNodeParameters(final ParameterMap params,
AuthContext authCtx, short serialVersion) throws RemoteException {
faultHandler.execute
((ProcessFaultHandler.Procedure)() -> {
checkRegistered("newArbNodeParameters");
ArbNodeParams arbNodeParams = new ArbNodeParams(params);
String serviceName =
arbNodeParams.getArbNodeId().getFullName();
logInfo(serviceName + ": newArbNodeParameters called");
/**
* Change the config file so the AN can see the state.
*/
sna.replaceArbNodeParams(arbNodeParams);
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy