package org.fi;
import org.fi.*;
import org.apache.hadoop.io.*;
// *************************************************** JOL
import jol.core.JolSystem;
import jol.core.Runtime;
import jol.types.basic.BasicTupleSet;
import jol.types.basic.Tuple;
import jol.types.basic.TupleSet;
import jol.types.exception.JolRuntimeException;
import jol.types.exception.UpdateException;
import jol.types.table.TableName;
import jol.types.table.Table.Callback;
import jol.types.table.Table;
// ************************************ XML RPC
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
// *************************************************** Java
import java.io.*;
import java.net.URL;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.channels.SocketChannel;
import java.lang.Thread;
import java.lang.StackTraceElement;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
// *************************************************** Axpect
import org.aspectj.lang.JoinPoint;
// *************************************************** HDFS
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.permission.PermissionStatus;
import org.apache.hadoop.hdfs.protocol.LocatedBlock;
import org.apache.hadoop.hdfs.protocol.ClientProtocol;
import org.apache.hadoop.hdfs.protocol.ClientDatanodeProtocol;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.protocol.Block;
import org.apache.hadoop.hdfs.protocol.LocatedBlocks;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.DFSClient;
import org.apache.hadoop.hdfs.DFSClient.DFSOutputStream;
import org.apache.hadoop.hdfs.protocol.DataTransferProtocol;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.protocol.DatanodeID;
// FrogClient send to FrogServer a list of String
// actually it will go to FMServer first
// the list of String is basically what the event should
// schedule
public class FrogClient {
// place of call interpose
public static enum Plc { BEFORE, RETURNING, EXCEPTION; }
public static final String ENABLE_FROG_FLAG = FMLogic.TMPFI + "enableFrogFlag";
private static PrintStream mps; // from DFSClient from WorkloadDriver
// #######################################################################
// #######################################################################
// #### ####
// #### G E N E R A L ####
// #### ####
// #######################################################################
// #######################################################################
// ***********************************************************
public static boolean isEnableFrogFlagExist() {
File f = new File(ENABLE_FROG_FLAG);
if (f.exists())
return true;
return false;
}
// ***********************************************************
public static void print(String buf) {
if (mps == null)
mps = DFSClient.getMyPrintStream();
Util.print(mps, buf);
}
// ***********************************************************
public static void println(String buf) {
print(buf+"\n");
}
// #######################################################################
// #######################################################################
// #### ####
// #### H A D O O P R P C ####
// #### ####
// #######################################################################
// #######################################################################
/*
private static FMProtocol fmp = null;
private static Configuration conf = new Configuration();
private static InetSocketAddress addr =
new InetSocketAddress(FMServer.bindAddr, FMServer.port);
// *********************************
public static void sendToFrogServer(FMJoinPoint fjp, FrogEvent fev) {
try {
// connect
if (fmp == null) {
try {
fmp = (FMProtocol)
RPC.getProxy(FMProtocol.class, FMProtocol.versionID, addr, conf);
} catch (IOException e) {
Util.WARNING("cannot contact FM from FrogClient");
return;
}
if (fmp == null)
return;
}
Thread t = Thread.currentThread();
FMStackTrace fst = new FMStackTrace(t.getStackTrace());
fmp.sendFrogEvent(fjp, fst, fev);
} catch (Exception e) {
Util.EXCEPTION("sendFrogEvent", e);
}
}
*/
// #######################################################################
// #######################################################################
// #### ####
// #### X M L R P C ####
// #### ####
// #######################################################################
// #######################################################################
private static XmlRpcClient frogClient;
// ******************************************************
private static boolean cannotConnectToServer() {
if (frogClient != null)
return false;
connectToFMServer();
if (frogClient == null)
return true;
return false;
}
// ******************************************************
private static void connectToFMServer() {
try {
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
String httpAddr = "http://127.0.0.1:" + FMServer.PORT + "/xmlrpc";
config.setServerURL(new URL(httpAddr));
frogClient = new XmlRpcClient();
frogClient.setConfig(config);
} catch (Exception e) {
frogClient = null;
}
}
// ******************************************************
public static void sendToFrogServer(FMJoinPoint fjp, FrogEvent fev) {
Thread t = Thread.currentThread();
FMStackTrace fst = new FMStackTrace(t.getStackTrace());
sendFrogEventViaXmlRpc(fjp, fst, fev);
}
// ******************************************************
private static void sendFrogEventViaXmlRpc(FMJoinPoint fjp,
FMStackTrace fst,
FrogEvent fev) {
// this is okay, because we don't always want to
// run hdfs with fm server
if (cannotConnectToServer())
return;
int randId = Util.r4();
File f = Util.getRpcFile(randId);
DataOutputStream dos = Util.getRpcOutputStream(randId);
try {
fjp.write(dos);
fst.write(dos);
fev.write(dos);
dos.close();
System.out.format("- Sending %d \n", randId);
Object[] params = new Object[]{new Integer(randId)};
Integer result = (Integer) frogClient.execute("FMServer.sendFrogEvent", params);
if (result.intValue() != 1) {
Util.FATAL("frog server returns something wrong");
}
System.out.format("- Received %d %s \n", result);
f.delete();
} catch (Exception e) {
f.delete();
Util.EXCEPTION("RPC frog client error", e);
Util.FATAL("RPC frog client error");
}
}
// ##################################################################
// ##################################################################
// ## ##
// ## D I S K M O D E L I N G ##
// ## ##
// ##################################################################
// ##################################################################
// *********************************
public static void scanEditBuffer(FMJoinPoint fjp,
ByteArrayOutputStream buf,
OutputStream out) {
if (out == null)
return;
if (out.getContext() == null)
return;
System.out.format(">> scanEditBuffer: [%s] \n", out.getContext().getTargetIO());
byte [] ba = buf.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(ba);
DataInputStream in = new DataInputStream(bais);
final byte OP_MKDIR = 3;
try {
try {
while (true) {
byte opcode = in.readByte();
if (opcode == OP_MKDIR) {
int length = in.readInt();
String pathServer = in.readUTF();
long timestamp = Long.parseLong(in.readUTF());
long atime = Long.parseLong(in.readUTF());
PermissionStatus permissions = PermissionStatus.read(in);
System.out.format(" OP_MKDIR: %d [%s] \n", length, pathServer);
addPathServer(fjp, pathServer, out.getContext().getTargetIO());
}
else {
// System.out.println(" It's not make dir");
break;
}
}
} catch (EOFException e) {
in.close();
}
} catch (IOException e) {
Util.EXCEPTION("scaneditbuffer", e);
}
}
// *********************************
public static void addStorageFile(FMJoinPoint fjp, String storageFile) {
System.out.format(">> addStorageFile [%s] \n", storageFile);
FrogEvent fev = new FrogEvent("model", "add_storage_file", storageFile);
sendToFrogServer(fjp, fev);
}
// *********************************
public static void renameStorageFile(FMJoinPoint fjp, String src, String dst) {
System.out.format(">> renameStorageFile [%s] to [%s] \n", src, dst);
FrogEvent fev = new FrogEvent("model", "rename_storage_file", src, dst);
sendToFrogServer(fjp, fev);
}
// *********************************
public static void scanFSImageEntry(FMJoinPoint fjp, String pathServer,
OutputStream out) {
addPathServer(fjp, pathServer, out.getContext().getTargetIO());
}
// *********************************
public static void addPathServer(FMJoinPoint fjp, String pathServer,
String storageFile) {
// the root .. ignore
if (pathServer.equals("")) {
pathServer = "/";
}
System.out.format(">> addPathServer [%s] to storage file [%s] \n",
pathServer, storageFile);
FrogEvent fev = new FrogEvent("model", "add_path_server",
pathServer, storageFile, "InFS");
sendToFrogServer(fjp, fev);
}
// *********************************
public static void truncateStorageFile(FMJoinPoint fjp, String storageFile) {
System.out.format(">> truncateStorage [%s] \n", storageFile);
FrogEvent fev = new FrogEvent("model", "truncate_storage_file", storageFile);
sendToFrogServer(fjp, fev);
}
// *********************************
public static void addPathUser(FMJoinPoint fjp, String pathUser) {
System.out.format(">> addPathUser [%s] \n", pathUser);
FrogEvent fev = new FrogEvent("model", "add_path_user", pathUser);
sendToFrogServer(fjp, fev);
}
// ##################################################################
// ##################################################################
// ## ##
// ## N E T W O R K M O D E L I N G ##
// ## ##
// ##################################################################
// ##################################################################
// *********************************
public static void failedConnection(FMJoinPoint fjp, SocketChannel sc) {
Socket s = sc.socket();
int port = sc.context.getPort();
String dnId = Util.getNodeIdFromKnownPort(port);
System.out.format(">> failedConnection [%d][%s] \n", port, dnId);
FrogEvent fev = new FrogEvent("model", "failed_connection", dnId, "Client");
sendToFrogServer(fjp, fev);
}
// *********************************
public static void returnedNodes(FMJoinPoint fjp, LocatedBlock lb) {
DatanodeInfo [] locs = lb.getLocations();
for (int i = 0; i < locs.length; i++) {
String dnId = Util.getDatanodeStringIdFromLocName(locs[i].getName());
System.out.format(">> returnedNodes [%s] \n", dnId);
FrogEvent fev = new FrogEvent("model", "returned_node", dnId);
sendToFrogServer(fjp, fev);
}
}
// *********************************
public static void deadNode(FMJoinPoint fjp, int exitStatus) {
// not what we want
if (exitStatus != FMClient.FAAS_SYSTEM_EXIT_STATUS)
return;
String pid = Util.getPid();
String dnId = Util.getNodeIdFromPid(pid);
System.out.format(">> deadNode [%s][%s] \n", pid, dnId);
FrogEvent fev = new FrogEvent("model", "dead_nodes", dnId, "FAAS");
sendToFrogServer(fjp, fev);
}
// #####################################################################
// #####################################################################
// ##### ####
// ##### C L I E N T P R O T O C O L H O O K S ####
// ##### ####
// #####################################################################
// #####################################################################
// *********************************
public static void cpHaryadiTest(JoinPoint jp, Plc plc, Object rv,
int x) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "cpHaryadiTest");
}
// *********************************
public static void cpGetBlockLocations(JoinPoint jp, Plc plc, Object rv,
String src, long offset, long length) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "cpGetBlockLocations");
}
// *********************************
public static void cpCreate(JoinPoint jp, Plc plc, Object rv,
String src, FsPermission masked,
String clientName, boolean overwrite,
short replication, long blockSize) {
if (!isEnableFrogFlagExist()) return;
String msg = String.format
("*cpCreate* src=%s rep=%d cn=%s", src, replication, clientName);
printProtocolMessage(plc, msg);
}
// *********************************
public static void cpAppend(JoinPoint jp, Plc plc, Object rv,
String src, String clientName) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "*cpAppend*");
}
// *********************************
public static void cpAbandonBlock(JoinPoint jp, Plc plc, Object rv,
Block b, String src, String holder) {
if (!isEnableFrogFlagExist()) return;
long blockId = b.getBlockId();
long gs = b.getGenerationStamp();
String msg = String.format
("*cpAbandonBlock* bid=%d gs=%d src=%s hd=%s",
blockId, gs, src, holder);
printProtocolMessage(plc, msg);
}
// *********************************
// supported
public static void cpAddBlock(JoinPoint jp, Plc plc, Object rv,
String src, String clientName) {
if (!isEnableFrogFlagExist())
return;
String msg = String.format
("*cpAddBlock* src=%s cn=%s", src, clientName);
printProtocolMessage(plc, msg);
if (plc == Plc.RETURNING) {
LocatedBlock lb = (LocatedBlock) rv;
Block b = lb.getBlock();
DatanodeInfo[] dns = lb.getLocations();
String blockName = b.getBlockName(); // just blk_blockId
long blockId = b.getBlockId();
long generationStamp = b.getGenerationStamp();
msg = String.format(" bid=%d gs=%d", blockId, generationStamp);
printProtocolMessage(plc, msg);
if (dns != null) {
for (int i = 0; i < dns.length; i++) {
String locName = dns[i].getName();
String nodeName = Util.getDatanodeStringIdFromLocName(locName);
String storageId = dns[i].getStorageID();
msg = String.format(" dn[%d] dn=%s sid=%s ",
i, nodeName, storageId);
printProtocolMessage(plc, msg);
}
}
}
}
// *********************************
public static void cpComplete(JoinPoint jp, Plc plc, Object rv,
String src, String clientName) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "*cpComplete*");
}
// *********************************
public static void cpReportBadBlocks(JoinPoint jp, Plc plc, Object rv,
LocatedBlock[] blocks) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "*cpReportBadBlocks*");
}
// *********************************
public static void cpRename(JoinPoint jp, Plc plc, Object rv,
String src, String dst) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "*cpRename*");
}
// *********************************
public static void cpDelete(JoinPoint jp, Plc plc, Object rv,
String src) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "*cpDelete1*");
}
// *********************************
public static void cpDelete(JoinPoint jp, Plc plc, Object rv,
String src, boolean recursive) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "*cpDelete2*");
}
// *********************************
// not supported right now ....
// *********************************
public static void cpRenewLease(JoinPoint jp, Plc plc, Object rv,
String clientName) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "*cpRenewLease*");
}
// *********************************
public static void cpFsync(JoinPoint jp, Plc plc, Object rv,
String src, String client) {
if (!isEnableFrogFlagExist()) return;
printProtocolMessage(plc, "*cpFsync*");
}
// ####################################################################
// ####################################################################
// #### ####
// #### C L I E N T D A T A N O D E P R O T O C O L ####
// #### ####
// ####################################################################
// ####################################################################
// remember it here ..
private static String latestDnProxy = "";
// *********************************
public static void cdpRecoverBlock(JoinPoint jp, Plc plc, Object rv,
ClientDatanodeProtocol cdp,
Block block, boolean keepLength,
DatanodeInfo[] targets) {
if (!isEnableFrogFlagExist()) return;
String src = Util.getNodeId();
String tgt = latestDnProxy;
String msg = String.format("*cdpRecoverBlock* (%s --> %s)", src, tgt);
printProtocolMessage(plc, msg);
}
// *********************************
// we cannot get the datanode target from ClientDatanodeProtocol
// because it's an interface, so we need a helper here
// *********************************
public static void cdpProxy(JoinPoint jp, Plc plc, Object rv,
DatanodeID dnid) {
if (!isEnableFrogFlagExist()) return;
String locName = dnid.getName();
String nodeId = Util.getDatanodeStringIdFromLocName(locName);
latestDnProxy = nodeId;
}
// ####################################################################
// ####################################################################
// #### ####
// #### D A T A T R A N S F E R P R O T O C O L ####
// #### ####
// ####################################################################
// ####################################################################
// *********************************
public static void dtpFlushOp(JoinPoint jp, Plc plc, Object rv, Context ctx) {
if (!isEnableFrogFlagExist()) return;
String src = Util.getNodeId();
String tgt = Util.getNodeIdFromNetIO(ctx.getTargetIO());
String msg = String.format("*dtpFlushOp* (%s --> %s)", src, tgt);
printProtocolMessage(plc, msg);
Object obj = ctx.getExtraContext();
if (obj != null &&
obj instanceof BufferedOutputStreamWrapper) {
BufferedOutputStreamWrapper bosw =
(BufferedOutputStreamWrapper) obj;
msg = getProtocolMessage(bosw);
}
else {
msg = "Unknown-NoBOSW";
}
if (plc == Plc.BEFORE) {
println(msg);
if (msg.equals("Unknown-NoBOSW")) {
FMJoinPoint fjp = new FMJoinPoint(jp);
println(fjp.toString());
}
}
}
// *********************************
public static void dtpReadStatus(JoinPoint jp, Plc plc, Object rv, Context ctx) {
if (!isEnableFrogFlagExist()) return;
String src = Util.getNodeId();
String tgt = Util.getNodeIdFromNetIO(ctx.getTargetIO());
String msg = String.format("*dtpReadStatus* (%s <-- %s)", src, tgt);
if (plc == Plc.RETURNING) {
String status = dtpOpStatusShortToString(((Short)rv).shortValue());
msg += ("returns " + status);
}
printProtocolMessage(plc, msg);
}
// *********************************
public static void dtpReadAny(JoinPoint jp, Plc plc, Object rv, Context ctx) {
if (!isEnableFrogFlagExist()) return;
String src = Util.getNodeId();
String tgt = Util.getNodeIdFromNetIO(ctx.getTargetIO());
String msg = String.format("*dtpReadAny* (%s <-- %s)", src, tgt);
printProtocolMessage(plc, msg);
}
// ####################################################################
// ####################################################################
// #### ####
// #### C L I E N T A P I P R O T O C O L ####
// #### ####
// ####################################################################
// ####################################################################
// *********************************
public static void apiClose(JoinPoint jp, Plc plc, Object rv,
DFSOutputStream dfsos) {
if (!isEnableFrogFlagExist()) return;
String src = dfsos.getSrc();
String msg = String.format("*apiClose* %s", src);
printProtocolMessage(plc, msg);
}
// ####################################################################
// ####################################################################
// #### ####
// #### U T I L I T Y ####
// #### ####
// ####################################################################
// ####################################################################
// *********************************
public static void printProtocolMessage(Plc plc, String msg) {
if (plc == Plc.BEFORE) {
println(" [FC][Call] " + msg);
}
else if (plc == Plc.RETURNING) {
println(" [FC][Rets] " + msg);
}
else {
println(" [FC][Excp] " + msg);
}
}
// *********************************
private static String dtpOpIntToString(int b) {
byte op = (byte)b;
if (op == DataTransferProtocol.OP_WRITE_BLOCK) return "WriteBlock";
else if (op == DataTransferProtocol.OP_READ_BLOCK) return "ReadBlock";
else if (op == DataTransferProtocol.OP_READ_METADATA) return "WriteMeta";
else if (op == DataTransferProtocol.OP_REPLACE_BLOCK) return "ReplaceBlock";
else if (op == DataTransferProtocol.OP_COPY_BLOCK) return "CopyBlock";
else if (op == DataTransferProtocol.OP_BLOCK_CHECKSUM) return "BlockChecksum";
else return null;
}
// *********************************
private static String dtpOpStatusShortToString(short s) {
if (s == DataTransferProtocol.OP_STATUS_SUCCESS) return "Success";
else if (s == DataTransferProtocol.OP_STATUS_ERROR) return "Error";
else if (s == DataTransferProtocol.OP_STATUS_ERROR_CHECKSUM) return "ErrorChecksum";
else if (s == DataTransferProtocol.OP_STATUS_ERROR_INVALID) return "ErrorInvalid";
else if (s == DataTransferProtocol.OP_STATUS_ERROR_EXISTS) return "ErrorExists";
else if (s == DataTransferProtocol.OP_STATUS_CHECKSUM_OK) return "ChecksumOk";
else return "UnknownStatus";
}
// *********************************
private static String getProtocolMessage(BufferedOutputStreamWrapper bosw) {
String buf = "";
if (bosw.getCount() == 0) {
return "Unknown-ZeroSizeBuffer";
}
byte op = (byte)0;
byte[] ba = bosw.getBuffer();
ByteArrayInputStream bais = new ByteArrayInputStream(ba);
DataInputStream in = new DataInputStream(bais);
try {
// from DataXceiver.java
short version = in.readShort();
if ( version != DataTransferProtocol.DATA_TRANSFER_VERSION ) {
return "Unknown-BufSize-" + bosw.getCount();
}
op = in.readByte();
} catch (Exception e) {
return "GotException";
}
switch ( op ) {
case DataTransferProtocol.OP_READ_BLOCK:
buf += "Op:ReadBlock";
break;
case DataTransferProtocol.OP_WRITE_BLOCK:
buf = writeBlock(in);
break;
case DataTransferProtocol.OP_READ_METADATA:
buf += "Op:ReadMetadata";
break;
case DataTransferProtocol.OP_REPLACE_BLOCK:
buf += "Op:ReplaceBlock";
break;
case DataTransferProtocol.OP_COPY_BLOCK:
buf += "Op:CopyBlock";
break;
case DataTransferProtocol.OP_BLOCK_CHECKSUM:
buf += "Op:BlockChecksum";
break;
default:
return "UnknownOpCode";
}
return buf;
}
// *********************************
private static String writeBlock(DataInputStream dis) {
String buf = "";
try {
buf += (" OpCode : WriteBlock \n");
long blockId = dis.readLong();
buf += (" BlkId : " + blockId + "\n");
long genTimeStamp = dis.readLong();
buf += (" GenTs : " + genTimeStamp + "\n");
int pipelineSize = dis.readInt();
buf += (" PipeSz : " + pipelineSize + "\n");
boolean isRecovery = dis.readBoolean();
buf += (" isRec : " + isRecovery + "\n");
String client = Text.readString(dis);
buf += (" Client : " + client + "\n");
boolean hasSrcDataNode = dis.readBoolean(); // is src node info present
buf += (" srcDn : " + hasSrcDataNode + "\n");
if (hasSrcDataNode) {
DatanodeInfo srcDataNode = null;
srcDataNode = new DatanodeInfo();
srcDataNode.readFields(dis);
buf += datanodeInfoToString(srcDataNode);
}
int numTargets = dis.readInt();
if (numTargets < 0) {
throw new IOException("Mislabelled incoming datastream.");
}
buf += (" numTgt : " + numTargets + "\n");
DatanodeInfo targets[] = new DatanodeInfo[numTargets];
for (int i = 0; i < targets.length; i++) {
DatanodeInfo tmp = new DatanodeInfo();
tmp.readFields(dis);
targets[i] = tmp;
buf += (" Target #" + i + "\n");
buf += datanodeInfoToString(tmp);
}
return buf;
} catch (IOException e) {
// return whatever we have
return buf;
}
}
// ****************************************
public static String datanodeInfoToString(DatanodeInfo tmp) {
String buf = "";
buf += (" Name : " + tmp.getName() + "\n");
buf += (" StorageId : " + tmp.getStorageID() + "\n");
buf += (" InfoPort : " + tmp.getInfoPort() + "\n");
buf += (" IpcPort : " + tmp.getIpcPort() + "\n");
buf += (" Capacity : " + tmp.getCapacity() + "\n");
buf += (" DfsUsed : " + tmp.getDfsUsed() + "\n");
buf += (" Remaining : " + tmp.getRemaining() + "\n");
buf += (" XceiverCn : " + tmp.getXceiverCount() + "\n");
buf += (" Location : " + tmp.getNetworkLocation() + "\n");
buf += (" HostName : " + tmp.getHostName() + "\n");
buf += (" AdminSt : " + tmp.getAdminState() + "\n");
return buf;
}
}