From: Alexandre Montplaisir Date: Thu, 30 Jul 2015 19:37:31 +0000 (-0400) Subject: Small refactor of the Java agent's TCP client X-Git-Url: http://git.efficios.com/?p=deliverable%2Flttng-ust.git;a=commitdiff_plain;h=301a3ddb302c9c2767f41f3b47d2f3e8ca8b9067 Small refactor of the Java agent's TCP client Better separate the "commands" (sent from the sessiond to the agent) from the "responses" (sent from the agent to the sessiond as replies to commands) into distinct objects. ISessiondCommand#execute() is now an interface method, and it returns an ILttngAgentResponse. This more rigorous handling of commands and responses will make it easier to add support for additional commands in the future. Signed-off-by: Alexandre Montplaisir Signed-off-by: Mathieu Desnoyers --- diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am b/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am index 67f999d1..26606b6b 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am @@ -14,13 +14,14 @@ dist_noinst_JAVA = $(pkgpath)/AbstractLttngAgent.java \ $(pkgpath)/ILttngAgent.java \ $(pkgpath)/ILttngHandler.java \ $(pkgpath)/LTTngAgent.java \ + $(pkgpath)/client/ILttngAgentResponse.java \ $(pkgpath)/client/ISessiondCommand.java \ - $(pkgpath)/client/ISessiondResponse.java \ $(pkgpath)/client/LttngTcpSessiondClient.java \ - $(pkgpath)/client/SessiondDisableHandler.java \ - $(pkgpath)/client/SessiondEnableHandler.java \ - $(pkgpath)/client/SessiondHeaderCommand.java \ - $(pkgpath)/client/SessiondListLoggersResponse.java + $(pkgpath)/client/SessiondCommandHeader.java \ + $(pkgpath)/client/SessiondDisableEventCommand.java \ + $(pkgpath)/client/SessiondEnableEventCommand.java \ + $(pkgpath)/client/SessiondListLoggersCommand.java + dist_noinst_DATA = $(jarfile_manifest) diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngAgentResponse.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngAgentResponse.java new file mode 100644 index 00000000..7752c950 --- /dev/null +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngAgentResponse.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir + * Copyright (C) 2013 - David Goulet + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package org.lttng.ust.agent.client; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * Interface for all response messages sent from the Java agent to the sessiond + * daemon. Normally sent after a command coming from the session daemon was + * executed. + * + * @author Alexandre Montplaisir + */ +interface ILttngAgentResponse { + + int INT_SIZE = 4; + + /** + * Return codes used in agent responses, to indicate success or different + * types of failures of the commands. + */ + enum ReturnCode { + + CODE_SUCCESS_CMD(1), + CODE_INVALID_CMD(2), + CODE_UNK_LOGGER_NAME(3); + + private int code; + + private ReturnCode(int c) { + code = c; + } + + public int getCode() { + return code; + } + } + + /** + * Get the {@link ReturnCode} that goes with this response. It is expected + * by the session daemon, but some commands may require more than this + * in their response. + * + * @return The return code + */ + ReturnCode getReturnCode(); + + /** + * Gets a byte array of the response so that it may be streamed. + * + * @return The byte array of the response + */ + byte[] getBytes(); + + ILttngAgentResponse SUCESS_RESPONSE = new ILttngAgentResponse() { + + @Override + public ReturnCode getReturnCode() { + return ReturnCode.CODE_SUCCESS_CMD; + } + + @Override + public byte[] getBytes() { + byte data[] = new byte[INT_SIZE]; + ByteBuffer buf = ByteBuffer.wrap(data); + buf.order(ByteOrder.BIG_ENDIAN); + buf.putInt(getReturnCode().getCode()); + return data; + } + }; + + ILttngAgentResponse FAILURE_RESPONSE = new ILttngAgentResponse() { + + @Override + public ReturnCode getReturnCode() { + return ReturnCode.CODE_INVALID_CMD; + } + + @Override + public byte[] getBytes() { + byte data[] = new byte[INT_SIZE]; + ByteBuffer buf = ByteBuffer.wrap(data); + buf.order(ByteOrder.BIG_ENDIAN); + buf.putInt(getReturnCode().getCode()); + return data; + } + }; +} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ISessiondCommand.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ISessiondCommand.java index 855ea9da..0b5a1644 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ISessiondCommand.java +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ISessiondCommand.java @@ -18,9 +18,18 @@ package org.lttng.ust.agent.client; +import org.lttng.ust.agent.AbstractLttngAgent; + +/** + * Interface to represent all commands sent from the session daemon to the Java + * agent. The agent is then expected to execute the command and provide a + * response. + * + * @author Alexandre Montplaisir + */ interface ISessiondCommand { - enum LttngAgentCommand { + enum CommandType { /** List logger(s). */ CMD_LIST(1), @@ -33,20 +42,21 @@ interface ISessiondCommand { private int code; - private LttngAgentCommand(int c) { + private CommandType(int c) { code = c; } - public int getCommand() { + public int getCommandType() { return code; } } /** - * Populate the class from a byte array + * Execute the command handler's action on the specified tracing agent. * - * @param data - * the byte array containing the streamed command + * @param agent + * The agent on which to execute the command + * @return If the command completed successfully or not */ - void populate(byte[] data); + public ILttngAgentResponse execute(AbstractLttngAgent agent); } \ No newline at end of file diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ISessiondResponse.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ISessiondResponse.java deleted file mode 100644 index 2cb66149..00000000 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ISessiondResponse.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir - * Copyright (C) 2013 - David Goulet - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License, version 2.1 only, - * as published by the Free Software Foundation. - * - * This library 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package org.lttng.ust.agent.client; - -interface ISessiondResponse { - - enum LttngAgentRetCode { - CODE_SUCCESS_CMD(1), - CODE_INVALID_CMD(2), - CODE_UNK_LOGGER_NAME(3); - private int code; - - private LttngAgentRetCode(int c) { - code = c; - } - - public int getCode() { - return code; - } - } - - /** - * Gets a byte array of the command so that it may be streamed - * - * @return the byte array of the command - */ - byte[] getBytes(); -} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java index d7ed6da4..3e9e24dd 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java @@ -48,7 +48,6 @@ public class LttngTcpSessiondClient implements Runnable { private static int protocolMinorVersion = 0; /** Command header from the session deamon. */ - private final SessiondHeaderCommand headerCmd = new SessiondHeaderCommand(); private final CountDownLatch registrationLatch = new CountDownLatch(1); private Socket sessiondSock; @@ -147,54 +146,92 @@ public class LttngTcpSessiondClient implements Runnable { } } - /** - * Receive header data from the session daemon using the LTTng command - * static buffer of the right size. - */ - private void recvHeader() throws IOException { - byte data[] = new byte[SessiondHeaderCommand.HEADER_SIZE]; + private void connectToSessiond() throws IOException { + int port; - int readLen = this.inFromSessiond.read(data, 0, data.length); - if (readLen != data.length) { - throw new IOException(); + if (this.isRoot) { + port = getPortFromFile(ROOT_PORT_FILE); + if (port == 0) { + /* No session daemon available. Stop and retry later. */ + throw new IOException(); + } + } else { + port = getPortFromFile(getHomePath() + USER_PORT_FILE); + if (port == 0) { + /* No session daemon available. Stop and retry later. */ + throw new IOException(); + } } - this.headerCmd.populate(data); + + this.sessiondSock = new Socket(SESSION_HOST, port); + this.inFromSessiond = new DataInputStream(sessiondSock.getInputStream()); + this.outToSessiond = new DataOutputStream(sessiondSock.getOutputStream()); + } + + private static String getHomePath() { + return System.getProperty("user.home"); } /** - * Receive payload from the session daemon. This MUST be done after a - * recvHeader() so the header value of a command are known. + * Read port number from file created by the session daemon. * - * The caller SHOULD use isPayload() before which returns true if a payload - * is expected after the header. + * @return port value if found else 0. */ - private byte[] recvPayload() throws IOException { - byte payload[] = new byte[(int) this.headerCmd.getDataSize()]; + private static int getPortFromFile(String path) throws IOException { + int port; + BufferedReader br = null; - /* Failsafe check so we don't waste our time reading 0 bytes. */ - if (payload.length == 0) { - return null; + try { + br = new BufferedReader(new FileReader(path)); + String line = br.readLine(); + port = Integer.parseInt(line, 10); + if (port < 0 || port > 65535) { + /* Invalid value. Ignore. */ + port = 0; + } + } catch (FileNotFoundException e) { + /* No port available. */ + port = 0; + } finally { + if (br != null) { + br.close(); + } } - this.inFromSessiond.read(payload, 0, payload.length); - return payload; + return port; + } + + private void registerToSessiond() throws IOException { + byte data[] = new byte[16]; + ByteBuffer buf = ByteBuffer.wrap(data); + String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; + + buf.putInt(logAgent.getDomain().value()); + buf.putInt(Integer.parseInt(pid)); + buf.putInt(protocolMajorVersion); + buf.putInt(protocolMinorVersion); + this.outToSessiond.write(data, 0, data.length); + this.outToSessiond.flush(); } /** * Handle session command from the session daemon. */ private void handleSessiondCmd() throws IOException { - byte data[] = null; + /* Data read from the socket */ + byte inputData[] = null; + /* Reply data written to the socket, sent to the sessiond */ + byte responseData[] = null; while (true) { /* Get header from session daemon. */ - recvHeader(); + SessiondCommandHeader cmdHeader = recvHeader(); - if (headerCmd.getDataSize() > 0) { - data = recvPayload(); + if (cmdHeader.getDataSize() > 0) { + inputData = recvPayload(cmdHeader); } - switch (headerCmd.getCommandType()) { + switch (cmdHeader.getCommandType()) { case CMD_REG_DONE: { /* @@ -210,125 +247,82 @@ public class LttngTcpSessiondClient implements Runnable { } case CMD_LIST: { - SessiondListLoggersResponse listLoggerCmd = new SessiondListLoggersResponse(); - listLoggerCmd.execute(logAgent); - data = listLoggerCmd.getBytes(); + ISessiondCommand listLoggerCmd = new SessiondListLoggersCommand(); + ILttngAgentResponse response = listLoggerCmd.execute(logAgent); + responseData = response.getBytes(); break; } case CMD_ENABLE: { - SessiondEnableHandler enableCmd = new SessiondEnableHandler(); - if (data == null) { - enableCmd.code = ISessiondResponse.LttngAgentRetCode.CODE_INVALID_CMD; + if (inputData == null) { + /* Invalid command */ + responseData = ILttngAgentResponse.FAILURE_RESPONSE.getBytes(); break; } - enableCmd.populate(data); - enableCmd.execute(logAgent); - data = enableCmd.getBytes(); + ISessiondCommand enableCmd = new SessiondEnableEventCommand(inputData); + ILttngAgentResponse response = enableCmd.execute(logAgent); + responseData = response.getBytes(); break; } case CMD_DISABLE: { - SessiondDisableHandler disableCmd = new SessiondDisableHandler(); - if (data == null) { - disableCmd.setRetCode(ISessiondResponse.LttngAgentRetCode.CODE_INVALID_CMD); + if (inputData == null) { + /* Invalid command */ + responseData = ILttngAgentResponse.FAILURE_RESPONSE.getBytes(); break; } - disableCmd.populate(data); - disableCmd.execute(logAgent); - data = disableCmd.getBytes(); + ISessiondCommand disableCmd = new SessiondDisableEventCommand(inputData); + ILttngAgentResponse response = disableCmd.execute(logAgent); + responseData = response.getBytes(); break; } default: { - data = new byte[4]; - ByteBuffer buf = ByteBuffer.wrap(data); + /* Unknown command, send empty reply */ + responseData = new byte[4]; + ByteBuffer buf = ByteBuffer.wrap(responseData); buf.order(ByteOrder.BIG_ENDIAN); break; } } - if (data == null) { - /* - * Simply used to silence a potential null access warning below. - * - * The flow analysis gets confused here and thinks "data" may be - * null at this point. It should not happen according to program - * logic, if it does we've done something wrong. - */ - throw new IllegalStateException(); - } - /* Send payload to session daemon. */ - this.outToSessiond.write(data, 0, data.length); + /* Send response to the session daemon. */ + this.outToSessiond.write(responseData, 0, responseData.length); this.outToSessiond.flush(); } } - private static String getHomePath() { - return System.getProperty("user.home"); - } - /** - * Read port number from file created by the session daemon. - * - * @return port value if found else 0. + * Receive header data from the session daemon using the LTTng command + * static buffer of the right size. */ - private static int getPortFromFile(String path) throws IOException { - int port; - BufferedReader br = null; + private SessiondCommandHeader recvHeader() throws IOException { + byte data[] = new byte[SessiondCommandHeader.HEADER_SIZE]; - try { - br = new BufferedReader(new FileReader(path)); - String line = br.readLine(); - port = Integer.parseInt(line, 10); - if (port < 0 || port > 65535) { - /* Invalid value. Ignore. */ - port = 0; - } - } catch (FileNotFoundException e) { - /* No port available. */ - port = 0; - } finally { - if (br != null) { - br.close(); - } + int readLen = this.inFromSessiond.read(data, 0, data.length); + if (readLen != data.length) { + throw new IOException(); } - - return port; + return new SessiondCommandHeader(data); } - private void connectToSessiond() throws IOException { - int port; + /** + * Receive payload from the session daemon. This MUST be done after a + * recvHeader() so the header value of a command are known. + * + * The caller SHOULD use isPayload() before which returns true if a payload + * is expected after the header. + */ + private byte[] recvPayload(SessiondCommandHeader headerCmd) throws IOException { + byte payload[] = new byte[(int) headerCmd.getDataSize()]; - if (this.isRoot) { - port = getPortFromFile(ROOT_PORT_FILE); - if (port == 0) { - /* No session daemon available. Stop and retry later. */ - throw new IOException(); - } - } else { - port = getPortFromFile(getHomePath() + USER_PORT_FILE); - if (port == 0) { - /* No session daemon available. Stop and retry later. */ - throw new IOException(); - } + /* Failsafe check so we don't waste our time reading 0 bytes. */ + if (payload.length == 0) { + return null; } - this.sessiondSock = new Socket(SESSION_HOST, port); - this.inFromSessiond = new DataInputStream(sessiondSock.getInputStream()); - this.outToSessiond = new DataOutputStream(sessiondSock.getOutputStream()); + this.inFromSessiond.read(payload, 0, payload.length); + return payload; } - private void registerToSessiond() throws IOException { - byte data[] = new byte[16]; - ByteBuffer buf = ByteBuffer.wrap(data); - String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; - - buf.putInt(logAgent.getDomain().value()); - buf.putInt(Integer.parseInt(pid)); - buf.putInt(protocolMajorVersion); - buf.putInt(protocolMinorVersion); - this.outToSessiond.write(data, 0, data.length); - this.outToSessiond.flush(); - } } diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java new file mode 100644 index 00000000..1ce6502b --- /dev/null +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir + * Copyright (C) 2013 - David Goulet + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package org.lttng.ust.agent.client; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.lttng.ust.agent.client.ISessiondCommand.CommandType; + +/** + * Header of session daemon commands. + * + * @author Alexandre Montplaisir + * @author David Goulet + */ +class SessiondCommandHeader { + + /** ABI size of command header. */ + public static final int HEADER_SIZE = 16; + + /** Payload size in bytes following this header. */ + private final long dataSize; + + /** Command type. */ + private final CommandType cmd; + + public SessiondCommandHeader(byte[] data) { + ByteBuffer buf = ByteBuffer.wrap(data); + buf.order(ByteOrder.BIG_ENDIAN); + + dataSize = buf.getLong(); + cmd = CommandType.values()[buf.getInt() - 1]; + buf.getInt(); // command version, currently unused + } + + public long getDataSize() { + return dataSize; + } + + public CommandType getCommandType() { + return cmd; + } +} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java new file mode 100644 index 00000000..39d14b0d --- /dev/null +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir + * Copyright (C) 2013 - David Goulet + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package org.lttng.ust.agent.client; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.lttng.ust.agent.AbstractLttngAgent; + +/** + * Session daemon command indicating to the Java agent that some events were + * disabled in the tracing session. + * + * @author Alexandre Montplaisir + * @author David Goulet + */ +class SessiondDisableEventCommand implements ISessiondCommand { + + /** Event name to disable from the tracing session */ + private final String eventName; + + public SessiondDisableEventCommand(byte[] data) { + if (data == null) { + throw new IllegalArgumentException(); + } + ByteBuffer buf = ByteBuffer.wrap(data); + buf.order(ByteOrder.LITTLE_ENDIAN); + eventName = new String(data).trim(); + } + + @Override + public ILttngAgentResponse execute(AbstractLttngAgent agent) { + boolean success = agent.eventDisabled(this.eventName); + return (success ? ILttngAgentResponse.SUCESS_RESPONSE : ILttngAgentResponse.FAILURE_RESPONSE); + } +} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableHandler.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableHandler.java deleted file mode 100644 index 9dad7f6d..00000000 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableHandler.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2013 - David Goulet - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License, version 2.1 only, - * as published by the Free Software Foundation. - * - * This library 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package org.lttng.ust.agent.client; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import org.lttng.ust.agent.AbstractLttngAgent; - -class SessiondDisableHandler implements ISessiondResponse, ISessiondCommand { - - private static final int INT_SIZE = 4; - - /** Event name to disable from the tracing session */ - private String eventName; - - /** Return status code to the session daemon. */ - private LttngAgentRetCode code; - - @Override - public void populate(byte[] data) { - ByteBuffer buf = ByteBuffer.wrap(data); - buf.order(ByteOrder.LITTLE_ENDIAN); - eventName = new String(data).trim(); - } - - @Override - public byte[] getBytes() { - byte data[] = new byte[INT_SIZE]; - ByteBuffer buf = ByteBuffer.wrap(data); - buf.order(ByteOrder.BIG_ENDIAN); - buf.putInt(code.getCode()); - return data; - } - - public String getEventName() { - return eventName; - } - - public void setRetCode(LttngAgentRetCode code) { - this.code = code; - } - - /** - * Execute disable handler action which is to disable the given handler to - * the received name. - * - * @param agent - * The agent on which to execute the command - */ - public void execute(AbstractLttngAgent agent) { - if (agent.eventDisabled(this.eventName)) { - this.code = LttngAgentRetCode.CODE_SUCCESS_CMD; - } else { - this.code = LttngAgentRetCode.CODE_INVALID_CMD; - } - } -} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java new file mode 100644 index 00000000..5f0fbd94 --- /dev/null +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir + * Copyright (C) 2013 - David Goulet + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package org.lttng.ust.agent.client; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.lttng.ust.agent.AbstractLttngAgent; + +/** + * Session daemon command indicating to the Java agent that some events were + * enabled in the tracing session. + * + * @author Alexandre Montplaisir + * @author David Goulet + */ +class SessiondEnableEventCommand implements ISessiondCommand { + + private static final int INT_SIZE = 4; + + /** Event name to enable in the tracing session */ + private final String eventName; + + public SessiondEnableEventCommand(byte[] data) { + if (data == null) { + throw new IllegalArgumentException(); + } + int dataOffset = INT_SIZE * 2; + + ByteBuffer buf = ByteBuffer.wrap(data); + buf.order(ByteOrder.LITTLE_ENDIAN); + buf.getInt(); // logLevel, currently unused + buf.getInt(); // logLevelType, currently unused + eventName = new String(data, dataOffset, data.length - dataOffset).trim(); + } + + @Override + public ILttngAgentResponse execute(AbstractLttngAgent agent) { + boolean success = agent.eventEnabled(this.eventName); + return (success ? ILttngAgentResponse.SUCESS_RESPONSE : ILttngAgentResponse.FAILURE_RESPONSE); + } +} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableHandler.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableHandler.java deleted file mode 100644 index ec49cb2f..00000000 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableHandler.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2013 - David Goulet - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License, version 2.1 only, - * as published by the Free Software Foundation. - * - * This library 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package org.lttng.ust.agent.client; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import org.lttng.ust.agent.AbstractLttngAgent; - -class SessiondEnableHandler implements ISessiondResponse, ISessiondCommand { - - private static final int INT_SIZE = 4; - - /** Event name to enable in the tracing session */ - private String eventName; - - /** Return status code to the session daemon. */ - public LttngAgentRetCode code; - - @Override - public void populate(byte[] data) { - int dataOffset = INT_SIZE * 2; - - ByteBuffer buf = ByteBuffer.wrap(data); - buf.order(ByteOrder.LITTLE_ENDIAN); - buf.getInt(); //logLevel, currently unused - buf.getInt(); //logLevelType, currently unused - eventName = new String(data, dataOffset, data.length - dataOffset).trim(); - } - - @Override - public byte[] getBytes() { - byte data[] = new byte[INT_SIZE]; - ByteBuffer buf = ByteBuffer.wrap(data); - buf.order(ByteOrder.BIG_ENDIAN); - buf.putInt(code.getCode()); - return data; - } - - public String getEventName() { - return eventName; - } - - /** - * Execute enable handler action which is to enable the given handler to the - * received name. - * - * @param agent - * The agent on which to execute the command - */ - public void execute(AbstractLttngAgent agent) { - if (agent.eventEnabled(this.eventName)) { - this.code = LttngAgentRetCode.CODE_SUCCESS_CMD; - } else { - this.code = LttngAgentRetCode.CODE_INVALID_CMD; - } - } -} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondHeaderCommand.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondHeaderCommand.java deleted file mode 100644 index a2697270..00000000 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondHeaderCommand.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2013 - David Goulet - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License, version 2.1 only, - * as published by the Free Software Foundation. - * - * This library 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package org.lttng.ust.agent.client; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -class SessiondHeaderCommand implements ISessiondCommand { - - /** ABI size of command header. */ - public static final int HEADER_SIZE = 16; - - /** Payload size in bytes following this header. */ - private long dataSize; - /** Command type. */ - private LttngAgentCommand cmd; - - @Override - public void populate(byte[] data) { - ByteBuffer buf = ByteBuffer.wrap(data); - buf.order(ByteOrder.BIG_ENDIAN); - - dataSize = buf.getLong(); - cmd = LttngAgentCommand.values()[buf.getInt() - 1]; - buf.getInt(); // command version, currently unused - } - - public long getDataSize() { - return dataSize; - } - - public LttngAgentCommand getCommandType() { - return cmd; - } -} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java new file mode 100644 index 00000000..cb20ea90 --- /dev/null +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir + * Copyright (C) 2013 - David Goulet + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package org.lttng.ust.agent.client; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; + +import org.lttng.ust.agent.AbstractLttngAgent; + +/** + * Session daemon command asking the Java agent to list its registered loggers, + * which corresponds to event names in the tracing session. + * + * @author Alexandre Montplaisir + * @author David Goulet + */ +class SessiondListLoggersCommand implements ISessiondCommand { + + @Override + public ILttngAgentResponse execute(AbstractLttngAgent agent) { + final List loggerList = new ArrayList(); + int dataSize = 0; + + for (String event : agent.listEnabledEvents()) { + loggerList.add(event); + dataSize += event.length() + 1; + } + + return new SessiondListLoggersResponse(loggerList, dataSize); + } + + private static class SessiondListLoggersResponse implements ILttngAgentResponse { + + private final static int SIZE = 12; + + private final List loggers; + private final int dataSize; + + public SessiondListLoggersResponse(List loggers, int dataSize) { + this.loggers = loggers; + this.dataSize = dataSize; + } + + @Override + public ReturnCode getReturnCode() { + /* This command can't really fail */ + return ILttngAgentResponse.SUCESS_RESPONSE.getReturnCode(); + } + + @Override + public byte[] getBytes() { + byte data[] = new byte[SIZE + dataSize]; + ByteBuffer buf = ByteBuffer.wrap(data); + buf.order(ByteOrder.BIG_ENDIAN); + + /* Returned code */ + buf.putInt(getReturnCode().getCode()); + buf.putInt(dataSize); + buf.putInt(loggers.size()); + + for (String logger : loggers) { + buf.put(logger.getBytes()); + /* NULL terminated byte after the logger name. */ + buf.put((byte) 0x0); + } + return data; + } + } + +} diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersResponse.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersResponse.java deleted file mode 100644 index a43c4887..00000000 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersResponse.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2013 - David Goulet - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License, version 2.1 only, - * as published by the Free Software Foundation. - * - * This library 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 Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package org.lttng.ust.agent.client; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.List; - -import org.lttng.ust.agent.ILttngAgent; - -class SessiondListLoggersResponse implements ISessiondResponse { - - private final static int SIZE = 12; - - private int dataSize = 0; - private int nbLogger = 0; - - private final List loggerList = new ArrayList(); - - /** Return status code to the session daemon. */ - public LttngAgentRetCode code; - - @Override - public byte[] getBytes() { - byte data[] = new byte[SIZE + dataSize]; - ByteBuffer buf = ByteBuffer.wrap(data); - buf.order(ByteOrder.BIG_ENDIAN); - - /* Returned code */ - buf.putInt(code.getCode()); - buf.putInt(dataSize); - buf.putInt(nbLogger); - - for (String logger : loggerList) { - buf.put(logger.getBytes()); - /* NULL terminated byte after the logger name. */ - buf.put((byte) 0x0); - } - return data; - } - - public void execute(ILttngAgent agent) { - for (String event : agent.listEnabledEvents()) { - this.loggerList.add(event); - this.nbLogger++; - this.dataSize += event.length() + 1; - } - - this.code = LttngAgentRetCode.CODE_SUCCESS_CMD; - } -}