/**
This file is part of Waarp Project.
Copyright 2009, Frederic Bregier, and individual contributors by the @author
tags. See the COPYRIGHT.txt in the distribution for a full listing of
individual contributors.
All Waarp Project is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Waarp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Waarp . If not, see <http://www.gnu.org/licenses/>.
*/
package org.waarp.openr66.protocol.localhandler;
import static org.waarp.openr66.context.R66FiniteDualStates.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import io.netty.channel.Channel;
import org.waarp.common.command.exception.CommandAbstractException;
import org.waarp.common.database.DbPreparedStatement;
import org.waarp.common.database.DbSession;
import org.waarp.common.database.data.AbstractDbData;
import org.waarp.common.database.exception.WaarpDatabaseException;
import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
import org.waarp.common.database.exception.WaarpDatabaseNoDataException;
import org.waarp.common.database.exception.WaarpDatabaseSqlException;
import org.waarp.common.exception.FileTransferException;
import org.waarp.common.exception.InvalidArgumentException;
import org.waarp.common.json.JsonHandler;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
import org.waarp.common.role.RoleDefault.ROLE;
import org.waarp.common.utility.WaarpStringUtils;
import org.waarp.openr66.configuration.AuthenticationFileBasedConfiguration;
import org.waarp.openr66.configuration.RuleFileBasedConfiguration;
import org.waarp.openr66.context.ErrorCode;
import org.waarp.openr66.context.R66Result;
import org.waarp.openr66.context.filesystem.R66Dir;
import org.waarp.openr66.context.filesystem.R66File;
import org.waarp.openr66.context.task.ExecJavaTask;
import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
import org.waarp.openr66.database.DbConstant;
import org.waarp.openr66.database.data.DbHostAuth;
import org.waarp.openr66.database.data.DbHostConfiguration;
import org.waarp.openr66.database.data.DbRule;
import org.waarp.openr66.database.data.DbTaskRunner;
import org.waarp.openr66.protocol.configuration.Configuration;
import org.waarp.openr66.protocol.configuration.Messages;
import org.waarp.openr66.protocol.configuration.PartnerConfiguration;
import org.waarp.openr66.protocol.exception.OpenR66DatabaseGlobalException;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessException;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessRemoteFileNotFoundException;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoDataException;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoSslException;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolNotAuthenticatedException;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolShutdownException;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolSystemException;
import org.waarp.openr66.protocol.localhandler.packet.BlockRequestPacket;
import org.waarp.openr66.protocol.localhandler.packet.BusinessRequestPacket;
import org.waarp.openr66.protocol.localhandler.packet.ErrorPacket;
import org.waarp.openr66.protocol.localhandler.packet.InformationPacket;
import org.waarp.openr66.protocol.localhandler.packet.JsonCommandPacket;
import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
import org.waarp.openr66.protocol.localhandler.packet.RequestPacket;
import org.waarp.openr66.protocol.localhandler.packet.ShutdownPacket;
import org.waarp.openr66.protocol.localhandler.packet.TestPacket;
import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.BandwidthJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.BusinessRequestJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.ConfigExportJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.ConfigExportResponseJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.ConfigImportJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.ConfigImportResponseJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.InformationJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.JsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.LogJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.LogResponseJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.ShutdownOrBlockJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.ShutdownRequestJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.StopOrCancelJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.RestartTransferJsonPacket;
import org.waarp.openr66.protocol.localhandler.packet.json.TransferRequestJsonPacket;
import org.waarp.openr66.protocol.networkhandler.NetworkChannelReference;
import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
import org.waarp.openr66.protocol.utils.ChannelCloseTimer;
import org.waarp.openr66.protocol.utils.ChannelUtils;
import org.waarp.openr66.protocol.utils.NbAndSpecialId;
import org.waarp.openr66.protocol.utils.R66Future;
import org.waarp.openr66.protocol.utils.R66ShutdownHook;
import org.waarp.openr66.protocol.utils.TransferUtils;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Class to implement actions related to extra server actions: shutdown, bandwidth control,
* configuration import/export, log purge, request restart/stop/cancel, business request, block new request control,
* information request and transfer request.
*
* Can be used in both standard mode (original packet), or in JSON mode.
*
* @author "Frederic Bregier"
*
*/
public class ServerActions extends ConnectionActions {
/**
* Internal Logger
*/
private static final WaarpLogger logger = WaarpLoggerFactory
.getLogger(ServerActions.class);
public ServerActions() {
}
/**
* Test reception
*
* @param channel
* @param packet
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolPacketException
*/
public void test(Channel channel, TestPacket packet)
throws OpenR66ProtocolNotAuthenticatedException,
OpenR66ProtocolPacketException {
if (!session.isAuthenticated()) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not authenticated while Test received");
}
// simply write back after+1
packet.update();
if (packet.getType() == LocalPacketFactory.VALIDPACKET) {
ValidPacket validPacket = new ValidPacket(packet.toString(), null,
LocalPacketFactory.TESTPACKET);
R66Result result = new R66Result(session, true,
ErrorCode.CompleteOk, null);
result.setOther(validPacket);
session.newState(VALIDOTHER);
localChannelReference.validateRequest(result);
ChannelUtils.writeAbstractLocalPacket(localChannelReference, validPacket, true);
logger.warn("Valid TEST MESSAGE from " +
session.getAuth().getUser() +
" [" + localChannelReference.getNetworkChannel().remoteAddress() +
"] Msg=" + packet.toString());
ChannelCloseTimer.closeFutureChannel(channel);
packet.clear();
} else {
ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, false);
}
}
/**
* Receive a request of information
*
* @param channel
* @param packet
* @throws CommandAbstractException
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolNoDataException
* @throws OpenR66ProtocolPacketException
*/
public void information(Channel channel, InformationPacket packet)
throws OpenR66ProtocolNotAuthenticatedException,
OpenR66ProtocolNoDataException, OpenR66ProtocolPacketException {
byte request = packet.getRequest();
String rulename = packet.getRulename();
String filename = packet.getFilename();
packet.clear();
long id = DbConstant.ILLEGALVALUE;
if (request == -1) {
try {
id = Long.parseLong(rulename);
} catch (NumberFormatException e) {
logger.error("Incorrect Transfer ID", e);
throw new OpenR66ProtocolNoDataException("Incorrect Transfer ID", e);
}
}
boolean isTo = filename.equals("1");
ValidPacket validPacket = null;
if (request == -1) {
validPacket = informationRequest(id, isTo, rulename, false);
} else {
validPacket = informationFile(request, rulename, filename, false);
}
if (validPacket != null) {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
validPacket, true);
channel.close();
} else {
session.newState(ERROR);
ErrorPacket error = new ErrorPacket("Error while Request " + request,
ErrorCode.Internal.getCode(), ErrorPacket.FORWARDCLOSECODE);
ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
ChannelCloseTimer.closeFutureChannel(channel);
}
}
/**
* Receive a validation or a special request
*
* @param channel
* @param packet
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66RunnerErrorException
* @throws OpenR66ProtocolSystemException
* @throws OpenR66ProtocolBusinessException
*/
public void valid(Channel channel, ValidPacket packet)
throws OpenR66ProtocolNotAuthenticatedException,
OpenR66RunnerErrorException, OpenR66ProtocolSystemException,
OpenR66ProtocolBusinessException {
// SHUTDOWNPACKET does not need authentication
if (packet.getTypeValid() != LocalPacketFactory.SHUTDOWNPACKET &&
(!session.isAuthenticated())) {
logger.warn("Valid packet received while not authenticated: {} {}", packet, session);
session.newState(ERROR);
packet.clear();
throw new OpenR66ProtocolNotAuthenticatedException(
"Not authenticated while Valid received");
}
switch (packet.getTypeValid()) {
case LocalPacketFactory.SHUTDOWNPACKET: {
int rank = -1;
if (session.getRunner() != null &&
session.getRunner().isInTransfer()) {
String srank = packet.getSmiddle();
if (srank != null && !srank.isEmpty()) {
// Save last rank from remote point of view
try {
rank = Integer.parseInt(srank);
} catch (NumberFormatException e) {
// ignore
}
}
}
R66Result result = new R66Result(
new OpenR66ProtocolShutdownException(), session, true,
ErrorCode.Shutdown, session.getRunner());
result.setOther(packet);
rank = shutdownRequest(result, rank);
if (rank >= 0) {
packet.setSmiddle(Integer.toString(rank));
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet,
true);
} catch (OpenR66ProtocolPacketException e) {
}
}
shutdownLocalChannel(channel);
break;
}
case LocalPacketFactory.STOPPACKET:
case LocalPacketFactory.CANCELPACKET: {
String[] keys = packet.getSmiddle().split(" ");
long id = Long.parseLong(keys[2]);
session.newState(VALIDOTHER);
R66Result resulttest = stopOrCancel(packet.getTypeValid(), keys[0], keys[1], id);
// inform back the requester
ValidPacket valid = new ValidPacket(packet.getSmiddle(), resulttest.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
resulttest.setOther(packet);
localChannelReference.validateRequest(resulttest);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
session.setStatus(27);
channel.close();
break;
}
case LocalPacketFactory.VALIDPACKET: {
// header = ?; middle = requested+blank+requester+blank+specialId
// note: might contains one more argument = time to reschedule in yyyyMMddHHmmss format
String[] keys = packet.getSmiddle().split(" ");
ValidPacket valid = null;
if (keys.length < 3) {
// not enough args
valid = new ValidPacket(packet.getSmiddle(),
ErrorCode.IncorrectCommand.getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
R66Result resulttest = new R66Result(
new OpenR66ProtocolBusinessRemoteFileNotFoundException("Not enough arguments"),
session, true,
ErrorCode.IncorrectCommand, null);
resulttest.setOther(packet);
localChannelReference.invalidateRequest(resulttest);
} else {
long id = Long.parseLong(keys[2]);
Date date = null;
if (keys.length > 3) {
// time to reschedule in yyyyMMddHHmmss format
logger.debug("Debug: restart with " + keys[3]);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
try {
date = dateFormat.parse(keys[3]);
} catch (ParseException e) {
}
}
session.newState(VALIDOTHER);
R66Result result = requestRestart(keys[0], keys[1], id, date);
valid = new ValidPacket(packet.getSmiddle(),
result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
result.setOther(packet);
if (isCodeValid(result.getCode())) {
localChannelReference.validateRequest(result);
} else {
localChannelReference.invalidateRequest(result);
}
}
// inform back the requester
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.REQUESTUSERPACKET: {
session.newState(VALIDOTHER);
// Validate user request
R66Result resulttest = new R66Result(session, true,
ErrorCode.getFromCode(packet.getSmiddle()), null);
resulttest.setOther(packet);
switch (resulttest.getCode()) {
case CompleteOk:
case InitOk:
case PostProcessingOk:
case PreProcessingOk:
case QueryAlreadyFinished:
case QueryStillRunning:
case Running:
case TransferOk:
break;
default:
localChannelReference.invalidateRequest(resulttest);
session.setStatus(102);
channel.close();
return;
}
localChannelReference.validateRequest(resulttest);
session.setStatus(28);
channel.close();
break;
}
case LocalPacketFactory.LOGPACKET:
case LocalPacketFactory.LOGPURGEPACKET: {
session.newState(VALIDOTHER);
// should be from the local server or from an authorized hosts: LOGCONTROL
try {
if (!session.getAuth().getUser().equals(
Configuration.configuration.getHostId(session.getAuth().isSsl())) &&
!session.getAuth().isValidRole(ROLE.LOGCONTROL)) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated");
}
} catch (OpenR66ProtocolNoSslException e1) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated since SSL is not supported", e1);
}
String sstart = packet.getSheader();
String sstop = packet.getSmiddle();
boolean isPurge = (packet.getTypeValid() == LocalPacketFactory.LOGPURGEPACKET);
Timestamp start = (sstart == null || sstart.isEmpty()) ? null :
Timestamp.valueOf(sstart);
Timestamp stop = (sstop == null || sstop.isEmpty()) ? null :
Timestamp.valueOf(sstop);
packet.clear();
// create export of log and optionally purge them from database
DbPreparedStatement getValid = null;
String filename = Configuration.configuration.getBaseDirectory() +
Configuration.configuration.getArchivePath() + R66Dir.SEPARATOR +
Configuration.configuration.getHOST_ID() + "_" + System.currentTimeMillis() +
"_runners.xml";
try {
getValid =
DbTaskRunner.getLogPrepareStatement(
localChannelReference.getDbSession(),
start, stop);
DbTaskRunner.writeXMLWriter(getValid, filename);
} catch (WaarpDatabaseNoConnectionException e1) {
throw new OpenR66ProtocolBusinessException(e1);
} catch (WaarpDatabaseSqlException e1) {
throw new OpenR66ProtocolBusinessException(e1);
} finally {
if (getValid != null) {
getValid.realClose();
}
}
// in case of purge
int nb = 0;
if (isPurge) {
// purge in same interval all runners with globallaststep
// as ALLDONETASK or ERRORTASK
if (Configuration.configuration.getR66Mib() != null) {
Configuration.configuration.getR66Mib().notifyWarning(
"Purge Log Order received", session.getAuth().getUser());
}
try {
nb = DbTaskRunner.purgeLogPrepareStatement(
localChannelReference.getDbSession(),
start, stop);
} catch (WaarpDatabaseNoConnectionException e) {
throw new OpenR66ProtocolBusinessException(e);
} catch (WaarpDatabaseSqlException e) {
throw new OpenR66ProtocolBusinessException(e);
}
}
R66Result result = new R66Result(session, true, ErrorCode.CompleteOk, null);
// Now answer
ValidPacket valid = new ValidPacket(filename + " " + nb, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.CONFEXPORTPACKET: {
String shost = packet.getSheader();
String srule = packet.getSmiddle();
boolean bhost = Boolean.parseBoolean(shost);
boolean brule = Boolean.parseBoolean(srule);
packet.clear();
session.newState(VALIDOTHER);
String[] sresult = configExport(bhost, brule, false, false, false);
R66Result result = null;
if (sresult[0] != null || sresult[1] != null) {
result = new R66Result(session, true, ErrorCode.CompleteOk, null);
} else {
result = new R66Result(session, true, ErrorCode.TransferError, null);
}
// Now answer
ValidPacket valid = new ValidPacket(shost + " " + srule, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.CONFIMPORTPACKET: {
session.newState(VALIDOTHER);
// Authentication must be the local server or CONFIGADMIN authorization
try {
if (!session.getAuth().getUser().equals(
Configuration.configuration.getHostId(session.getAuth().isSsl())) &&
!session.getAuth().isValidRole(ROLE.CONFIGADMIN)) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated");
}
} catch (OpenR66ProtocolNoSslException e1) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated since SSL is not supported", e1);
}
if (Configuration.configuration.getR66Mib() != null) {
Configuration.configuration.getR66Mib().notifyWarning(
"Import Configuration Order received", session.getAuth().getUser());
}
String shost = packet.getSheader();
String srule = packet.getSmiddle();
boolean bhostPurge = shost.startsWith("1 ");
shost = shost.substring(2);
boolean brulePurge = srule.startsWith("1 ");
srule = srule.substring(2);
boolean bhost = !shost.isEmpty();
boolean brule = !srule.isEmpty();
packet.clear();
if (bhost) {
DbHostAuth[] oldHosts = null;
if (bhostPurge) {
// Need to first delete all entries
try {
oldHosts = DbHostAuth.deleteAll(localChannelReference.getDbSession());
} catch (WaarpDatabaseException e) {
// ignore
}
}
String filename = shost;
if (AuthenticationFileBasedConfiguration.loadAuthentication(
Configuration.configuration,
filename)) {
shost = "Host:OK";
} else {
logger.error("Error in Load Hosts");
shost = "Host:KO";
bhost = false;
}
if (!bhost) {
if (oldHosts != null) {
for (DbHostAuth dbHost : oldHosts) {
try {
if (!dbHost.exist()) {
dbHost.insert();
}
} catch (WaarpDatabaseException e1) {
// ignore
}
}
}
}
}
if (brule) {
DbRule[] oldRules = null;
if (brulePurge) {
// Need to first delete all entries
try {
oldRules = DbRule.deleteAll(localChannelReference.getDbSession());
} catch (WaarpDatabaseException e) {
// ignore
}
}
File file = new File(srule);
try {
RuleFileBasedConfiguration.getMultipleFromFile(file);
srule = "Rule:OK";
brule = true;
} catch (WaarpDatabaseNoConnectionException e) {
logger.error("Error", e);
srule = "Rule:KO";
brule = false;
} catch (WaarpDatabaseSqlException e) {
logger.error("Error", e);
srule = "Rule:KO";
brule = false;
} catch (WaarpDatabaseNoDataException e) {
logger.error("Error", e);
srule = "Rule:KO";
brule = false;
} catch (WaarpDatabaseException e) {
logger.error("Error", e);
srule = "Rule:KO";
brule = false;
}
if (!brule) {
if (oldRules != null) {
for (DbRule dbRule : oldRules) {
try {
if (!dbRule.exist()) {
dbRule.insert();
}
} catch (WaarpDatabaseException e1) {
// ignore
}
}
}
}
}
R66Result result = null;
if (brule || bhost) {
result = new R66Result(session, true, ErrorCode.CompleteOk, null);
} else {
result = new R66Result(session, true, ErrorCode.TransferError, null);
}
// Now answer
ValidPacket valid = new ValidPacket(shost + " " + srule, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.INFORMATIONPACKET: {
session.newState(VALIDOTHER);
// Validate user request
R66Result resulttest = new R66Result(session, true,
ErrorCode.CompleteOk, null);
resulttest.setOther(packet);
localChannelReference.validateRequest(resulttest);
channel.close();
break;
}
case LocalPacketFactory.BANDWIDTHPACKET: {
String[] splitglobal = packet.getSheader().split(" ");
String[] splitsession = packet.getSmiddle().split(" ");
packet.clear();
R66Result result = new R66Result(session, true, ErrorCode.CompleteOk, null);
ValidPacket valid = null;
if (splitglobal.length < 2 || splitsession.length < 2) {
// request of current values
session.newState(VALIDOTHER);
long[] lresult = bandwidth(false, 0, 0, 0, 0);
// Now answer
valid = new ValidPacket(lresult[0] + " " + lresult[1] +
" " + lresult[2] + " " + lresult[3], result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
} else {
session.newState(VALIDOTHER);
bandwidth(true, Long.parseLong(splitglobal[0]), Long.parseLong(splitglobal[1]),
Long.parseLong(splitsession[0]), Long.parseLong(splitsession[1]));
// Now answer
valid = new ValidPacket("Bandwidth changed", result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
}
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.TESTPACKET: {
session.newState(VALIDOTHER);
logger.info("Valid TEST MESSAGE: " + packet.toString());
R66Result resulttest = new R66Result(session, true,
ErrorCode.CompleteOk, null);
resulttest.setOther(packet);
localChannelReference.validateRequest(resulttest);
channel.close();
break;
}
default:
logger.info("Validation is ignored: " + packet.getTypeValid());
packet.clear();
}
}
/**
* Receive a json request
*
* @param channel
* @param packet
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66RunnerErrorException
* @throws OpenR66ProtocolSystemException
* @throws OpenR66ProtocolBusinessException
* @throws OpenR66ProtocolShutdownException
* @throws OpenR66ProtocolPacketException
* @throws OpenR66ProtocolNoDataException
*/
public void jsonCommand(Channel channel, JsonCommandPacket packet)
throws OpenR66ProtocolNotAuthenticatedException,
OpenR66RunnerErrorException, OpenR66ProtocolSystemException,
OpenR66ProtocolBusinessException, OpenR66ProtocolShutdownException, OpenR66ProtocolPacketException,
OpenR66ProtocolNoDataException {
// SHUTDOWNPACKET does not need authentication
if (packet.getTypeValid() != LocalPacketFactory.SHUTDOWNPACKET &&
!session.isAuthenticated()) {
logger.warn("JsonCommand packet received while not authenticated: {} {}", packet, session);
session.newState(ERROR);
throw new OpenR66ProtocolNotAuthenticatedException(
"Not authenticated while Valid received");
}
JsonPacket json = packet.getJsonRequest();
if (json == null) {
ErrorCode code = ErrorCode.CommandNotFound;
R66Result resulttest = new R66Result(session, true,
code, session.getRunner());
json = new JsonPacket();
json.setComment("Invalid command");
json.setRequestUserPacket(packet.getTypeValid());
JsonCommandPacket valid = new JsonCommandPacket(json, resulttest.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
resulttest.setOther(packet);
localChannelReference.validateRequest(resulttest);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
session.setStatus(99);
channel.close();
return;
}
json.setRequestUserPacket(packet.getTypeValid());
switch (packet.getTypeValid()) {
case LocalPacketFactory.SHUTDOWNPACKET: {
ShutdownRequestJsonPacket node = (ShutdownRequestJsonPacket) json;
int rank = -1;
if (session.getRunner() != null &&
session.getRunner().isInTransfer()) {
rank = node.getRank();
}
R66Result result = new R66Result(
new OpenR66ProtocolShutdownException(), session, true,
ErrorCode.Shutdown, session.getRunner());
result.setOther(packet);
rank = shutdownRequest(result, rank);
if (rank >= 0) {
node.setRank(rank);
JsonCommandPacket valid = new JsonCommandPacket(node, result.getCode().getCode(),
LocalPacketFactory.SHUTDOWNPACKET);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference, valid,
true);
} catch (OpenR66ProtocolPacketException e) {
}
}
shutdownLocalChannel(channel);
break;
}
case LocalPacketFactory.BLOCKREQUESTPACKET: {
ShutdownOrBlockJsonPacket node = (ShutdownOrBlockJsonPacket) json;
byte[] key = node.getKey();
if (node.isShutdownOrBlock()) {
// Shutdown
session.newState(SHUTDOWN);
shutdown(key, node.isRestartOrBlock());
} else {
// Block
R66Result result = blockRequest(key, node.isRestartOrBlock());
node.setComment((node.isRestartOrBlock() ? "Block" : "Unblock") + " new request");
JsonCommandPacket valid = new JsonCommandPacket(json, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
}
break;
}
case LocalPacketFactory.BUSINESSREQUESTPACKET: {
BusinessRequestJsonPacket node = (BusinessRequestJsonPacket) json;
if (node.isToApplied()) {
session.newState(BUSINESSD);
}
R66Future future = businessRequest(node.isToApplied(), node.getClassName(), node.getArguments(),
node.getExtraArguments(), node.getDelay());
if (future != null && !future.isSuccess()) {
R66Result result = future.getResult();
if (result == null) {
result = new R66Result(session, false, ErrorCode.ExternalOp, session.getRunner());
}
logger.info("Task in Error:" + node.getClassName() + " " + result);
if (!result.isAnswered()) {
node.setValidated(false);
session.newState(ERROR);
ErrorPacket error = new ErrorPacket(
"BusinessRequest in error: for " + node.toString() + " since " +
result.getMessage(),
result.getCode().getCode(), ErrorPacket.FORWARDCLOSECODE);
ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
session.setStatus(203);
}
session.setStatus(204);
}
break;
}
case LocalPacketFactory.INFORMATIONPACKET: {
InformationJsonPacket node = (InformationJsonPacket) json;
ValidPacket validPacket = null;
if (node.isIdRequest()) {
validPacket = informationRequest(node.getId(), node.isTo(), node.getRulename(), false);
} else {
validPacket = informationFile(node.getRequest(), node.getRulename(), node.getFilename(), false);
}
if (validPacket != null) {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
validPacket, true);
channel.close();
} else {
session.newState(ERROR);
ErrorPacket error = new ErrorPacket("Error while Request " + node,
ErrorCode.Internal.getCode(), ErrorPacket.FORWARDCLOSECODE);
ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
ChannelCloseTimer.closeFutureChannel(channel);
}
break;
}
case LocalPacketFactory.REQUESTPACKET: {
TransferRequestJsonPacket node = (TransferRequestJsonPacket) json;
R66Result result = transferRequest(node);
if (isCodeValid(result.getCode())) {
JsonCommandPacket valid = new JsonCommandPacket(json, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
result.setOther(packet);
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
session.setStatus(27);
channel.close();
} else {
result.setOther(packet);
localChannelReference.invalidateRequest(result);
ErrorPacket error = new ErrorPacket(
"TransferRequest in error: for " + node.toString() + " since " +
result.getMessage(),
result.getCode().getCode(), ErrorPacket.FORWARDCLOSECODE);
ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
ChannelCloseTimer.closeFutureChannel(channel);
}
break;
}
case LocalPacketFactory.STOPPACKET:
case LocalPacketFactory.CANCELPACKET: {
StopOrCancelJsonPacket node = (StopOrCancelJsonPacket) json;
R66Result resulttest;
if (node.getRequested() == null || node.getRequester() == null
|| node.getSpecialid() == DbConstant.ILLEGALVALUE) {
ErrorCode code = ErrorCode.CommandNotFound;
resulttest = new R66Result(session, true,
code, session.getRunner());
} else {
String reqd = node.getRequested();
String reqr = node.getRequester();
long id = node.getSpecialid();
session.newState(VALIDOTHER);
resulttest = stopOrCancel(packet.getTypeValid(), reqd, reqr, id);
}
// inform back the requester
JsonCommandPacket valid = new JsonCommandPacket(json, resulttest.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
resulttest.setOther(packet);
localChannelReference.validateRequest(resulttest);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
session.setStatus(27);
channel.close();
break;
}
case LocalPacketFactory.VALIDPACKET: {
RestartTransferJsonPacket node = (RestartTransferJsonPacket) json;
session.newState(VALIDOTHER);
R66Result result = requestRestart(node.getRequested(), node.getRequester(), node.getSpecialid(),
node.getRestarttime());
result.setOther(packet);
JsonCommandPacket valid = new JsonCommandPacket(node,
result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
if (isCodeValid(result.getCode())) {
localChannelReference.validateRequest(result);
} else {
localChannelReference.invalidateRequest(result);
}
// inform back the requester
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.REQUESTUSERPACKET: {
session.newState(VALIDOTHER);
// Validate user request
R66Result resulttest = new R66Result(session, true,
ErrorCode.getFromCode(packet.getResult()), null);
resulttest.setOther(packet);
switch (resulttest.getCode()) {
case CompleteOk:
case InitOk:
case PostProcessingOk:
case PreProcessingOk:
case QueryAlreadyFinished:
case QueryStillRunning:
case Running:
case TransferOk:
break;
default:
localChannelReference.invalidateRequest(resulttest);
session.setStatus(102);
channel.close();
return;
}
localChannelReference.validateRequest(resulttest);
session.setStatus(28);
channel.close();
break;
}
case LocalPacketFactory.LOGPACKET:
case LocalPacketFactory.LOGPURGEPACKET: {
LogJsonPacket node = (LogJsonPacket) json;
boolean purge = node.isPurge();
boolean clean = node.isClean();
Timestamp start = (node.getStart() == null) ? null :
new Timestamp(node.getStart().getTime());
Timestamp stop = (node.getStop() == null) ? null :
new Timestamp(node.getStop().getTime());
String startid = node.getStartid();
String stopid = node.getStopid();
String rule = node.getRule();
String request = node.getRequest();
boolean pending = node.isStatuspending();
boolean transfer = node.isStatustransfer();
boolean done = node.isStatusdone();
boolean error = node.isStatuserror();
boolean isPurge = (packet.getTypeValid() == LocalPacketFactory.LOGPURGEPACKET || purge);
session.newState(VALIDOTHER);
String sresult[] = logPurge(purge, clean, start, stop, startid, stopid, rule, request, pending,
transfer, done, error, isPurge);
LogResponseJsonPacket newjson = new LogResponseJsonPacket();
newjson.fromJson(node);
// Now answer
newjson.setCommand(packet.getTypeValid());
newjson.setFilename(sresult[0]);
newjson.setExported(Long.parseLong(sresult[1]));
newjson.setPurged(Long.parseLong(sresult[2]));
R66Result result = new R66Result(session, true, ErrorCode.CompleteOk, null);
JsonCommandPacket valid = new JsonCommandPacket(newjson, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.CONFEXPORTPACKET: {
// host, rule, business, alias, roles
ConfigExportJsonPacket node = (ConfigExportJsonPacket) json;
boolean bhost = node.isHost();
boolean brule = node.isRule();
boolean bbusiness = node.isBusiness();
boolean balias = node.isAlias();
boolean broles = node.isRoles();
session.newState(VALIDOTHER);
String sresult[] = configExport(bhost, brule, bbusiness, balias, broles);
// Now answer
ConfigExportResponseJsonPacket resp = new ConfigExportResponseJsonPacket();
resp.fromJson(node);
resp.setFilehost(sresult[0]);
resp.setFilerule(sresult[1]);
resp.setFilebusiness(sresult[2]);
resp.setFilealias(sresult[3]);
resp.setFileroles(sresult[4]);
R66Result result = null;
if (resp.getFilerule() != null || resp.getFilehost() != null ||
resp.getFilebusiness() != null || resp.getFilealias() != null ||
resp.getFileroles() != null) {
result = new R66Result(session, true, ErrorCode.CompleteOk, null);
} else {
result = new R66Result(session, true, ErrorCode.TransferError, null);
}
JsonCommandPacket valid = new JsonCommandPacket(resp, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.CONFIMPORTPACKET: {
ConfigImportResponseJsonPacket resp = configImport((ConfigImportJsonPacket) json);
R66Result result = null;
if (resp.isImportedhost() || resp.isImportedrule() ||
resp.isImportedbusiness() || resp.isImportedalias() ||
resp.isImportedroles()) {
result = new R66Result(session, true, ErrorCode.CompleteOk, null);
} else {
result = new R66Result(session, true, ErrorCode.TransferError, null);
}
JsonCommandPacket valid = new JsonCommandPacket(resp, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
logger.debug(valid.getRequest());
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.BANDWIDTHPACKET: {
// setter, writeglobal, readglobal, writesession, readsession
BandwidthJsonPacket node = (BandwidthJsonPacket) json;
boolean setter = node.isSetter();
// request of current values or set new values
session.newState(VALIDOTHER);
long[] lresult = bandwidth(setter,
node.getWriteglobal(), node.getReadglobal(),
node.getWritesession(), node.getReadsession());
// Now answer
node.setWriteglobal(lresult[0]);
node.setReadglobal(lresult[1]);
node.setWritesession(lresult[2]);
node.setReadsession(lresult[3]);
R66Result result = new R66Result(session, true, ErrorCode.CompleteOk, null);
JsonCommandPacket valid = new JsonCommandPacket(node, result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
localChannelReference.validateRequest(result);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
break;
}
case LocalPacketFactory.TESTPACKET: {
session.newState(VALIDOTHER);
logger.info("Valid TEST MESSAGE: " + packet.toString());
R66Result resulttest = new R66Result(session, true,
ErrorCode.CompleteOk, null);
resulttest.setOther(packet);
localChannelReference.validateRequest(resulttest);
channel.close();
break;
}
default:
logger.info("Validation is ignored: " + packet.getTypeValid());
}
}
/**
* Shutdown Local Channel after the request is shutdown
*
* @param channel
*/
private final void shutdownLocalChannel(Channel channel) {
session.setStatus(26);
logger.warn("Will Close Local from Network Channel since Remote shutdown received");
ChannelCloseTimer.closeFutureChannel(channel);
try {
Thread.sleep(Configuration.WAITFORNETOP * 2);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
NetworkChannelReference ncr = localChannelReference.getNetworkChannelObject();
NetworkTransaction.shuttingDownNetworkChannel(ncr);
NetworkTransaction.shuttingdownNetworkChannelsPerHostID(ncr.getHostId());
}
/**
* Shutdown the current request with an optional rank to set for future restart
*
* @param result
* the result to be associated in finalization
* @param rank
* the future rank to set if restart (<0 if none)
* @return the rank to set for future restart if any (< 0 if none)
* @throws OpenR66RunnerErrorException
* @throws OpenR66ProtocolSystemException
*/
private final int shutdownRequest(R66Result result, int rank)
throws OpenR66RunnerErrorException, OpenR66ProtocolSystemException {
session.newState(SHUTDOWN);
logger.warn("Shutdown received so Will close channel" +
localChannelReference.toString());
if (session.getRunner() != null &&
session.getRunner().isInTransfer()) {
DbTaskRunner runner = session.getRunner();
if (rank >= 0) {
// Save last rank from remote point of view
runner.setRankAtStartup(rank);
session.setFinalizeTransfer(false, result);
} else if (!runner.isSender()) {
// is receiver so informs back for the rank to use next time
int newrank = runner.getRank();
try {
runner.saveStatus();
} catch (OpenR66RunnerErrorException e) {
}
session.setFinalizeTransfer(false, result);
return newrank;
} else {
session.setFinalizeTransfer(false, result);
}
} else {
session.setFinalizeTransfer(false, result);
}
return -1;
}
/**
* Get or Set the bandwidth configuration
*
* @param setter
* @param writeglobal
* @param readglobal
* @param writesession
* @param readsession
* @return the 4 current values for the bandwidth (in the same order)
* @throws OpenR66ProtocolNotAuthenticatedException
*/
public final long[] bandwidth(boolean setter,
long writeglobal, long readglobal,
long writesession, long readsession)
throws OpenR66ProtocolNotAuthenticatedException {
// Authentication must be the local server or LIMIT authorization
try {
if (!session.getAuth().getUser().equals(
Configuration.configuration.getHostId(session.getAuth().isSsl()))
&& !session.getAuth().isValidRole(ROLE.LIMIT)) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated");
}
} catch (OpenR66ProtocolNoSslException e1) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated since SSL is not supported", e1);
}
if (!setter) {
// request of current values
// Now answer
return new long[] { Configuration.configuration.getServerGlobalWriteLimit(),
Configuration.configuration.getServerGlobalReadLimit(),
Configuration.configuration.getServerChannelWriteLimit(),
Configuration.configuration.getServerChannelReadLimit() };
} else {
long wgl = (writeglobal / 10) * 10;
long rgl = (readglobal / 10) * 10;
long wsl = (writesession / 10) * 10;
long rsl = (readsession / 10) * 10;
if (wgl < 0) {
wgl = Configuration.configuration.getServerGlobalWriteLimit();
}
if (rgl < 0) {
rgl = Configuration.configuration.getServerGlobalReadLimit();
}
if (wsl < 0) {
wsl = Configuration.configuration.getServerChannelWriteLimit();
}
if (rsl < 0) {
rsl = Configuration.configuration.getServerChannelReadLimit();
}
if (Configuration.configuration.getR66Mib() != null) {
Configuration.configuration.getR66Mib().notifyWarning(
"Change Bandwidth Limit Order received: Global " +
wgl + ":" + rgl + " (W:R) Local " + wsl + ":" + rsl + " (W:R)",
session.getAuth().getUser());
}
Configuration.configuration.changeNetworkLimit(wgl, rgl, wsl, rsl,
Configuration.configuration.getDelayLimit());
// Now answer
return new long[] { Configuration.configuration.getServerGlobalWriteLimit(),
Configuration.configuration.getServerGlobalReadLimit(),
Configuration.configuration.getServerChannelWriteLimit(),
Configuration.configuration.getServerChannelReadLimit() };
}
}
/**
* Import configuration from files as parameter
*
* @param json
* @return the packet to answer
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolSystemException
*/
public final ConfigImportResponseJsonPacket configImport(ConfigImportJsonPacket json)
throws OpenR66ProtocolNotAuthenticatedException, OpenR66ProtocolSystemException {
session.newState(VALIDOTHER);
// Authentication must be the local server or CONFIGADMIN authorization
try {
if (!session.getAuth().getUser().equals(
Configuration.configuration.getHostId(session.getAuth().isSsl())) &&
!session.getAuth().isValidRole(ROLE.CONFIGADMIN)) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated");
}
} catch (OpenR66ProtocolNoSslException e1) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated since SSL is not supported", e1);
}
if (Configuration.configuration.getR66Mib() != null) {
Configuration.configuration.getR66Mib().notifyWarning(
"Import Configuration Order received", session.getAuth().getUser());
}
//purgehost, purgerule, purgebusiness, purgealias, purgeroles, host, rule, business, alias, roles
ConfigImportJsonPacket node = json;
boolean bhostPurge = node.isPurgehost();
boolean brulePurge = node.isPurgerule();
boolean bbusinessPurge = node.isPurgebusiness();
boolean baliasPurge = node.isPurgealias();
boolean brolesPurge = node.isPurgeroles();
boolean importedhost = false, importedrule = false, importedbusiness = false, importedalias = false, importedroles = false;
String shost = node.getHost();
String srule = node.getRule();
String sbusiness = node.getBusiness();
String salias = node.getAlias();
String sroles = node.getRoles();
long hostid = node.getHostid();
long ruleid = node.getRuleid();
long businessid = node.getBusinessid();
long aliasid = node.getAliasid();
long roleid = node.getRolesid();
DbSession dbSession = (localChannelReference != null) ? localChannelReference.getDbSession()
: DbConstant.admin.getSession();
String remote = session.getAuth().getUser();
String local = null;
try {
local = Configuration.configuration.getHostId(session.getAuth().isSsl());
} catch (OpenR66ProtocolNoSslException e1) {
logger.warn("Local Ssl Host is unknown", e1);
}
if (shost != null || (hostid != DbConstant.ILLEGALVALUE && local != null)) {
DbHostAuth[] oldHosts = null;
DbTaskRunner runner = null;
if (hostid != DbConstant.ILLEGALVALUE && local != null) {
// need to find the local filename
try {
runner = new DbTaskRunner(dbSession,
session, null,
hostid, remote, local);
shost = runner.getFullFilePath();
} catch (WaarpDatabaseException e) {
logger.error("RunnerTask is not found: " + hostid, e);
shost = null;
} catch (CommandAbstractException e) {
logger.error("File is not found: " + hostid, e);
shost = null;
}
}
if (shost != null) {
if (bhostPurge) {
// Need to first delete all entries
try {
oldHosts = DbHostAuth.deleteAll(dbSession);
} catch (WaarpDatabaseException e) {
// ignore
}
}
if (AuthenticationFileBasedConfiguration.loadAuthentication(
Configuration.configuration, shost)) {
importedhost = true;
logger.debug("Host configuration imported from " + shost);
} else {
logger.error("Error in Load Hosts");
importedhost = false;
}
if (!importedhost && bhostPurge) {
if (oldHosts != null) {
for (DbHostAuth dbHost : oldHosts) {
try {
if (!dbHost.exist()) {
dbHost.insert();
}
} catch (WaarpDatabaseException e1) {
// ignore
}
}
}
}
}
}
if (srule != null || (ruleid != DbConstant.ILLEGALVALUE && local != null)) {
DbRule[] oldRules = null;
DbTaskRunner runner = null;
if (ruleid != DbConstant.ILLEGALVALUE && local != null) {
// need to find the local filename
try {
runner = new DbTaskRunner(dbSession,
session, null,
ruleid, remote, local);
srule = runner.getFullFilePath();
} catch (WaarpDatabaseException e) {
logger.error("RunnerTask is not found: " + ruleid, e);
srule = null;
} catch (CommandAbstractException e) {
logger.error("File is not found: " + hostid, e);
srule = null;
}
}
if (srule != null) {
if (brulePurge) {
// Need to first delete all entries
try {
oldRules = DbRule.deleteAll(dbSession);
} catch (WaarpDatabaseException e) {
// ignore
}
}
File file = new File(srule);
try {
RuleFileBasedConfiguration.getMultipleFromFile(file);
importedrule = true;
logger.debug("Rule configuration imported from " + srule);
} catch (WaarpDatabaseNoConnectionException e) {
logger.error("Error", e);
importedrule = false;
} catch (WaarpDatabaseSqlException e) {
logger.error("Error", e);
importedrule = false;
} catch (WaarpDatabaseNoDataException e) {
logger.error("Error", e);
importedrule = false;
} catch (WaarpDatabaseException e) {
logger.error("Error", e);
importedrule = false;
}
if (!importedrule && brulePurge) {
if (oldRules != null) {
for (DbRule dbRule : oldRules) {
try {
if (!dbRule.exist()) {
dbRule.insert();
}
} catch (WaarpDatabaseException e1) {
// ignore
}
}
}
}
}
}
// load from file ! not from filename ! Moreover: filename might be incorrect => Must get the remote filename (recv)
if (sbusiness != null || salias != null || sroles != null || bbusinessPurge || baliasPurge || brolesPurge
|| ((businessid != DbConstant.ILLEGALVALUE || aliasid != DbConstant.ILLEGALVALUE ||
roleid != DbConstant.ILLEGALVALUE) && local != null)) {
DbHostConfiguration host = null;
try {
host = new DbHostConfiguration(dbSession, Configuration.configuration.getHOST_ID());
DbTaskRunner runner = null;
if (businessid != DbConstant.ILLEGALVALUE && local != null) {
// need to find the local filename
try {
runner = new DbTaskRunner(dbSession,
session, null,
businessid, remote, local);
sbusiness = runner.getFullFilePath();
} catch (WaarpDatabaseException e) {
logger.error("RunnerTask is not found: " + businessid, e);
sbusiness = null;
} catch (CommandAbstractException e) {
logger.error("File is not found: " + hostid, e);
sbusiness = null;
}
}
if (sbusiness != null) {
try {
String content = WaarpStringUtils.readFileException(sbusiness);
importedbusiness = host.updateBusiness(Configuration.configuration, content, bbusinessPurge);
logger.debug("Business configuration imported from " + sbusiness + "(" + importedbusiness + ")");
} catch (InvalidArgumentException e) {
logger.error("Error", e);
importedbusiness = false;
} catch (FileTransferException e) {
logger.error("Error", e);
importedbusiness = false;
}
}
if (aliasid != DbConstant.ILLEGALVALUE && local != null) {
// need to find the local filename
try {
runner = new DbTaskRunner(dbSession,
session, null,
aliasid, remote, local);
salias = runner.getFullFilePath();
} catch (WaarpDatabaseException e) {
logger.error("RunnerTask is not found: " + aliasid, e);
salias = null;
} catch (CommandAbstractException e) {
logger.error("File is not found: " + hostid, e);
salias = null;
}
}
if (salias != null) {
try {
String content = WaarpStringUtils.readFileException(salias);
importedalias = host.updateAlias(Configuration.configuration, content, baliasPurge);
logger.debug("Alias configuration imported from " + salias + "(" + importedalias + ")");
} catch (InvalidArgumentException e) {
logger.error("Error", e);
importedalias = false;
} catch (FileTransferException e) {
logger.error("Error", e);
importedalias = false;
}
}
if (roleid != DbConstant.ILLEGALVALUE && local != null) {
// need to find the local filename
try {
runner = new DbTaskRunner(dbSession,
session, null,
roleid, remote, local);
sroles = runner.getFullFilePath();
} catch (WaarpDatabaseException e) {
logger.error("RunnerTask is not found: " + roleid, e);
sroles = null;
} catch (CommandAbstractException e) {
logger.error("File is not found: " + hostid, e);
sroles = null;
}
}
if (sroles != null) {
try {
String content = WaarpStringUtils.readFileException(sroles);
importedroles = host.updateRoles(Configuration.configuration, content, brolesPurge);
logger.debug("Roles configuration imported from " + sroles + "(" + importedroles + ")");
} catch (InvalidArgumentException e) {
logger.error("Error", e);
importedroles = false;
} catch (FileTransferException e) {
logger.error("Error", e);
importedroles = false;
}
}
} catch (WaarpDatabaseException e1) {
logger.error("Error while trying to open: " + sbusiness, e1);
importedbusiness = false;
importedalias = false;
importedroles = false;
}
}
// Now answer
ConfigImportResponseJsonPacket resp = new ConfigImportResponseJsonPacket();
resp.fromJson(node);
if (bhostPurge || shost != null) {
resp.setPurgedhost(bhostPurge);
resp.setImportedhost(importedhost);
}
if (brulePurge || srule != null) {
resp.setPurgedrule(brulePurge);
resp.setImportedrule(importedrule);
}
if (bbusinessPurge || sbusiness != null) {
resp.setPurgedbusiness(bbusinessPurge);
resp.setImportedbusiness(importedbusiness);
}
if (baliasPurge || salias != null) {
resp.setPurgedalias(baliasPurge);
resp.setImportedalias(importedalias);
}
if (brolesPurge || sroles != null) {
resp.setPurgedroles(brolesPurge);
resp.setImportedroles(importedroles);
}
return resp;
}
/**
* Export configuration and return filenames in order
*
* @param bhost
* @param brule
* @param bbusiness
* @param balias
* @param broles
* @return filenames in order
* @throws OpenR66ProtocolNotAuthenticatedException
*/
public final String[] configExport(boolean bhost, boolean brule,
boolean bbusiness, boolean balias, boolean broles)
throws OpenR66ProtocolNotAuthenticatedException {
// Authentication must be the local server or CONFIGADMIN authorization
try {
if (!session.getAuth().getUser().equals(
Configuration.configuration.getHostId(session.getAuth().isSsl())) &&
!session.getAuth().isValidRole(ROLE.CONFIGADMIN)) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated");
}
} catch (OpenR66ProtocolNoSslException e1) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated since SSL is not supported", e1);
}
if (Configuration.configuration.getR66Mib() != null) {
Configuration.configuration.getR66Mib().notifyWarning(
"Export Configuration Order received", session.getAuth().getUser());
}
String dir = Configuration.configuration.getBaseDirectory() +
Configuration.configuration.getArchivePath();
DbSession dbSession = (localChannelReference != null) ? localChannelReference.getDbSession()
: DbConstant.admin.getSession();
return staticConfigExport(dbSession, dir, bhost, brule, bbusiness, balias, broles);
}
/**
* Export configuration and return filenames in order
*
* @param dbSession
* @param dir
* @param bhost
* @param brule
* @param bbusiness
* @param balias
* @param broles
* @return filenames in order
*/
public static String[] staticConfigExport(DbSession dbSession, String dir, boolean bhost, boolean brule,
boolean bbusiness, boolean balias, boolean broles) {
String shost = null, srule = null, sbusiness = null, salias = null, sroles = null;
String hostname = Configuration.configuration.getHOST_ID();
if (bhost) {
String filename = dir + File.separator + hostname + "_Authentications.xml";
try {
AuthenticationFileBasedConfiguration.writeXML(Configuration.configuration,
filename);
shost = filename;
} catch (WaarpDatabaseNoConnectionException e) {
logger.error("Error", e);
shost = null;
bhost = false;
} catch (WaarpDatabaseSqlException e) {
logger.error("Error", e);
shost = null;
bhost = false;
} catch (OpenR66ProtocolSystemException e) {
logger.error("Error", e);
shost = null;
bhost = false;
}
}
if (brule) {
try {
srule = RuleFileBasedConfiguration.writeOneXml(dir, hostname);
} catch (WaarpDatabaseNoConnectionException e1) {
logger.error("Error", e1);
srule = null;
brule = false;
} catch (WaarpDatabaseSqlException e1) {
logger.error("Error", e1);
srule = null;
brule = false;
} catch (OpenR66ProtocolSystemException e1) {
logger.error("Error", e1);
srule = null;
brule = false;
}
}
if (bbusiness || balias || broles) {
try {
DbHostConfiguration host = new DbHostConfiguration(dbSession, Configuration.configuration.getHOST_ID());
if (bbusiness) {
sbusiness = host.getBusiness();
if (sbusiness != null) {
String filename = dir + File.separator + hostname + "_Business.xml";
FileOutputStream outputStream = new FileOutputStream(filename);
outputStream.write(sbusiness.getBytes());
outputStream.flush();
outputStream.close();
sbusiness = filename;
}
bbusiness = (sbusiness != null);
}
if (balias) {
salias = host.getAliases();
if (salias != null) {
String filename = dir + File.separator + hostname + "_Aliases.xml";
FileOutputStream outputStream = new FileOutputStream(filename);
outputStream.write(salias.getBytes());
outputStream.flush();
outputStream.close();
salias = filename;
}
balias = (salias != null);
}
if (broles) {
sroles = host.getRoles();
if (sroles != null) {
String filename = dir + File.separator + hostname + "_Roles.xml";
FileOutputStream outputStream = new FileOutputStream(filename);
outputStream.write(sroles.getBytes());
outputStream.flush();
outputStream.close();
sroles = filename;
}
broles = (sroles != null);
}
} catch (WaarpDatabaseNoConnectionException e1) {
logger.error("Error", e1);
bbusiness = (sbusiness != null);
balias = (salias != null);
broles = (sroles != null);
} catch (WaarpDatabaseSqlException e1) {
logger.error("Error", e1);
bbusiness = (sbusiness != null);
balias = (salias != null);
broles = (sroles != null);
} catch (WaarpDatabaseException e) {
logger.error("Error", e);
bbusiness = (sbusiness != null);
balias = (salias != null);
broles = (sroles != null);
} catch (IOException e) {
logger.error("Error", e);
bbusiness = (sbusiness != null);
balias = (salias != null);
broles = (sroles != null);
}
}
// Now answer
return new String[] { shost, srule, sbusiness, salias, sroles };
}
/**
* Request to restart a transfer
*
* @param reqd
* requested
* @param reqr
* requester
* @param id
* id of the Transfer
* @param date
* time start if any
* @return the Result including the error code to use in return
* @throws OpenR66ProtocolNotAuthenticatedException
*/
public final R66Result requestRestart(String reqd, String reqr, long id, Date date)
throws OpenR66ProtocolNotAuthenticatedException {
ErrorCode returnCode = ErrorCode.Internal;
R66Result resulttest = null;
// should be from the local server or from an authorized hosts: TRANSFER
try {
if (!session.getAuth().getUser().equals(
Configuration.configuration.getHostId(session.getAuth().isSsl())) &&
!session.getAuth().isValidRole(ROLE.TRANSFER)) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated");
}
} catch (OpenR66ProtocolNoSslException e1) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated since SSL is not supported", e1);
}
// Try to validate a restarting transfer
// validLimit on requested side
if (Configuration.configuration.getConstraintLimitHandler().checkConstraints()) {
logger.error("Limit exceeded {} while asking to relaunch a task"
+ reqd + ":" + reqr + ":" + id, Configuration.configuration.getConstraintLimitHandler().lastAlert);
session.setStatus(100);
returnCode = ErrorCode.ServerOverloaded;
resulttest = new R66Result(null, session, true,
returnCode, null);
} else {
// Try to validate a restarting transfer
// header = ?; middle = requested+blank+requester+blank+specialId
// note: might contains one more argument = time to reschedule in yyyyMMddHHmmss format
if (reqd == null || reqr == null || id == DbConstant.ILLEGALVALUE) {
// not enough args
returnCode = ErrorCode.IncorrectCommand;
resulttest = new R66Result(new OpenR66ProtocolBusinessRemoteFileNotFoundException(
"Not enough arguments"), session, true,
returnCode, null);
} else {
DbTaskRunner taskRunner = null;
try {
DbSession dbSession = (localChannelReference != null) ? localChannelReference.getDbSession()
: DbConstant.admin.getSession();
taskRunner = new DbTaskRunner(dbSession, session,
null, id, reqr, reqd);
Timestamp timestart = null;
if (date != null) {
// time to reschedule in yyyyMMddHHmmss format
logger.debug("Debug: restart with " + date);
timestart = new Timestamp(date.getTime());
taskRunner.setStart(timestart);
}
LocalChannelReference lcr =
Configuration.configuration.getLocalTransaction().
getFromRequest(reqd + " " + reqr + " " + id);
// since it comes from a request transfer, cannot redo it
logger.info("Will try to restart: " + taskRunner.toShortString());
resulttest = TransferUtils.restartTransfer(taskRunner, lcr);
returnCode = resulttest.getCode();
} catch (WaarpDatabaseException e1) {
returnCode = ErrorCode.Internal;
resulttest = new R66Result(new OpenR66DatabaseGlobalException(e1),
session, true,
returnCode, taskRunner);
}
}
}
return resulttest;
}
/**
*
* @param code
* @return True if the code is an OK code and not an error
*/
public final boolean isCodeValid(ErrorCode code) {
switch (code) {
case BadAuthent:
case CanceledTransfer:
case CommandNotFound:
case ConnectionImpossible:
case Disconnection:
case ExternalOp:
case FileNotAllowed:
case FileNotFound:
case FinalOp:
case IncorrectCommand:
case Internal:
case LoopSelfRequestedHost:
case MD5Error:
case NotKnownHost:
case PassThroughMode:
case QueryRemotelyUnknown:
case RemoteError:
case RemoteShutdown:
case ServerOverloaded:
case Shutdown:
case SizeNotAllowed:
case StoppedTransfer:
case TransferError:
case Unimplemented:
case Unknown:
case Warning:
return false;
case CompleteOk:
case InitOk:
case PostProcessingOk:
case PreProcessingOk:
case QueryAlreadyFinished:
case QueryStillRunning:
case Running:
case TransferOk:
return true;
default:
return false;
}
}
/**
* Purge the logs as required
*
* @param purge
* @param clean
* @param start
* @param stop
* @param startid
* @param stopid
* @param rule
* @param request
* @param pending
* @param transfer
* @param done
* @param error
* @param isPurge
* @return an array of Strings as: filename, nb of exported, nb of purged
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolBusinessException
*/
public final String[] logPurge(boolean purge, boolean clean,
Timestamp start, Timestamp stop, String startid, String stopid, String rule, String request,
boolean pending, boolean transfer, boolean done, boolean error, boolean isPurge)
throws OpenR66ProtocolNotAuthenticatedException, OpenR66ProtocolBusinessException {
// should be from the local server or from an authorized hosts: LOGCONTROL
try {
if (!session.getAuth().getUser().equals(
Configuration.configuration.getHostId(session.getAuth().isSsl())) &&
!session.getAuth().isValidRole(ROLE.LOGCONTROL)) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated");
}
} catch (OpenR66ProtocolNoSslException e1) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated since SSL is not supported", e1);
}
DbSession dbSession = (localChannelReference != null) ? localChannelReference.getDbSession()
: DbConstant.admin.getSession();
// first clean if ask
if (clean) {
// Update all UpdatedInfo to DONE
// where GlobalLastStep = ALLDONETASK and status = CompleteOk
try {
DbTaskRunner.changeFinishedToDone(dbSession);
} catch (WaarpDatabaseNoConnectionException e) {
logger.warn("Clean cannot be done {}", e.getMessage());
}
}
// create export of log and optionally purge them from database
DbPreparedStatement getValid = null;
String filename = Configuration.configuration.getBaseDirectory() +
Configuration.configuration.getArchivePath() + R66Dir.SEPARATOR +
Configuration.configuration.getHOST_ID() + "_" + System.currentTimeMillis() +
"_runners.xml";
NbAndSpecialId nb = null;
try {
getValid =
DbTaskRunner.getFilterPrepareStatement(dbSession, 0,// 0 means no limit
true, startid, stopid, start, stop, rule, request,
pending, transfer, error, done, false);
nb = DbTaskRunner.writeXMLWriter(getValid, filename);
} catch (WaarpDatabaseNoConnectionException e1) {
throw new OpenR66ProtocolBusinessException(e1);
} catch (WaarpDatabaseSqlException e1) {
throw new OpenR66ProtocolBusinessException(e1);
} finally {
if (getValid != null) {
getValid.realClose();
}
}
// in case of purge
int npurge = 0;
if (nb != null && nb.nb > 0 && isPurge) {
// purge in same interval all runners with globallaststep
// as ALLDONETASK or ERRORTASK
if (Configuration.configuration.getR66Mib() != null) {
Configuration.configuration.getR66Mib().notifyWarning(
"Purge Log Order received", session.getAuth().getUser());
}
try {
if (stopid != null) {
long newstopid = Long.parseLong(stopid);
if (nb.higherSpecialId < newstopid) {
stopid = Long.toString(nb.higherSpecialId);
}
} else {
stopid = Long.toString(nb.higherSpecialId);
}
// not pending or in transfer
npurge =
DbTaskRunner.purgeLogPrepareStatement(dbSession,
startid, stopid, start, stop, rule, request,
false, false, error, done, false);
} catch (WaarpDatabaseNoConnectionException e) {
throw new OpenR66ProtocolBusinessException(e);
} catch (WaarpDatabaseSqlException e) {
throw new OpenR66ProtocolBusinessException(e);
}
}
return new String[] { filename, Long.toString(nb.nb), Long.toString(npurge) };
}
/**
* Stop or Cancel a transfer
*
* @param type
* @param reqd
* @param reqr
* @param id
* @return the Result to answer
* @throws OpenR66ProtocolNotAuthenticatedException
*/
public final R66Result stopOrCancel(byte type, String reqd, String reqr, long id)
throws OpenR66ProtocolNotAuthenticatedException {
// should be from the local server or from an authorized hosts: SYSTEM
try {
if (!session.getAuth().getUser().equals(
Configuration.configuration.getHostId(session.getAuth().isSsl())) &&
!session.getAuth().isValidRole(ROLE.SYSTEM)) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated");
}
} catch (OpenR66ProtocolNoSslException e1) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not correctly authenticated since SSL is not supported", e1);
}
R66Result resulttest;
String key = reqd + " " + reqr + " " + id;
// header = ?; middle = requested+blank+requester+blank+specialId
LocalChannelReference lcr =
Configuration.configuration.getLocalTransaction().
getFromRequest(key);
// stop the current transfer
ErrorCode code = (type == LocalPacketFactory.STOPPACKET) ?
ErrorCode.StoppedTransfer : ErrorCode.CanceledTransfer;
if (lcr != null) {
int rank = 0;
if (code == ErrorCode.StoppedTransfer && lcr.getSession() != null) {
DbTaskRunner taskRunner = lcr.getSession().getRunner();
if (taskRunner != null) {
rank = taskRunner.getRank();
}
}
session.newState(ERROR);
ErrorPacket error = new ErrorPacket(code.name() + " " + rank,
code.getCode(), ErrorPacket.FORWARDCLOSECODE);
try {
// XXX ChannelUtils.writeAbstractLocalPacket(lcr, error);
// inform local instead of remote
ChannelUtils.writeAbstractLocalPacketToLocal(lcr, error);
} catch (Exception e) {
logger.warn("Write local packet error", e);
}
resulttest = new R66Result(session, true,
ErrorCode.CompleteOk, session.getRunner());
} else {
// Transfer is not running
// but maybe need action on database
if (stopOrCancelRunner(id, reqd, reqr, code)) {
resulttest = new R66Result(session, true,
ErrorCode.CompleteOk, session.getRunner());
} else {
resulttest = new R66Result(session, true,
ErrorCode.TransferOk, session.getRunner());
}
}
return resulttest;
}
/**
* Stop or Cancel a Runner
*
* @param id
* @param reqd
* @param reqr
* @param code
* @return True if correctly stopped or canceled
*/
private final boolean stopOrCancelRunner(long id, String reqd, String reqr, ErrorCode code) {
try {
DbSession dbSession = (localChannelReference != null) ? localChannelReference.getDbSession()
: DbConstant.admin.getSession();
DbTaskRunner taskRunner =
new DbTaskRunner(dbSession, session,
null, id, reqr, reqd);
return taskRunner.stopOrCancelRunner(code);
} catch (WaarpDatabaseException e) {
}
return false;
}
/**
* Receive a Shutdown request
*
* @param channel
* @param packet
* @throws OpenR66ProtocolShutdownException
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolBusinessException
*/
public void shutdown(Channel channel, ShutdownPacket packet)
throws OpenR66ProtocolShutdownException,
OpenR66ProtocolNotAuthenticatedException,
OpenR66ProtocolBusinessException {
session.newState(SHUTDOWN);
shutdown(packet.getKey(), packet.isRestart());
packet.clear();
}
/**
* Receive a Shutdown request
*
* @param key
* @param isRestart
* @throws OpenR66ProtocolShutdownException
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolBusinessException
*/
public final void shutdown(byte[] key, boolean isRestart)
throws OpenR66ProtocolShutdownException,
OpenR66ProtocolNotAuthenticatedException,
OpenR66ProtocolBusinessException {
if (!session.isAuthenticated()) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not authenticated while Shutdown received");
}
// SYSTEM authorization
boolean isAdmin = session.getAuth().isValidRole(ROLE.SYSTEM);
boolean isKeyValid = Configuration.configuration.isKeyValid(key);
if (isAdmin && isKeyValid) {
if (Configuration.configuration.getR66Mib() != null) {
Configuration.configuration.getR66Mib().notifyStartStop(
"Shutdown Order received effective in " +
Configuration.configuration.getTIMEOUTCON() + " ms",
session.getAuth().getUser());
}
if (Configuration.configuration.getShutdownConfiguration().serviceFuture != null) {
logger.warn("R66 started as a service, Windows Services might not shown it as stopped");
}
if (isRestart) {
R66ShutdownHook.setRestart(true);
logger.warn("Server will shutdown and restart");
}
throw new OpenR66ProtocolShutdownException("Shutdown Type received");
}
logger.error("Invalid Shutdown command: from " + session.getAuth().getUser()
+ " AdmValid: " + isAdmin + " KeyValid: " + isKeyValid);
throw new OpenR66ProtocolBusinessException("Invalid Shutdown comand");
}
/**
* Business Request (channel should stay open)
*
* Note: the thread called should manage all writeback informations, as well as status, channel
* closing if needed or not.
*
* @param channel
* @param packet
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolPacketException
*/
public void businessRequest(Channel channel, BusinessRequestPacket packet)
throws OpenR66ProtocolNotAuthenticatedException,
OpenR66ProtocolPacketException {
String argRule = packet.getSheader();
if (packet.isToValidate()) {
session.newState(BUSINESSD);
}
R66Future future = businessRequest(packet.isToValidate(), argRule, null, null, packet.getDelay());
if (future != null && !future.isSuccess()) {
R66Result result = future.getResult();
if (result == null) {
result = new R66Result(session, false, ErrorCode.ExternalOp, session.getRunner());
}
logger.info("Task in Error:" + argRule + " " + result);
if (!result.isAnswered()) {
packet.invalidate();
session.newState(ERROR);
ErrorPacket error = new ErrorPacket(
"BusinessRequest in error: for " + packet.toString() + " since " +
result.getMessage(),
result.getCode().getCode(), ErrorPacket.FORWARDCLOSECODE);
ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
session.setStatus(203);
}
session.setStatus(204);
}
packet.clear();
}
/**
* Business Request (channel should stay open)
*
* Note: the thread called should manage all writeback informations, as well as status, channel
* closing if needed or not.
*
* @param isToApplied
* True means this is an action request, False it is the feedback
* @param className
* @param arguments
* @param extraArguments
* @param delay
* @return future of the execution
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolPacketException
*/
public final R66Future businessRequest(boolean isToApplied, String className, String arguments,
String extraArguments, int delay)
throws OpenR66ProtocolNotAuthenticatedException,
OpenR66ProtocolPacketException {
if (!session.isAuthenticated()) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not authenticated while BusinessRequest received");
}
boolean argTransfer = isToApplied;
if (argTransfer && !Configuration.configuration.getBusinessWhiteSet().contains(session.getAuth().getUser())) {
logger.warn("Not allow to execute a BusinessRequest: " + session.getAuth().getUser());
throw new OpenR66ProtocolNotAuthenticatedException(
"Not allow to execute a BusinessRequest");
}
session.setStatus(200);
String argRule = className;
if (arguments != null) {
argRule += " " + arguments;
}
ExecJavaTask task = new ExecJavaTask(argRule + " " + argTransfer,
delay, extraArguments, session);
task.setBusinessRequest(true);
task.run();
session.setStatus(201);
if (task.isSuccess()) {
session.setStatus(202);
logger.info("Task done: " + className.split(" ")[0]);
}
return task.getFutureCompletion();
}
/**
* Block/Unblock Request
*
*
* @param channel
* @param packet
* @throws OpenR66ProtocolPacketException
* @throws OpenR66ProtocolBusinessException
*/
public void blockRequest(Channel channel, BlockRequestPacket packet)
throws OpenR66ProtocolPacketException, OpenR66ProtocolBusinessException {
R66Result result = blockRequest(packet.getKey(), packet.getBlock());
ValidPacket valid = new ValidPacket((packet.getBlock() ? "Block" : "Unblock") + " new request",
result.getCode().getCode(),
LocalPacketFactory.REQUESTUSERPACKET);
try {
ChannelUtils.writeAbstractLocalPacket(localChannelReference,
valid, true);
} catch (OpenR66ProtocolPacketException e) {
}
channel.close();
packet.clear();
}
/**
* Block/Unblock Request
*
*
* @param key
* @param isBlocking
* @return The result
* @throws OpenR66ProtocolPacketException
* @throws OpenR66ProtocolBusinessException
*/
public final R66Result blockRequest(byte[] key, boolean isBlocking)
throws OpenR66ProtocolBusinessException {
if (!session.isAuthenticated()) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not authenticated while BlockRequest received");
}
// SYSTEM authorization
boolean isAdmin = session.getAuth().isValidRole(ROLE.SYSTEM);
boolean isKeyValid = Configuration.configuration.isKeyValid(key);
if (isAdmin && isKeyValid) {
boolean block = isBlocking;
if (Configuration.configuration.getR66Mib() != null) {
Configuration.configuration.getR66Mib().notifyWarning(
(block ? "Block" : "Unblock") + " Order received",
session.getAuth().getUser());
}
logger.debug((block ? "Block" : "Unblock") + " Order received");
Configuration.configuration.setShutdown(block);
// inform back the requester
// request of current values
R66Result result = new R66Result(session, true, ErrorCode.CompleteOk, null);
if (localChannelReference != null) {
localChannelReference.validateRequest(result);
}
return result;
}
logger.error("Invalid Block command: from " + session.getAuth().getUser()
+ " AdmValid: " + isAdmin + " KeyValid: " + isKeyValid);
throw new OpenR66ProtocolBusinessException("Invalid Block comand");
}
/**
* Receive a request of information (Transfer information or File listing)
*
* @param request
* InformationPacket.ASKENUM ordinal
* @param rulename
* rulename for file path
* @param filename
* partial name (including wildcard)
* @param jsonOutput
* ValidPacket will contain Json format ?
* @return the ValidPacket to answer containing: File Listing as Header and Number of entries as Middle
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolNoDataException
* @throws OpenR66ProtocolPacketException
*/
public final ValidPacket informationFile(byte request, String rulename, String filename, boolean jsonOutput)
throws OpenR66ProtocolNotAuthenticatedException,
OpenR66ProtocolNoDataException, OpenR66ProtocolPacketException {
if (!session.isAuthenticated()) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not authenticated while Information received");
}
DbSession dbSession = (localChannelReference != null) ? localChannelReference.getDbSession()
: DbConstant.admin.getSession();
DbRule rule;
try {
rule = new DbRule(dbSession, rulename);
} catch (WaarpDatabaseException e) {
logger.error("Rule is unknown: " + rulename, e);
throw new OpenR66ProtocolNoDataException(e);
}
try {
session.getDir().changeDirectory(rule.getSendPath());
if (request == InformationPacket.ASKENUM.ASKLIST.ordinal() ||
request == InformationPacket.ASKENUM.ASKMLSLIST.ordinal()) {
// ls or mls from current directory
List<String> list;
if (request == InformationPacket.ASKENUM.ASKLIST.ordinal()) {
list = session.getDir().list(filename);
} else {
list = session.getDir().listFull(filename, false);
}
StringBuilder builder = new StringBuilder();
if (jsonOutput) {
ObjectNode node = JsonHandler.createObjectNode();
String asked = request == InformationPacket.ASKENUM.ASKLIST.ordinal() ? "ls" : "mls";
ArrayNode array = node.putArray(asked);
for (String elt : list) {
array.add(elt);
}
builder.append(JsonHandler.writeAsString(node));
} else {
for (String elt : list) {
builder.append(elt).append('\n');
}
}
if (!jsonOutput) {
session.newState(VALIDOTHER);
}
ValidPacket validPacket = new ValidPacket(builder.toString(), "" + list.size(),
LocalPacketFactory.INFORMATIONPACKET);
R66Result result = new R66Result(session, true,
ErrorCode.CompleteOk, null);
result.setOther(validPacket);
if (localChannelReference != null) {
localChannelReference.validateEndTransfer(result);
localChannelReference.validateRequest(result);
}
return validPacket;
} else {
// exists or ls or mls from current directory and filename
R66File file = (R66File) session.getDir().setFile(filename, false);
String sresult = null;
if (request == InformationPacket.ASKENUM.ASKEXIST.ordinal()) {
if (jsonOutput) {
ObjectNode node = JsonHandler.createObjectNode();
node.put("exist", file.exists());
sresult = JsonHandler.writeAsString(node);
} else {
sresult = "" + file.exists();
}
} else if (request == InformationPacket.ASKENUM.ASKMLSDETAIL.ordinal()) {
sresult = session.getDir().fileFull(filename, false);
String[] list = sresult.split("\n");
sresult = list[1];
if (jsonOutput) {
ObjectNode node = JsonHandler.createObjectNode();
node.put("mls", sresult);
sresult = JsonHandler.writeAsString(node);
}
} else {
session.newState(ERROR);
logger.warn("Unknown Request " + request);
return null;
}
if (!jsonOutput) {
session.newState(VALIDOTHER);
}
ValidPacket validPacket = new ValidPacket(sresult, "1",
LocalPacketFactory.INFORMATIONPACKET);
R66Result result = new R66Result(session, true,
ErrorCode.CompleteOk, null);
result.setOther(validPacket);
if (localChannelReference != null) {
localChannelReference.validateEndTransfer(result);
localChannelReference.validateRequest(result);
}
return validPacket;
}
} catch (CommandAbstractException e) {
session.newState(ERROR);
logger.warn("Error while Request " + request + " "
+ e.getMessage());
return null;
}
}
/**
* Receive a request of information (Transfer information or File listing)
*
* @param id
* Id of request
* @param isTo
* True for remote host is requester, False for requested (default)
* @param remoteHost
* requester/requested for transfer if jsonOutput is True, else (jsonOutput False) remoteHost is from current
* Authenticated user
* @param jsonOutput
* ValidPacket will contain Json format ?
* @return the ValidPacket to answer containing: Transfer Information as Header
* @throws OpenR66ProtocolNotAuthenticatedException
* @throws OpenR66ProtocolNoDataException
* @throws OpenR66ProtocolPacketException
*/
public final ValidPacket informationRequest(long id, boolean isTo, String remoteHost, boolean jsonOutput)
throws OpenR66ProtocolNotAuthenticatedException,
OpenR66ProtocolNoDataException, OpenR66ProtocolPacketException {
if (!session.isAuthenticated()) {
throw new OpenR66ProtocolNotAuthenticatedException(
"Not authenticated while Information received");
}
DbSession dbSession = (localChannelReference != null) ? localChannelReference.getDbSession()
: DbConstant.admin.getSession();
String remote = session.getAuth().getUser();
if (jsonOutput && remoteHost != null && !remoteHost.isEmpty()) {
remote = remoteHost;
}
String local = null;
try {
local = Configuration.configuration.getHostId(dbSession, remote);
} catch (WaarpDatabaseException e1) {
logger.error("Remote Host is unknown", e1);
throw new OpenR66ProtocolNoDataException("Remote Host is unknown", e1);
}
DbTaskRunner runner = null;
if (isTo) {
try {
runner = new DbTaskRunner(dbSession,
session, null,
id, remote, local);
} catch (WaarpDatabaseException e) {
logger.error(Messages.getString("LocalServerHandler.21") + id); //$NON-NLS-1$
logger.debug("RunnerTask is not found: " + id + ":" + remote + ":" + local, e);
throw new OpenR66ProtocolNoDataException(Messages.getString("LocalServerHandler.22") + id, e); //$NON-NLS-1$
}
} else {
try {
runner = new DbTaskRunner(dbSession,
session, null,
id, local, remote);
} catch (WaarpDatabaseException e) {
logger.debug("RunnerTask is not found: " + id + ":" + local + ":" + remote, e);
logger.error(Messages.getString("LocalServerHandler.21") + id);
throw new OpenR66ProtocolNoDataException("(Local) " + Messages.getString("LocalServerHandler.21") + id,
e);
}
}
if (!jsonOutput) {
session.newState(VALIDOTHER);
}
ValidPacket validPacket;
try {
validPacket = new ValidPacket(jsonOutput ? runner.asJson() : runner.asXML(), "",
LocalPacketFactory.INFORMATIONPACKET);
} catch (OpenR66ProtocolBusinessException e) {
logger.error("RunnerTask cannot be found: " + id, e);
throw new OpenR66ProtocolNoDataException("RunnerTask cannot be found: " + id, e);
}
R66Result result = new R66Result(session, true,
ErrorCode.CompleteOk, null);
result.setOther(validPacket);
if (localChannelReference != null) {
localChannelReference.validateEndTransfer(result);
localChannelReference.validateRequest(result);
}
return validPacket;
}
/**
* Receive a TransferRequest in JSON mode: just setting it to be scheduled
*
* @param request
* @return the result associated with the new transfer request
*/
public final R66Result transferRequest(TransferRequestJsonPacket request) {
DbTaskRunner runner = initTransferRequest(request);
if (runner != null) {
runner.changeUpdatedInfo(AbstractDbData.UpdatedInfo.TOSUBMIT);
boolean isSender = runner.isSender();
if (!runner.forceSaveStatus()) {
logger.warn("Cannot prepare task");
return new R66Result(session, false, ErrorCode.CommandNotFound,
runner);
}
R66Result result = new R66Result(session, false, ErrorCode.InitOk,
runner);
try {
runner.select();
} catch (WaarpDatabaseException e) {
}
runner.setSender(isSender);
request.setFromDbTaskRunner(runner);
request.validate();
return result;
} else {
logger.warn("ERROR: Transfer NOT scheduled");
R66Result result = new R66Result(session, false, ErrorCode.Internal,
runner);
return result;
}
}
/**
* initialize a new Transfer Request
*
* @param request
* @return the associated DbTaskRunner
*/
private final DbTaskRunner initTransferRequest(TransferRequestJsonPacket request) {
Timestamp ttimestart = null;
Date date = request.getStart();
if (date != null) {
ttimestart = new Timestamp(date.getTime());
} else if (request.getDelay() > 0) {
if (request.isAdditionalDelay()) {
ttimestart = new Timestamp(System.currentTimeMillis() +
request.getDelay());
} else {
ttimestart = new Timestamp(request.getDelay());
}
}
DbRule rule;
try {
rule = new DbRule(DbConstant.admin.getSession(), request.getRulename());
} catch (WaarpDatabaseException e) {
logger.warn("Cannot get Rule: " + request.getRulename(), e);
return null;
}
int mode = rule.getMode();
if (RequestPacket.isMD5Mode(request.getMode())) {
mode = RequestPacket.getModeMD5(mode);
}
DbTaskRunner taskRunner = null;
long tid = DbConstant.ILLEGALVALUE;
if (request.getSpecialId() != 0 || request.getSpecialId() == DbConstant.ILLEGALVALUE) {
tid = request.getSpecialId();
}
if (tid != DbConstant.ILLEGALVALUE) {
try {
taskRunner = new DbTaskRunner(DbConstant.admin.getSession(), tid,
request.getRequested());
// requested
taskRunner.setSenderByRequestToValidate(true);
} catch (WaarpDatabaseException e) {
logger.warn("Cannot get task", e);
return null;
}
} else {
String sep = PartnerConfiguration.getSeparator(request.getRequested());
RequestPacket requestPacket = new RequestPacket(request.getRulename(),
mode, request.getFilename(), request.getBlocksize(), 0,
tid, request.getFileInformation(), -1, sep);
// Not isRecv since it is the requester, so send => isRetrieve is true
boolean isRetrieve = !RequestPacket.isRecvMode(requestPacket.getMode());
try {
taskRunner =
new DbTaskRunner(DbConstant.admin.getSession(), rule, isRetrieve, requestPacket,
request.getRequested(), ttimestart);
} catch (WaarpDatabaseException e) {
logger.warn("Cannot get task", e);
return null;
}
}
return taskRunner;
}
}