From 3165c2f51abe3093f4c5512b499e33cb380b387d Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Fri, 28 Aug 2015 22:41:04 -0400 Subject: [PATCH] Introduce a new client listener interface for the Java agent Decouple the TCP client from the implementation of the LTTng Java agent. Instead of using AbstractLttngAgent directly, the TCP client (and the command subclasses) can deal with the new ILttngTcpClientListener interface. The agent will implement this interface. This will also allow easier testing of the TCP client and its protocol, since test classess can now implement their own listener and verify the contents of each command. Signed-off-by: Alexandre Montplaisir Signed-off-by: Mathieu Desnoyers --- .../java/lttng-ust-agent-common/Makefile.am | 3 +- .../lttng/ust/agent/AbstractLttngAgent.java | 56 +++++++----------- .../org/lttng/ust/agent/ILttngAgent.java | 10 +--- .../agent/client/ILttngTcpClientListener.java | 59 +++++++++++++++++++ .../ust/agent/client/ISessiondCommand.java | 4 +- .../agent/client/LttngTcpSessiondClient.java | 17 +++--- .../client/SessiondDisableEventCommand.java | 4 +- .../client/SessiondEnableEventCommand.java | 4 +- .../client/SessiondListLoggersCommand.java | 4 +- 9 files changed, 97 insertions(+), 64 deletions(-) create mode 100644 liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java 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 2258fdc0..bbf98f64 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,8 +14,9 @@ dist_noinst_JAVA = $(pkgpath)/AbstractLttngAgent.java \ $(pkgpath)/ILttngAgent.java \ $(pkgpath)/ILttngHandler.java \ $(pkgpath)/LTTngAgent.java \ - $(pkgpath)/client/LttngAgentResponse.java \ + $(pkgpath)/client/ILttngTcpClientListener.java \ $(pkgpath)/client/ISessiondCommand.java \ + $(pkgpath)/client/LttngAgentResponse.java \ $(pkgpath)/client/LttngTcpSessiondClient.java \ $(pkgpath)/client/SessiondCommandHeader.java \ $(pkgpath)/client/SessiondDisableEventCommand.java \ diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java index 64b33b6c..c3fc339b 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java @@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.atomic.AtomicInteger; +import org.lttng.ust.agent.client.ILttngTcpClientListener; import org.lttng.ust.agent.client.LttngTcpSessiondClient; /** @@ -37,7 +38,8 @@ import org.lttng.ust.agent.client.LttngTcpSessiondClient; * @param * The type of logging handler that should register to this agent */ -public abstract class AbstractLttngAgent implements ILttngAgent { +public abstract class AbstractLttngAgent + implements ILttngAgent, ILttngTcpClientListener { private static final String WILDCARD = "*"; private static final int INIT_TIMEOUT = 3; /* Seconds */ @@ -134,14 +136,14 @@ public abstract class AbstractLttngAgent implements ILt } String rootClientThreadName = "Root sessiond client started by agent: " + this.getClass().getSimpleName(); - rootSessiondClient = new LttngTcpSessiondClient(this, true); + rootSessiondClient = new LttngTcpSessiondClient(this, getDomain().value(), true); rootSessiondClientThread = new Thread(rootSessiondClient, rootClientThreadName); rootSessiondClientThread.setDaemon(true); rootSessiondClientThread.start(); String userClientThreadName = "User sessiond client started by agent: " + this.getClass().getSimpleName(); - userSessiondClient = new LttngTcpSessiondClient(this, false); + userSessiondClient = new LttngTcpSessiondClient(this, getDomain().value(), false); userSessiondClientThread = new Thread(userSessiondClient, userClientThreadName); userSessiondClientThread.setDaemon(true); userSessiondClientThread.start(); @@ -186,15 +188,7 @@ public abstract class AbstractLttngAgent implements ILt } - /** - * Callback for the TCP clients to notify the agent that a request for - * enabling an event was sent from the session daemon. - * - * @param eventName - * The name of the event that was requested to be enabled. - * @return Since we do not track individual sessions, right now this command - * cannot fail. It will always return true. - */ + @Override public boolean eventEnabled(String eventName) { if (eventName.equals(WILDCARD)) { enabledWildcards.incrementAndGet(); @@ -210,15 +204,7 @@ public abstract class AbstractLttngAgent implements ILt return incrementEventCount(eventName, enabledEvents); } - /** - * Callback for the TCP clients to notify the agent that a request for - * disabling an event was sent from the session daemon. - * - * @param eventName - * The name of the event that was requested to be disabled. - * @return True if the command completed successfully, false if we should - * report an error (event was not enabled, etc.) - */ + @Override public boolean eventDisabled(String eventName) { if (eventName.equals(WILDCARD)) { int newCount = enabledWildcards.decrementAndGet(); @@ -239,6 +225,20 @@ public abstract class AbstractLttngAgent implements ILt return decrementEventCount(eventName, enabledEvents); } + @Override + public Iterable listEnabledEvents() { + List events = new LinkedList(); + + if (enabledWildcards.get() > 0) { + events.add(WILDCARD); + } + for (String prefix : enabledEventPrefixes.keySet()) { + events.add(new String(prefix + WILDCARD)); + } + events.addAll(enabledEvents.keySet()); + return events; + } + @Override public boolean isEventEnabled(String eventName) { /* If at least one session enabled the "*" wildcard, send the event */ @@ -260,20 +260,6 @@ public abstract class AbstractLttngAgent implements ILt return false; } - @Override - public Iterable listEnabledEvents() { - List events = new LinkedList(); - - if (enabledWildcards.get() > 0) { - events.add(WILDCARD); - } - for (String prefix : enabledEventPrefixes.keySet()) { - events.add(new String(prefix + WILDCARD)); - } - events.addAll(enabledEvents.keySet()); - return events; - } - private static boolean incrementEventCount(String eventName, Map eventMap) { synchronized (eventMap) { Integer count = eventMap.get(eventName); diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java index 044bdf07..fd20a9eb 100644 --- a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java @@ -86,19 +86,11 @@ public interface ILttngAgent { /** * Query if a given event is currently enabled in a current tracing session, - * meaning it should be sent to UST. May be quicker than listing all events - * via {@link #listEnabledEvents()}. + * meaning it should be sent to UST. * * @param eventName * The name of the event to check. * @return True if the event is currently enabled, false if it is not. */ boolean isEventEnabled(String eventName); - - /** - * List the all events currently enabled in the current tracing sessions. - * - * @return The list of enabled events - */ - Iterable listEnabledEvents(); } diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java new file mode 100644 index 00000000..662b9982 --- /dev/null +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir + * + * 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; + +/** + * TCP client listener interface. + * + * This interface contains callbacks that are called when the TCP client + * receives commands from the session daemon. These callbacks will define what + * do to with each command. + * + * @author Alexandre Montplaisir + */ +public interface ILttngTcpClientListener { + + /** + * Callback for the TCP client to notify the listener agent that a request + * for enabling an event was sent from the session daemon. + * + * @param eventName + * The name of the event that was requested to be enabled. + * @return Since we do not track individual sessions, right now this command + * cannot fail. It will always return true. + */ + boolean eventEnabled(String eventName); + + /** + * Callback for the TCP client to notify the listener agent that a request + * for disabling an event was sent from the session daemon. + * + * @param eventName + * The name of the event that was requested to be disabled. + * @return True if the command completed successfully, false if we should + * report an error (event was not enabled, etc.) + */ + boolean eventDisabled(String eventName); + + /** + * List the all events currently enabled in the current tracing sessions. + * + * @return The list of enabled events + */ + Iterable listEnabledEvents(); +} 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 c7d4faf8..c1faa15f 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,8 +18,6 @@ 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 @@ -58,5 +56,5 @@ interface ISessiondCommand { * The agent on which to execute the command * @return If the command completed successfully or not */ - public LttngAgentResponse execute(AbstractLttngAgent agent); + public LttngAgentResponse execute(ILttngTcpClientListener agent); } \ No newline at end of file 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 8fb0f5a5..d8788d32 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 @@ -31,8 +31,6 @@ import java.nio.ByteOrder; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.lttng.ust.agent.AbstractLttngAgent; - /** * Client for agents to connect to a local session daemon, using a TCP socket. * @@ -56,21 +54,26 @@ public class LttngTcpSessiondClient implements Runnable { private DataInputStream inFromSessiond; private DataOutputStream outToSessiond; - private final AbstractLttngAgent logAgent; + private final ILttngTcpClientListener logAgent; + private final int domainValue; private final boolean isRoot; - /** * Constructor * * @param logAgent - * The logging agent this client will operate on. + * The listener this client will operate on, typically an LTTng + * agent. + * @param domainValue + * The integer to send to the session daemon representing the + * tracing domain to handle. * @param isRoot * True if this client should connect to the root session daemon, * false if it should connect to the user one. */ - public LttngTcpSessiondClient(AbstractLttngAgent logAgent, boolean isRoot) { + public LttngTcpSessiondClient(ILttngTcpClientListener logAgent, int domainValue, boolean isRoot) { this.logAgent = logAgent; + this.domainValue = domainValue; this.isRoot = isRoot; } @@ -206,7 +209,7 @@ public class LttngTcpSessiondClient implements Runnable { ByteBuffer buf = ByteBuffer.wrap(data); String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; - buf.putInt(logAgent.getDomain().value()); + buf.putInt(domainValue); buf.putInt(Integer.parseInt(pid)); buf.putInt(protocolMajorVersion); buf.putInt(protocolMinorVersion); 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 index ee9d519f..03cd9de6 100644 --- 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 @@ -21,8 +21,6 @@ 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. @@ -45,7 +43,7 @@ class SessiondDisableEventCommand implements ISessiondCommand { } @Override - public LttngAgentResponse execute(AbstractLttngAgent agent) { + public LttngAgentResponse execute(ILttngTcpClientListener agent) { boolean success = agent.eventDisabled(this.eventName); return (success ? LttngAgentResponse.SUCESS_RESPONSE : DISABLE_EVENT_FAILURE_RESPONSE); } 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 index bb20ac57..82204eb1 100644 --- 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 @@ -21,8 +21,6 @@ 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. @@ -51,7 +49,7 @@ class SessiondEnableEventCommand implements ISessiondCommand { } @Override - public LttngAgentResponse execute(AbstractLttngAgent agent) { + public LttngAgentResponse execute(ILttngTcpClientListener agent) { boolean success = agent.eventEnabled(this.eventName); return (success ? LttngAgentResponse.SUCESS_RESPONSE : LttngAgentResponse.FAILURE_RESPONSE); } 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 index f5ad9c50..c06eaaad 100644 --- 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 @@ -23,8 +23,6 @@ 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. @@ -35,7 +33,7 @@ import org.lttng.ust.agent.AbstractLttngAgent; class SessiondListLoggersCommand implements ISessiondCommand { @Override - public LttngAgentResponse execute(AbstractLttngAgent agent) { + public LttngAgentResponse execute(ILttngTcpClientListener agent) { final List loggerList = new ArrayList(); int dataSize = 0; -- 2.34.1