Commit 20f70c5c authored by Vít Kabele's avatar Vít Kabele

ObjectFree events parsed directly from byteArray

parent 6d15525e
/**
* This file is part of disl project
* Author: Vit Kabele <vit@kabele.me>
* Created on the 04/03/2019
*/
package ch.usi.dag.dislreserver;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import static org.junit.Assert.*;
public class ByteArrayUtilsTest {
/**
* Very basic test with the simplest data
*/
@Test
public void ReadLongOne__Test()
{
byte[] byteArray = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x00, 0x01};
long l = ByteArrayUtils.ReadLong (byteArray, 0);
assertEquals (1, l);
}
/**
* Test against some random number
*/
@Test
public void ReadLongRandom__Test()
{
byte[] byteArray = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x59};
long l = ByteArrayUtils.ReadLong (byteArray, 0);
assertEquals (16473, l);
}
/**
* Test the result against the result of the function which behaviour we try to simulate.
*
* @throws IOException
*/
@Test
public void ReadLongAgainstStream__Test() throws IOException
{
byte[] byteArray = { 0x0a, 0x75, 0x0, 0x11, 0x0, 0x75, 0x40, 0x59};
long l = ByteArrayUtils.ReadLong (byteArray, 0);
DataInputStream dataInputStream = new DataInputStream (
new ByteArrayInputStream (
byteArray
)
);
assertEquals (dataInputStream.readLong (), l);
}
}
......@@ -46,7 +46,7 @@ public abstract class DiSLREServer {
__log.debug ("server started");
__serverStarted ();
ISHVM server = new SHVM (socket, __log, debug);
ISHVM server = new SHVM (__log);
try {
final SocketChannel clientSocket = socket.accept ();
......@@ -79,6 +79,13 @@ public abstract class DiSLREServer {
}
/**
* Parse the input stream to protocol buffers messages and pass them to SHVM model, via request
* dispatcher.
*
* @param sock
* @param server
*/
private static void processRequests (final Socket sock, final ISHVM server) {
try {
final DataInputStream is = new DataInputStream (
......@@ -105,7 +112,7 @@ public abstract class DiSLREServer {
agentMessage = Protocol.AgentMessage.parseFrom (pole);
requestDispatcher.ProcessMessage (agentMessage);
requestDispatcher.ProcessMessage (agentMessage, __log);
}
} catch (final Exception e) {
......
package ch.usi.dag.dislreserver;
import ch.usi.dag.dislreserver.Protocol.*;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import ch.usi.dag.util.logging.Logger;
/**
......@@ -15,11 +12,14 @@ final class RequestDispatcher {
private final ISHVM __shadowVM;
RequestDispatcher(ISHVM shadowVM) {
RequestDispatcher(ISHVM shadowVM)
{
__shadowVM = shadowVM;
}
void ProcessMessage(final AgentMessage agentMessage) throws DiSLREServerException {
void ProcessMessage(final AgentMessage agentMessage, final Logger logger)
throws DiSLREServerException
{
switch (agentMessage.getRequestCase ())
{
......@@ -75,21 +75,19 @@ final class RequestDispatcher {
case OBJECT_FREE:
int count = agentMessage.getObjectFree().getCount ();
long[] ids = new long[count];
byte[] byteArray = agentMessage.getObjectFree ().getRawData ().toByteArray ();
DataInputStream dataInputStream = new DataInputStream (
new ByteArrayInputStream(
agentMessage.getObjectFree ().getRawData ().toByteArray ()
));
logger.error (
"Serious error in data transfer: Indicated length (%d) does not match real length (%d)",
count, byteArray.length);
try {
// ByteArrayUtils method used here, since it's much more lightweight solution than
// creating an input stream again.
for (int i = 0; i < count; ++i) {
long netref = dataInputStream.readLong ();
ids[i] = netref;
ids[i] = ByteArrayUtils.ReadLong (byteArray, i * Long.BYTES);
}
__shadowVM.HandleObjectFree (ids);
} catch (IOException e){}
break;
case REQUEST_NOT_SET:
default:
......
......@@ -21,22 +21,11 @@ import ch.usi.dag.util.logging.Logger;
*/
public class SHVM implements ISHVM {
/**
* Socket for communication with client
*/
private final ServerSocketChannel __socket;
/**
* Logger instance
*/
private final Logger __log;
/**
* Debug flag
*/
@Deprecated
private final boolean __debug;
/**
* Shadow VM context. It's used in the request dispatcher,
* but since the name is {@link SHVMContext} it does make
......@@ -44,27 +33,24 @@ public class SHVM implements ISHVM {
*/
private final SHVMContext __shvmContext;
private final AnalysisHandler __anlHndl;
/**
* Handler for analysis requests.
*/
private final AnalysisHandler __analysisHandler;
/**
* Public constructor
*
* @param socket
* @param logger
* @param debug
*/
SHVM (
final ServerSocketChannel socket,
final Logger logger,
final boolean debug
final Logger logger
) {
__socket = socket;
__log = logger;
__debug = debug;
__shvmContext = new SHVMContext (__log);
__anlHndl = new AnalysisHandler (__shvmContext);
__analysisHandler = new AnalysisHandler (__shvmContext, __log);
}
/**
......@@ -77,11 +63,9 @@ public class SHVM implements ISHVM {
public void HandleAnalyze (byte[] rawData) throws DiSLREServerException
{
__anlHndl
__analysisHandler
.handle (
new DataInputStream (new ByteArrayInputStream (rawData)),
null,
__debug
new DataInputStream (new ByteArrayInputStream (rawData))
);
}
......@@ -104,12 +88,17 @@ public class SHVM implements ISHVM {
.registerClass (tag, signature, generic, loaderTag, superClassTag);
}
/**
* Handle the close message about closing connection.
* Wait for all analysis to finish, triggers atExit method on each of them.
*/
@Override
public void HandleClose ()
{
// Wait for all executors to complete run of the analysis invocation
__anlHndl.exit ();
__analysisHandler.exit ();
// invoke atExit on all analyses
for (final RemoteAnalysis analysis : __shvmContext.getAnalysisResolver ().getAllAnalyses ()) {
......@@ -132,6 +121,13 @@ public class SHVM implements ISHVM {
}
/**
* Register the new class loaded to the observed JVM.
*
* @param name Class name.
* @param tag Unique identifier of the class in the context of observed VM.
* @param data Bytes with class code.
*/
@Override
public void HandleNewClass (String name, long tag, byte[] data)
{
......@@ -149,7 +145,7 @@ public class SHVM implements ISHVM {
@Override
public void HandleObjectFree (long[] tags)
{
__anlHndl.objectsFreed (tags);
__analysisHandler.objectsFreed (tags);
}
......@@ -194,7 +190,7 @@ public class SHVM implements ISHVM {
@Override
public void HandleThreadEnd (long threadID)
{
__anlHndl
__analysisHandler
.threadEnded (threadID);
}
......
......@@ -10,6 +10,7 @@ import java.util.List;
import ch.usi.dag.dislreserver.AnalysisResolver.AnalysisMethodHolder;
import ch.usi.dag.dislreserver.shadow.ShadowObject;
import ch.usi.dag.dislreserver.shadow.ShadowObjectTable;
import ch.usi.dag.util.logging.Logger;
/**
......@@ -17,7 +18,7 @@ import ch.usi.dag.dislreserver.shadow.ShadowObjectTable;
*
* Takes care of handling the requests to analysis invocations.
*/
public final class AnalysisHandler implements RequestHandler {
public final class AnalysisHandler {
private AnalysisDispatcher dispatcher;
......@@ -27,16 +28,19 @@ public final class AnalysisHandler implements RequestHandler {
private final SHVMContext __shvmContext;
private final Logger __log;
AnalysisHandler(
final SHVMContext shvmContext
final SHVMContext shvmContext,
final Logger logger
) {
__shvmContext = shvmContext;
__log = logger;
dispatcher = new AnalysisDispatcher (__shvmContext);
}
@Override
public void handle (
final DataInputStream is, final DataOutputStream os, final boolean debug
final DataInputStream is
) throws DiSLREServerException {
try {
......@@ -53,7 +57,7 @@ public final class AnalysisHandler implements RequestHandler {
}
List <AnalysisInvocation> invocations = __unmarshalInvocations (
invocationCount, is, debug
invocationCount, is
);
dispatcher.addTask (orderingID, invocations);
......@@ -65,13 +69,13 @@ public final class AnalysisHandler implements RequestHandler {
private List <AnalysisInvocation> __unmarshalInvocations (
final int invocationCount, final DataInputStream is, final boolean debug
final int invocationCount, final DataInputStream is
) throws DiSLREServerException {
final List <AnalysisInvocation> result =
new LinkedList <AnalysisInvocation> ();
for (int i = 0; i < invocationCount; ++i) {
result.add (__unmarshalInvocation (is, debug));
result.add (__unmarshalInvocation (is));
}
return result;
......@@ -79,7 +83,7 @@ public final class AnalysisHandler implements RequestHandler {
private AnalysisInvocation __unmarshalInvocation (
final DataInputStream is, final boolean debug
final DataInputStream is
) throws DiSLREServerException {
try {
// *** retrieve method ***
......@@ -131,13 +135,11 @@ public final class AnalysisHandler implements RequestHandler {
// *** create analysis invocation ***
if(debug) {
System.out.printf (
__log.debug (
"DiSL-RE: dispatching analysis method (%d) to %s.%s()\n",
methodId, amh.getAnalysisInstance().getClass().getSimpleName (),
method.getName()
);
}
return new AnalysisInvocation (
method, amh.getAnalysisInstance (), args
......@@ -218,7 +220,6 @@ public final class AnalysisHandler implements RequestHandler {
dispatcher.objectsFreedEvent(objFreeIDs);
}
@Override
public void exit() {
dispatcher.exit();
}
......
/**
* This file is part of disl project
* Author: Vit Kabele <vit@kabele.me>
* Created on the 04/03/2019
*/
package ch.usi.dag.dislreserver;
/**
* Helper class to provide similar tools for bytearray,
* that are available for input stream
*/
abstract class ByteArrayUtils {
/**
* Read eight consecutive bytes from byteArray and converts them to the little endianed long.
*
* @param byteArray
* @param offset
* @return
*/
static long ReadLong(byte[] byteArray, int offset)
{
long result = 0;
for (int i = 0; i < Long.BYTES; i++) {
result <<= 8;
result |= (byteArray[offset + i] & 0xFF);
}
return result;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment